blob: b6b0d2469e985ca00651ffbf8935a1c159176d52 [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();
Greg Clayton70436352010-06-30 23:03:03 +0000234 strm.Indent (" Summary: ");
Chris Lattner24943d22010-06-08 16:52:24 +0000235 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
Greg Clayton70436352010-06-30 23:03:03 +0000236 strm.EOL();
237 if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext))
238 strm.EOL();
Greg Clayton12bec712010-06-28 21:30:43 +0000239 strm.IndentLess();
Chris Lattner24943d22010-06-08 16:52:24 +0000240 return true;
241 }
242
243 return false;
244}
245
246static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000247LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000248{
249 if (module)
250 {
251 SymbolContext sc;
252
253 ObjectFile *objfile = module->GetObjectFile ();
254 if (objfile)
255 {
256 Symtab *symtab = objfile->GetSymtab();
257 if (symtab)
258 {
259 uint32_t i;
260 std::vector<uint32_t> match_indexes;
261 ConstString symbol_name (name);
262 uint32_t num_matches = 0;
263 if (name_is_regex)
264 {
265 RegularExpression name_regexp(name);
266 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp, eSymbolTypeAny,
267 match_indexes);
268 }
269 else
270 {
271 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
272 }
273
274
275 if (num_matches > 0)
276 {
277 strm.Indent ();
278 strm.Printf("%u symbols match %s'%s' in ", num_matches,
279 name_is_regex ? "the regular expression " : "", name);
280 DumpFullpath (strm, &module->GetFileSpec(), 0);
281 strm.PutCString(":\n");
282 strm.IndentMore ();
283 Symtab::DumpSymbolHeader (&strm);
284 for (i=0; i < num_matches; ++i)
285 {
286 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
287 strm.Indent ();
Greg Clayton63094e02010-06-23 01:19:29 +0000288 symbol->Dump (&strm, interpreter.GetDebugger().GetExecutionContext().process, i);
Chris Lattner24943d22010-06-08 16:52:24 +0000289 }
290 strm.IndentLess ();
291 return num_matches;
292 }
293 }
294 }
295 }
296 return 0;
297}
298
299
300static void
Greg Clayton63094e02010-06-23 01:19:29 +0000301DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000302{
303 strm.IndentMore ();
304 uint32_t i;
305 const uint32_t num_matches = sc_list.GetSize();
306
307 for (i=0; i<num_matches; ++i)
308 {
309 SymbolContext sc;
310 if (sc_list.GetContextAtIndex(i, sc))
311 {
312 strm.Indent();
313 if (prepend_addr)
314 {
315 if (sc.line_entry.range.GetBaseAddress().IsValid())
316 {
317 lldb::addr_t vm_addr =
Greg Clayton63094e02010-06-23 01:19:29 +0000318 sc.line_entry.range.GetBaseAddress().GetLoadAddress(interpreter.GetDebugger().GetExecutionContext().process);
Chris Lattner24943d22010-06-08 16:52:24 +0000319 int addr_size = sizeof (addr_t);
Greg Clayton63094e02010-06-23 01:19:29 +0000320 Process *process = interpreter.GetDebugger().GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000321 if (process)
322 addr_size = process->GetAddressByteSize();
323 if (vm_addr != LLDB_INVALID_ADDRESS)
324 strm.Address (vm_addr, addr_size);
325 else
326 sc.line_entry.range.GetBaseAddress().Dump (&strm, NULL, Address::DumpStyleSectionNameOffset);
327
328 strm.PutCString(" in ");
329 }
330 }
Greg Clayton63094e02010-06-23 01:19:29 +0000331 sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress());
Chris Lattner24943d22010-06-08 16:52:24 +0000332 }
333 }
334 strm.IndentLess ();
335}
336
337static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000338LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000339{
340 if (module && name && name[0])
341 {
342 SymbolContextList sc_list;
343
344 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
345 if (symbol_vendor)
346 {
347 uint32_t num_matches = 0;
348 if (name_is_regex)
349 {
350 RegularExpression function_name_regex (name);
351 num_matches = symbol_vendor->FindFunctions(function_name_regex, true, sc_list);
352
353 }
354 else
355 {
356 ConstString function_name(name);
Greg Clayton12bec712010-06-28 21:30:43 +0000357 num_matches = symbol_vendor->FindFunctions(function_name, eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000358 }
359
360 if (num_matches)
361 {
362 strm.Indent ();
363 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
364 DumpFullpath (strm, &module->GetFileSpec(), 0);
365 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000366 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000367 }
368 return num_matches;
369 }
370 }
371 return 0;
372}
373
374static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000375LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines)
Chris Lattner24943d22010-06-08 16:52:24 +0000376{
377 if (module && file_spec)
378 {
379 SymbolContextList sc_list;
380 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
381 eSymbolContextEverything, sc_list);
382 if (num_matches > 0)
383 {
384 strm.Indent ();
385 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
386 strm << file_spec;
387 if (line > 0)
388 strm.Printf (":%u", line);
389 strm << " in ";
390 DumpFullpath (strm, &module->GetFileSpec(), 0);
391 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000392 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000393 return num_matches;
394 }
395 }
396 return 0;
397
398}
399
400
401//----------------------------------------------------------------------
402// Image symbol table dumping command
403//----------------------------------------------------------------------
404
405class CommandObjectImageDumpModuleList : public CommandObject
406{
407public:
408
409 CommandObjectImageDumpModuleList (const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000410 const char *help,
411 const char *syntax) :
Chris Lattner24943d22010-06-08 16:52:24 +0000412 CommandObject (name, help, syntax)
413 {
414 }
415
416 virtual
417 ~CommandObjectImageDumpModuleList ()
418 {
419 }
420
421 virtual int
Greg Clayton63094e02010-06-23 01:19:29 +0000422 HandleArgumentCompletion (CommandInterpreter &interpreter,
423 Args &input,
424 int &cursor_index,
425 int &cursor_char_position,
426 OptionElementVector &opt_element_vector,
427 int match_start_point,
428 int max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000429 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000430 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000431 {
432 // Arguments are the standard module completer.
433 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
434 completion_str.erase (cursor_char_position);
435
Greg Clayton63094e02010-06-23 01:19:29 +0000436 CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
437 CommandCompletions::eModuleCompletion,
438 completion_str.c_str(),
439 match_start_point,
440 max_return_elements,
441 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000442 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000443 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000444 return matches.GetSize();
445 }
446};
447
448class CommandObjectImageDumpSourceFileList : public CommandObject
449{
450public:
451
452 CommandObjectImageDumpSourceFileList (const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000453 const char *help,
454 const char *syntax) :
Chris Lattner24943d22010-06-08 16:52:24 +0000455 CommandObject (name, help, syntax)
456 {
457 }
458
459 virtual
460 ~CommandObjectImageDumpSourceFileList ()
461 {
462 }
463
464 virtual int
Greg Clayton63094e02010-06-23 01:19:29 +0000465 HandleArgumentCompletion (CommandInterpreter &interpreter,
466 Args &input,
467 int &cursor_index,
468 int &cursor_char_position,
469 OptionElementVector &opt_element_vector,
470 int match_start_point,
471 int max_return_elements,
Greg Clayton54e7afa2010-07-09 20:39:50 +0000472 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000473 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000474 {
475 // Arguments are the standard source file completer.
476 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
477 completion_str.erase (cursor_char_position);
478
Greg Clayton63094e02010-06-23 01:19:29 +0000479 CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
480 CommandCompletions::eSourceFileCompletion,
481 completion_str.c_str(),
482 match_start_point,
483 max_return_elements,
484 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000485 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000486 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000487 return matches.GetSize();
488 }
489};
490
491
492class CommandObjectImageDumpSymtab : public CommandObjectImageDumpModuleList
493{
494public:
495 CommandObjectImageDumpSymtab () :
496 CommandObjectImageDumpModuleList ("image dump symtab",
497 "Dump the symbol table from one or more executable images.",
498 "image dump symtab [<file1> ...]")
499 {
500 }
501
502 virtual
503 ~CommandObjectImageDumpSymtab ()
504 {
505 }
506
507 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000508 Execute (CommandInterpreter &interpreter,
509 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000510 CommandReturnObject &result)
511 {
Greg Clayton63094e02010-06-23 01:19:29 +0000512 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000513 if (target == NULL)
514 {
515 result.AppendError ("invalid target, set executable file using 'file' command");
516 result.SetStatus (eReturnStatusFailed);
517 return false;
518 }
519 else
520 {
521 uint32_t num_dumped = 0;
522
523 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
524 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
525 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
526
527 if (command.GetArgumentCount() == 0)
528 {
529 // Dump all sections for all modules images
530 const uint32_t num_modules = target->GetImages().GetSize();
531 if (num_modules > 0)
532 {
533 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
534 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
535 {
536 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000537 DumpModuleSymtab (interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000538 }
539 }
540 else
541 {
542 result.AppendError ("the target has no associated executable images");
543 result.SetStatus (eReturnStatusFailed);
544 return false;
545 }
546 }
547 else
548 {
549 // Dump specified images (by basename or fullpath)
550 const char *arg_cstr;
551 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
552 {
553 FileSpec image_file(arg_cstr);
554 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000555 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000556
Greg Clayton661825b2010-06-28 23:51:11 +0000557 // Not found in our module list for our target, check the main
558 // shared module list in case it is a extra file used somewhere
559 // else
560 if (num_matching_modules == 0)
561 num_matching_modules = ModuleList::FindSharedModules (image_file,
562 target->GetArchitecture(),
563 NULL,
564 NULL,
565 matching_modules);
566
Chris Lattner24943d22010-06-08 16:52:24 +0000567 if (num_matching_modules > 0)
568 {
569 for (size_t i=0; i<num_matching_modules; ++i)
570 {
571 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
572 if (image_module)
573 {
574 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000575 DumpModuleSymtab (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000576 }
577 }
578 }
579 else
580 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
581 }
582 }
583
584 if (num_dumped > 0)
585 result.SetStatus (eReturnStatusSuccessFinishResult);
586 else
587 {
588 result.AppendError ("no matching executable images found");
589 result.SetStatus (eReturnStatusFailed);
590 }
591 }
592 return result.Succeeded();
593 }
594
595};
596
597//----------------------------------------------------------------------
598// Image section dumping command
599//----------------------------------------------------------------------
600class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList
601{
602public:
603 CommandObjectImageDumpSections () :
Greg Clayton63094e02010-06-23 01:19:29 +0000604 CommandObjectImageDumpModuleList ("image dump sections",
605 "Dump the sections from one or more executable images.",
606 "image dump sections [<file1> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000607 {
608 }
609
610 virtual
611 ~CommandObjectImageDumpSections ()
612 {
613 }
614
615 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000616 Execute (CommandInterpreter &interpreter,
617 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000618 CommandReturnObject &result)
619 {
Greg Clayton63094e02010-06-23 01:19:29 +0000620 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000621 if (target == NULL)
622 {
623 result.AppendError ("invalid target, set executable file using 'file' command");
624 result.SetStatus (eReturnStatusFailed);
625 return false;
626 }
627 else
628 {
629 uint32_t num_dumped = 0;
630
631 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
632 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
633 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
634
635 if (command.GetArgumentCount() == 0)
636 {
637 // Dump all sections for all modules images
638 const uint32_t num_modules = target->GetImages().GetSize();
639 if (num_modules > 0)
640 {
641 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
642 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
643 {
644 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000645 DumpModuleSections (interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000646 }
647 }
648 else
649 {
650 result.AppendError ("the target has no associated executable images");
651 result.SetStatus (eReturnStatusFailed);
652 return false;
653 }
654 }
655 else
656 {
657 // Dump specified images (by basename or fullpath)
658 const char *arg_cstr;
659 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
660 {
661 FileSpec image_file(arg_cstr);
662 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000663 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000664
Greg Clayton661825b2010-06-28 23:51:11 +0000665 // Not found in our module list for our target, check the main
666 // shared module list in case it is a extra file used somewhere
667 // else
668 if (num_matching_modules == 0)
669 num_matching_modules = ModuleList::FindSharedModules (image_file,
670 target->GetArchitecture(),
671 NULL,
672 NULL,
673 matching_modules);
674
Chris Lattner24943d22010-06-08 16:52:24 +0000675 if (num_matching_modules > 0)
676 {
677 for (size_t i=0; i<num_matching_modules; ++i)
678 {
679 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
680 if (image_module)
681 {
682 num_dumped++;
Greg Clayton63094e02010-06-23 01:19:29 +0000683 DumpModuleSections (interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000684 }
685 }
686 }
687 else
688 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
689 }
690 }
691
692 if (num_dumped > 0)
693 result.SetStatus (eReturnStatusSuccessFinishResult);
694 else
695 {
696 result.AppendError ("no matching executable images found");
697 result.SetStatus (eReturnStatusFailed);
698 }
699 }
700 return result.Succeeded();
701 }
702};
703
704//----------------------------------------------------------------------
705// Image debug symbol dumping command
706//----------------------------------------------------------------------
707class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList
708{
709public:
710 CommandObjectImageDumpSymfile () :
711 CommandObjectImageDumpModuleList ("image dump symfile",
712 "Dump the debug symbol file for one or more executable images.",
713 "image dump symfile [<file1> ...]")
714 {
715 }
716
717 virtual
718 ~CommandObjectImageDumpSymfile ()
719 {
720 }
721
722 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000723 Execute (CommandInterpreter &interpreter,
724 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000725 CommandReturnObject &result)
726 {
Greg Clayton63094e02010-06-23 01:19:29 +0000727 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000728 if (target == NULL)
729 {
730 result.AppendError ("invalid target, set executable file using 'file' command");
731 result.SetStatus (eReturnStatusFailed);
732 return false;
733 }
734 else
735 {
736 uint32_t num_dumped = 0;
737
738 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
739 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
740 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
741
742 if (command.GetArgumentCount() == 0)
743 {
744 // Dump all sections for all modules images
745 const uint32_t num_modules = target->GetImages().GetSize();
746 if (num_modules > 0)
747 {
748 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
749 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
750 {
751 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
752 num_dumped++;
753 }
754 }
755 else
756 {
757 result.AppendError ("the target has no associated executable images");
758 result.SetStatus (eReturnStatusFailed);
759 return false;
760 }
761 }
762 else
763 {
764 // Dump specified images (by basename or fullpath)
765 const char *arg_cstr;
766 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
767 {
768 FileSpec image_file(arg_cstr);
769 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000770 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000771
Greg Clayton661825b2010-06-28 23:51:11 +0000772 // Not found in our module list for our target, check the main
773 // shared module list in case it is a extra file used somewhere
774 // else
775 if (num_matching_modules == 0)
776 num_matching_modules = ModuleList::FindSharedModules (image_file,
777 target->GetArchitecture(),
778 NULL,
779 NULL,
780 matching_modules);
781
Chris Lattner24943d22010-06-08 16:52:24 +0000782 if (num_matching_modules > 0)
783 {
784 for (size_t i=0; i<num_matching_modules; ++i)
785 {
786 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
787 if (image_module)
788 {
789 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
790 num_dumped++;
791 }
792 }
793 }
794 else
795 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
796 }
797 }
798
799 if (num_dumped > 0)
800 result.SetStatus (eReturnStatusSuccessFinishResult);
801 else
802 {
803 result.AppendError ("no matching executable images found");
804 result.SetStatus (eReturnStatusFailed);
805 }
806 }
807 return result.Succeeded();
808 }
809};
810
811//----------------------------------------------------------------------
812// Image debug symbol dumping command
813//----------------------------------------------------------------------
814class CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList
815{
816public:
817 CommandObjectImageDumpLineTable () :
818 CommandObjectImageDumpSourceFileList ("image dump line-table",
819 "Dump the debug symbol file for one or more executable images.",
820 "image dump line-table <file1> [<file2> ...]")
821 {
822 }
823
824 virtual
825 ~CommandObjectImageDumpLineTable ()
826 {
827 }
828
829 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000830 Execute (CommandInterpreter &interpreter,
831 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000832 CommandReturnObject &result)
833 {
Greg Clayton63094e02010-06-23 01:19:29 +0000834 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000835 if (target == NULL)
836 {
837 result.AppendError ("invalid target, set executable file using 'file' command");
838 result.SetStatus (eReturnStatusFailed);
839 return false;
840 }
841 else
842 {
Greg Clayton63094e02010-06-23 01:19:29 +0000843 ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000844 uint32_t total_num_dumped = 0;
845
846 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
847 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
848 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
849
850 if (command.GetArgumentCount() == 0)
851 {
852 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
853 result.SetStatus (eReturnStatusFailed);
854 }
855 else
856 {
857 // Dump specified images (by basename or fullpath)
858 const char *arg_cstr;
859 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
860 {
861 FileSpec file_spec(arg_cstr);
862 const uint32_t num_modules = target->GetImages().GetSize();
863 if (num_modules > 0)
864 {
865 uint32_t num_dumped = 0;
866 for (uint32_t i = 0; i<num_modules; ++i)
867 {
Greg Clayton63094e02010-06-23 01:19:29 +0000868 if (DumpCompileUnitLineTable (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000869 result.GetOutputStream(),
870 target->GetImages().GetModulePointerAtIndex(i),
871 file_spec,
872 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
873 num_dumped++;
874 }
875 if (num_dumped == 0)
876 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
877 else
878 total_num_dumped += num_dumped;
879 }
880 }
881 }
882
883 if (total_num_dumped > 0)
884 result.SetStatus (eReturnStatusSuccessFinishResult);
885 else
886 {
887 result.AppendError ("no source filenames matched any command arguments");
888 result.SetStatus (eReturnStatusFailed);
889 }
890 }
891 return result.Succeeded();
892 }
893};
894
895//----------------------------------------------------------------------
896// Dump multi-word command
897//----------------------------------------------------------------------
898class CommandObjectImageDump : public CommandObjectMultiword
899{
900public:
901
902 //------------------------------------------------------------------
903 // Constructors and Destructors
904 //------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +0000905 CommandObjectImageDump(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +0000906 CommandObjectMultiword ("image dump",
Greg Clayton63094e02010-06-23 01:19:29 +0000907 "Dumps information in one or more executable images; 'line-table' expects a source file name",
908 "image dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000909 {
Greg Clayton63094e02010-06-23 01:19:29 +0000910 LoadSubCommand (interpreter, "symtab", CommandObjectSP (new CommandObjectImageDumpSymtab ()));
911 LoadSubCommand (interpreter, "sections", CommandObjectSP (new CommandObjectImageDumpSections ()));
912 LoadSubCommand (interpreter, "symfile", CommandObjectSP (new CommandObjectImageDumpSymfile ()));
913 LoadSubCommand (interpreter, "line-table", CommandObjectSP (new CommandObjectImageDumpLineTable ()));
Chris Lattner24943d22010-06-08 16:52:24 +0000914 }
915
916 virtual
917 ~CommandObjectImageDump()
918 {
919 }
920};
921
922//----------------------------------------------------------------------
923// List images with associated information
924//----------------------------------------------------------------------
925class CommandObjectImageList : public CommandObject
926{
927public:
928
929 class CommandOptions : public Options
930 {
931 public:
932
933 CommandOptions () :
934 Options(),
935 m_format_array()
936 {
937 }
938
939 virtual
940 ~CommandOptions ()
941 {
942 }
943
944 virtual Error
945 SetOptionValue (int option_idx, const char *option_arg)
946 {
947 char short_option = (char) m_getopt_table[option_idx].val;
948 uint32_t width = 0;
949 if (option_arg)
950 width = strtoul (option_arg, NULL, 0);
951 m_format_array.push_back(std::make_pair(short_option, width));
952 Error error;
953 return error;
954 }
955
956 void
957 ResetOptionValues ()
958 {
959 Options::ResetOptionValues();
960 m_format_array.clear();
961 }
962
963 const lldb::OptionDefinition*
964 GetDefinitions ()
965 {
966 return g_option_table;
967 }
968
969 // Options table: Required for subclasses of Options.
970
971 static lldb::OptionDefinition g_option_table[];
972
973 // Instance variables to hold the values for command options.
974 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
975 FormatWidthCollection m_format_array;
976 };
977
978 CommandObjectImageList () :
979 CommandObject (
980 "image list",
981 "List current executable and dependent shared library images.",
982 "image list [<cmd-options>]")
983 {
984 }
985
986 virtual
987 ~CommandObjectImageList ()
988 {
989 }
990
991 virtual
992 Options *
993 GetOptions ()
994 {
995 return &m_options;
996 }
997
998 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000999 Execute (CommandInterpreter &interpreter,
1000 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001001 CommandReturnObject &result)
1002 {
Greg Clayton63094e02010-06-23 01:19:29 +00001003 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001004 if (target == NULL)
1005 {
1006 result.AppendError ("invalid target, set executable file using 'file' command");
1007 result.SetStatus (eReturnStatusFailed);
1008 return false;
1009 }
1010 else
1011 {
1012 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1013 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1014 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1015 // Dump all sections for all modules images
1016 const uint32_t num_modules = target->GetImages().GetSize();
1017 if (num_modules > 0)
1018 {
1019 Stream &strm = result.GetOutputStream();
1020
1021 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1022 {
1023 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
1024 strm.Printf("[%3u] ", image_idx);
1025
1026 if (m_options.m_format_array.empty())
1027 {
1028 DumpFullpath(strm, &module->GetFileSpec(), 0);
1029 }
1030 else
1031 {
1032 const size_t num_entries = m_options.m_format_array.size();
1033 for (size_t i=0; i<num_entries; ++i)
1034 {
1035 if (i > 0)
1036 strm.PutChar(' ');
1037 char format_char = m_options.m_format_array[i].first;
1038 uint32_t width = m_options.m_format_array[i].second;
1039 switch (format_char)
1040 {
1041 case 'a':
1042 DumpModuleArchitecture (strm, module, width);
1043 break;
1044
1045 case 'f':
1046 DumpFullpath (strm, &module->GetFileSpec(), width);
1047 break;
1048
1049 case 'd':
1050 DumpDirectory (strm, &module->GetFileSpec(), width);
1051 break;
1052
1053 case 'b':
1054 DumpBasename (strm, &module->GetFileSpec(), width);
1055 break;
1056
1057 case 's':
1058 case 'S':
1059 {
1060 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1061 if (symbol_vendor)
1062 {
1063 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
1064 if (symbol_file)
1065 {
1066 if (format_char == 'S')
1067 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1068 else
1069 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1070 break;
1071 }
1072 }
1073 strm.Printf("%.*s", width, "<NONE>");
1074 }
1075 break;
1076
1077 case 'u':
1078 DumpModuleUUID(strm, module);
1079 break;
1080
1081 default:
1082 break;
1083 }
1084 }
1085 }
1086 strm.EOL();
1087 }
1088 result.SetStatus (eReturnStatusSuccessFinishResult);
1089 }
1090 else
1091 {
1092 result.AppendError ("the target has no associated executable images");
1093 result.SetStatus (eReturnStatusFailed);
1094 return false;
1095 }
1096 }
1097 return result.Succeeded();
1098 }
1099protected:
1100
1101 CommandOptions m_options;
1102};
1103
1104lldb::OptionDefinition
1105CommandObjectImageList::CommandOptions::g_option_table[] =
1106{
Jim Ingham34e9a982010-06-15 18:47:14 +00001107{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, "<width>", "Display the architecture when listing images."},
1108{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, NULL, "Display the UUID when listing images."},
1109{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image object file."},
1110{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, "<width>", "Display the directory with optional width for the image object file."},
1111{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, "<width>", "Display the basename with optional width for the image object file."},
1112{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, "<width>", "Display the fullpath to the image symbol file with optional width."},
1113{ 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 +00001114{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1115};
1116
1117
1118
1119//----------------------------------------------------------------------
1120// Lookup information in images
1121//----------------------------------------------------------------------
1122class CommandObjectImageLookup : public CommandObject
1123{
1124public:
1125
1126 enum
1127 {
1128 eLookupTypeInvalid = -1,
1129 eLookupTypeAddress = 0,
1130 eLookupTypeSymbol,
1131 eLookupTypeFileLine, // Line is optional
1132 eLookupTypeFunction,
1133 kNumLookupTypes
1134 };
1135
1136 class CommandOptions : public Options
1137 {
1138 public:
1139
1140 CommandOptions () :
1141 Options()
1142 {
1143 ResetOptionValues();
1144 }
1145
1146 virtual
1147 ~CommandOptions ()
1148 {
1149 }
1150
1151 virtual Error
1152 SetOptionValue (int option_idx, const char *option_arg)
1153 {
1154 Error error;
1155
1156 char short_option = (char) m_getopt_table[option_idx].val;
1157
1158 switch (short_option)
1159 {
1160 case 'a':
1161 m_type = eLookupTypeAddress;
1162 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1163 if (m_addr == LLDB_INVALID_ADDRESS)
1164 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
1165 break;
1166
1167 case 'o':
1168 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1169 if (m_offset == LLDB_INVALID_ADDRESS)
1170 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
1171 break;
1172
1173 case 's':
1174 m_str = option_arg;
1175 m_type = eLookupTypeSymbol;
1176 break;
1177
1178 case 'f':
1179 m_file.SetFile (option_arg);
1180 m_type = eLookupTypeFileLine;
1181 break;
1182
1183 case 'i':
1184 m_check_inlines = false;
1185 break;
1186
1187 case 'l':
1188 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
1189 if (m_line_number == UINT32_MAX)
1190 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
1191 else if (m_line_number == 0)
1192 error.SetErrorString ("Zero is an invalid line number.");
1193 m_type = eLookupTypeFileLine;
1194 break;
1195
1196 case 'n':
1197 m_str = option_arg;
1198 m_type = eLookupTypeFunction;
1199 break;
1200
1201 case 'r':
1202 m_use_regex = true;
1203 break;
1204 }
1205
1206 return error;
1207 }
1208
1209 void
1210 ResetOptionValues ()
1211 {
1212 Options::ResetOptionValues();
1213 m_type = eLookupTypeInvalid;
1214 m_str.clear();
1215 m_file.Clear();
1216 m_addr = LLDB_INVALID_ADDRESS;
1217 m_offset = 0;
1218 m_line_number = 0;
1219 m_use_regex = false;
1220 m_check_inlines = true;
1221 }
1222
1223 const lldb::OptionDefinition*
1224 GetDefinitions ()
1225 {
1226 return g_option_table;
1227 }
1228
1229 // Options table: Required for subclasses of Options.
1230
1231 static lldb::OptionDefinition g_option_table[];
1232 int m_type; // Should be a eLookupTypeXXX enum after parsing options
1233 std::string m_str; // Holds name lookup
1234 FileSpec m_file; // Files for file lookups
1235 lldb::addr_t m_addr; // Holds the address to lookup
1236 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
1237 uint32_t m_line_number; // Line number for file+line lookups
1238 bool m_use_regex; // Name lookups in m_str are regular expressions.
1239 bool m_check_inlines;// Check for inline entries when looking up by file/line.
1240 };
1241
1242 CommandObjectImageLookup () :
1243 CommandObject (
1244 "image lookup",
1245 "Look up information within executable and dependent shared library images.",
1246 "image lookup [<cmd-options>] [<file1>...]")
1247 {
1248 }
1249
1250 virtual
1251 ~CommandObjectImageLookup ()
1252 {
1253 }
1254
1255 virtual
1256 Options *
1257 GetOptions ()
1258 {
1259 return &m_options;
1260 }
1261
1262
1263 bool
Greg Clayton63094e02010-06-23 01:19:29 +00001264 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
Chris Lattner24943d22010-06-08 16:52:24 +00001265 {
1266 switch (m_options.m_type)
1267 {
1268 case eLookupTypeAddress:
1269 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
1270 {
Greg Clayton63094e02010-06-23 01:19:29 +00001271 if (LookupAddressInModule (interpreter, result.GetOutputStream(), module, eSymbolContextEverything, m_options.m_addr, m_options.m_offset))
Chris Lattner24943d22010-06-08 16:52:24 +00001272 {
1273 result.SetStatus(eReturnStatusSuccessFinishResult);
1274 return true;
1275 }
1276 }
1277 break;
1278
1279 case eLookupTypeSymbol:
1280 if (!m_options.m_str.empty())
1281 {
Greg Clayton63094e02010-06-23 01:19:29 +00001282 if (LookupSymbolInModule (interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
Chris Lattner24943d22010-06-08 16:52:24 +00001283 {
1284 result.SetStatus(eReturnStatusSuccessFinishResult);
1285 return true;
1286 }
1287 }
1288 break;
1289
1290 case eLookupTypeFileLine:
1291 if (m_options.m_file)
1292 {
1293
Greg Clayton63094e02010-06-23 01:19:29 +00001294 if (LookupFileAndLineInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001295 result.GetOutputStream(),
1296 module,
1297 m_options.m_file,
1298 m_options.m_line_number,
1299 m_options.m_check_inlines))
1300 {
1301 result.SetStatus(eReturnStatusSuccessFinishResult);
1302 return true;
1303 }
1304 }
1305 break;
1306
1307 case eLookupTypeFunction:
1308 if (!m_options.m_str.empty())
1309 {
Greg Clayton63094e02010-06-23 01:19:29 +00001310 if (LookupFunctionInModule (interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001311 result.GetOutputStream(),
1312 module,
1313 m_options.m_str.c_str(),
1314 m_options.m_use_regex))
1315 {
1316 result.SetStatus(eReturnStatusSuccessFinishResult);
1317 return true;
1318 }
1319 }
1320 break;
1321
1322 default:
1323 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
1324 syntax_error = true;
1325 break;
1326 }
1327
1328 result.SetStatus (eReturnStatusFailed);
1329 return false;
1330 }
1331
1332 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +00001333 Execute (CommandInterpreter &interpreter,
1334 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001335 CommandReturnObject &result)
1336 {
Greg Clayton63094e02010-06-23 01:19:29 +00001337 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001338 if (target == NULL)
1339 {
1340 result.AppendError ("invalid target, set executable file using 'file' command");
1341 result.SetStatus (eReturnStatusFailed);
1342 return false;
1343 }
1344 else
1345 {
1346 bool syntax_error = false;
1347 uint32_t i;
1348 uint32_t num_successful_lookups = 0;
1349 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1350 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1351 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1352 // Dump all sections for all modules images
1353
1354 if (command.GetArgumentCount() == 0)
1355 {
1356 // Dump all sections for all modules images
1357 const uint32_t num_modules = target->GetImages().GetSize();
1358 if (num_modules > 0)
1359 {
1360 for (i = 0; i<num_modules && syntax_error == false; ++i)
1361 {
Greg Clayton63094e02010-06-23 01:19:29 +00001362 if (LookupInModule (interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001363 {
1364 result.GetOutputStream().EOL();
1365 num_successful_lookups++;
1366 }
1367 }
1368 }
1369 else
1370 {
1371 result.AppendError ("the target has no associated executable images");
1372 result.SetStatus (eReturnStatusFailed);
1373 return false;
1374 }
1375 }
1376 else
1377 {
1378 // Dump specified images (by basename or fullpath)
1379 const char *arg_cstr;
1380 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
1381 {
1382 FileSpec image_file(arg_cstr);
1383 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +00001384 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +00001385
Greg Clayton661825b2010-06-28 23:51:11 +00001386 // Not found in our module list for our target, check the main
1387 // shared module list in case it is a extra file used somewhere
1388 // else
1389 if (num_matching_modules == 0)
1390 num_matching_modules = ModuleList::FindSharedModules (image_file,
1391 target->GetArchitecture(),
1392 NULL,
1393 NULL,
1394 matching_modules);
1395
Chris Lattner24943d22010-06-08 16:52:24 +00001396 if (num_matching_modules > 0)
1397 {
Greg Claytonbef15832010-07-14 00:18:15 +00001398 for (size_t j=0; j<num_matching_modules; ++j)
Chris Lattner24943d22010-06-08 16:52:24 +00001399 {
Greg Claytonbef15832010-07-14 00:18:15 +00001400 Module * image_module = matching_modules.GetModulePointerAtIndex(j);
Chris Lattner24943d22010-06-08 16:52:24 +00001401 if (image_module)
1402 {
Greg Clayton63094e02010-06-23 01:19:29 +00001403 if (LookupInModule (interpreter, image_module, result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001404 {
1405 result.GetOutputStream().EOL();
1406 num_successful_lookups++;
1407 }
1408 }
1409 }
1410 }
1411 else
1412 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1413 }
1414 }
1415
1416 if (num_successful_lookups > 0)
1417 result.SetStatus (eReturnStatusSuccessFinishResult);
1418 else
1419 result.SetStatus (eReturnStatusFailed);
1420 }
1421 return result.Succeeded();
1422 }
1423protected:
1424
1425 CommandOptions m_options;
1426};
1427
1428lldb::OptionDefinition
1429CommandObjectImageLookup::CommandOptions::g_option_table[] =
1430{
Jim Ingham34e9a982010-06-15 18:47:14 +00001431{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, "<addr>", "Lookup an address in one or more executable images."},
1432{ 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."},
1433{ 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."},
1434{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, NULL, "The <name> argument for name lookups are regular expressions."},
1435{ 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."},
1436{ 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)."},
1437{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, NULL, "Check inline line entries (must be used in conjunction with --file)."},
1438{ 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 +00001439{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1440};
1441
1442
1443
1444
1445
1446//----------------------------------------------------------------------
1447// CommandObjectImage constructor
1448//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001449CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +00001450 CommandObjectMultiword ("image",
Greg Clayton63094e02010-06-23 01:19:29 +00001451 "Access information for one or more executable images.",
1452 "image [dump|list] ...")
Chris Lattner24943d22010-06-08 16:52:24 +00001453{
Greg Clayton63094e02010-06-23 01:19:29 +00001454 LoadSubCommand (interpreter, "dump", CommandObjectSP (new CommandObjectImageDump (interpreter)));
1455 LoadSubCommand (interpreter, "list", CommandObjectSP (new CommandObjectImageList ()));
1456 LoadSubCommand (interpreter, "lookup", CommandObjectSP (new CommandObjectImageLookup ()));
Chris Lattner24943d22010-06-08 16:52:24 +00001457}
1458
1459//----------------------------------------------------------------------
1460// Destructor
1461//----------------------------------------------------------------------
1462CommandObjectImage::~CommandObjectImage()
1463{
1464}
1465