blob: 0bf339c016587d8900be8c380027ccdf00ebf6e5 [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 Clayton63094e02010-06-23 01:19:29 +0000204LookupAddressInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, uint32_t resolve_mask, lldb::addr_t raw_addr, lldb::addr_t offset)
Chris Lattner24943d22010-06-08 16:52:24 +0000205{
206 if (module)
207 {
208 lldb::addr_t addr = raw_addr - offset;
209 Address so_addr;
210 SymbolContext sc;
Greg Clayton63094e02010-06-23 01:19:29 +0000211 Process *process = interpreter.GetDebugger().GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000212 if (process && process->IsAlive())
213 {
214 if (!process->ResolveLoadAddress (addr, so_addr))
215 return false;
216 else if (so_addr.GetModule() != module)
217 return false;
218 }
219 else
220 {
221 if (!module->ResolveFileAddress (addr, so_addr))
222 return false;
223 }
224
225 // If an offset was given, print out the address we ended up looking up
226 if (offset)
227 strm.Printf("0x%llx: ", addr);
228
Greg Clayton63094e02010-06-23 01:19:29 +0000229 ExecutionContextScope *exe_scope = interpreter.GetDebugger().GetExecutionContext().GetBestExecutionContextScope();
Greg Clayton12bec712010-06-28 21:30:43 +0000230 strm.IndentMore();
231 strm.Indent (" Address: ");
232 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
233 strm.EOL();
Chris Lattner24943d22010-06-08 16:52:24 +0000234 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
Greg Clayton12bec712010-06-28 21:30:43 +0000235 strm.IndentLess();
Chris Lattner24943d22010-06-08 16:52:24 +0000236 return true;
237 }
238
239 return false;
240}
241
242static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000243LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000244{
245 if (module)
246 {
247 SymbolContext sc;
248
249 ObjectFile *objfile = module->GetObjectFile ();
250 if (objfile)
251 {
252 Symtab *symtab = objfile->GetSymtab();
253 if (symtab)
254 {
255 uint32_t i;
256 std::vector<uint32_t> match_indexes;
257 ConstString symbol_name (name);
258 uint32_t num_matches = 0;
259 if (name_is_regex)
260 {
261 RegularExpression name_regexp(name);
262 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp, eSymbolTypeAny,
263 match_indexes);
264 }
265 else
266 {
267 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
268 }
269
270
271 if (num_matches > 0)
272 {
273 strm.Indent ();
274 strm.Printf("%u symbols match %s'%s' in ", num_matches,
275 name_is_regex ? "the regular expression " : "", name);
276 DumpFullpath (strm, &module->GetFileSpec(), 0);
277 strm.PutCString(":\n");
278 strm.IndentMore ();
279 Symtab::DumpSymbolHeader (&strm);
280 for (i=0; i < num_matches; ++i)
281 {
282 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
283 strm.Indent ();
Greg Clayton63094e02010-06-23 01:19:29 +0000284 symbol->Dump (&strm, interpreter.GetDebugger().GetExecutionContext().process, i);
Chris Lattner24943d22010-06-08 16:52:24 +0000285 }
286 strm.IndentLess ();
287 return num_matches;
288 }
289 }
290 }
291 }
292 return 0;
293}
294
295
296static void
Greg Clayton63094e02010-06-23 01:19:29 +0000297DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000298{
299 strm.IndentMore ();
300 uint32_t i;
301 const uint32_t num_matches = sc_list.GetSize();
302
303 for (i=0; i<num_matches; ++i)
304 {
305 SymbolContext sc;
306 if (sc_list.GetContextAtIndex(i, sc))
307 {
308 strm.Indent();
309 if (prepend_addr)
310 {
311 if (sc.line_entry.range.GetBaseAddress().IsValid())
312 {
313 lldb::addr_t vm_addr =
Greg Clayton63094e02010-06-23 01:19:29 +0000314 sc.line_entry.range.GetBaseAddress().GetLoadAddress(interpreter.GetDebugger().GetExecutionContext().process);
Chris Lattner24943d22010-06-08 16:52:24 +0000315 int addr_size = sizeof (addr_t);
Greg Clayton63094e02010-06-23 01:19:29 +0000316 Process *process = interpreter.GetDebugger().GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000317 if (process)
318 addr_size = process->GetAddressByteSize();
319 if (vm_addr != LLDB_INVALID_ADDRESS)
320 strm.Address (vm_addr, addr_size);
321 else
322 sc.line_entry.range.GetBaseAddress().Dump (&strm, NULL, Address::DumpStyleSectionNameOffset);
323
324 strm.PutCString(" in ");
325 }
326 }
Greg Clayton63094e02010-06-23 01:19:29 +0000327 sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress());
Chris Lattner24943d22010-06-08 16:52:24 +0000328 }
329 }
330 strm.IndentLess ();
331}
332
333static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000334LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000335{
336 if (module && name && name[0])
337 {
338 SymbolContextList sc_list;
339
340 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
341 if (symbol_vendor)
342 {
343 uint32_t num_matches = 0;
344 if (name_is_regex)
345 {
346 RegularExpression function_name_regex (name);
347 num_matches = symbol_vendor->FindFunctions(function_name_regex, true, sc_list);
348
349 }
350 else
351 {
352 ConstString function_name(name);
Greg Clayton12bec712010-06-28 21:30:43 +0000353 num_matches = symbol_vendor->FindFunctions(function_name, eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000354 }
355
356 if (num_matches)
357 {
358 strm.Indent ();
359 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
360 DumpFullpath (strm, &module->GetFileSpec(), 0);
361 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000362 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000363 }
364 return num_matches;
365 }
366 }
367 return 0;
368}
369
370static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000371LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines)
Chris Lattner24943d22010-06-08 16:52:24 +0000372{
373 if (module && file_spec)
374 {
375 SymbolContextList sc_list;
376 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
377 eSymbolContextEverything, sc_list);
378 if (num_matches > 0)
379 {
380 strm.Indent ();
381 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
382 strm << file_spec;
383 if (line > 0)
384 strm.Printf (":%u", line);
385 strm << " in ";
386 DumpFullpath (strm, &module->GetFileSpec(), 0);
387 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000388 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000389 return num_matches;
390 }
391 }
392 return 0;
393
394}
395
396
397//----------------------------------------------------------------------
398// Image symbol table dumping command
399//----------------------------------------------------------------------
400
401class CommandObjectImageDumpModuleList : public CommandObject
402{
403public:
404
405 CommandObjectImageDumpModuleList (const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000406 const char *help,
407 const char *syntax) :
Chris Lattner24943d22010-06-08 16:52:24 +0000408 CommandObject (name, help, syntax)
409 {
410 }
411
412 virtual
413 ~CommandObjectImageDumpModuleList ()
414 {
415 }
416
417 virtual int
Greg Clayton63094e02010-06-23 01:19:29 +0000418 HandleArgumentCompletion (CommandInterpreter &interpreter,
419 Args &input,
420 int &cursor_index,
421 int &cursor_char_position,
422 OptionElementVector &opt_element_vector,
423 int match_start_point,
424 int max_return_elements,
425 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000426 {
427 // Arguments are the standard module completer.
428 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
429 completion_str.erase (cursor_char_position);
430
Greg Clayton63094e02010-06-23 01:19:29 +0000431 CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
432 CommandCompletions::eModuleCompletion,
433 completion_str.c_str(),
434 match_start_point,
435 max_return_elements,
436 NULL,
437 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000438 return matches.GetSize();
439 }
440};
441
442class CommandObjectImageDumpSourceFileList : public CommandObject
443{
444public:
445
446 CommandObjectImageDumpSourceFileList (const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000447 const char *help,
448 const char *syntax) :
Chris Lattner24943d22010-06-08 16:52:24 +0000449 CommandObject (name, help, syntax)
450 {
451 }
452
453 virtual
454 ~CommandObjectImageDumpSourceFileList ()
455 {
456 }
457
458 virtual int
Greg Clayton63094e02010-06-23 01:19:29 +0000459 HandleArgumentCompletion (CommandInterpreter &interpreter,
460 Args &input,
461 int &cursor_index,
462 int &cursor_char_position,
463 OptionElementVector &opt_element_vector,
464 int match_start_point,
465 int max_return_elements,
466 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000467 {
468 // Arguments are the standard source file completer.
469 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
470 completion_str.erase (cursor_char_position);
471
Greg Clayton63094e02010-06-23 01:19:29 +0000472 CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
473 CommandCompletions::eSourceFileCompletion,
474 completion_str.c_str(),
475 match_start_point,
476 max_return_elements,
477 NULL,
478 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000479 return matches.GetSize();
480 }
481};
482
483
484class CommandObjectImageDumpSymtab : public CommandObjectImageDumpModuleList
485{
486public:
487 CommandObjectImageDumpSymtab () :
488 CommandObjectImageDumpModuleList ("image dump symtab",
489 "Dump the symbol table from one or more executable images.",
490 "image dump symtab [<file1> ...]")
491 {
492 }
493
494 virtual
495 ~CommandObjectImageDumpSymtab ()
496 {
497 }
498
499 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000500 Execute (CommandInterpreter &interpreter,
501 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000502 CommandReturnObject &result)
503 {
Greg Clayton63094e02010-06-23 01:19:29 +0000504 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000505 if (target == NULL)
506 {
507 result.AppendError ("invalid target, set executable file using 'file' command");
508 result.SetStatus (eReturnStatusFailed);
509 return false;
510 }
511 else
512 {
513 uint32_t num_dumped = 0;
514
515 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
516 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
517 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
518
519 if (command.GetArgumentCount() == 0)
520 {
521 // Dump all sections for all modules images
522 const uint32_t num_modules = target->GetImages().GetSize();
523 if (num_modules > 0)
524 {
525 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
526 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
527 {
528 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000529 DumpModuleSymtab (interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000530 }
531 }
532 else
533 {
534 result.AppendError ("the target has no associated executable images");
535 result.SetStatus (eReturnStatusFailed);
536 return false;
537 }
538 }
539 else
540 {
541 // Dump specified images (by basename or fullpath)
542 const char *arg_cstr;
543 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
544 {
545 FileSpec image_file(arg_cstr);
546 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000547 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000548
Greg Clayton661825b2010-06-28 23:51:11 +0000549 // Not found in our module list for our target, check the main
550 // shared module list in case it is a extra file used somewhere
551 // else
552 if (num_matching_modules == 0)
553 num_matching_modules = ModuleList::FindSharedModules (image_file,
554 target->GetArchitecture(),
555 NULL,
556 NULL,
557 matching_modules);
558
Chris Lattner24943d22010-06-08 16:52:24 +0000559 if (num_matching_modules > 0)
560 {
561 for (size_t i=0; i<num_matching_modules; ++i)
562 {
563 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
564 if (image_module)
565 {
566 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000567 DumpModuleSymtab (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000568 }
569 }
570 }
571 else
572 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
573 }
574 }
575
576 if (num_dumped > 0)
577 result.SetStatus (eReturnStatusSuccessFinishResult);
578 else
579 {
580 result.AppendError ("no matching executable images found");
581 result.SetStatus (eReturnStatusFailed);
582 }
583 }
584 return result.Succeeded();
585 }
586
587};
588
589//----------------------------------------------------------------------
590// Image section dumping command
591//----------------------------------------------------------------------
592class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList
593{
594public:
595 CommandObjectImageDumpSections () :
Greg Clayton63094e02010-06-23 01:19:29 +0000596 CommandObjectImageDumpModuleList ("image dump sections",
597 "Dump the sections from one or more executable images.",
598 "image dump sections [<file1> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000599 {
600 }
601
602 virtual
603 ~CommandObjectImageDumpSections ()
604 {
605 }
606
607 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000608 Execute (CommandInterpreter &interpreter,
609 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000610 CommandReturnObject &result)
611 {
Greg Clayton63094e02010-06-23 01:19:29 +0000612 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000613 if (target == NULL)
614 {
615 result.AppendError ("invalid target, set executable file using 'file' command");
616 result.SetStatus (eReturnStatusFailed);
617 return false;
618 }
619 else
620 {
621 uint32_t num_dumped = 0;
622
623 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
624 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
625 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
626
627 if (command.GetArgumentCount() == 0)
628 {
629 // Dump all sections for all modules images
630 const uint32_t num_modules = target->GetImages().GetSize();
631 if (num_modules > 0)
632 {
633 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
634 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
635 {
636 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000637 DumpModuleSections (interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000638 }
639 }
640 else
641 {
642 result.AppendError ("the target has no associated executable images");
643 result.SetStatus (eReturnStatusFailed);
644 return false;
645 }
646 }
647 else
648 {
649 // Dump specified images (by basename or fullpath)
650 const char *arg_cstr;
651 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
652 {
653 FileSpec image_file(arg_cstr);
654 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000655 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000656
Greg Clayton661825b2010-06-28 23:51:11 +0000657 // Not found in our module list for our target, check the main
658 // shared module list in case it is a extra file used somewhere
659 // else
660 if (num_matching_modules == 0)
661 num_matching_modules = ModuleList::FindSharedModules (image_file,
662 target->GetArchitecture(),
663 NULL,
664 NULL,
665 matching_modules);
666
Chris Lattner24943d22010-06-08 16:52:24 +0000667 if (num_matching_modules > 0)
668 {
669 for (size_t i=0; i<num_matching_modules; ++i)
670 {
671 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
672 if (image_module)
673 {
674 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000675 DumpModuleSections (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000676 }
677 }
678 }
679 else
680 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
681 }
682 }
683
684 if (num_dumped > 0)
685 result.SetStatus (eReturnStatusSuccessFinishResult);
686 else
687 {
688 result.AppendError ("no matching executable images found");
689 result.SetStatus (eReturnStatusFailed);
690 }
691 }
692 return result.Succeeded();
693 }
694};
695
696//----------------------------------------------------------------------
697// Image debug symbol dumping command
698//----------------------------------------------------------------------
699class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList
700{
701public:
702 CommandObjectImageDumpSymfile () :
703 CommandObjectImageDumpModuleList ("image dump symfile",
704 "Dump the debug symbol file for one or more executable images.",
705 "image dump symfile [<file1> ...]")
706 {
707 }
708
709 virtual
710 ~CommandObjectImageDumpSymfile ()
711 {
712 }
713
714 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000715 Execute (CommandInterpreter &interpreter,
716 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000717 CommandReturnObject &result)
718 {
Greg Clayton63094e02010-06-23 01:19:29 +0000719 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000720 if (target == NULL)
721 {
722 result.AppendError ("invalid target, set executable file using 'file' command");
723 result.SetStatus (eReturnStatusFailed);
724 return false;
725 }
726 else
727 {
728 uint32_t num_dumped = 0;
729
730 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
731 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
732 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
733
734 if (command.GetArgumentCount() == 0)
735 {
736 // Dump all sections for all modules images
737 const uint32_t num_modules = target->GetImages().GetSize();
738 if (num_modules > 0)
739 {
740 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
741 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
742 {
743 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
744 num_dumped++;
745 }
746 }
747 else
748 {
749 result.AppendError ("the target has no associated executable images");
750 result.SetStatus (eReturnStatusFailed);
751 return false;
752 }
753 }
754 else
755 {
756 // Dump specified images (by basename or fullpath)
757 const char *arg_cstr;
758 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
759 {
760 FileSpec image_file(arg_cstr);
761 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000762 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000763
Greg Clayton661825b2010-06-28 23:51:11 +0000764 // Not found in our module list for our target, check the main
765 // shared module list in case it is a extra file used somewhere
766 // else
767 if (num_matching_modules == 0)
768 num_matching_modules = ModuleList::FindSharedModules (image_file,
769 target->GetArchitecture(),
770 NULL,
771 NULL,
772 matching_modules);
773
Chris Lattner24943d22010-06-08 16:52:24 +0000774 if (num_matching_modules > 0)
775 {
776 for (size_t i=0; i<num_matching_modules; ++i)
777 {
778 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
779 if (image_module)
780 {
781 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
782 num_dumped++;
783 }
784 }
785 }
786 else
787 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
788 }
789 }
790
791 if (num_dumped > 0)
792 result.SetStatus (eReturnStatusSuccessFinishResult);
793 else
794 {
795 result.AppendError ("no matching executable images found");
796 result.SetStatus (eReturnStatusFailed);
797 }
798 }
799 return result.Succeeded();
800 }
801};
802
803//----------------------------------------------------------------------
804// Image debug symbol dumping command
805//----------------------------------------------------------------------
806class CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList
807{
808public:
809 CommandObjectImageDumpLineTable () :
810 CommandObjectImageDumpSourceFileList ("image dump line-table",
811 "Dump the debug symbol file for one or more executable images.",
812 "image dump line-table <file1> [<file2> ...]")
813 {
814 }
815
816 virtual
817 ~CommandObjectImageDumpLineTable ()
818 {
819 }
820
821 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000822 Execute (CommandInterpreter &interpreter,
823 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000824 CommandReturnObject &result)
825 {
Greg Clayton63094e02010-06-23 01:19:29 +0000826 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000827 if (target == NULL)
828 {
829 result.AppendError ("invalid target, set executable file using 'file' command");
830 result.SetStatus (eReturnStatusFailed);
831 return false;
832 }
833 else
834 {
Greg Clayton63094e02010-06-23 01:19:29 +0000835 ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000836 uint32_t total_num_dumped = 0;
837
838 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
839 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
840 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
841
842 if (command.GetArgumentCount() == 0)
843 {
844 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
845 result.SetStatus (eReturnStatusFailed);
846 }
847 else
848 {
849 // Dump specified images (by basename or fullpath)
850 const char *arg_cstr;
851 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
852 {
853 FileSpec file_spec(arg_cstr);
854 const uint32_t num_modules = target->GetImages().GetSize();
855 if (num_modules > 0)
856 {
857 uint32_t num_dumped = 0;
858 for (uint32_t i = 0; i<num_modules; ++i)
859 {
Greg Clayton63094e02010-06-23 01:19:29 +0000860 if (DumpCompileUnitLineTable (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000861 result.GetOutputStream(),
862 target->GetImages().GetModulePointerAtIndex(i),
863 file_spec,
864 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
865 num_dumped++;
866 }
867 if (num_dumped == 0)
868 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
869 else
870 total_num_dumped += num_dumped;
871 }
872 }
873 }
874
875 if (total_num_dumped > 0)
876 result.SetStatus (eReturnStatusSuccessFinishResult);
877 else
878 {
879 result.AppendError ("no source filenames matched any command arguments");
880 result.SetStatus (eReturnStatusFailed);
881 }
882 }
883 return result.Succeeded();
884 }
885};
886
887//----------------------------------------------------------------------
888// Dump multi-word command
889//----------------------------------------------------------------------
890class CommandObjectImageDump : public CommandObjectMultiword
891{
892public:
893
894 //------------------------------------------------------------------
895 // Constructors and Destructors
896 //------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +0000897 CommandObjectImageDump(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +0000898 CommandObjectMultiword ("image dump",
Greg Clayton63094e02010-06-23 01:19:29 +0000899 "Dumps information in one or more executable images; 'line-table' expects a source file name",
900 "image dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000901 {
Greg Clayton63094e02010-06-23 01:19:29 +0000902 LoadSubCommand (interpreter, "symtab", CommandObjectSP (new CommandObjectImageDumpSymtab ()));
903 LoadSubCommand (interpreter, "sections", CommandObjectSP (new CommandObjectImageDumpSections ()));
904 LoadSubCommand (interpreter, "symfile", CommandObjectSP (new CommandObjectImageDumpSymfile ()));
905 LoadSubCommand (interpreter, "line-table", CommandObjectSP (new CommandObjectImageDumpLineTable ()));
Chris Lattner24943d22010-06-08 16:52:24 +0000906 }
907
908 virtual
909 ~CommandObjectImageDump()
910 {
911 }
912};
913
914//----------------------------------------------------------------------
915// List images with associated information
916//----------------------------------------------------------------------
917class CommandObjectImageList : public CommandObject
918{
919public:
920
921 class CommandOptions : public Options
922 {
923 public:
924
925 CommandOptions () :
926 Options(),
927 m_format_array()
928 {
929 }
930
931 virtual
932 ~CommandOptions ()
933 {
934 }
935
936 virtual Error
937 SetOptionValue (int option_idx, const char *option_arg)
938 {
939 char short_option = (char) m_getopt_table[option_idx].val;
940 uint32_t width = 0;
941 if (option_arg)
942 width = strtoul (option_arg, NULL, 0);
943 m_format_array.push_back(std::make_pair(short_option, width));
944 Error error;
945 return error;
946 }
947
948 void
949 ResetOptionValues ()
950 {
951 Options::ResetOptionValues();
952 m_format_array.clear();
953 }
954
955 const lldb::OptionDefinition*
956 GetDefinitions ()
957 {
958 return g_option_table;
959 }
960
961 // Options table: Required for subclasses of Options.
962
963 static lldb::OptionDefinition g_option_table[];
964
965 // Instance variables to hold the values for command options.
966 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
967 FormatWidthCollection m_format_array;
968 };
969
970 CommandObjectImageList () :
971 CommandObject (
972 "image list",
973 "List current executable and dependent shared library images.",
974 "image list [<cmd-options>]")
975 {
976 }
977
978 virtual
979 ~CommandObjectImageList ()
980 {
981 }
982
983 virtual
984 Options *
985 GetOptions ()
986 {
987 return &m_options;
988 }
989
990 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000991 Execute (CommandInterpreter &interpreter,
992 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000993 CommandReturnObject &result)
994 {
Greg Clayton63094e02010-06-23 01:19:29 +0000995 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000996 if (target == NULL)
997 {
998 result.AppendError ("invalid target, set executable file using 'file' command");
999 result.SetStatus (eReturnStatusFailed);
1000 return false;
1001 }
1002 else
1003 {
1004 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1005 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1006 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1007 // Dump all sections for all modules images
1008 const uint32_t num_modules = target->GetImages().GetSize();
1009 if (num_modules > 0)
1010 {
1011 Stream &strm = result.GetOutputStream();
1012
1013 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1014 {
1015 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
1016 strm.Printf("[%3u] ", image_idx);
1017
1018 if (m_options.m_format_array.empty())
1019 {
1020 DumpFullpath(strm, &module->GetFileSpec(), 0);
1021 }
1022 else
1023 {
1024 const size_t num_entries = m_options.m_format_array.size();
1025 for (size_t i=0; i<num_entries; ++i)
1026 {
1027 if (i > 0)
1028 strm.PutChar(' ');
1029 char format_char = m_options.m_format_array[i].first;
1030 uint32_t width = m_options.m_format_array[i].second;
1031 switch (format_char)
1032 {
1033 case 'a':
1034 DumpModuleArchitecture (strm, module, width);
1035 break;
1036
1037 case 'f':
1038 DumpFullpath (strm, &module->GetFileSpec(), width);
1039 break;
1040
1041 case 'd':
1042 DumpDirectory (strm, &module->GetFileSpec(), width);
1043 break;
1044
1045 case 'b':
1046 DumpBasename (strm, &module->GetFileSpec(), width);
1047 break;
1048
1049 case 's':
1050 case 'S':
1051 {
1052 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1053 if (symbol_vendor)
1054 {
1055 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
1056 if (symbol_file)
1057 {
1058 if (format_char == 'S')
1059 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1060 else
1061 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1062 break;
1063 }
1064 }
1065 strm.Printf("%.*s", width, "<NONE>");
1066 }
1067 break;
1068
1069 case 'u':
1070 DumpModuleUUID(strm, module);
1071 break;
1072
1073 default:
1074 break;
1075 }
1076 }
1077 }
1078 strm.EOL();
1079 }
1080 result.SetStatus (eReturnStatusSuccessFinishResult);
1081 }
1082 else
1083 {
1084 result.AppendError ("the target has no associated executable images");
1085 result.SetStatus (eReturnStatusFailed);
1086 return false;
1087 }
1088 }
1089 return result.Succeeded();
1090 }
1091protected:
1092
1093 CommandOptions m_options;
1094};
1095
1096lldb::OptionDefinition
1097CommandObjectImageList::CommandOptions::g_option_table[] =
1098{
Jim Ingham34e9a982010-06-15 18:47:14 +00001099{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, "<width>", "Display the architecture when listing images."},
1100{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, NULL, "Display the UUID when listing images."},
1101{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image object file."},
1102{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, "<width>", "Display the directory with optional width for the image object file."},
1103{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, "<width>", "Display the basename with optional width for the image object file."},
1104{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image symbol file with optional width."},
1105{ 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 +00001106{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1107};
1108
1109
1110
1111//----------------------------------------------------------------------
1112// Lookup information in images
1113//----------------------------------------------------------------------
1114class CommandObjectImageLookup : public CommandObject
1115{
1116public:
1117
1118 enum
1119 {
1120 eLookupTypeInvalid = -1,
1121 eLookupTypeAddress = 0,
1122 eLookupTypeSymbol,
1123 eLookupTypeFileLine, // Line is optional
1124 eLookupTypeFunction,
1125 kNumLookupTypes
1126 };
1127
1128 class CommandOptions : public Options
1129 {
1130 public:
1131
1132 CommandOptions () :
1133 Options()
1134 {
1135 ResetOptionValues();
1136 }
1137
1138 virtual
1139 ~CommandOptions ()
1140 {
1141 }
1142
1143 virtual Error
1144 SetOptionValue (int option_idx, const char *option_arg)
1145 {
1146 Error error;
1147
1148 char short_option = (char) m_getopt_table[option_idx].val;
1149
1150 switch (short_option)
1151 {
1152 case 'a':
1153 m_type = eLookupTypeAddress;
1154 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1155 if (m_addr == LLDB_INVALID_ADDRESS)
1156 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
1157 break;
1158
1159 case 'o':
1160 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1161 if (m_offset == LLDB_INVALID_ADDRESS)
1162 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
1163 break;
1164
1165 case 's':
1166 m_str = option_arg;
1167 m_type = eLookupTypeSymbol;
1168 break;
1169
1170 case 'f':
1171 m_file.SetFile (option_arg);
1172 m_type = eLookupTypeFileLine;
1173 break;
1174
1175 case 'i':
1176 m_check_inlines = false;
1177 break;
1178
1179 case 'l':
1180 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
1181 if (m_line_number == UINT32_MAX)
1182 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
1183 else if (m_line_number == 0)
1184 error.SetErrorString ("Zero is an invalid line number.");
1185 m_type = eLookupTypeFileLine;
1186 break;
1187
1188 case 'n':
1189 m_str = option_arg;
1190 m_type = eLookupTypeFunction;
1191 break;
1192
1193 case 'r':
1194 m_use_regex = true;
1195 break;
1196 }
1197
1198 return error;
1199 }
1200
1201 void
1202 ResetOptionValues ()
1203 {
1204 Options::ResetOptionValues();
1205 m_type = eLookupTypeInvalid;
1206 m_str.clear();
1207 m_file.Clear();
1208 m_addr = LLDB_INVALID_ADDRESS;
1209 m_offset = 0;
1210 m_line_number = 0;
1211 m_use_regex = false;
1212 m_check_inlines = true;
1213 }
1214
1215 const lldb::OptionDefinition*
1216 GetDefinitions ()
1217 {
1218 return g_option_table;
1219 }
1220
1221 // Options table: Required for subclasses of Options.
1222
1223 static lldb::OptionDefinition g_option_table[];
1224 int m_type; // Should be a eLookupTypeXXX enum after parsing options
1225 std::string m_str; // Holds name lookup
1226 FileSpec m_file; // Files for file lookups
1227 lldb::addr_t m_addr; // Holds the address to lookup
1228 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
1229 uint32_t m_line_number; // Line number for file+line lookups
1230 bool m_use_regex; // Name lookups in m_str are regular expressions.
1231 bool m_check_inlines;// Check for inline entries when looking up by file/line.
1232 };
1233
1234 CommandObjectImageLookup () :
1235 CommandObject (
1236 "image lookup",
1237 "Look up information within executable and dependent shared library images.",
1238 "image lookup [<cmd-options>] [<file1>...]")
1239 {
1240 }
1241
1242 virtual
1243 ~CommandObjectImageLookup ()
1244 {
1245 }
1246
1247 virtual
1248 Options *
1249 GetOptions ()
1250 {
1251 return &m_options;
1252 }
1253
1254
1255 bool
Greg Clayton63094e02010-06-23 01:19:29 +00001256 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
Chris Lattner24943d22010-06-08 16:52:24 +00001257 {
1258 switch (m_options.m_type)
1259 {
1260 case eLookupTypeAddress:
1261 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
1262 {
Greg Clayton63094e02010-06-23 01:19:29 +00001263 if (LookupAddressInModule (interpreter, result.GetOutputStream(), module, eSymbolContextEverything, m_options.m_addr, m_options.m_offset))
Chris Lattner24943d22010-06-08 16:52:24 +00001264 {
1265 result.SetStatus(eReturnStatusSuccessFinishResult);
1266 return true;
1267 }
1268 }
1269 break;
1270
1271 case eLookupTypeSymbol:
1272 if (!m_options.m_str.empty())
1273 {
Greg Clayton63094e02010-06-23 01:19:29 +00001274 if (LookupSymbolInModule (interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
Chris Lattner24943d22010-06-08 16:52:24 +00001275 {
1276 result.SetStatus(eReturnStatusSuccessFinishResult);
1277 return true;
1278 }
1279 }
1280 break;
1281
1282 case eLookupTypeFileLine:
1283 if (m_options.m_file)
1284 {
1285
Greg Clayton63094e02010-06-23 01:19:29 +00001286 if (LookupFileAndLineInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001287 result.GetOutputStream(),
1288 module,
1289 m_options.m_file,
1290 m_options.m_line_number,
1291 m_options.m_check_inlines))
1292 {
1293 result.SetStatus(eReturnStatusSuccessFinishResult);
1294 return true;
1295 }
1296 }
1297 break;
1298
1299 case eLookupTypeFunction:
1300 if (!m_options.m_str.empty())
1301 {
Greg Clayton63094e02010-06-23 01:19:29 +00001302 if (LookupFunctionInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001303 result.GetOutputStream(),
1304 module,
1305 m_options.m_str.c_str(),
1306 m_options.m_use_regex))
1307 {
1308 result.SetStatus(eReturnStatusSuccessFinishResult);
1309 return true;
1310 }
1311 }
1312 break;
1313
1314 default:
1315 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
1316 syntax_error = true;
1317 break;
1318 }
1319
1320 result.SetStatus (eReturnStatusFailed);
1321 return false;
1322 }
1323
1324 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001325 Execute (CommandInterpreter &interpreter,
1326 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001327 CommandReturnObject &result)
1328 {
Greg Clayton63094e02010-06-23 01:19:29 +00001329 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001330 if (target == NULL)
1331 {
1332 result.AppendError ("invalid target, set executable file using 'file' command");
1333 result.SetStatus (eReturnStatusFailed);
1334 return false;
1335 }
1336 else
1337 {
1338 bool syntax_error = false;
1339 uint32_t i;
1340 uint32_t num_successful_lookups = 0;
1341 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1342 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1343 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1344 // Dump all sections for all modules images
1345
1346 if (command.GetArgumentCount() == 0)
1347 {
1348 // Dump all sections for all modules images
1349 const uint32_t num_modules = target->GetImages().GetSize();
1350 if (num_modules > 0)
1351 {
1352 for (i = 0; i<num_modules && syntax_error == false; ++i)
1353 {
Greg Clayton63094e02010-06-23 01:19:29 +00001354 if (LookupInModule (interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001355 {
1356 result.GetOutputStream().EOL();
1357 num_successful_lookups++;
1358 }
1359 }
1360 }
1361 else
1362 {
1363 result.AppendError ("the target has no associated executable images");
1364 result.SetStatus (eReturnStatusFailed);
1365 return false;
1366 }
1367 }
1368 else
1369 {
1370 // Dump specified images (by basename or fullpath)
1371 const char *arg_cstr;
1372 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
1373 {
1374 FileSpec image_file(arg_cstr);
1375 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +00001376 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +00001377
Greg Clayton661825b2010-06-28 23:51:11 +00001378 // Not found in our module list for our target, check the main
1379 // shared module list in case it is a extra file used somewhere
1380 // else
1381 if (num_matching_modules == 0)
1382 num_matching_modules = ModuleList::FindSharedModules (image_file,
1383 target->GetArchitecture(),
1384 NULL,
1385 NULL,
1386 matching_modules);
1387
Chris Lattner24943d22010-06-08 16:52:24 +00001388 if (num_matching_modules > 0)
1389 {
1390 for (size_t i=0; i<num_matching_modules; ++i)
1391 {
1392 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
1393 if (image_module)
1394 {
Greg Clayton63094e02010-06-23 01:19:29 +00001395 if (LookupInModule (interpreter, image_module, result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001396 {
1397 result.GetOutputStream().EOL();
1398 num_successful_lookups++;
1399 }
1400 }
1401 }
1402 }
1403 else
1404 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1405 }
1406 }
1407
1408 if (num_successful_lookups > 0)
1409 result.SetStatus (eReturnStatusSuccessFinishResult);
1410 else
1411 result.SetStatus (eReturnStatusFailed);
1412 }
1413 return result.Succeeded();
1414 }
1415protected:
1416
1417 CommandOptions m_options;
1418};
1419
1420lldb::OptionDefinition
1421CommandObjectImageLookup::CommandOptions::g_option_table[] =
1422{
Jim Ingham34e9a982010-06-15 18:47:14 +00001423{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, "<addr>", "Lookup an address in one or more executable images."},
1424{ 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."},
1425{ 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."},
1426{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, NULL, "The <name> argument for name lookups are regular expressions."},
1427{ 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."},
1428{ 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)."},
1429{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, NULL, "Check inline line entries (must be used in conjunction with --file)."},
1430{ 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."},
Chris Lattner24943d22010-06-08 16:52:24 +00001431{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1432};
1433
1434
1435
1436
1437
1438//----------------------------------------------------------------------
1439// CommandObjectImage constructor
1440//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001441CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +00001442 CommandObjectMultiword ("image",
Greg Clayton63094e02010-06-23 01:19:29 +00001443 "Access information for one or more executable images.",
1444 "image [dump|list] ...")
Chris Lattner24943d22010-06-08 16:52:24 +00001445{
Greg Clayton63094e02010-06-23 01:19:29 +00001446 LoadSubCommand (interpreter, "dump", CommandObjectSP (new CommandObjectImageDump (interpreter)));
1447 LoadSubCommand (interpreter, "list", CommandObjectSP (new CommandObjectImageList ()));
1448 LoadSubCommand (interpreter, "lookup", CommandObjectSP (new CommandObjectImageLookup ()));
Chris Lattner24943d22010-06-08 16:52:24 +00001449}
1450
1451//----------------------------------------------------------------------
1452// Destructor
1453//----------------------------------------------------------------------
1454CommandObjectImage::~CommandObjectImage()
1455{
1456}
1457