blob: 909b36d09c253a3158511462e1f0e0b9cc040a30 [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,
Jim Ingham802f8b02010-06-30 05:02:46 +0000425 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000426 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000427 {
428 // Arguments are the standard module completer.
429 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
430 completion_str.erase (cursor_char_position);
431
Greg Clayton63094e02010-06-23 01:19:29 +0000432 CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
433 CommandCompletions::eModuleCompletion,
434 completion_str.c_str(),
435 match_start_point,
436 max_return_elements,
437 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000438 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000439 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000440 return matches.GetSize();
441 }
442};
443
444class CommandObjectImageDumpSourceFileList : public CommandObject
445{
446public:
447
448 CommandObjectImageDumpSourceFileList (const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000449 const char *help,
450 const char *syntax) :
Chris Lattner24943d22010-06-08 16:52:24 +0000451 CommandObject (name, help, syntax)
452 {
453 }
454
455 virtual
456 ~CommandObjectImageDumpSourceFileList ()
457 {
458 }
459
460 virtual int
Greg Clayton63094e02010-06-23 01:19:29 +0000461 HandleArgumentCompletion (CommandInterpreter &interpreter,
462 Args &input,
463 int &cursor_index,
464 int &cursor_char_position,
465 OptionElementVector &opt_element_vector,
466 int match_start_point,
467 int max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000468 bool word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000469 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000470 {
471 // Arguments are the standard source file completer.
472 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
473 completion_str.erase (cursor_char_position);
474
Greg Clayton63094e02010-06-23 01:19:29 +0000475 CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
476 CommandCompletions::eSourceFileCompletion,
477 completion_str.c_str(),
478 match_start_point,
479 max_return_elements,
480 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000481 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000482 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000483 return matches.GetSize();
484 }
485};
486
487
488class CommandObjectImageDumpSymtab : public CommandObjectImageDumpModuleList
489{
490public:
491 CommandObjectImageDumpSymtab () :
492 CommandObjectImageDumpModuleList ("image dump symtab",
493 "Dump the symbol table from one or more executable images.",
494 "image dump symtab [<file1> ...]")
495 {
496 }
497
498 virtual
499 ~CommandObjectImageDumpSymtab ()
500 {
501 }
502
503 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000504 Execute (CommandInterpreter &interpreter,
505 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000506 CommandReturnObject &result)
507 {
Greg Clayton63094e02010-06-23 01:19:29 +0000508 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000509 if (target == NULL)
510 {
511 result.AppendError ("invalid target, set executable file using 'file' command");
512 result.SetStatus (eReturnStatusFailed);
513 return false;
514 }
515 else
516 {
517 uint32_t num_dumped = 0;
518
519 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
520 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
521 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
522
523 if (command.GetArgumentCount() == 0)
524 {
525 // Dump all sections for all modules images
526 const uint32_t num_modules = target->GetImages().GetSize();
527 if (num_modules > 0)
528 {
529 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
530 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
531 {
532 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000533 DumpModuleSymtab (interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000534 }
535 }
536 else
537 {
538 result.AppendError ("the target has no associated executable images");
539 result.SetStatus (eReturnStatusFailed);
540 return false;
541 }
542 }
543 else
544 {
545 // Dump specified images (by basename or fullpath)
546 const char *arg_cstr;
547 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
548 {
549 FileSpec image_file(arg_cstr);
550 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000551 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000552
Greg Clayton661825b2010-06-28 23:51:11 +0000553 // Not found in our module list for our target, check the main
554 // shared module list in case it is a extra file used somewhere
555 // else
556 if (num_matching_modules == 0)
557 num_matching_modules = ModuleList::FindSharedModules (image_file,
558 target->GetArchitecture(),
559 NULL,
560 NULL,
561 matching_modules);
562
Chris Lattner24943d22010-06-08 16:52:24 +0000563 if (num_matching_modules > 0)
564 {
565 for (size_t i=0; i<num_matching_modules; ++i)
566 {
567 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
568 if (image_module)
569 {
570 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000571 DumpModuleSymtab (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000572 }
573 }
574 }
575 else
576 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
577 }
578 }
579
580 if (num_dumped > 0)
581 result.SetStatus (eReturnStatusSuccessFinishResult);
582 else
583 {
584 result.AppendError ("no matching executable images found");
585 result.SetStatus (eReturnStatusFailed);
586 }
587 }
588 return result.Succeeded();
589 }
590
591};
592
593//----------------------------------------------------------------------
594// Image section dumping command
595//----------------------------------------------------------------------
596class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList
597{
598public:
599 CommandObjectImageDumpSections () :
Greg Clayton63094e02010-06-23 01:19:29 +0000600 CommandObjectImageDumpModuleList ("image dump sections",
601 "Dump the sections from one or more executable images.",
602 "image dump sections [<file1> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000603 {
604 }
605
606 virtual
607 ~CommandObjectImageDumpSections ()
608 {
609 }
610
611 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000612 Execute (CommandInterpreter &interpreter,
613 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000614 CommandReturnObject &result)
615 {
Greg Clayton63094e02010-06-23 01:19:29 +0000616 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000617 if (target == NULL)
618 {
619 result.AppendError ("invalid target, set executable file using 'file' command");
620 result.SetStatus (eReturnStatusFailed);
621 return false;
622 }
623 else
624 {
625 uint32_t num_dumped = 0;
626
627 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
628 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
629 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
630
631 if (command.GetArgumentCount() == 0)
632 {
633 // Dump all sections for all modules images
634 const uint32_t num_modules = target->GetImages().GetSize();
635 if (num_modules > 0)
636 {
637 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
638 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
639 {
640 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000641 DumpModuleSections (interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000642 }
643 }
644 else
645 {
646 result.AppendError ("the target has no associated executable images");
647 result.SetStatus (eReturnStatusFailed);
648 return false;
649 }
650 }
651 else
652 {
653 // Dump specified images (by basename or fullpath)
654 const char *arg_cstr;
655 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
656 {
657 FileSpec image_file(arg_cstr);
658 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000659 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000660
Greg Clayton661825b2010-06-28 23:51:11 +0000661 // Not found in our module list for our target, check the main
662 // shared module list in case it is a extra file used somewhere
663 // else
664 if (num_matching_modules == 0)
665 num_matching_modules = ModuleList::FindSharedModules (image_file,
666 target->GetArchitecture(),
667 NULL,
668 NULL,
669 matching_modules);
670
Chris Lattner24943d22010-06-08 16:52:24 +0000671 if (num_matching_modules > 0)
672 {
673 for (size_t i=0; i<num_matching_modules; ++i)
674 {
675 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
676 if (image_module)
677 {
678 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000679 DumpModuleSections (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000680 }
681 }
682 }
683 else
684 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
685 }
686 }
687
688 if (num_dumped > 0)
689 result.SetStatus (eReturnStatusSuccessFinishResult);
690 else
691 {
692 result.AppendError ("no matching executable images found");
693 result.SetStatus (eReturnStatusFailed);
694 }
695 }
696 return result.Succeeded();
697 }
698};
699
700//----------------------------------------------------------------------
701// Image debug symbol dumping command
702//----------------------------------------------------------------------
703class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList
704{
705public:
706 CommandObjectImageDumpSymfile () :
707 CommandObjectImageDumpModuleList ("image dump symfile",
708 "Dump the debug symbol file for one or more executable images.",
709 "image dump symfile [<file1> ...]")
710 {
711 }
712
713 virtual
714 ~CommandObjectImageDumpSymfile ()
715 {
716 }
717
718 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000719 Execute (CommandInterpreter &interpreter,
720 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000721 CommandReturnObject &result)
722 {
Greg Clayton63094e02010-06-23 01:19:29 +0000723 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000724 if (target == NULL)
725 {
726 result.AppendError ("invalid target, set executable file using 'file' command");
727 result.SetStatus (eReturnStatusFailed);
728 return false;
729 }
730 else
731 {
732 uint32_t num_dumped = 0;
733
734 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
735 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
736 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
737
738 if (command.GetArgumentCount() == 0)
739 {
740 // Dump all sections for all modules images
741 const uint32_t num_modules = target->GetImages().GetSize();
742 if (num_modules > 0)
743 {
744 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
745 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
746 {
747 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
748 num_dumped++;
749 }
750 }
751 else
752 {
753 result.AppendError ("the target has no associated executable images");
754 result.SetStatus (eReturnStatusFailed);
755 return false;
756 }
757 }
758 else
759 {
760 // Dump specified images (by basename or fullpath)
761 const char *arg_cstr;
762 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
763 {
764 FileSpec image_file(arg_cstr);
765 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000766 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000767
Greg Clayton661825b2010-06-28 23:51:11 +0000768 // Not found in our module list for our target, check the main
769 // shared module list in case it is a extra file used somewhere
770 // else
771 if (num_matching_modules == 0)
772 num_matching_modules = ModuleList::FindSharedModules (image_file,
773 target->GetArchitecture(),
774 NULL,
775 NULL,
776 matching_modules);
777
Chris Lattner24943d22010-06-08 16:52:24 +0000778 if (num_matching_modules > 0)
779 {
780 for (size_t i=0; i<num_matching_modules; ++i)
781 {
782 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
783 if (image_module)
784 {
785 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
786 num_dumped++;
787 }
788 }
789 }
790 else
791 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
792 }
793 }
794
795 if (num_dumped > 0)
796 result.SetStatus (eReturnStatusSuccessFinishResult);
797 else
798 {
799 result.AppendError ("no matching executable images found");
800 result.SetStatus (eReturnStatusFailed);
801 }
802 }
803 return result.Succeeded();
804 }
805};
806
807//----------------------------------------------------------------------
808// Image debug symbol dumping command
809//----------------------------------------------------------------------
810class CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList
811{
812public:
813 CommandObjectImageDumpLineTable () :
814 CommandObjectImageDumpSourceFileList ("image dump line-table",
815 "Dump the debug symbol file for one or more executable images.",
816 "image dump line-table <file1> [<file2> ...]")
817 {
818 }
819
820 virtual
821 ~CommandObjectImageDumpLineTable ()
822 {
823 }
824
825 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000826 Execute (CommandInterpreter &interpreter,
827 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000828 CommandReturnObject &result)
829 {
Greg Clayton63094e02010-06-23 01:19:29 +0000830 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000831 if (target == NULL)
832 {
833 result.AppendError ("invalid target, set executable file using 'file' command");
834 result.SetStatus (eReturnStatusFailed);
835 return false;
836 }
837 else
838 {
Greg Clayton63094e02010-06-23 01:19:29 +0000839 ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000840 uint32_t total_num_dumped = 0;
841
842 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
843 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
844 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
845
846 if (command.GetArgumentCount() == 0)
847 {
848 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
849 result.SetStatus (eReturnStatusFailed);
850 }
851 else
852 {
853 // Dump specified images (by basename or fullpath)
854 const char *arg_cstr;
855 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
856 {
857 FileSpec file_spec(arg_cstr);
858 const uint32_t num_modules = target->GetImages().GetSize();
859 if (num_modules > 0)
860 {
861 uint32_t num_dumped = 0;
862 for (uint32_t i = 0; i<num_modules; ++i)
863 {
Greg Clayton63094e02010-06-23 01:19:29 +0000864 if (DumpCompileUnitLineTable (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000865 result.GetOutputStream(),
866 target->GetImages().GetModulePointerAtIndex(i),
867 file_spec,
868 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
869 num_dumped++;
870 }
871 if (num_dumped == 0)
872 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
873 else
874 total_num_dumped += num_dumped;
875 }
876 }
877 }
878
879 if (total_num_dumped > 0)
880 result.SetStatus (eReturnStatusSuccessFinishResult);
881 else
882 {
883 result.AppendError ("no source filenames matched any command arguments");
884 result.SetStatus (eReturnStatusFailed);
885 }
886 }
887 return result.Succeeded();
888 }
889};
890
891//----------------------------------------------------------------------
892// Dump multi-word command
893//----------------------------------------------------------------------
894class CommandObjectImageDump : public CommandObjectMultiword
895{
896public:
897
898 //------------------------------------------------------------------
899 // Constructors and Destructors
900 //------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +0000901 CommandObjectImageDump(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +0000902 CommandObjectMultiword ("image dump",
Greg Clayton63094e02010-06-23 01:19:29 +0000903 "Dumps information in one or more executable images; 'line-table' expects a source file name",
904 "image dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000905 {
Greg Clayton63094e02010-06-23 01:19:29 +0000906 LoadSubCommand (interpreter, "symtab", CommandObjectSP (new CommandObjectImageDumpSymtab ()));
907 LoadSubCommand (interpreter, "sections", CommandObjectSP (new CommandObjectImageDumpSections ()));
908 LoadSubCommand (interpreter, "symfile", CommandObjectSP (new CommandObjectImageDumpSymfile ()));
909 LoadSubCommand (interpreter, "line-table", CommandObjectSP (new CommandObjectImageDumpLineTable ()));
Chris Lattner24943d22010-06-08 16:52:24 +0000910 }
911
912 virtual
913 ~CommandObjectImageDump()
914 {
915 }
916};
917
918//----------------------------------------------------------------------
919// List images with associated information
920//----------------------------------------------------------------------
921class CommandObjectImageList : public CommandObject
922{
923public:
924
925 class CommandOptions : public Options
926 {
927 public:
928
929 CommandOptions () :
930 Options(),
931 m_format_array()
932 {
933 }
934
935 virtual
936 ~CommandOptions ()
937 {
938 }
939
940 virtual Error
941 SetOptionValue (int option_idx, const char *option_arg)
942 {
943 char short_option = (char) m_getopt_table[option_idx].val;
944 uint32_t width = 0;
945 if (option_arg)
946 width = strtoul (option_arg, NULL, 0);
947 m_format_array.push_back(std::make_pair(short_option, width));
948 Error error;
949 return error;
950 }
951
952 void
953 ResetOptionValues ()
954 {
955 Options::ResetOptionValues();
956 m_format_array.clear();
957 }
958
959 const lldb::OptionDefinition*
960 GetDefinitions ()
961 {
962 return g_option_table;
963 }
964
965 // Options table: Required for subclasses of Options.
966
967 static lldb::OptionDefinition g_option_table[];
968
969 // Instance variables to hold the values for command options.
970 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
971 FormatWidthCollection m_format_array;
972 };
973
974 CommandObjectImageList () :
975 CommandObject (
976 "image list",
977 "List current executable and dependent shared library images.",
978 "image list [<cmd-options>]")
979 {
980 }
981
982 virtual
983 ~CommandObjectImageList ()
984 {
985 }
986
987 virtual
988 Options *
989 GetOptions ()
990 {
991 return &m_options;
992 }
993
994 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000995 Execute (CommandInterpreter &interpreter,
996 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000997 CommandReturnObject &result)
998 {
Greg Clayton63094e02010-06-23 01:19:29 +0000999 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001000 if (target == NULL)
1001 {
1002 result.AppendError ("invalid target, set executable file using 'file' command");
1003 result.SetStatus (eReturnStatusFailed);
1004 return false;
1005 }
1006 else
1007 {
1008 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1009 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1010 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1011 // Dump all sections for all modules images
1012 const uint32_t num_modules = target->GetImages().GetSize();
1013 if (num_modules > 0)
1014 {
1015 Stream &strm = result.GetOutputStream();
1016
1017 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1018 {
1019 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
1020 strm.Printf("[%3u] ", image_idx);
1021
1022 if (m_options.m_format_array.empty())
1023 {
1024 DumpFullpath(strm, &module->GetFileSpec(), 0);
1025 }
1026 else
1027 {
1028 const size_t num_entries = m_options.m_format_array.size();
1029 for (size_t i=0; i<num_entries; ++i)
1030 {
1031 if (i > 0)
1032 strm.PutChar(' ');
1033 char format_char = m_options.m_format_array[i].first;
1034 uint32_t width = m_options.m_format_array[i].second;
1035 switch (format_char)
1036 {
1037 case 'a':
1038 DumpModuleArchitecture (strm, module, width);
1039 break;
1040
1041 case 'f':
1042 DumpFullpath (strm, &module->GetFileSpec(), width);
1043 break;
1044
1045 case 'd':
1046 DumpDirectory (strm, &module->GetFileSpec(), width);
1047 break;
1048
1049 case 'b':
1050 DumpBasename (strm, &module->GetFileSpec(), width);
1051 break;
1052
1053 case 's':
1054 case 'S':
1055 {
1056 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1057 if (symbol_vendor)
1058 {
1059 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
1060 if (symbol_file)
1061 {
1062 if (format_char == 'S')
1063 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1064 else
1065 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1066 break;
1067 }
1068 }
1069 strm.Printf("%.*s", width, "<NONE>");
1070 }
1071 break;
1072
1073 case 'u':
1074 DumpModuleUUID(strm, module);
1075 break;
1076
1077 default:
1078 break;
1079 }
1080 }
1081 }
1082 strm.EOL();
1083 }
1084 result.SetStatus (eReturnStatusSuccessFinishResult);
1085 }
1086 else
1087 {
1088 result.AppendError ("the target has no associated executable images");
1089 result.SetStatus (eReturnStatusFailed);
1090 return false;
1091 }
1092 }
1093 return result.Succeeded();
1094 }
1095protected:
1096
1097 CommandOptions m_options;
1098};
1099
1100lldb::OptionDefinition
1101CommandObjectImageList::CommandOptions::g_option_table[] =
1102{
Jim Ingham34e9a982010-06-15 18:47:14 +00001103{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, "<width>", "Display the architecture when listing images."},
1104{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, NULL, "Display the UUID when listing images."},
1105{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image object file."},
1106{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, "<width>", "Display the directory with optional width for the image object file."},
1107{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, "<width>", "Display the basename with optional width for the image object file."},
1108{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image symbol file with optional width."},
1109{ 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 +00001110{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1111};
1112
1113
1114
1115//----------------------------------------------------------------------
1116// Lookup information in images
1117//----------------------------------------------------------------------
1118class CommandObjectImageLookup : public CommandObject
1119{
1120public:
1121
1122 enum
1123 {
1124 eLookupTypeInvalid = -1,
1125 eLookupTypeAddress = 0,
1126 eLookupTypeSymbol,
1127 eLookupTypeFileLine, // Line is optional
1128 eLookupTypeFunction,
1129 kNumLookupTypes
1130 };
1131
1132 class CommandOptions : public Options
1133 {
1134 public:
1135
1136 CommandOptions () :
1137 Options()
1138 {
1139 ResetOptionValues();
1140 }
1141
1142 virtual
1143 ~CommandOptions ()
1144 {
1145 }
1146
1147 virtual Error
1148 SetOptionValue (int option_idx, const char *option_arg)
1149 {
1150 Error error;
1151
1152 char short_option = (char) m_getopt_table[option_idx].val;
1153
1154 switch (short_option)
1155 {
1156 case 'a':
1157 m_type = eLookupTypeAddress;
1158 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1159 if (m_addr == LLDB_INVALID_ADDRESS)
1160 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
1161 break;
1162
1163 case 'o':
1164 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1165 if (m_offset == LLDB_INVALID_ADDRESS)
1166 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
1167 break;
1168
1169 case 's':
1170 m_str = option_arg;
1171 m_type = eLookupTypeSymbol;
1172 break;
1173
1174 case 'f':
1175 m_file.SetFile (option_arg);
1176 m_type = eLookupTypeFileLine;
1177 break;
1178
1179 case 'i':
1180 m_check_inlines = false;
1181 break;
1182
1183 case 'l':
1184 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
1185 if (m_line_number == UINT32_MAX)
1186 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
1187 else if (m_line_number == 0)
1188 error.SetErrorString ("Zero is an invalid line number.");
1189 m_type = eLookupTypeFileLine;
1190 break;
1191
1192 case 'n':
1193 m_str = option_arg;
1194 m_type = eLookupTypeFunction;
1195 break;
1196
1197 case 'r':
1198 m_use_regex = true;
1199 break;
1200 }
1201
1202 return error;
1203 }
1204
1205 void
1206 ResetOptionValues ()
1207 {
1208 Options::ResetOptionValues();
1209 m_type = eLookupTypeInvalid;
1210 m_str.clear();
1211 m_file.Clear();
1212 m_addr = LLDB_INVALID_ADDRESS;
1213 m_offset = 0;
1214 m_line_number = 0;
1215 m_use_regex = false;
1216 m_check_inlines = true;
1217 }
1218
1219 const lldb::OptionDefinition*
1220 GetDefinitions ()
1221 {
1222 return g_option_table;
1223 }
1224
1225 // Options table: Required for subclasses of Options.
1226
1227 static lldb::OptionDefinition g_option_table[];
1228 int m_type; // Should be a eLookupTypeXXX enum after parsing options
1229 std::string m_str; // Holds name lookup
1230 FileSpec m_file; // Files for file lookups
1231 lldb::addr_t m_addr; // Holds the address to lookup
1232 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
1233 uint32_t m_line_number; // Line number for file+line lookups
1234 bool m_use_regex; // Name lookups in m_str are regular expressions.
1235 bool m_check_inlines;// Check for inline entries when looking up by file/line.
1236 };
1237
1238 CommandObjectImageLookup () :
1239 CommandObject (
1240 "image lookup",
1241 "Look up information within executable and dependent shared library images.",
1242 "image lookup [<cmd-options>] [<file1>...]")
1243 {
1244 }
1245
1246 virtual
1247 ~CommandObjectImageLookup ()
1248 {
1249 }
1250
1251 virtual
1252 Options *
1253 GetOptions ()
1254 {
1255 return &m_options;
1256 }
1257
1258
1259 bool
Greg Clayton63094e02010-06-23 01:19:29 +00001260 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
Chris Lattner24943d22010-06-08 16:52:24 +00001261 {
1262 switch (m_options.m_type)
1263 {
1264 case eLookupTypeAddress:
1265 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
1266 {
Greg Clayton63094e02010-06-23 01:19:29 +00001267 if (LookupAddressInModule (interpreter, result.GetOutputStream(), module, eSymbolContextEverything, m_options.m_addr, m_options.m_offset))
Chris Lattner24943d22010-06-08 16:52:24 +00001268 {
1269 result.SetStatus(eReturnStatusSuccessFinishResult);
1270 return true;
1271 }
1272 }
1273 break;
1274
1275 case eLookupTypeSymbol:
1276 if (!m_options.m_str.empty())
1277 {
Greg Clayton63094e02010-06-23 01:19:29 +00001278 if (LookupSymbolInModule (interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
Chris Lattner24943d22010-06-08 16:52:24 +00001279 {
1280 result.SetStatus(eReturnStatusSuccessFinishResult);
1281 return true;
1282 }
1283 }
1284 break;
1285
1286 case eLookupTypeFileLine:
1287 if (m_options.m_file)
1288 {
1289
Greg Clayton63094e02010-06-23 01:19:29 +00001290 if (LookupFileAndLineInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001291 result.GetOutputStream(),
1292 module,
1293 m_options.m_file,
1294 m_options.m_line_number,
1295 m_options.m_check_inlines))
1296 {
1297 result.SetStatus(eReturnStatusSuccessFinishResult);
1298 return true;
1299 }
1300 }
1301 break;
1302
1303 case eLookupTypeFunction:
1304 if (!m_options.m_str.empty())
1305 {
Greg Clayton63094e02010-06-23 01:19:29 +00001306 if (LookupFunctionInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001307 result.GetOutputStream(),
1308 module,
1309 m_options.m_str.c_str(),
1310 m_options.m_use_regex))
1311 {
1312 result.SetStatus(eReturnStatusSuccessFinishResult);
1313 return true;
1314 }
1315 }
1316 break;
1317
1318 default:
1319 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
1320 syntax_error = true;
1321 break;
1322 }
1323
1324 result.SetStatus (eReturnStatusFailed);
1325 return false;
1326 }
1327
1328 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001329 Execute (CommandInterpreter &interpreter,
1330 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001331 CommandReturnObject &result)
1332 {
Greg Clayton63094e02010-06-23 01:19:29 +00001333 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001334 if (target == NULL)
1335 {
1336 result.AppendError ("invalid target, set executable file using 'file' command");
1337 result.SetStatus (eReturnStatusFailed);
1338 return false;
1339 }
1340 else
1341 {
1342 bool syntax_error = false;
1343 uint32_t i;
1344 uint32_t num_successful_lookups = 0;
1345 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1346 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1347 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1348 // Dump all sections for all modules images
1349
1350 if (command.GetArgumentCount() == 0)
1351 {
1352 // Dump all sections for all modules images
1353 const uint32_t num_modules = target->GetImages().GetSize();
1354 if (num_modules > 0)
1355 {
1356 for (i = 0; i<num_modules && syntax_error == false; ++i)
1357 {
Greg Clayton63094e02010-06-23 01:19:29 +00001358 if (LookupInModule (interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001359 {
1360 result.GetOutputStream().EOL();
1361 num_successful_lookups++;
1362 }
1363 }
1364 }
1365 else
1366 {
1367 result.AppendError ("the target has no associated executable images");
1368 result.SetStatus (eReturnStatusFailed);
1369 return false;
1370 }
1371 }
1372 else
1373 {
1374 // Dump specified images (by basename or fullpath)
1375 const char *arg_cstr;
1376 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
1377 {
1378 FileSpec image_file(arg_cstr);
1379 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +00001380 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +00001381
Greg Clayton661825b2010-06-28 23:51:11 +00001382 // Not found in our module list for our target, check the main
1383 // shared module list in case it is a extra file used somewhere
1384 // else
1385 if (num_matching_modules == 0)
1386 num_matching_modules = ModuleList::FindSharedModules (image_file,
1387 target->GetArchitecture(),
1388 NULL,
1389 NULL,
1390 matching_modules);
1391
Chris Lattner24943d22010-06-08 16:52:24 +00001392 if (num_matching_modules > 0)
1393 {
1394 for (size_t i=0; i<num_matching_modules; ++i)
1395 {
1396 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
1397 if (image_module)
1398 {
Greg Clayton63094e02010-06-23 01:19:29 +00001399 if (LookupInModule (interpreter, image_module, result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001400 {
1401 result.GetOutputStream().EOL();
1402 num_successful_lookups++;
1403 }
1404 }
1405 }
1406 }
1407 else
1408 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1409 }
1410 }
1411
1412 if (num_successful_lookups > 0)
1413 result.SetStatus (eReturnStatusSuccessFinishResult);
1414 else
1415 result.SetStatus (eReturnStatusFailed);
1416 }
1417 return result.Succeeded();
1418 }
1419protected:
1420
1421 CommandOptions m_options;
1422};
1423
1424lldb::OptionDefinition
1425CommandObjectImageLookup::CommandOptions::g_option_table[] =
1426{
Jim Ingham34e9a982010-06-15 18:47:14 +00001427{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, "<addr>", "Lookup an address in one or more executable images."},
1428{ 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."},
1429{ 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."},
1430{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, NULL, "The <name> argument for name lookups are regular expressions."},
1431{ 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."},
1432{ 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)."},
1433{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, NULL, "Check inline line entries (must be used in conjunction with --file)."},
1434{ 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 +00001435{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1436};
1437
1438
1439
1440
1441
1442//----------------------------------------------------------------------
1443// CommandObjectImage constructor
1444//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001445CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +00001446 CommandObjectMultiword ("image",
Greg Clayton63094e02010-06-23 01:19:29 +00001447 "Access information for one or more executable images.",
1448 "image [dump|list] ...")
Chris Lattner24943d22010-06-08 16:52:24 +00001449{
Greg Clayton63094e02010-06-23 01:19:29 +00001450 LoadSubCommand (interpreter, "dump", CommandObjectSP (new CommandObjectImageDump (interpreter)));
1451 LoadSubCommand (interpreter, "list", CommandObjectSP (new CommandObjectImageList ()));
1452 LoadSubCommand (interpreter, "lookup", CommandObjectSP (new CommandObjectImageLookup ()));
Chris Lattner24943d22010-06-08 16:52:24 +00001453}
1454
1455//----------------------------------------------------------------------
1456// Destructor
1457//----------------------------------------------------------------------
1458CommandObjectImage::~CommandObjectImage()
1459{
1460}
1461