blob: cb717c41bbd62fbe33125d49f0145cbef5e65ef3 [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;
547 const size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
548
549 if (num_matching_modules > 0)
550 {
551 for (size_t i=0; i<num_matching_modules; ++i)
552 {
553 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
554 if (image_module)
555 {
556 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000557 DumpModuleSymtab (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000558 }
559 }
560 }
561 else
562 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
563 }
564 }
565
566 if (num_dumped > 0)
567 result.SetStatus (eReturnStatusSuccessFinishResult);
568 else
569 {
570 result.AppendError ("no matching executable images found");
571 result.SetStatus (eReturnStatusFailed);
572 }
573 }
574 return result.Succeeded();
575 }
576
577};
578
579//----------------------------------------------------------------------
580// Image section dumping command
581//----------------------------------------------------------------------
582class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList
583{
584public:
585 CommandObjectImageDumpSections () :
Greg Clayton63094e02010-06-23 01:19:29 +0000586 CommandObjectImageDumpModuleList ("image dump sections",
587 "Dump the sections from one or more executable images.",
588 "image dump sections [<file1> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000589 {
590 }
591
592 virtual
593 ~CommandObjectImageDumpSections ()
594 {
595 }
596
597 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000598 Execute (CommandInterpreter &interpreter,
599 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000600 CommandReturnObject &result)
601 {
Greg Clayton63094e02010-06-23 01:19:29 +0000602 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000603 if (target == NULL)
604 {
605 result.AppendError ("invalid target, set executable file using 'file' command");
606 result.SetStatus (eReturnStatusFailed);
607 return false;
608 }
609 else
610 {
611 uint32_t num_dumped = 0;
612
613 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
614 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
615 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
616
617 if (command.GetArgumentCount() == 0)
618 {
619 // Dump all sections for all modules images
620 const uint32_t num_modules = target->GetImages().GetSize();
621 if (num_modules > 0)
622 {
623 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
624 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
625 {
626 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000627 DumpModuleSections (interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000628 }
629 }
630 else
631 {
632 result.AppendError ("the target has no associated executable images");
633 result.SetStatus (eReturnStatusFailed);
634 return false;
635 }
636 }
637 else
638 {
639 // Dump specified images (by basename or fullpath)
640 const char *arg_cstr;
641 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
642 {
643 FileSpec image_file(arg_cstr);
644 ModuleList matching_modules;
645 const size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
646
647 if (num_matching_modules > 0)
648 {
649 for (size_t i=0; i<num_matching_modules; ++i)
650 {
651 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
652 if (image_module)
653 {
654 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000655 DumpModuleSections (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000656 }
657 }
658 }
659 else
660 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
661 }
662 }
663
664 if (num_dumped > 0)
665 result.SetStatus (eReturnStatusSuccessFinishResult);
666 else
667 {
668 result.AppendError ("no matching executable images found");
669 result.SetStatus (eReturnStatusFailed);
670 }
671 }
672 return result.Succeeded();
673 }
674};
675
676//----------------------------------------------------------------------
677// Image debug symbol dumping command
678//----------------------------------------------------------------------
679class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList
680{
681public:
682 CommandObjectImageDumpSymfile () :
683 CommandObjectImageDumpModuleList ("image dump symfile",
684 "Dump the debug symbol file for one or more executable images.",
685 "image dump symfile [<file1> ...]")
686 {
687 }
688
689 virtual
690 ~CommandObjectImageDumpSymfile ()
691 {
692 }
693
694 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000695 Execute (CommandInterpreter &interpreter,
696 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000697 CommandReturnObject &result)
698 {
Greg Clayton63094e02010-06-23 01:19:29 +0000699 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000700 if (target == NULL)
701 {
702 result.AppendError ("invalid target, set executable file using 'file' command");
703 result.SetStatus (eReturnStatusFailed);
704 return false;
705 }
706 else
707 {
708 uint32_t num_dumped = 0;
709
710 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
711 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
712 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
713
714 if (command.GetArgumentCount() == 0)
715 {
716 // Dump all sections for all modules images
717 const uint32_t num_modules = target->GetImages().GetSize();
718 if (num_modules > 0)
719 {
720 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
721 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
722 {
723 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
724 num_dumped++;
725 }
726 }
727 else
728 {
729 result.AppendError ("the target has no associated executable images");
730 result.SetStatus (eReturnStatusFailed);
731 return false;
732 }
733 }
734 else
735 {
736 // Dump specified images (by basename or fullpath)
737 const char *arg_cstr;
738 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
739 {
740 FileSpec image_file(arg_cstr);
741 ModuleList matching_modules;
742 const size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
743
744 if (num_matching_modules > 0)
745 {
746 for (size_t i=0; i<num_matching_modules; ++i)
747 {
748 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
749 if (image_module)
750 {
751 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
752 num_dumped++;
753 }
754 }
755 }
756 else
757 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
758 }
759 }
760
761 if (num_dumped > 0)
762 result.SetStatus (eReturnStatusSuccessFinishResult);
763 else
764 {
765 result.AppendError ("no matching executable images found");
766 result.SetStatus (eReturnStatusFailed);
767 }
768 }
769 return result.Succeeded();
770 }
771};
772
773//----------------------------------------------------------------------
774// Image debug symbol dumping command
775//----------------------------------------------------------------------
776class CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList
777{
778public:
779 CommandObjectImageDumpLineTable () :
780 CommandObjectImageDumpSourceFileList ("image dump line-table",
781 "Dump the debug symbol file for one or more executable images.",
782 "image dump line-table <file1> [<file2> ...]")
783 {
784 }
785
786 virtual
787 ~CommandObjectImageDumpLineTable ()
788 {
789 }
790
791 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000792 Execute (CommandInterpreter &interpreter,
793 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000794 CommandReturnObject &result)
795 {
Greg Clayton63094e02010-06-23 01:19:29 +0000796 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000797 if (target == NULL)
798 {
799 result.AppendError ("invalid target, set executable file using 'file' command");
800 result.SetStatus (eReturnStatusFailed);
801 return false;
802 }
803 else
804 {
Greg Clayton63094e02010-06-23 01:19:29 +0000805 ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000806 uint32_t total_num_dumped = 0;
807
808 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
809 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
810 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
811
812 if (command.GetArgumentCount() == 0)
813 {
814 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
815 result.SetStatus (eReturnStatusFailed);
816 }
817 else
818 {
819 // Dump specified images (by basename or fullpath)
820 const char *arg_cstr;
821 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
822 {
823 FileSpec file_spec(arg_cstr);
824 const uint32_t num_modules = target->GetImages().GetSize();
825 if (num_modules > 0)
826 {
827 uint32_t num_dumped = 0;
828 for (uint32_t i = 0; i<num_modules; ++i)
829 {
Greg Clayton63094e02010-06-23 01:19:29 +0000830 if (DumpCompileUnitLineTable (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000831 result.GetOutputStream(),
832 target->GetImages().GetModulePointerAtIndex(i),
833 file_spec,
834 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
835 num_dumped++;
836 }
837 if (num_dumped == 0)
838 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
839 else
840 total_num_dumped += num_dumped;
841 }
842 }
843 }
844
845 if (total_num_dumped > 0)
846 result.SetStatus (eReturnStatusSuccessFinishResult);
847 else
848 {
849 result.AppendError ("no source filenames matched any command arguments");
850 result.SetStatus (eReturnStatusFailed);
851 }
852 }
853 return result.Succeeded();
854 }
855};
856
857//----------------------------------------------------------------------
858// Dump multi-word command
859//----------------------------------------------------------------------
860class CommandObjectImageDump : public CommandObjectMultiword
861{
862public:
863
864 //------------------------------------------------------------------
865 // Constructors and Destructors
866 //------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +0000867 CommandObjectImageDump(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +0000868 CommandObjectMultiword ("image dump",
Greg Clayton63094e02010-06-23 01:19:29 +0000869 "Dumps information in one or more executable images; 'line-table' expects a source file name",
870 "image dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000871 {
Greg Clayton63094e02010-06-23 01:19:29 +0000872 LoadSubCommand (interpreter, "symtab", CommandObjectSP (new CommandObjectImageDumpSymtab ()));
873 LoadSubCommand (interpreter, "sections", CommandObjectSP (new CommandObjectImageDumpSections ()));
874 LoadSubCommand (interpreter, "symfile", CommandObjectSP (new CommandObjectImageDumpSymfile ()));
875 LoadSubCommand (interpreter, "line-table", CommandObjectSP (new CommandObjectImageDumpLineTable ()));
Chris Lattner24943d22010-06-08 16:52:24 +0000876 }
877
878 virtual
879 ~CommandObjectImageDump()
880 {
881 }
882};
883
884//----------------------------------------------------------------------
885// List images with associated information
886//----------------------------------------------------------------------
887class CommandObjectImageList : public CommandObject
888{
889public:
890
891 class CommandOptions : public Options
892 {
893 public:
894
895 CommandOptions () :
896 Options(),
897 m_format_array()
898 {
899 }
900
901 virtual
902 ~CommandOptions ()
903 {
904 }
905
906 virtual Error
907 SetOptionValue (int option_idx, const char *option_arg)
908 {
909 char short_option = (char) m_getopt_table[option_idx].val;
910 uint32_t width = 0;
911 if (option_arg)
912 width = strtoul (option_arg, NULL, 0);
913 m_format_array.push_back(std::make_pair(short_option, width));
914 Error error;
915 return error;
916 }
917
918 void
919 ResetOptionValues ()
920 {
921 Options::ResetOptionValues();
922 m_format_array.clear();
923 }
924
925 const lldb::OptionDefinition*
926 GetDefinitions ()
927 {
928 return g_option_table;
929 }
930
931 // Options table: Required for subclasses of Options.
932
933 static lldb::OptionDefinition g_option_table[];
934
935 // Instance variables to hold the values for command options.
936 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
937 FormatWidthCollection m_format_array;
938 };
939
940 CommandObjectImageList () :
941 CommandObject (
942 "image list",
943 "List current executable and dependent shared library images.",
944 "image list [<cmd-options>]")
945 {
946 }
947
948 virtual
949 ~CommandObjectImageList ()
950 {
951 }
952
953 virtual
954 Options *
955 GetOptions ()
956 {
957 return &m_options;
958 }
959
960 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000961 Execute (CommandInterpreter &interpreter,
962 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000963 CommandReturnObject &result)
964 {
Greg Clayton63094e02010-06-23 01:19:29 +0000965 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000966 if (target == NULL)
967 {
968 result.AppendError ("invalid target, set executable file using 'file' command");
969 result.SetStatus (eReturnStatusFailed);
970 return false;
971 }
972 else
973 {
974 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
975 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
976 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
977 // Dump all sections for all modules images
978 const uint32_t num_modules = target->GetImages().GetSize();
979 if (num_modules > 0)
980 {
981 Stream &strm = result.GetOutputStream();
982
983 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
984 {
985 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
986 strm.Printf("[%3u] ", image_idx);
987
988 if (m_options.m_format_array.empty())
989 {
990 DumpFullpath(strm, &module->GetFileSpec(), 0);
991 }
992 else
993 {
994 const size_t num_entries = m_options.m_format_array.size();
995 for (size_t i=0; i<num_entries; ++i)
996 {
997 if (i > 0)
998 strm.PutChar(' ');
999 char format_char = m_options.m_format_array[i].first;
1000 uint32_t width = m_options.m_format_array[i].second;
1001 switch (format_char)
1002 {
1003 case 'a':
1004 DumpModuleArchitecture (strm, module, width);
1005 break;
1006
1007 case 'f':
1008 DumpFullpath (strm, &module->GetFileSpec(), width);
1009 break;
1010
1011 case 'd':
1012 DumpDirectory (strm, &module->GetFileSpec(), width);
1013 break;
1014
1015 case 'b':
1016 DumpBasename (strm, &module->GetFileSpec(), width);
1017 break;
1018
1019 case 's':
1020 case 'S':
1021 {
1022 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1023 if (symbol_vendor)
1024 {
1025 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
1026 if (symbol_file)
1027 {
1028 if (format_char == 'S')
1029 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1030 else
1031 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1032 break;
1033 }
1034 }
1035 strm.Printf("%.*s", width, "<NONE>");
1036 }
1037 break;
1038
1039 case 'u':
1040 DumpModuleUUID(strm, module);
1041 break;
1042
1043 default:
1044 break;
1045 }
1046 }
1047 }
1048 strm.EOL();
1049 }
1050 result.SetStatus (eReturnStatusSuccessFinishResult);
1051 }
1052 else
1053 {
1054 result.AppendError ("the target has no associated executable images");
1055 result.SetStatus (eReturnStatusFailed);
1056 return false;
1057 }
1058 }
1059 return result.Succeeded();
1060 }
1061protected:
1062
1063 CommandOptions m_options;
1064};
1065
1066lldb::OptionDefinition
1067CommandObjectImageList::CommandOptions::g_option_table[] =
1068{
Jim Ingham34e9a982010-06-15 18:47:14 +00001069{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, "<width>", "Display the architecture when listing images."},
1070{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, NULL, "Display the UUID when listing images."},
1071{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image object file."},
1072{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, "<width>", "Display the directory with optional width for the image object file."},
1073{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, "<width>", "Display the basename with optional width for the image object file."},
1074{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image symbol file with optional width."},
1075{ 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 +00001076{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1077};
1078
1079
1080
1081//----------------------------------------------------------------------
1082// Lookup information in images
1083//----------------------------------------------------------------------
1084class CommandObjectImageLookup : public CommandObject
1085{
1086public:
1087
1088 enum
1089 {
1090 eLookupTypeInvalid = -1,
1091 eLookupTypeAddress = 0,
1092 eLookupTypeSymbol,
1093 eLookupTypeFileLine, // Line is optional
1094 eLookupTypeFunction,
1095 kNumLookupTypes
1096 };
1097
1098 class CommandOptions : public Options
1099 {
1100 public:
1101
1102 CommandOptions () :
1103 Options()
1104 {
1105 ResetOptionValues();
1106 }
1107
1108 virtual
1109 ~CommandOptions ()
1110 {
1111 }
1112
1113 virtual Error
1114 SetOptionValue (int option_idx, const char *option_arg)
1115 {
1116 Error error;
1117
1118 char short_option = (char) m_getopt_table[option_idx].val;
1119
1120 switch (short_option)
1121 {
1122 case 'a':
1123 m_type = eLookupTypeAddress;
1124 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1125 if (m_addr == LLDB_INVALID_ADDRESS)
1126 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
1127 break;
1128
1129 case 'o':
1130 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1131 if (m_offset == LLDB_INVALID_ADDRESS)
1132 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
1133 break;
1134
1135 case 's':
1136 m_str = option_arg;
1137 m_type = eLookupTypeSymbol;
1138 break;
1139
1140 case 'f':
1141 m_file.SetFile (option_arg);
1142 m_type = eLookupTypeFileLine;
1143 break;
1144
1145 case 'i':
1146 m_check_inlines = false;
1147 break;
1148
1149 case 'l':
1150 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
1151 if (m_line_number == UINT32_MAX)
1152 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
1153 else if (m_line_number == 0)
1154 error.SetErrorString ("Zero is an invalid line number.");
1155 m_type = eLookupTypeFileLine;
1156 break;
1157
1158 case 'n':
1159 m_str = option_arg;
1160 m_type = eLookupTypeFunction;
1161 break;
1162
1163 case 'r':
1164 m_use_regex = true;
1165 break;
1166 }
1167
1168 return error;
1169 }
1170
1171 void
1172 ResetOptionValues ()
1173 {
1174 Options::ResetOptionValues();
1175 m_type = eLookupTypeInvalid;
1176 m_str.clear();
1177 m_file.Clear();
1178 m_addr = LLDB_INVALID_ADDRESS;
1179 m_offset = 0;
1180 m_line_number = 0;
1181 m_use_regex = false;
1182 m_check_inlines = true;
1183 }
1184
1185 const lldb::OptionDefinition*
1186 GetDefinitions ()
1187 {
1188 return g_option_table;
1189 }
1190
1191 // Options table: Required for subclasses of Options.
1192
1193 static lldb::OptionDefinition g_option_table[];
1194 int m_type; // Should be a eLookupTypeXXX enum after parsing options
1195 std::string m_str; // Holds name lookup
1196 FileSpec m_file; // Files for file lookups
1197 lldb::addr_t m_addr; // Holds the address to lookup
1198 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
1199 uint32_t m_line_number; // Line number for file+line lookups
1200 bool m_use_regex; // Name lookups in m_str are regular expressions.
1201 bool m_check_inlines;// Check for inline entries when looking up by file/line.
1202 };
1203
1204 CommandObjectImageLookup () :
1205 CommandObject (
1206 "image lookup",
1207 "Look up information within executable and dependent shared library images.",
1208 "image lookup [<cmd-options>] [<file1>...]")
1209 {
1210 }
1211
1212 virtual
1213 ~CommandObjectImageLookup ()
1214 {
1215 }
1216
1217 virtual
1218 Options *
1219 GetOptions ()
1220 {
1221 return &m_options;
1222 }
1223
1224
1225 bool
Greg Clayton63094e02010-06-23 01:19:29 +00001226 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
Chris Lattner24943d22010-06-08 16:52:24 +00001227 {
1228 switch (m_options.m_type)
1229 {
1230 case eLookupTypeAddress:
1231 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
1232 {
Greg Clayton63094e02010-06-23 01:19:29 +00001233 if (LookupAddressInModule (interpreter, result.GetOutputStream(), module, eSymbolContextEverything, m_options.m_addr, m_options.m_offset))
Chris Lattner24943d22010-06-08 16:52:24 +00001234 {
1235 result.SetStatus(eReturnStatusSuccessFinishResult);
1236 return true;
1237 }
1238 }
1239 break;
1240
1241 case eLookupTypeSymbol:
1242 if (!m_options.m_str.empty())
1243 {
Greg Clayton63094e02010-06-23 01:19:29 +00001244 if (LookupSymbolInModule (interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
Chris Lattner24943d22010-06-08 16:52:24 +00001245 {
1246 result.SetStatus(eReturnStatusSuccessFinishResult);
1247 return true;
1248 }
1249 }
1250 break;
1251
1252 case eLookupTypeFileLine:
1253 if (m_options.m_file)
1254 {
1255
Greg Clayton63094e02010-06-23 01:19:29 +00001256 if (LookupFileAndLineInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001257 result.GetOutputStream(),
1258 module,
1259 m_options.m_file,
1260 m_options.m_line_number,
1261 m_options.m_check_inlines))
1262 {
1263 result.SetStatus(eReturnStatusSuccessFinishResult);
1264 return true;
1265 }
1266 }
1267 break;
1268
1269 case eLookupTypeFunction:
1270 if (!m_options.m_str.empty())
1271 {
Greg Clayton63094e02010-06-23 01:19:29 +00001272 if (LookupFunctionInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001273 result.GetOutputStream(),
1274 module,
1275 m_options.m_str.c_str(),
1276 m_options.m_use_regex))
1277 {
1278 result.SetStatus(eReturnStatusSuccessFinishResult);
1279 return true;
1280 }
1281 }
1282 break;
1283
1284 default:
1285 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
1286 syntax_error = true;
1287 break;
1288 }
1289
1290 result.SetStatus (eReturnStatusFailed);
1291 return false;
1292 }
1293
1294 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001295 Execute (CommandInterpreter &interpreter,
1296 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001297 CommandReturnObject &result)
1298 {
Greg Clayton63094e02010-06-23 01:19:29 +00001299 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001300 if (target == NULL)
1301 {
1302 result.AppendError ("invalid target, set executable file using 'file' command");
1303 result.SetStatus (eReturnStatusFailed);
1304 return false;
1305 }
1306 else
1307 {
1308 bool syntax_error = false;
1309 uint32_t i;
1310 uint32_t num_successful_lookups = 0;
1311 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1312 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1313 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1314 // Dump all sections for all modules images
1315
1316 if (command.GetArgumentCount() == 0)
1317 {
1318 // Dump all sections for all modules images
1319 const uint32_t num_modules = target->GetImages().GetSize();
1320 if (num_modules > 0)
1321 {
1322 for (i = 0; i<num_modules && syntax_error == false; ++i)
1323 {
Greg Clayton63094e02010-06-23 01:19:29 +00001324 if (LookupInModule (interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001325 {
1326 result.GetOutputStream().EOL();
1327 num_successful_lookups++;
1328 }
1329 }
1330 }
1331 else
1332 {
1333 result.AppendError ("the target has no associated executable images");
1334 result.SetStatus (eReturnStatusFailed);
1335 return false;
1336 }
1337 }
1338 else
1339 {
1340 // Dump specified images (by basename or fullpath)
1341 const char *arg_cstr;
1342 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
1343 {
1344 FileSpec image_file(arg_cstr);
1345 ModuleList matching_modules;
1346 const size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
1347
1348 if (num_matching_modules > 0)
1349 {
1350 for (size_t i=0; i<num_matching_modules; ++i)
1351 {
1352 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
1353 if (image_module)
1354 {
Greg Clayton63094e02010-06-23 01:19:29 +00001355 if (LookupInModule (interpreter, image_module, result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001356 {
1357 result.GetOutputStream().EOL();
1358 num_successful_lookups++;
1359 }
1360 }
1361 }
1362 }
1363 else
1364 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1365 }
1366 }
1367
1368 if (num_successful_lookups > 0)
1369 result.SetStatus (eReturnStatusSuccessFinishResult);
1370 else
1371 result.SetStatus (eReturnStatusFailed);
1372 }
1373 return result.Succeeded();
1374 }
1375protected:
1376
1377 CommandOptions m_options;
1378};
1379
1380lldb::OptionDefinition
1381CommandObjectImageLookup::CommandOptions::g_option_table[] =
1382{
Jim Ingham34e9a982010-06-15 18:47:14 +00001383{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, "<addr>", "Lookup an address in one or more executable images."},
1384{ 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."},
1385{ 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."},
1386{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, NULL, "The <name> argument for name lookups are regular expressions."},
1387{ 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."},
1388{ 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)."},
1389{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, NULL, "Check inline line entries (must be used in conjunction with --file)."},
1390{ 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 +00001391{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1392};
1393
1394
1395
1396
1397
1398//----------------------------------------------------------------------
1399// CommandObjectImage constructor
1400//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001401CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +00001402 CommandObjectMultiword ("image",
Greg Clayton63094e02010-06-23 01:19:29 +00001403 "Access information for one or more executable images.",
1404 "image [dump|list] ...")
Chris Lattner24943d22010-06-08 16:52:24 +00001405{
Greg Clayton63094e02010-06-23 01:19:29 +00001406 LoadSubCommand (interpreter, "dump", CommandObjectSP (new CommandObjectImageDump (interpreter)));
1407 LoadSubCommand (interpreter, "list", CommandObjectSP (new CommandObjectImageList ()));
1408 LoadSubCommand (interpreter, "lookup", CommandObjectSP (new CommandObjectImageLookup ()));
Chris Lattner24943d22010-06-08 16:52:24 +00001409}
1410
1411//----------------------------------------------------------------------
1412// Destructor
1413//----------------------------------------------------------------------
1414CommandObjectImage::~CommandObjectImage()
1415{
1416}
1417