blob: 38a04ecf5f09c01af1f913ceeecaecb4a2f477d2 [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();
Chris Lattner24943d22010-06-08 16:52:24 +0000230 if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset))
231 strm.PutCString(": ");
232 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
233 return true;
234 }
235
236 return false;
237}
238
239static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000240LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000241{
242 if (module)
243 {
244 SymbolContext sc;
245
246 ObjectFile *objfile = module->GetObjectFile ();
247 if (objfile)
248 {
249 Symtab *symtab = objfile->GetSymtab();
250 if (symtab)
251 {
252 uint32_t i;
253 std::vector<uint32_t> match_indexes;
254 ConstString symbol_name (name);
255 uint32_t num_matches = 0;
256 if (name_is_regex)
257 {
258 RegularExpression name_regexp(name);
259 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp, eSymbolTypeAny,
260 match_indexes);
261 }
262 else
263 {
264 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
265 }
266
267
268 if (num_matches > 0)
269 {
270 strm.Indent ();
271 strm.Printf("%u symbols match %s'%s' in ", num_matches,
272 name_is_regex ? "the regular expression " : "", name);
273 DumpFullpath (strm, &module->GetFileSpec(), 0);
274 strm.PutCString(":\n");
275 strm.IndentMore ();
276 Symtab::DumpSymbolHeader (&strm);
277 for (i=0; i < num_matches; ++i)
278 {
279 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
280 strm.Indent ();
Greg Clayton63094e02010-06-23 01:19:29 +0000281 symbol->Dump (&strm, interpreter.GetDebugger().GetExecutionContext().process, i);
Chris Lattner24943d22010-06-08 16:52:24 +0000282 }
283 strm.IndentLess ();
284 return num_matches;
285 }
286 }
287 }
288 }
289 return 0;
290}
291
292
293static void
Greg Clayton63094e02010-06-23 01:19:29 +0000294DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000295{
296 strm.IndentMore ();
297 uint32_t i;
298 const uint32_t num_matches = sc_list.GetSize();
299
300 for (i=0; i<num_matches; ++i)
301 {
302 SymbolContext sc;
303 if (sc_list.GetContextAtIndex(i, sc))
304 {
305 strm.Indent();
306 if (prepend_addr)
307 {
308 if (sc.line_entry.range.GetBaseAddress().IsValid())
309 {
310 lldb::addr_t vm_addr =
Greg Clayton63094e02010-06-23 01:19:29 +0000311 sc.line_entry.range.GetBaseAddress().GetLoadAddress(interpreter.GetDebugger().GetExecutionContext().process);
Chris Lattner24943d22010-06-08 16:52:24 +0000312 int addr_size = sizeof (addr_t);
Greg Clayton63094e02010-06-23 01:19:29 +0000313 Process *process = interpreter.GetDebugger().GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000314 if (process)
315 addr_size = process->GetAddressByteSize();
316 if (vm_addr != LLDB_INVALID_ADDRESS)
317 strm.Address (vm_addr, addr_size);
318 else
319 sc.line_entry.range.GetBaseAddress().Dump (&strm, NULL, Address::DumpStyleSectionNameOffset);
320
321 strm.PutCString(" in ");
322 }
323 }
Greg Clayton63094e02010-06-23 01:19:29 +0000324 sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress());
Chris Lattner24943d22010-06-08 16:52:24 +0000325 }
326 }
327 strm.IndentLess ();
328}
329
330static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000331LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000332{
333 if (module && name && name[0])
334 {
335 SymbolContextList sc_list;
336
337 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
338 if (symbol_vendor)
339 {
340 uint32_t num_matches = 0;
341 if (name_is_regex)
342 {
343 RegularExpression function_name_regex (name);
344 num_matches = symbol_vendor->FindFunctions(function_name_regex, true, sc_list);
345
346 }
347 else
348 {
349 ConstString function_name(name);
350 num_matches = symbol_vendor->FindFunctions(function_name, true, sc_list);
351 }
352
353 if (num_matches)
354 {
355 strm.Indent ();
356 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
357 DumpFullpath (strm, &module->GetFileSpec(), 0);
358 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000359 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000360 }
361 return num_matches;
362 }
363 }
364 return 0;
365}
366
367static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000368LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines)
Chris Lattner24943d22010-06-08 16:52:24 +0000369{
370 if (module && file_spec)
371 {
372 SymbolContextList sc_list;
373 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
374 eSymbolContextEverything, sc_list);
375 if (num_matches > 0)
376 {
377 strm.Indent ();
378 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
379 strm << file_spec;
380 if (line > 0)
381 strm.Printf (":%u", line);
382 strm << " in ";
383 DumpFullpath (strm, &module->GetFileSpec(), 0);
384 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000385 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000386 return num_matches;
387 }
388 }
389 return 0;
390
391}
392
393
394//----------------------------------------------------------------------
395// Image symbol table dumping command
396//----------------------------------------------------------------------
397
398class CommandObjectImageDumpModuleList : public CommandObject
399{
400public:
401
402 CommandObjectImageDumpModuleList (const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000403 const char *help,
404 const char *syntax) :
Chris Lattner24943d22010-06-08 16:52:24 +0000405 CommandObject (name, help, syntax)
406 {
407 }
408
409 virtual
410 ~CommandObjectImageDumpModuleList ()
411 {
412 }
413
414 virtual int
Greg Clayton63094e02010-06-23 01:19:29 +0000415 HandleArgumentCompletion (CommandInterpreter &interpreter,
416 Args &input,
417 int &cursor_index,
418 int &cursor_char_position,
419 OptionElementVector &opt_element_vector,
420 int match_start_point,
421 int max_return_elements,
422 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000423 {
424 // Arguments are the standard module completer.
425 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
426 completion_str.erase (cursor_char_position);
427
Greg Clayton63094e02010-06-23 01:19:29 +0000428 CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
429 CommandCompletions::eModuleCompletion,
430 completion_str.c_str(),
431 match_start_point,
432 max_return_elements,
433 NULL,
434 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000435 return matches.GetSize();
436 }
437};
438
439class CommandObjectImageDumpSourceFileList : public CommandObject
440{
441public:
442
443 CommandObjectImageDumpSourceFileList (const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000444 const char *help,
445 const char *syntax) :
Chris Lattner24943d22010-06-08 16:52:24 +0000446 CommandObject (name, help, syntax)
447 {
448 }
449
450 virtual
451 ~CommandObjectImageDumpSourceFileList ()
452 {
453 }
454
455 virtual int
Greg Clayton63094e02010-06-23 01:19:29 +0000456 HandleArgumentCompletion (CommandInterpreter &interpreter,
457 Args &input,
458 int &cursor_index,
459 int &cursor_char_position,
460 OptionElementVector &opt_element_vector,
461 int match_start_point,
462 int max_return_elements,
463 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000464 {
465 // Arguments are the standard source file completer.
466 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
467 completion_str.erase (cursor_char_position);
468
Greg Clayton63094e02010-06-23 01:19:29 +0000469 CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
470 CommandCompletions::eSourceFileCompletion,
471 completion_str.c_str(),
472 match_start_point,
473 max_return_elements,
474 NULL,
475 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000476 return matches.GetSize();
477 }
478};
479
480
481class CommandObjectImageDumpSymtab : public CommandObjectImageDumpModuleList
482{
483public:
484 CommandObjectImageDumpSymtab () :
485 CommandObjectImageDumpModuleList ("image dump symtab",
486 "Dump the symbol table from one or more executable images.",
487 "image dump symtab [<file1> ...]")
488 {
489 }
490
491 virtual
492 ~CommandObjectImageDumpSymtab ()
493 {
494 }
495
496 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000497 Execute (CommandInterpreter &interpreter,
498 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000499 CommandReturnObject &result)
500 {
Greg Clayton63094e02010-06-23 01:19:29 +0000501 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000502 if (target == NULL)
503 {
504 result.AppendError ("invalid target, set executable file using 'file' command");
505 result.SetStatus (eReturnStatusFailed);
506 return false;
507 }
508 else
509 {
510 uint32_t num_dumped = 0;
511
512 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
513 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
514 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
515
516 if (command.GetArgumentCount() == 0)
517 {
518 // Dump all sections for all modules images
519 const uint32_t num_modules = target->GetImages().GetSize();
520 if (num_modules > 0)
521 {
522 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
523 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
524 {
525 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000526 DumpModuleSymtab (interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000527 }
528 }
529 else
530 {
531 result.AppendError ("the target has no associated executable images");
532 result.SetStatus (eReturnStatusFailed);
533 return false;
534 }
535 }
536 else
537 {
538 // Dump specified images (by basename or fullpath)
539 const char *arg_cstr;
540 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
541 {
542 FileSpec image_file(arg_cstr);
543 ModuleList matching_modules;
544 const size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
545
546 if (num_matching_modules > 0)
547 {
548 for (size_t i=0; i<num_matching_modules; ++i)
549 {
550 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
551 if (image_module)
552 {
553 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000554 DumpModuleSymtab (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000555 }
556 }
557 }
558 else
559 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
560 }
561 }
562
563 if (num_dumped > 0)
564 result.SetStatus (eReturnStatusSuccessFinishResult);
565 else
566 {
567 result.AppendError ("no matching executable images found");
568 result.SetStatus (eReturnStatusFailed);
569 }
570 }
571 return result.Succeeded();
572 }
573
574};
575
576//----------------------------------------------------------------------
577// Image section dumping command
578//----------------------------------------------------------------------
579class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList
580{
581public:
582 CommandObjectImageDumpSections () :
Greg Clayton63094e02010-06-23 01:19:29 +0000583 CommandObjectImageDumpModuleList ("image dump sections",
584 "Dump the sections from one or more executable images.",
585 "image dump sections [<file1> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000586 {
587 }
588
589 virtual
590 ~CommandObjectImageDumpSections ()
591 {
592 }
593
594 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000595 Execute (CommandInterpreter &interpreter,
596 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000597 CommandReturnObject &result)
598 {
Greg Clayton63094e02010-06-23 01:19:29 +0000599 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000600 if (target == NULL)
601 {
602 result.AppendError ("invalid target, set executable file using 'file' command");
603 result.SetStatus (eReturnStatusFailed);
604 return false;
605 }
606 else
607 {
608 uint32_t num_dumped = 0;
609
610 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
611 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
612 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
613
614 if (command.GetArgumentCount() == 0)
615 {
616 // Dump all sections for all modules images
617 const uint32_t num_modules = target->GetImages().GetSize();
618 if (num_modules > 0)
619 {
620 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
621 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
622 {
623 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000624 DumpModuleSections (interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000625 }
626 }
627 else
628 {
629 result.AppendError ("the target has no associated executable images");
630 result.SetStatus (eReturnStatusFailed);
631 return false;
632 }
633 }
634 else
635 {
636 // Dump specified images (by basename or fullpath)
637 const char *arg_cstr;
638 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
639 {
640 FileSpec image_file(arg_cstr);
641 ModuleList matching_modules;
642 const size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
643
644 if (num_matching_modules > 0)
645 {
646 for (size_t i=0; i<num_matching_modules; ++i)
647 {
648 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
649 if (image_module)
650 {
651 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000652 DumpModuleSections (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000653 }
654 }
655 }
656 else
657 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
658 }
659 }
660
661 if (num_dumped > 0)
662 result.SetStatus (eReturnStatusSuccessFinishResult);
663 else
664 {
665 result.AppendError ("no matching executable images found");
666 result.SetStatus (eReturnStatusFailed);
667 }
668 }
669 return result.Succeeded();
670 }
671};
672
673//----------------------------------------------------------------------
674// Image debug symbol dumping command
675//----------------------------------------------------------------------
676class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList
677{
678public:
679 CommandObjectImageDumpSymfile () :
680 CommandObjectImageDumpModuleList ("image dump symfile",
681 "Dump the debug symbol file for one or more executable images.",
682 "image dump symfile [<file1> ...]")
683 {
684 }
685
686 virtual
687 ~CommandObjectImageDumpSymfile ()
688 {
689 }
690
691 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000692 Execute (CommandInterpreter &interpreter,
693 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000694 CommandReturnObject &result)
695 {
Greg Clayton63094e02010-06-23 01:19:29 +0000696 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000697 if (target == NULL)
698 {
699 result.AppendError ("invalid target, set executable file using 'file' command");
700 result.SetStatus (eReturnStatusFailed);
701 return false;
702 }
703 else
704 {
705 uint32_t num_dumped = 0;
706
707 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
708 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
709 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
710
711 if (command.GetArgumentCount() == 0)
712 {
713 // Dump all sections for all modules images
714 const uint32_t num_modules = target->GetImages().GetSize();
715 if (num_modules > 0)
716 {
717 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
718 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
719 {
720 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
721 num_dumped++;
722 }
723 }
724 else
725 {
726 result.AppendError ("the target has no associated executable images");
727 result.SetStatus (eReturnStatusFailed);
728 return false;
729 }
730 }
731 else
732 {
733 // Dump specified images (by basename or fullpath)
734 const char *arg_cstr;
735 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
736 {
737 FileSpec image_file(arg_cstr);
738 ModuleList matching_modules;
739 const size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
740
741 if (num_matching_modules > 0)
742 {
743 for (size_t i=0; i<num_matching_modules; ++i)
744 {
745 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
746 if (image_module)
747 {
748 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
749 num_dumped++;
750 }
751 }
752 }
753 else
754 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
755 }
756 }
757
758 if (num_dumped > 0)
759 result.SetStatus (eReturnStatusSuccessFinishResult);
760 else
761 {
762 result.AppendError ("no matching executable images found");
763 result.SetStatus (eReturnStatusFailed);
764 }
765 }
766 return result.Succeeded();
767 }
768};
769
770//----------------------------------------------------------------------
771// Image debug symbol dumping command
772//----------------------------------------------------------------------
773class CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList
774{
775public:
776 CommandObjectImageDumpLineTable () :
777 CommandObjectImageDumpSourceFileList ("image dump line-table",
778 "Dump the debug symbol file for one or more executable images.",
779 "image dump line-table <file1> [<file2> ...]")
780 {
781 }
782
783 virtual
784 ~CommandObjectImageDumpLineTable ()
785 {
786 }
787
788 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000789 Execute (CommandInterpreter &interpreter,
790 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000791 CommandReturnObject &result)
792 {
Greg Clayton63094e02010-06-23 01:19:29 +0000793 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000794 if (target == NULL)
795 {
796 result.AppendError ("invalid target, set executable file using 'file' command");
797 result.SetStatus (eReturnStatusFailed);
798 return false;
799 }
800 else
801 {
Greg Clayton63094e02010-06-23 01:19:29 +0000802 ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000803 uint32_t total_num_dumped = 0;
804
805 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
806 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
807 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
808
809 if (command.GetArgumentCount() == 0)
810 {
811 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
812 result.SetStatus (eReturnStatusFailed);
813 }
814 else
815 {
816 // Dump specified images (by basename or fullpath)
817 const char *arg_cstr;
818 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
819 {
820 FileSpec file_spec(arg_cstr);
821 const uint32_t num_modules = target->GetImages().GetSize();
822 if (num_modules > 0)
823 {
824 uint32_t num_dumped = 0;
825 for (uint32_t i = 0; i<num_modules; ++i)
826 {
Greg Clayton63094e02010-06-23 01:19:29 +0000827 if (DumpCompileUnitLineTable (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000828 result.GetOutputStream(),
829 target->GetImages().GetModulePointerAtIndex(i),
830 file_spec,
831 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
832 num_dumped++;
833 }
834 if (num_dumped == 0)
835 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
836 else
837 total_num_dumped += num_dumped;
838 }
839 }
840 }
841
842 if (total_num_dumped > 0)
843 result.SetStatus (eReturnStatusSuccessFinishResult);
844 else
845 {
846 result.AppendError ("no source filenames matched any command arguments");
847 result.SetStatus (eReturnStatusFailed);
848 }
849 }
850 return result.Succeeded();
851 }
852};
853
854//----------------------------------------------------------------------
855// Dump multi-word command
856//----------------------------------------------------------------------
857class CommandObjectImageDump : public CommandObjectMultiword
858{
859public:
860
861 //------------------------------------------------------------------
862 // Constructors and Destructors
863 //------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +0000864 CommandObjectImageDump(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +0000865 CommandObjectMultiword ("image dump",
Greg Clayton63094e02010-06-23 01:19:29 +0000866 "Dumps information in one or more executable images; 'line-table' expects a source file name",
867 "image dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000868 {
Greg Clayton63094e02010-06-23 01:19:29 +0000869 LoadSubCommand (interpreter, "symtab", CommandObjectSP (new CommandObjectImageDumpSymtab ()));
870 LoadSubCommand (interpreter, "sections", CommandObjectSP (new CommandObjectImageDumpSections ()));
871 LoadSubCommand (interpreter, "symfile", CommandObjectSP (new CommandObjectImageDumpSymfile ()));
872 LoadSubCommand (interpreter, "line-table", CommandObjectSP (new CommandObjectImageDumpLineTable ()));
Chris Lattner24943d22010-06-08 16:52:24 +0000873 }
874
875 virtual
876 ~CommandObjectImageDump()
877 {
878 }
879};
880
881//----------------------------------------------------------------------
882// List images with associated information
883//----------------------------------------------------------------------
884class CommandObjectImageList : public CommandObject
885{
886public:
887
888 class CommandOptions : public Options
889 {
890 public:
891
892 CommandOptions () :
893 Options(),
894 m_format_array()
895 {
896 }
897
898 virtual
899 ~CommandOptions ()
900 {
901 }
902
903 virtual Error
904 SetOptionValue (int option_idx, const char *option_arg)
905 {
906 char short_option = (char) m_getopt_table[option_idx].val;
907 uint32_t width = 0;
908 if (option_arg)
909 width = strtoul (option_arg, NULL, 0);
910 m_format_array.push_back(std::make_pair(short_option, width));
911 Error error;
912 return error;
913 }
914
915 void
916 ResetOptionValues ()
917 {
918 Options::ResetOptionValues();
919 m_format_array.clear();
920 }
921
922 const lldb::OptionDefinition*
923 GetDefinitions ()
924 {
925 return g_option_table;
926 }
927
928 // Options table: Required for subclasses of Options.
929
930 static lldb::OptionDefinition g_option_table[];
931
932 // Instance variables to hold the values for command options.
933 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
934 FormatWidthCollection m_format_array;
935 };
936
937 CommandObjectImageList () :
938 CommandObject (
939 "image list",
940 "List current executable and dependent shared library images.",
941 "image list [<cmd-options>]")
942 {
943 }
944
945 virtual
946 ~CommandObjectImageList ()
947 {
948 }
949
950 virtual
951 Options *
952 GetOptions ()
953 {
954 return &m_options;
955 }
956
957 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000958 Execute (CommandInterpreter &interpreter,
959 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000960 CommandReturnObject &result)
961 {
Greg Clayton63094e02010-06-23 01:19:29 +0000962 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000963 if (target == NULL)
964 {
965 result.AppendError ("invalid target, set executable file using 'file' command");
966 result.SetStatus (eReturnStatusFailed);
967 return false;
968 }
969 else
970 {
971 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
972 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
973 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
974 // Dump all sections for all modules images
975 const uint32_t num_modules = target->GetImages().GetSize();
976 if (num_modules > 0)
977 {
978 Stream &strm = result.GetOutputStream();
979
980 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
981 {
982 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
983 strm.Printf("[%3u] ", image_idx);
984
985 if (m_options.m_format_array.empty())
986 {
987 DumpFullpath(strm, &module->GetFileSpec(), 0);
988 }
989 else
990 {
991 const size_t num_entries = m_options.m_format_array.size();
992 for (size_t i=0; i<num_entries; ++i)
993 {
994 if (i > 0)
995 strm.PutChar(' ');
996 char format_char = m_options.m_format_array[i].first;
997 uint32_t width = m_options.m_format_array[i].second;
998 switch (format_char)
999 {
1000 case 'a':
1001 DumpModuleArchitecture (strm, module, width);
1002 break;
1003
1004 case 'f':
1005 DumpFullpath (strm, &module->GetFileSpec(), width);
1006 break;
1007
1008 case 'd':
1009 DumpDirectory (strm, &module->GetFileSpec(), width);
1010 break;
1011
1012 case 'b':
1013 DumpBasename (strm, &module->GetFileSpec(), width);
1014 break;
1015
1016 case 's':
1017 case 'S':
1018 {
1019 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1020 if (symbol_vendor)
1021 {
1022 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
1023 if (symbol_file)
1024 {
1025 if (format_char == 'S')
1026 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1027 else
1028 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1029 break;
1030 }
1031 }
1032 strm.Printf("%.*s", width, "<NONE>");
1033 }
1034 break;
1035
1036 case 'u':
1037 DumpModuleUUID(strm, module);
1038 break;
1039
1040 default:
1041 break;
1042 }
1043 }
1044 }
1045 strm.EOL();
1046 }
1047 result.SetStatus (eReturnStatusSuccessFinishResult);
1048 }
1049 else
1050 {
1051 result.AppendError ("the target has no associated executable images");
1052 result.SetStatus (eReturnStatusFailed);
1053 return false;
1054 }
1055 }
1056 return result.Succeeded();
1057 }
1058protected:
1059
1060 CommandOptions m_options;
1061};
1062
1063lldb::OptionDefinition
1064CommandObjectImageList::CommandOptions::g_option_table[] =
1065{
Jim Ingham34e9a982010-06-15 18:47:14 +00001066{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, "<width>", "Display the architecture when listing images."},
1067{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, NULL, "Display the UUID when listing images."},
1068{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image object file."},
1069{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, "<width>", "Display the directory with optional width for the image object file."},
1070{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, "<width>", "Display the basename with optional width for the image object file."},
1071{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image symbol file with optional width."},
1072{ 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 +00001073{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1074};
1075
1076
1077
1078//----------------------------------------------------------------------
1079// Lookup information in images
1080//----------------------------------------------------------------------
1081class CommandObjectImageLookup : public CommandObject
1082{
1083public:
1084
1085 enum
1086 {
1087 eLookupTypeInvalid = -1,
1088 eLookupTypeAddress = 0,
1089 eLookupTypeSymbol,
1090 eLookupTypeFileLine, // Line is optional
1091 eLookupTypeFunction,
1092 kNumLookupTypes
1093 };
1094
1095 class CommandOptions : public Options
1096 {
1097 public:
1098
1099 CommandOptions () :
1100 Options()
1101 {
1102 ResetOptionValues();
1103 }
1104
1105 virtual
1106 ~CommandOptions ()
1107 {
1108 }
1109
1110 virtual Error
1111 SetOptionValue (int option_idx, const char *option_arg)
1112 {
1113 Error error;
1114
1115 char short_option = (char) m_getopt_table[option_idx].val;
1116
1117 switch (short_option)
1118 {
1119 case 'a':
1120 m_type = eLookupTypeAddress;
1121 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1122 if (m_addr == LLDB_INVALID_ADDRESS)
1123 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
1124 break;
1125
1126 case 'o':
1127 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1128 if (m_offset == LLDB_INVALID_ADDRESS)
1129 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
1130 break;
1131
1132 case 's':
1133 m_str = option_arg;
1134 m_type = eLookupTypeSymbol;
1135 break;
1136
1137 case 'f':
1138 m_file.SetFile (option_arg);
1139 m_type = eLookupTypeFileLine;
1140 break;
1141
1142 case 'i':
1143 m_check_inlines = false;
1144 break;
1145
1146 case 'l':
1147 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
1148 if (m_line_number == UINT32_MAX)
1149 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
1150 else if (m_line_number == 0)
1151 error.SetErrorString ("Zero is an invalid line number.");
1152 m_type = eLookupTypeFileLine;
1153 break;
1154
1155 case 'n':
1156 m_str = option_arg;
1157 m_type = eLookupTypeFunction;
1158 break;
1159
1160 case 'r':
1161 m_use_regex = true;
1162 break;
1163 }
1164
1165 return error;
1166 }
1167
1168 void
1169 ResetOptionValues ()
1170 {
1171 Options::ResetOptionValues();
1172 m_type = eLookupTypeInvalid;
1173 m_str.clear();
1174 m_file.Clear();
1175 m_addr = LLDB_INVALID_ADDRESS;
1176 m_offset = 0;
1177 m_line_number = 0;
1178 m_use_regex = false;
1179 m_check_inlines = true;
1180 }
1181
1182 const lldb::OptionDefinition*
1183 GetDefinitions ()
1184 {
1185 return g_option_table;
1186 }
1187
1188 // Options table: Required for subclasses of Options.
1189
1190 static lldb::OptionDefinition g_option_table[];
1191 int m_type; // Should be a eLookupTypeXXX enum after parsing options
1192 std::string m_str; // Holds name lookup
1193 FileSpec m_file; // Files for file lookups
1194 lldb::addr_t m_addr; // Holds the address to lookup
1195 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
1196 uint32_t m_line_number; // Line number for file+line lookups
1197 bool m_use_regex; // Name lookups in m_str are regular expressions.
1198 bool m_check_inlines;// Check for inline entries when looking up by file/line.
1199 };
1200
1201 CommandObjectImageLookup () :
1202 CommandObject (
1203 "image lookup",
1204 "Look up information within executable and dependent shared library images.",
1205 "image lookup [<cmd-options>] [<file1>...]")
1206 {
1207 }
1208
1209 virtual
1210 ~CommandObjectImageLookup ()
1211 {
1212 }
1213
1214 virtual
1215 Options *
1216 GetOptions ()
1217 {
1218 return &m_options;
1219 }
1220
1221
1222 bool
Greg Clayton63094e02010-06-23 01:19:29 +00001223 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
Chris Lattner24943d22010-06-08 16:52:24 +00001224 {
1225 switch (m_options.m_type)
1226 {
1227 case eLookupTypeAddress:
1228 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
1229 {
Greg Clayton63094e02010-06-23 01:19:29 +00001230 if (LookupAddressInModule (interpreter, result.GetOutputStream(), module, eSymbolContextEverything, m_options.m_addr, m_options.m_offset))
Chris Lattner24943d22010-06-08 16:52:24 +00001231 {
1232 result.SetStatus(eReturnStatusSuccessFinishResult);
1233 return true;
1234 }
1235 }
1236 break;
1237
1238 case eLookupTypeSymbol:
1239 if (!m_options.m_str.empty())
1240 {
Greg Clayton63094e02010-06-23 01:19:29 +00001241 if (LookupSymbolInModule (interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
Chris Lattner24943d22010-06-08 16:52:24 +00001242 {
1243 result.SetStatus(eReturnStatusSuccessFinishResult);
1244 return true;
1245 }
1246 }
1247 break;
1248
1249 case eLookupTypeFileLine:
1250 if (m_options.m_file)
1251 {
1252
Greg Clayton63094e02010-06-23 01:19:29 +00001253 if (LookupFileAndLineInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001254 result.GetOutputStream(),
1255 module,
1256 m_options.m_file,
1257 m_options.m_line_number,
1258 m_options.m_check_inlines))
1259 {
1260 result.SetStatus(eReturnStatusSuccessFinishResult);
1261 return true;
1262 }
1263 }
1264 break;
1265
1266 case eLookupTypeFunction:
1267 if (!m_options.m_str.empty())
1268 {
Greg Clayton63094e02010-06-23 01:19:29 +00001269 if (LookupFunctionInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001270 result.GetOutputStream(),
1271 module,
1272 m_options.m_str.c_str(),
1273 m_options.m_use_regex))
1274 {
1275 result.SetStatus(eReturnStatusSuccessFinishResult);
1276 return true;
1277 }
1278 }
1279 break;
1280
1281 default:
1282 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
1283 syntax_error = true;
1284 break;
1285 }
1286
1287 result.SetStatus (eReturnStatusFailed);
1288 return false;
1289 }
1290
1291 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001292 Execute (CommandInterpreter &interpreter,
1293 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001294 CommandReturnObject &result)
1295 {
Greg Clayton63094e02010-06-23 01:19:29 +00001296 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001297 if (target == NULL)
1298 {
1299 result.AppendError ("invalid target, set executable file using 'file' command");
1300 result.SetStatus (eReturnStatusFailed);
1301 return false;
1302 }
1303 else
1304 {
1305 bool syntax_error = false;
1306 uint32_t i;
1307 uint32_t num_successful_lookups = 0;
1308 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1309 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1310 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1311 // Dump all sections for all modules images
1312
1313 if (command.GetArgumentCount() == 0)
1314 {
1315 // Dump all sections for all modules images
1316 const uint32_t num_modules = target->GetImages().GetSize();
1317 if (num_modules > 0)
1318 {
1319 for (i = 0; i<num_modules && syntax_error == false; ++i)
1320 {
Greg Clayton63094e02010-06-23 01:19:29 +00001321 if (LookupInModule (interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001322 {
1323 result.GetOutputStream().EOL();
1324 num_successful_lookups++;
1325 }
1326 }
1327 }
1328 else
1329 {
1330 result.AppendError ("the target has no associated executable images");
1331 result.SetStatus (eReturnStatusFailed);
1332 return false;
1333 }
1334 }
1335 else
1336 {
1337 // Dump specified images (by basename or fullpath)
1338 const char *arg_cstr;
1339 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
1340 {
1341 FileSpec image_file(arg_cstr);
1342 ModuleList matching_modules;
1343 const size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
1344
1345 if (num_matching_modules > 0)
1346 {
1347 for (size_t i=0; i<num_matching_modules; ++i)
1348 {
1349 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
1350 if (image_module)
1351 {
Greg Clayton63094e02010-06-23 01:19:29 +00001352 if (LookupInModule (interpreter, image_module, result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001353 {
1354 result.GetOutputStream().EOL();
1355 num_successful_lookups++;
1356 }
1357 }
1358 }
1359 }
1360 else
1361 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1362 }
1363 }
1364
1365 if (num_successful_lookups > 0)
1366 result.SetStatus (eReturnStatusSuccessFinishResult);
1367 else
1368 result.SetStatus (eReturnStatusFailed);
1369 }
1370 return result.Succeeded();
1371 }
1372protected:
1373
1374 CommandOptions m_options;
1375};
1376
1377lldb::OptionDefinition
1378CommandObjectImageLookup::CommandOptions::g_option_table[] =
1379{
Jim Ingham34e9a982010-06-15 18:47:14 +00001380{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, "<addr>", "Lookup an address in one or more executable images."},
1381{ 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."},
1382{ 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."},
1383{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, NULL, "The <name> argument for name lookups are regular expressions."},
1384{ 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."},
1385{ 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)."},
1386{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, NULL, "Check inline line entries (must be used in conjunction with --file)."},
1387{ 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 +00001388{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1389};
1390
1391
1392
1393
1394
1395//----------------------------------------------------------------------
1396// CommandObjectImage constructor
1397//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001398CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +00001399 CommandObjectMultiword ("image",
Greg Clayton63094e02010-06-23 01:19:29 +00001400 "Access information for one or more executable images.",
1401 "image [dump|list] ...")
Chris Lattner24943d22010-06-08 16:52:24 +00001402{
Greg Clayton63094e02010-06-23 01:19:29 +00001403 LoadSubCommand (interpreter, "dump", CommandObjectSP (new CommandObjectImageDump (interpreter)));
1404 LoadSubCommand (interpreter, "list", CommandObjectSP (new CommandObjectImageList ()));
1405 LoadSubCommand (interpreter, "lookup", CommandObjectSP (new CommandObjectImageLookup ()));
Chris Lattner24943d22010-06-08 16:52:24 +00001406}
1407
1408//----------------------------------------------------------------------
1409// Destructor
1410//----------------------------------------------------------------------
1411CommandObjectImage::~CommandObjectImage()
1412{
1413}
1414