blob: 8953490034f75b744b42f5458f7512d92ce21436 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectImage.cpp ----------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectImage.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Greg Clayton63094e02010-06-23 01:19:29 +000016#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/FileSpec.h"
Greg Clayton63094e02010-06-23 01:19:29 +000018#include "lldb/Core/Module.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Core/RegularExpression.h"
20#include "lldb/Core/Stream.h"
Greg Clayton63094e02010-06-23 01:19:29 +000021#include "lldb/Interpreter/Args.h"
22#include "lldb/Interpreter/Options.h"
23#include "lldb/Interpreter/CommandCompletions.h"
24#include "lldb/Interpreter/CommandInterpreter.h"
25#include "lldb/Interpreter/CommandReturnObject.h"
26#include "lldb/Symbol/LineTable.h"
27#include "lldb/Symbol/ObjectFile.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028#include "lldb/Symbol/SymbolFile.h"
29#include "lldb/Symbol/SymbolVendor.h"
Chris Lattner24943d22010-06-08 16:52:24 +000030#include "lldb/Target/Process.h"
31#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000032
33using namespace lldb;
34using namespace lldb_private;
35
36//----------------------------------------------------------------------
37// Static Helper functions
38//----------------------------------------------------------------------
39static void
40DumpModuleArchitecture (Stream &strm, Module *module, uint32_t width)
41{
42 if (module)
43 {
44 if (width)
45 strm.Printf("%-*s", width, module->GetArchitecture().AsCString());
46 else
47 strm.PutCString(module->GetArchitecture().AsCString());
48 }
49}
50
51static void
52DumpModuleUUID (Stream &strm, Module *module)
53{
54 module->GetUUID().Dump (&strm);
55}
56
57static uint32_t
58DumpCompileUnitLineTable
59(
Greg Clayton63094e02010-06-23 01:19:29 +000060 CommandInterpreter &interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +000061 Stream &strm,
62 Module *module,
63 const FileSpec &file_spec,
64 bool load_addresses
65)
66{
67 uint32_t num_matches = 0;
68 if (module)
69 {
70 SymbolContextList sc_list;
71 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
72 0,
73 false,
74 eSymbolContextCompUnit,
75 sc_list);
76
77 for (uint32_t i=0; i<num_matches; ++i)
78 {
79 SymbolContext sc;
80 if (sc_list.GetContextAtIndex(i, sc))
81 {
82 if (i > 0)
83 strm << "\n\n";
84
85 strm << "Line table for " << *dynamic_cast<FileSpec*> (sc.comp_unit) << " in `"
86 << module->GetFileSpec().GetFilename() << "\n";
87 LineTable *line_table = sc.comp_unit->GetLineTable();
88 if (line_table)
Greg Clayton63094e02010-06-23 01:19:29 +000089 line_table->GetDescription (&strm,
90 interpreter.GetDebugger().GetExecutionContext().process,
91 lldb::eDescriptionLevelBrief);
Chris Lattner24943d22010-06-08 16:52:24 +000092 else
93 strm << "No line table";
94 }
95 }
96 }
97 return num_matches;
98}
99
100static void
101DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
102{
103 if (file_spec_ptr)
104 {
105 if (width > 0)
106 {
107 char fullpath[PATH_MAX];
108 if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath)))
109 {
110 strm.Printf("%-*s", width, fullpath);
111 return;
112 }
113 }
114 else
115 {
116 file_spec_ptr->Dump(&strm);
117 return;
118 }
119 }
120 // Keep the width spacing correct if things go wrong...
121 if (width > 0)
122 strm.Printf("%-*s", width, "");
123}
124
125static void
126DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
127{
128 if (file_spec_ptr)
129 {
130 if (width > 0)
131 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
132 else
133 file_spec_ptr->GetDirectory().Dump(&strm);
134 return;
135 }
136 // Keep the width spacing correct if things go wrong...
137 if (width > 0)
138 strm.Printf("%-*s", width, "");
139}
140
141static void
142DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
143{
144 if (file_spec_ptr)
145 {
146 if (width > 0)
147 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
148 else
149 file_spec_ptr->GetFilename().Dump(&strm);
150 return;
151 }
152 // Keep the width spacing correct if things go wrong...
153 if (width > 0)
154 strm.Printf("%-*s", width, "");
155}
156
157
158static void
Greg Clayton63094e02010-06-23 01:19:29 +0000159DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module)
Chris Lattner24943d22010-06-08 16:52:24 +0000160{
161 if (module)
162 {
163 ObjectFile *objfile = module->GetObjectFile ();
164 if (objfile)
165 {
166 Symtab *symtab = objfile->GetSymtab();
167 if (symtab)
Greg Clayton63094e02010-06-23 01:19:29 +0000168 symtab->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().process);
Chris Lattner24943d22010-06-08 16:52:24 +0000169 }
170 }
171}
172
173static void
Greg Clayton63094e02010-06-23 01:19:29 +0000174DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
Chris Lattner24943d22010-06-08 16:52:24 +0000175{
176 if (module)
177 {
178 ObjectFile *objfile = module->GetObjectFile ();
179 if (objfile)
180 {
181 SectionList *section_list = objfile->GetSectionList();
182 if (section_list)
Greg Clayton63094e02010-06-23 01:19:29 +0000183 section_list->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().process, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000184 }
185 }
186}
187
188static bool
189DumpModuleSymbolVendor (Stream &strm, Module *module)
190{
191 if (module)
192 {
193 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
194 if (symbol_vendor)
195 {
196 symbol_vendor->Dump(&strm);
197 return true;
198 }
199 }
200 return false;
201}
202
203static bool
Greg Clayton960d6a42010-08-03 00:35:52 +0000204LookupAddressInModule
205(
206 CommandInterpreter &interpreter,
207 Stream &strm,
208 Module *module,
209 uint32_t resolve_mask,
210 lldb::addr_t raw_addr,
211 lldb::addr_t offset,
212 bool verbose
213)
Chris Lattner24943d22010-06-08 16:52:24 +0000214{
215 if (module)
216 {
217 lldb::addr_t addr = raw_addr - offset;
218 Address so_addr;
219 SymbolContext sc;
Greg Clayton63094e02010-06-23 01:19:29 +0000220 Process *process = interpreter.GetDebugger().GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000221 if (process && process->IsAlive())
222 {
223 if (!process->ResolveLoadAddress (addr, so_addr))
224 return false;
225 else if (so_addr.GetModule() != module)
226 return false;
227 }
228 else
229 {
230 if (!module->ResolveFileAddress (addr, so_addr))
231 return false;
232 }
233
234 // If an offset was given, print out the address we ended up looking up
235 if (offset)
236 strm.Printf("0x%llx: ", addr);
237
Greg Clayton63094e02010-06-23 01:19:29 +0000238 ExecutionContextScope *exe_scope = interpreter.GetDebugger().GetExecutionContext().GetBestExecutionContextScope();
Greg Clayton12bec712010-06-28 21:30:43 +0000239 strm.IndentMore();
240 strm.Indent (" Address: ");
241 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
242 strm.EOL();
Greg Clayton70436352010-06-30 23:03:03 +0000243 strm.Indent (" Summary: ");
Chris Lattner24943d22010-06-08 16:52:24 +0000244 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
Greg Clayton70436352010-06-30 23:03:03 +0000245 strm.EOL();
Greg Clayton960d6a42010-08-03 00:35:52 +0000246 // Print out detailed address information when verbose is enabled
247 if (verbose)
248 {
249 if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext))
250 strm.EOL();
251 }
Greg Clayton12bec712010-06-28 21:30:43 +0000252 strm.IndentLess();
Chris Lattner24943d22010-06-08 16:52:24 +0000253 return true;
254 }
255
256 return false;
257}
258
259static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000260LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000261{
262 if (module)
263 {
264 SymbolContext sc;
265
266 ObjectFile *objfile = module->GetObjectFile ();
267 if (objfile)
268 {
269 Symtab *symtab = objfile->GetSymtab();
270 if (symtab)
271 {
272 uint32_t i;
273 std::vector<uint32_t> match_indexes;
274 ConstString symbol_name (name);
275 uint32_t num_matches = 0;
276 if (name_is_regex)
277 {
278 RegularExpression name_regexp(name);
Greg Clayton7c36fa02010-09-11 03:13:28 +0000279 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
280 eSymbolTypeAny,
Chris Lattner24943d22010-06-08 16:52:24 +0000281 match_indexes);
282 }
283 else
284 {
285 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
286 }
287
288
289 if (num_matches > 0)
290 {
291 strm.Indent ();
292 strm.Printf("%u symbols match %s'%s' in ", num_matches,
293 name_is_regex ? "the regular expression " : "", name);
294 DumpFullpath (strm, &module->GetFileSpec(), 0);
295 strm.PutCString(":\n");
296 strm.IndentMore ();
297 Symtab::DumpSymbolHeader (&strm);
298 for (i=0; i < num_matches; ++i)
299 {
300 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
301 strm.Indent ();
Greg Clayton63094e02010-06-23 01:19:29 +0000302 symbol->Dump (&strm, interpreter.GetDebugger().GetExecutionContext().process, i);
Chris Lattner24943d22010-06-08 16:52:24 +0000303 }
304 strm.IndentLess ();
305 return num_matches;
306 }
307 }
308 }
309 }
310 return 0;
311}
312
313
314static void
Greg Clayton63094e02010-06-23 01:19:29 +0000315DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000316{
317 strm.IndentMore ();
318 uint32_t i;
319 const uint32_t num_matches = sc_list.GetSize();
320
321 for (i=0; i<num_matches; ++i)
322 {
323 SymbolContext sc;
324 if (sc_list.GetContextAtIndex(i, sc))
325 {
326 strm.Indent();
327 if (prepend_addr)
328 {
329 if (sc.line_entry.range.GetBaseAddress().IsValid())
330 {
331 lldb::addr_t vm_addr =
Greg Clayton63094e02010-06-23 01:19:29 +0000332 sc.line_entry.range.GetBaseAddress().GetLoadAddress(interpreter.GetDebugger().GetExecutionContext().process);
Chris Lattner24943d22010-06-08 16:52:24 +0000333 int addr_size = sizeof (addr_t);
Greg Clayton63094e02010-06-23 01:19:29 +0000334 Process *process = interpreter.GetDebugger().GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000335 if (process)
336 addr_size = process->GetAddressByteSize();
337 if (vm_addr != LLDB_INVALID_ADDRESS)
338 strm.Address (vm_addr, addr_size);
339 else
340 sc.line_entry.range.GetBaseAddress().Dump (&strm, NULL, Address::DumpStyleSectionNameOffset);
341
342 strm.PutCString(" in ");
343 }
344 }
Greg Clayton72b71582010-09-02 21:44:10 +0000345 sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress(), true, true, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000346 }
347 }
348 strm.IndentLess ();
349}
350
351static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000352LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000353{
354 if (module && name && name[0])
355 {
356 SymbolContextList sc_list;
357
358 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
359 if (symbol_vendor)
360 {
361 uint32_t num_matches = 0;
362 if (name_is_regex)
363 {
364 RegularExpression function_name_regex (name);
365 num_matches = symbol_vendor->FindFunctions(function_name_regex, true, sc_list);
366
367 }
368 else
369 {
370 ConstString function_name(name);
Greg Clayton12bec712010-06-28 21:30:43 +0000371 num_matches = symbol_vendor->FindFunctions(function_name, eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000372 }
373
374 if (num_matches)
375 {
376 strm.Indent ();
377 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
378 DumpFullpath (strm, &module->GetFileSpec(), 0);
379 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000380 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000381 }
382 return num_matches;
383 }
384 }
385 return 0;
386}
387
388static uint32_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000389LookupTypeInModule
390(
391 CommandInterpreter &interpreter,
392 Stream &strm,
393 Module *module,
394 const char *name_cstr,
395 bool name_is_regex
396)
397{
398 if (module && name_cstr && name_cstr[0])
399 {
400 SymbolContextList sc_list;
401
402 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
403 if (symbol_vendor)
404 {
405 TypeList type_list;
406 uint32_t num_matches = 0;
407 SymbolContext sc;
408// if (name_is_regex)
409// {
410// RegularExpression name_regex (name_cstr);
411// num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list);
412// }
413// else
414// {
415 ConstString name(name_cstr);
416 num_matches = symbol_vendor->FindTypes(sc, name, true, UINT32_MAX, type_list);
417// }
418
419 if (num_matches)
420 {
421 strm.Indent ();
422 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
423 DumpFullpath (strm, &module->GetFileSpec(), 0);
424 strm.PutCString(":\n");
425 const uint32_t num_types = type_list.GetSize();
426 for (uint32_t i=0; i<num_types; ++i)
427 {
428 TypeSP type_sp (type_list.GetTypeAtIndex(i));
429 if (type_sp)
430 {
431 // Resolve the clang type so that any forward references
432 // to types that haven't yet been parsed will get parsed.
433 type_sp->GetOpaqueClangQualType ();
434 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
435 }
436 strm.EOL();
437 }
438 }
439 return num_matches;
440 }
441 }
442 return 0;
443}
444
445static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000446LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines)
Chris Lattner24943d22010-06-08 16:52:24 +0000447{
448 if (module && file_spec)
449 {
450 SymbolContextList sc_list;
451 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
452 eSymbolContextEverything, sc_list);
453 if (num_matches > 0)
454 {
455 strm.Indent ();
456 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
457 strm << file_spec;
458 if (line > 0)
459 strm.Printf (":%u", line);
460 strm << " in ";
461 DumpFullpath (strm, &module->GetFileSpec(), 0);
462 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000463 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000464 return num_matches;
465 }
466 }
467 return 0;
468
469}
470
471
472//----------------------------------------------------------------------
473// Image symbol table dumping command
474//----------------------------------------------------------------------
475
476class CommandObjectImageDumpModuleList : public CommandObject
477{
478public:
479
480 CommandObjectImageDumpModuleList (const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000481 const char *help,
482 const char *syntax) :
Chris Lattner24943d22010-06-08 16:52:24 +0000483 CommandObject (name, help, syntax)
484 {
485 }
486
487 virtual
488 ~CommandObjectImageDumpModuleList ()
489 {
490 }
491
492 virtual int
Greg Clayton63094e02010-06-23 01:19:29 +0000493 HandleArgumentCompletion (CommandInterpreter &interpreter,
494 Args &input,
495 int &cursor_index,
496 int &cursor_char_position,
497 OptionElementVector &opt_element_vector,
498 int match_start_point,
499 int max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000500 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000501 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000502 {
503 // Arguments are the standard module completer.
504 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
505 completion_str.erase (cursor_char_position);
506
Greg Clayton63094e02010-06-23 01:19:29 +0000507 CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
508 CommandCompletions::eModuleCompletion,
509 completion_str.c_str(),
510 match_start_point,
511 max_return_elements,
512 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000513 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000514 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000515 return matches.GetSize();
516 }
517};
518
519class CommandObjectImageDumpSourceFileList : public CommandObject
520{
521public:
522
523 CommandObjectImageDumpSourceFileList (const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000524 const char *help,
525 const char *syntax) :
Chris Lattner24943d22010-06-08 16:52:24 +0000526 CommandObject (name, help, syntax)
527 {
528 }
529
530 virtual
531 ~CommandObjectImageDumpSourceFileList ()
532 {
533 }
534
535 virtual int
Greg Clayton63094e02010-06-23 01:19:29 +0000536 HandleArgumentCompletion (CommandInterpreter &interpreter,
537 Args &input,
538 int &cursor_index,
539 int &cursor_char_position,
540 OptionElementVector &opt_element_vector,
541 int match_start_point,
542 int max_return_elements,
Greg Clayton54e7afa2010-07-09 20:39:50 +0000543 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000544 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000545 {
546 // Arguments are the standard source file completer.
547 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
548 completion_str.erase (cursor_char_position);
549
Greg Clayton63094e02010-06-23 01:19:29 +0000550 CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
551 CommandCompletions::eSourceFileCompletion,
552 completion_str.c_str(),
553 match_start_point,
554 max_return_elements,
555 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000556 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000557 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000558 return matches.GetSize();
559 }
560};
561
562
563class CommandObjectImageDumpSymtab : public CommandObjectImageDumpModuleList
564{
565public:
566 CommandObjectImageDumpSymtab () :
567 CommandObjectImageDumpModuleList ("image dump symtab",
568 "Dump the symbol table from one or more executable images.",
569 "image dump symtab [<file1> ...]")
570 {
571 }
572
573 virtual
574 ~CommandObjectImageDumpSymtab ()
575 {
576 }
577
578 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000579 Execute (CommandInterpreter &interpreter,
580 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000581 CommandReturnObject &result)
582 {
Jim Inghamc8332952010-08-26 21:32:51 +0000583 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000584 if (target == NULL)
585 {
586 result.AppendError ("invalid target, set executable file using 'file' command");
587 result.SetStatus (eReturnStatusFailed);
588 return false;
589 }
590 else
591 {
592 uint32_t num_dumped = 0;
593
594 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
595 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
596 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
597
598 if (command.GetArgumentCount() == 0)
599 {
600 // Dump all sections for all modules images
601 const uint32_t num_modules = target->GetImages().GetSize();
602 if (num_modules > 0)
603 {
604 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
605 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
606 {
607 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000608 DumpModuleSymtab (interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000609 }
610 }
611 else
612 {
613 result.AppendError ("the target has no associated executable images");
614 result.SetStatus (eReturnStatusFailed);
615 return false;
616 }
617 }
618 else
619 {
620 // Dump specified images (by basename or fullpath)
621 const char *arg_cstr;
622 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
623 {
624 FileSpec image_file(arg_cstr);
625 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000626 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000627
Greg Clayton661825b2010-06-28 23:51:11 +0000628 // Not found in our module list for our target, check the main
629 // shared module list in case it is a extra file used somewhere
630 // else
631 if (num_matching_modules == 0)
632 num_matching_modules = ModuleList::FindSharedModules (image_file,
633 target->GetArchitecture(),
634 NULL,
635 NULL,
636 matching_modules);
637
Chris Lattner24943d22010-06-08 16:52:24 +0000638 if (num_matching_modules > 0)
639 {
640 for (size_t i=0; i<num_matching_modules; ++i)
641 {
642 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
643 if (image_module)
644 {
645 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000646 DumpModuleSymtab (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000647 }
648 }
649 }
650 else
651 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
652 }
653 }
654
655 if (num_dumped > 0)
656 result.SetStatus (eReturnStatusSuccessFinishResult);
657 else
658 {
659 result.AppendError ("no matching executable images found");
660 result.SetStatus (eReturnStatusFailed);
661 }
662 }
663 return result.Succeeded();
664 }
665
666};
667
668//----------------------------------------------------------------------
669// Image section dumping command
670//----------------------------------------------------------------------
671class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList
672{
673public:
674 CommandObjectImageDumpSections () :
Greg Clayton63094e02010-06-23 01:19:29 +0000675 CommandObjectImageDumpModuleList ("image dump sections",
676 "Dump the sections from one or more executable images.",
677 "image dump sections [<file1> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000678 {
679 }
680
681 virtual
682 ~CommandObjectImageDumpSections ()
683 {
684 }
685
686 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000687 Execute (CommandInterpreter &interpreter,
688 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000689 CommandReturnObject &result)
690 {
Jim Inghamc8332952010-08-26 21:32:51 +0000691 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000692 if (target == NULL)
693 {
694 result.AppendError ("invalid target, set executable file using 'file' command");
695 result.SetStatus (eReturnStatusFailed);
696 return false;
697 }
698 else
699 {
700 uint32_t num_dumped = 0;
701
702 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
703 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
704 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
705
706 if (command.GetArgumentCount() == 0)
707 {
708 // Dump all sections for all modules images
709 const uint32_t num_modules = target->GetImages().GetSize();
710 if (num_modules > 0)
711 {
712 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
713 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
714 {
715 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000716 DumpModuleSections (interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000717 }
718 }
719 else
720 {
721 result.AppendError ("the target has no associated executable images");
722 result.SetStatus (eReturnStatusFailed);
723 return false;
724 }
725 }
726 else
727 {
728 // Dump specified images (by basename or fullpath)
729 const char *arg_cstr;
730 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
731 {
732 FileSpec image_file(arg_cstr);
733 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000734 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000735
Greg Clayton661825b2010-06-28 23:51:11 +0000736 // Not found in our module list for our target, check the main
737 // shared module list in case it is a extra file used somewhere
738 // else
739 if (num_matching_modules == 0)
740 num_matching_modules = ModuleList::FindSharedModules (image_file,
741 target->GetArchitecture(),
742 NULL,
743 NULL,
744 matching_modules);
745
Chris Lattner24943d22010-06-08 16:52:24 +0000746 if (num_matching_modules > 0)
747 {
748 for (size_t i=0; i<num_matching_modules; ++i)
749 {
750 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
751 if (image_module)
752 {
753 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000754 DumpModuleSections (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000755 }
756 }
757 }
758 else
759 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
760 }
761 }
762
763 if (num_dumped > 0)
764 result.SetStatus (eReturnStatusSuccessFinishResult);
765 else
766 {
767 result.AppendError ("no matching executable images found");
768 result.SetStatus (eReturnStatusFailed);
769 }
770 }
771 return result.Succeeded();
772 }
773};
774
775//----------------------------------------------------------------------
776// Image debug symbol dumping command
777//----------------------------------------------------------------------
778class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList
779{
780public:
781 CommandObjectImageDumpSymfile () :
782 CommandObjectImageDumpModuleList ("image dump symfile",
783 "Dump the debug symbol file for one or more executable images.",
784 "image dump symfile [<file1> ...]")
785 {
786 }
787
788 virtual
789 ~CommandObjectImageDumpSymfile ()
790 {
791 }
792
793 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000794 Execute (CommandInterpreter &interpreter,
795 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000796 CommandReturnObject &result)
797 {
Jim Inghamc8332952010-08-26 21:32:51 +0000798 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000799 if (target == NULL)
800 {
801 result.AppendError ("invalid target, set executable file using 'file' command");
802 result.SetStatus (eReturnStatusFailed);
803 return false;
804 }
805 else
806 {
807 uint32_t num_dumped = 0;
808
809 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
810 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
811 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
812
813 if (command.GetArgumentCount() == 0)
814 {
815 // Dump all sections for all modules images
816 const uint32_t num_modules = target->GetImages().GetSize();
817 if (num_modules > 0)
818 {
819 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
820 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
821 {
822 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
823 num_dumped++;
824 }
825 }
826 else
827 {
828 result.AppendError ("the target has no associated executable images");
829 result.SetStatus (eReturnStatusFailed);
830 return false;
831 }
832 }
833 else
834 {
835 // Dump specified images (by basename or fullpath)
836 const char *arg_cstr;
837 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
838 {
839 FileSpec image_file(arg_cstr);
840 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000841 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000842
Greg Clayton661825b2010-06-28 23:51:11 +0000843 // Not found in our module list for our target, check the main
844 // shared module list in case it is a extra file used somewhere
845 // else
846 if (num_matching_modules == 0)
847 num_matching_modules = ModuleList::FindSharedModules (image_file,
848 target->GetArchitecture(),
849 NULL,
850 NULL,
851 matching_modules);
852
Chris Lattner24943d22010-06-08 16:52:24 +0000853 if (num_matching_modules > 0)
854 {
855 for (size_t i=0; i<num_matching_modules; ++i)
856 {
857 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
858 if (image_module)
859 {
860 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
861 num_dumped++;
862 }
863 }
864 }
865 else
866 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
867 }
868 }
869
870 if (num_dumped > 0)
871 result.SetStatus (eReturnStatusSuccessFinishResult);
872 else
873 {
874 result.AppendError ("no matching executable images found");
875 result.SetStatus (eReturnStatusFailed);
876 }
877 }
878 return result.Succeeded();
879 }
880};
881
882//----------------------------------------------------------------------
883// Image debug symbol dumping command
884//----------------------------------------------------------------------
885class CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList
886{
887public:
888 CommandObjectImageDumpLineTable () :
889 CommandObjectImageDumpSourceFileList ("image dump line-table",
890 "Dump the debug symbol file for one or more executable images.",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000891 "image dump line-table <source-file1> [<source-file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000892 {
893 }
894
895 virtual
896 ~CommandObjectImageDumpLineTable ()
897 {
898 }
899
900 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000901 Execute (CommandInterpreter &interpreter,
902 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000903 CommandReturnObject &result)
904 {
Jim Inghamc8332952010-08-26 21:32:51 +0000905 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000906 if (target == NULL)
907 {
908 result.AppendError ("invalid target, set executable file using 'file' command");
909 result.SetStatus (eReturnStatusFailed);
910 return false;
911 }
912 else
913 {
Greg Clayton63094e02010-06-23 01:19:29 +0000914 ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000915 uint32_t total_num_dumped = 0;
916
917 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
918 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
919 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
920
921 if (command.GetArgumentCount() == 0)
922 {
923 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
924 result.SetStatus (eReturnStatusFailed);
925 }
926 else
927 {
928 // Dump specified images (by basename or fullpath)
929 const char *arg_cstr;
930 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
931 {
932 FileSpec file_spec(arg_cstr);
933 const uint32_t num_modules = target->GetImages().GetSize();
934 if (num_modules > 0)
935 {
936 uint32_t num_dumped = 0;
937 for (uint32_t i = 0; i<num_modules; ++i)
938 {
Greg Clayton63094e02010-06-23 01:19:29 +0000939 if (DumpCompileUnitLineTable (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000940 result.GetOutputStream(),
941 target->GetImages().GetModulePointerAtIndex(i),
942 file_spec,
943 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
944 num_dumped++;
945 }
946 if (num_dumped == 0)
947 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
948 else
949 total_num_dumped += num_dumped;
950 }
951 }
952 }
953
954 if (total_num_dumped > 0)
955 result.SetStatus (eReturnStatusSuccessFinishResult);
956 else
957 {
958 result.AppendError ("no source filenames matched any command arguments");
959 result.SetStatus (eReturnStatusFailed);
960 }
961 }
962 return result.Succeeded();
963 }
964};
965
966//----------------------------------------------------------------------
967// Dump multi-word command
968//----------------------------------------------------------------------
969class CommandObjectImageDump : public CommandObjectMultiword
970{
971public:
972
973 //------------------------------------------------------------------
974 // Constructors and Destructors
975 //------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +0000976 CommandObjectImageDump(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +0000977 CommandObjectMultiword ("image dump",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000978 "A set of commands for dumping information about one or more executable images; 'line-table' expects a source file name",
Greg Clayton63094e02010-06-23 01:19:29 +0000979 "image dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000980 {
Greg Clayton63094e02010-06-23 01:19:29 +0000981 LoadSubCommand (interpreter, "symtab", CommandObjectSP (new CommandObjectImageDumpSymtab ()));
982 LoadSubCommand (interpreter, "sections", CommandObjectSP (new CommandObjectImageDumpSections ()));
983 LoadSubCommand (interpreter, "symfile", CommandObjectSP (new CommandObjectImageDumpSymfile ()));
984 LoadSubCommand (interpreter, "line-table", CommandObjectSP (new CommandObjectImageDumpLineTable ()));
Chris Lattner24943d22010-06-08 16:52:24 +0000985 }
986
987 virtual
988 ~CommandObjectImageDump()
989 {
990 }
991};
992
993//----------------------------------------------------------------------
994// List images with associated information
995//----------------------------------------------------------------------
996class CommandObjectImageList : public CommandObject
997{
998public:
999
1000 class CommandOptions : public Options
1001 {
1002 public:
1003
1004 CommandOptions () :
1005 Options(),
1006 m_format_array()
1007 {
1008 }
1009
1010 virtual
1011 ~CommandOptions ()
1012 {
1013 }
1014
1015 virtual Error
1016 SetOptionValue (int option_idx, const char *option_arg)
1017 {
1018 char short_option = (char) m_getopt_table[option_idx].val;
1019 uint32_t width = 0;
1020 if (option_arg)
1021 width = strtoul (option_arg, NULL, 0);
1022 m_format_array.push_back(std::make_pair(short_option, width));
1023 Error error;
1024 return error;
1025 }
1026
1027 void
1028 ResetOptionValues ()
1029 {
1030 Options::ResetOptionValues();
1031 m_format_array.clear();
1032 }
1033
1034 const lldb::OptionDefinition*
1035 GetDefinitions ()
1036 {
1037 return g_option_table;
1038 }
1039
1040 // Options table: Required for subclasses of Options.
1041
1042 static lldb::OptionDefinition g_option_table[];
1043
1044 // Instance variables to hold the values for command options.
1045 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
1046 FormatWidthCollection m_format_array;
1047 };
1048
1049 CommandObjectImageList () :
1050 CommandObject (
1051 "image list",
1052 "List current executable and dependent shared library images.",
1053 "image list [<cmd-options>]")
1054 {
1055 }
1056
1057 virtual
1058 ~CommandObjectImageList ()
1059 {
1060 }
1061
1062 virtual
1063 Options *
1064 GetOptions ()
1065 {
1066 return &m_options;
1067 }
1068
1069 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001070 Execute (CommandInterpreter &interpreter,
1071 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001072 CommandReturnObject &result)
1073 {
Jim Inghamc8332952010-08-26 21:32:51 +00001074 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001075 if (target == NULL)
1076 {
1077 result.AppendError ("invalid target, set executable file using 'file' command");
1078 result.SetStatus (eReturnStatusFailed);
1079 return false;
1080 }
1081 else
1082 {
1083 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1084 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1085 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1086 // Dump all sections for all modules images
1087 const uint32_t num_modules = target->GetImages().GetSize();
1088 if (num_modules > 0)
1089 {
1090 Stream &strm = result.GetOutputStream();
1091
1092 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1093 {
1094 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
1095 strm.Printf("[%3u] ", image_idx);
1096
1097 if (m_options.m_format_array.empty())
1098 {
1099 DumpFullpath(strm, &module->GetFileSpec(), 0);
1100 }
1101 else
1102 {
1103 const size_t num_entries = m_options.m_format_array.size();
1104 for (size_t i=0; i<num_entries; ++i)
1105 {
1106 if (i > 0)
1107 strm.PutChar(' ');
1108 char format_char = m_options.m_format_array[i].first;
1109 uint32_t width = m_options.m_format_array[i].second;
1110 switch (format_char)
1111 {
1112 case 'a':
1113 DumpModuleArchitecture (strm, module, width);
1114 break;
1115
1116 case 'f':
1117 DumpFullpath (strm, &module->GetFileSpec(), width);
1118 break;
1119
1120 case 'd':
1121 DumpDirectory (strm, &module->GetFileSpec(), width);
1122 break;
1123
1124 case 'b':
1125 DumpBasename (strm, &module->GetFileSpec(), width);
1126 break;
1127
1128 case 's':
1129 case 'S':
1130 {
1131 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1132 if (symbol_vendor)
1133 {
1134 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
1135 if (symbol_file)
1136 {
1137 if (format_char == 'S')
1138 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1139 else
1140 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1141 break;
1142 }
1143 }
1144 strm.Printf("%.*s", width, "<NONE>");
1145 }
1146 break;
1147
1148 case 'u':
1149 DumpModuleUUID(strm, module);
1150 break;
1151
1152 default:
1153 break;
1154 }
1155 }
1156 }
1157 strm.EOL();
1158 }
1159 result.SetStatus (eReturnStatusSuccessFinishResult);
1160 }
1161 else
1162 {
1163 result.AppendError ("the target has no associated executable images");
1164 result.SetStatus (eReturnStatusFailed);
1165 return false;
1166 }
1167 }
1168 return result.Succeeded();
1169 }
1170protected:
1171
1172 CommandOptions m_options;
1173};
1174
1175lldb::OptionDefinition
1176CommandObjectImageList::CommandOptions::g_option_table[] =
1177{
Jim Ingham34e9a982010-06-15 18:47:14 +00001178{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, "<width>", "Display the architecture when listing images."},
1179{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, NULL, "Display the UUID when listing images."},
1180{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image object file."},
1181{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, "<width>", "Display the directory with optional width for the image object file."},
1182{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, "<width>", "Display the basename with optional width for the image object file."},
1183{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image symbol file with optional width."},
1184{ LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, "<width>", "Display the basename to the image symbol file with optional width."},
Chris Lattner24943d22010-06-08 16:52:24 +00001185{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1186};
1187
1188
1189
1190//----------------------------------------------------------------------
1191// Lookup information in images
1192//----------------------------------------------------------------------
1193class CommandObjectImageLookup : public CommandObject
1194{
1195public:
1196
1197 enum
1198 {
1199 eLookupTypeInvalid = -1,
1200 eLookupTypeAddress = 0,
1201 eLookupTypeSymbol,
1202 eLookupTypeFileLine, // Line is optional
1203 eLookupTypeFunction,
Greg Clayton960d6a42010-08-03 00:35:52 +00001204 eLookupTypeType,
Chris Lattner24943d22010-06-08 16:52:24 +00001205 kNumLookupTypes
1206 };
1207
1208 class CommandOptions : public Options
1209 {
1210 public:
1211
1212 CommandOptions () :
1213 Options()
1214 {
1215 ResetOptionValues();
1216 }
1217
1218 virtual
1219 ~CommandOptions ()
1220 {
1221 }
1222
1223 virtual Error
1224 SetOptionValue (int option_idx, const char *option_arg)
1225 {
1226 Error error;
1227
1228 char short_option = (char) m_getopt_table[option_idx].val;
1229
1230 switch (short_option)
1231 {
1232 case 'a':
1233 m_type = eLookupTypeAddress;
1234 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1235 if (m_addr == LLDB_INVALID_ADDRESS)
1236 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
1237 break;
1238
1239 case 'o':
1240 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1241 if (m_offset == LLDB_INVALID_ADDRESS)
1242 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
1243 break;
1244
1245 case 's':
1246 m_str = option_arg;
1247 m_type = eLookupTypeSymbol;
1248 break;
1249
1250 case 'f':
1251 m_file.SetFile (option_arg);
1252 m_type = eLookupTypeFileLine;
1253 break;
1254
1255 case 'i':
1256 m_check_inlines = false;
1257 break;
1258
1259 case 'l':
1260 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
1261 if (m_line_number == UINT32_MAX)
1262 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
1263 else if (m_line_number == 0)
1264 error.SetErrorString ("Zero is an invalid line number.");
1265 m_type = eLookupTypeFileLine;
1266 break;
1267
1268 case 'n':
1269 m_str = option_arg;
1270 m_type = eLookupTypeFunction;
1271 break;
1272
Greg Clayton960d6a42010-08-03 00:35:52 +00001273 case 't':
1274 m_str = option_arg;
1275 m_type = eLookupTypeType;
1276 break;
1277
1278 case 'v':
1279 m_verbose = 1;
1280 break;
1281
Chris Lattner24943d22010-06-08 16:52:24 +00001282 case 'r':
1283 m_use_regex = true;
1284 break;
1285 }
1286
1287 return error;
1288 }
1289
1290 void
1291 ResetOptionValues ()
1292 {
1293 Options::ResetOptionValues();
1294 m_type = eLookupTypeInvalid;
1295 m_str.clear();
1296 m_file.Clear();
1297 m_addr = LLDB_INVALID_ADDRESS;
1298 m_offset = 0;
1299 m_line_number = 0;
1300 m_use_regex = false;
1301 m_check_inlines = true;
Greg Clayton960d6a42010-08-03 00:35:52 +00001302 m_verbose = false;
Chris Lattner24943d22010-06-08 16:52:24 +00001303 }
1304
1305 const lldb::OptionDefinition*
1306 GetDefinitions ()
1307 {
1308 return g_option_table;
1309 }
1310
1311 // Options table: Required for subclasses of Options.
1312
1313 static lldb::OptionDefinition g_option_table[];
1314 int m_type; // Should be a eLookupTypeXXX enum after parsing options
1315 std::string m_str; // Holds name lookup
1316 FileSpec m_file; // Files for file lookups
1317 lldb::addr_t m_addr; // Holds the address to lookup
1318 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
1319 uint32_t m_line_number; // Line number for file+line lookups
1320 bool m_use_regex; // Name lookups in m_str are regular expressions.
1321 bool m_check_inlines;// Check for inline entries when looking up by file/line.
Greg Clayton960d6a42010-08-03 00:35:52 +00001322 bool m_verbose; // Enable verbose lookup info
1323
Chris Lattner24943d22010-06-08 16:52:24 +00001324 };
1325
1326 CommandObjectImageLookup () :
1327 CommandObject (
1328 "image lookup",
1329 "Look up information within executable and dependent shared library images.",
1330 "image lookup [<cmd-options>] [<file1>...]")
1331 {
1332 }
1333
1334 virtual
1335 ~CommandObjectImageLookup ()
1336 {
1337 }
1338
1339 virtual
1340 Options *
1341 GetOptions ()
1342 {
1343 return &m_options;
1344 }
1345
1346
1347 bool
Greg Clayton63094e02010-06-23 01:19:29 +00001348 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
Chris Lattner24943d22010-06-08 16:52:24 +00001349 {
1350 switch (m_options.m_type)
1351 {
1352 case eLookupTypeAddress:
1353 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
1354 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001355 if (LookupAddressInModule (interpreter,
1356 result.GetOutputStream(),
1357 module,
1358 eSymbolContextEverything,
1359 m_options.m_addr,
1360 m_options.m_offset,
1361 m_options.m_verbose))
Chris Lattner24943d22010-06-08 16:52:24 +00001362 {
1363 result.SetStatus(eReturnStatusSuccessFinishResult);
1364 return true;
1365 }
1366 }
1367 break;
1368
1369 case eLookupTypeSymbol:
1370 if (!m_options.m_str.empty())
1371 {
Greg Clayton63094e02010-06-23 01:19:29 +00001372 if (LookupSymbolInModule (interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
Chris Lattner24943d22010-06-08 16:52:24 +00001373 {
1374 result.SetStatus(eReturnStatusSuccessFinishResult);
1375 return true;
1376 }
1377 }
1378 break;
1379
1380 case eLookupTypeFileLine:
1381 if (m_options.m_file)
1382 {
1383
Greg Clayton63094e02010-06-23 01:19:29 +00001384 if (LookupFileAndLineInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001385 result.GetOutputStream(),
1386 module,
1387 m_options.m_file,
1388 m_options.m_line_number,
1389 m_options.m_check_inlines))
1390 {
1391 result.SetStatus(eReturnStatusSuccessFinishResult);
1392 return true;
1393 }
1394 }
1395 break;
1396
1397 case eLookupTypeFunction:
1398 if (!m_options.m_str.empty())
1399 {
Greg Clayton63094e02010-06-23 01:19:29 +00001400 if (LookupFunctionInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001401 result.GetOutputStream(),
1402 module,
1403 m_options.m_str.c_str(),
1404 m_options.m_use_regex))
1405 {
1406 result.SetStatus(eReturnStatusSuccessFinishResult);
1407 return true;
1408 }
1409 }
1410 break;
1411
Greg Clayton960d6a42010-08-03 00:35:52 +00001412 case eLookupTypeType:
1413 if (!m_options.m_str.empty())
1414 {
1415 if (LookupTypeInModule (interpreter,
1416 result.GetOutputStream(),
1417 module,
1418 m_options.m_str.c_str(),
1419 m_options.m_use_regex))
1420 {
1421 result.SetStatus(eReturnStatusSuccessFinishResult);
1422 return true;
1423 }
1424 }
1425 break;
1426
Chris Lattner24943d22010-06-08 16:52:24 +00001427 default:
Caroline Tice1d2aefd2010-09-09 06:25:08 +00001428 m_options.GenerateOptionUsage (result.GetErrorStream(), this, interpreter.GetDebugger().GetInstanceName().AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001429 syntax_error = true;
1430 break;
1431 }
1432
1433 result.SetStatus (eReturnStatusFailed);
1434 return false;
1435 }
1436
1437 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001438 Execute (CommandInterpreter &interpreter,
1439 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001440 CommandReturnObject &result)
1441 {
Jim Inghamc8332952010-08-26 21:32:51 +00001442 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001443 if (target == NULL)
1444 {
1445 result.AppendError ("invalid target, set executable file using 'file' command");
1446 result.SetStatus (eReturnStatusFailed);
1447 return false;
1448 }
1449 else
1450 {
1451 bool syntax_error = false;
1452 uint32_t i;
1453 uint32_t num_successful_lookups = 0;
1454 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1455 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1456 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1457 // Dump all sections for all modules images
1458
1459 if (command.GetArgumentCount() == 0)
1460 {
1461 // Dump all sections for all modules images
1462 const uint32_t num_modules = target->GetImages().GetSize();
1463 if (num_modules > 0)
1464 {
1465 for (i = 0; i<num_modules && syntax_error == false; ++i)
1466 {
Greg Clayton63094e02010-06-23 01:19:29 +00001467 if (LookupInModule (interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001468 {
1469 result.GetOutputStream().EOL();
1470 num_successful_lookups++;
1471 }
1472 }
1473 }
1474 else
1475 {
1476 result.AppendError ("the target has no associated executable images");
1477 result.SetStatus (eReturnStatusFailed);
1478 return false;
1479 }
1480 }
1481 else
1482 {
1483 // Dump specified images (by basename or fullpath)
1484 const char *arg_cstr;
1485 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
1486 {
1487 FileSpec image_file(arg_cstr);
1488 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +00001489 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +00001490
Greg Clayton661825b2010-06-28 23:51:11 +00001491 // Not found in our module list for our target, check the main
1492 // shared module list in case it is a extra file used somewhere
1493 // else
1494 if (num_matching_modules == 0)
1495 num_matching_modules = ModuleList::FindSharedModules (image_file,
1496 target->GetArchitecture(),
1497 NULL,
1498 NULL,
1499 matching_modules);
1500
Chris Lattner24943d22010-06-08 16:52:24 +00001501 if (num_matching_modules > 0)
1502 {
Greg Claytonbef15832010-07-14 00:18:15 +00001503 for (size_t j=0; j<num_matching_modules; ++j)
Chris Lattner24943d22010-06-08 16:52:24 +00001504 {
Greg Claytonbef15832010-07-14 00:18:15 +00001505 Module * image_module = matching_modules.GetModulePointerAtIndex(j);
Chris Lattner24943d22010-06-08 16:52:24 +00001506 if (image_module)
1507 {
Greg Clayton63094e02010-06-23 01:19:29 +00001508 if (LookupInModule (interpreter, image_module, result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001509 {
1510 result.GetOutputStream().EOL();
1511 num_successful_lookups++;
1512 }
1513 }
1514 }
1515 }
1516 else
1517 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1518 }
1519 }
1520
1521 if (num_successful_lookups > 0)
1522 result.SetStatus (eReturnStatusSuccessFinishResult);
1523 else
1524 result.SetStatus (eReturnStatusFailed);
1525 }
1526 return result.Succeeded();
1527 }
1528protected:
1529
1530 CommandOptions m_options;
1531};
1532
1533lldb::OptionDefinition
1534CommandObjectImageLookup::CommandOptions::g_option_table[] =
1535{
Greg Clayton960d6a42010-08-03 00:35:52 +00001536{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, "<addr>", "Lookup an address in one or more executable images."},
1537{ LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, "<offset>", "When looking up an address subtract <offset> from any addresses before doing the lookup."},
1538{ LLDB_OPT_SET_2, true, "symbol", 's', required_argument, NULL, 0, "<name>", "Lookup a symbol by name in the symbol tables in one or more executable images."},
1539{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, NULL, "The <name> argument for name lookups are regular expressions."},
1540{ LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, 0, "<file>", "Lookup a file by fullpath or basename in one or more executable images."},
1541{ LLDB_OPT_SET_3, false, "line", 'l', required_argument, NULL, 0, "<line>", "Lookup a line number in a file (must be used in conjunction with --file)."},
1542{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, NULL, "Check inline line entries (must be used in conjunction with --file)."},
1543{ LLDB_OPT_SET_4, true, "function", 'n', required_argument, NULL, 0, "<name>", "Lookup a function by name in the debug symbols in one or more executable images."},
1544{ LLDB_OPT_SET_5, true, "type", 't', required_argument, NULL, 0, "<name>", "Lookup a type by name in the debug symbols in one or more executable images."},
1545{ LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, NULL, "Enable verbose lookup information."},
Chris Lattner24943d22010-06-08 16:52:24 +00001546{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1547};
1548
1549
1550
1551
1552
1553//----------------------------------------------------------------------
1554// CommandObjectImage constructor
1555//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001556CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +00001557 CommandObjectMultiword ("image",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001558 "A set of commands for accessing information for one or more executable images.",
1559 "image <sub-command> ...")
Chris Lattner24943d22010-06-08 16:52:24 +00001560{
Greg Clayton63094e02010-06-23 01:19:29 +00001561 LoadSubCommand (interpreter, "dump", CommandObjectSP (new CommandObjectImageDump (interpreter)));
1562 LoadSubCommand (interpreter, "list", CommandObjectSP (new CommandObjectImageList ()));
1563 LoadSubCommand (interpreter, "lookup", CommandObjectSP (new CommandObjectImageLookup ()));
Chris Lattner24943d22010-06-08 16:52:24 +00001564}
1565
1566//----------------------------------------------------------------------
1567// Destructor
1568//----------------------------------------------------------------------
1569CommandObjectImage::~CommandObjectImage()
1570{
1571}
1572