blob: ebbc0f1c8403a8ef133ee111d500230e6d1c92f1 [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,
Greg Claytoneea26402010-09-14 23:36:40 +000090 interpreter.GetDebugger().GetExecutionContext().target,
Greg Clayton63094e02010-06-23 01:19:29 +000091 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 Clayton8d3802d2010-10-08 04:20:14 +0000159DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, lldb::SortOrder sort_order)
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 Clayton8d3802d2010-10-08 04:20:14 +0000168 symtab->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, sort_order);
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 Clayton3fed8b92010-10-08 00:21:05 +0000183 {
184 strm.PutCString ("Sections for '");
185 strm << module->GetFileSpec();
186 strm.Printf ("' (%s):\n", module->GetArchitecture().AsCString());
187 strm.IndentMore();
Greg Claytoneea26402010-09-14 23:36:40 +0000188 section_list->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, true);
Greg Clayton3fed8b92010-10-08 00:21:05 +0000189 strm.IndentLess();
190 }
Chris Lattner24943d22010-06-08 16:52:24 +0000191 }
192 }
193}
194
195static bool
196DumpModuleSymbolVendor (Stream &strm, Module *module)
197{
198 if (module)
199 {
200 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
201 if (symbol_vendor)
202 {
203 symbol_vendor->Dump(&strm);
204 return true;
205 }
206 }
207 return false;
208}
209
210static bool
Greg Clayton960d6a42010-08-03 00:35:52 +0000211LookupAddressInModule
212(
213 CommandInterpreter &interpreter,
214 Stream &strm,
215 Module *module,
216 uint32_t resolve_mask,
217 lldb::addr_t raw_addr,
218 lldb::addr_t offset,
219 bool verbose
220)
Chris Lattner24943d22010-06-08 16:52:24 +0000221{
222 if (module)
223 {
224 lldb::addr_t addr = raw_addr - offset;
225 Address so_addr;
226 SymbolContext sc;
Greg Claytoneea26402010-09-14 23:36:40 +0000227 Target *target = interpreter.GetDebugger().GetExecutionContext().target;
228 if (target && !target->GetSectionLoadList().IsEmpty())
Chris Lattner24943d22010-06-08 16:52:24 +0000229 {
Greg Claytoneea26402010-09-14 23:36:40 +0000230 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
Chris Lattner24943d22010-06-08 16:52:24 +0000231 return false;
232 else if (so_addr.GetModule() != module)
233 return false;
234 }
235 else
236 {
237 if (!module->ResolveFileAddress (addr, so_addr))
238 return false;
239 }
240
241 // If an offset was given, print out the address we ended up looking up
242 if (offset)
243 strm.Printf("0x%llx: ", addr);
244
Greg Clayton63094e02010-06-23 01:19:29 +0000245 ExecutionContextScope *exe_scope = interpreter.GetDebugger().GetExecutionContext().GetBestExecutionContextScope();
Greg Clayton12bec712010-06-28 21:30:43 +0000246 strm.IndentMore();
247 strm.Indent (" Address: ");
248 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
249 strm.EOL();
Greg Clayton70436352010-06-30 23:03:03 +0000250 strm.Indent (" Summary: ");
Chris Lattner24943d22010-06-08 16:52:24 +0000251 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
Greg Clayton70436352010-06-30 23:03:03 +0000252 strm.EOL();
Greg Clayton960d6a42010-08-03 00:35:52 +0000253 // Print out detailed address information when verbose is enabled
254 if (verbose)
255 {
256 if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext))
257 strm.EOL();
258 }
Greg Clayton12bec712010-06-28 21:30:43 +0000259 strm.IndentLess();
Chris Lattner24943d22010-06-08 16:52:24 +0000260 return true;
261 }
262
263 return false;
264}
265
266static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000267LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000268{
269 if (module)
270 {
271 SymbolContext sc;
272
273 ObjectFile *objfile = module->GetObjectFile ();
274 if (objfile)
275 {
276 Symtab *symtab = objfile->GetSymtab();
277 if (symtab)
278 {
279 uint32_t i;
280 std::vector<uint32_t> match_indexes;
281 ConstString symbol_name (name);
282 uint32_t num_matches = 0;
283 if (name_is_regex)
284 {
285 RegularExpression name_regexp(name);
Greg Clayton7c36fa02010-09-11 03:13:28 +0000286 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
287 eSymbolTypeAny,
Chris Lattner24943d22010-06-08 16:52:24 +0000288 match_indexes);
289 }
290 else
291 {
292 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
293 }
294
295
296 if (num_matches > 0)
297 {
298 strm.Indent ();
299 strm.Printf("%u symbols match %s'%s' in ", num_matches,
300 name_is_regex ? "the regular expression " : "", name);
301 DumpFullpath (strm, &module->GetFileSpec(), 0);
302 strm.PutCString(":\n");
303 strm.IndentMore ();
304 Symtab::DumpSymbolHeader (&strm);
305 for (i=0; i < num_matches; ++i)
306 {
307 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
308 strm.Indent ();
Greg Claytoneea26402010-09-14 23:36:40 +0000309 symbol->Dump (&strm, interpreter.GetDebugger().GetExecutionContext().target, i);
Chris Lattner24943d22010-06-08 16:52:24 +0000310 }
311 strm.IndentLess ();
312 return num_matches;
313 }
314 }
315 }
316 }
317 return 0;
318}
319
320
321static void
Greg Clayton63094e02010-06-23 01:19:29 +0000322DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000323{
324 strm.IndentMore ();
325 uint32_t i;
326 const uint32_t num_matches = sc_list.GetSize();
327
328 for (i=0; i<num_matches; ++i)
329 {
330 SymbolContext sc;
331 if (sc_list.GetContextAtIndex(i, sc))
332 {
333 strm.Indent();
334 if (prepend_addr)
335 {
336 if (sc.line_entry.range.GetBaseAddress().IsValid())
337 {
Greg Claytoneea26402010-09-14 23:36:40 +0000338 lldb::addr_t vm_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(interpreter.GetDebugger().GetExecutionContext().target);
Chris Lattner24943d22010-06-08 16:52:24 +0000339 int addr_size = sizeof (addr_t);
Greg Clayton63094e02010-06-23 01:19:29 +0000340 Process *process = interpreter.GetDebugger().GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000341 if (process)
342 addr_size = process->GetAddressByteSize();
343 if (vm_addr != LLDB_INVALID_ADDRESS)
344 strm.Address (vm_addr, addr_size);
345 else
346 sc.line_entry.range.GetBaseAddress().Dump (&strm, NULL, Address::DumpStyleSectionNameOffset);
347
348 strm.PutCString(" in ");
349 }
350 }
Greg Clayton72b71582010-09-02 21:44:10 +0000351 sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress(), true, true, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000352 }
353 }
354 strm.IndentLess ();
355}
356
357static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000358LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000359{
360 if (module && name && name[0])
361 {
362 SymbolContextList sc_list;
363
364 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
365 if (symbol_vendor)
366 {
367 uint32_t num_matches = 0;
368 if (name_is_regex)
369 {
370 RegularExpression function_name_regex (name);
371 num_matches = symbol_vendor->FindFunctions(function_name_regex, true, sc_list);
372
373 }
374 else
375 {
376 ConstString function_name(name);
Greg Clayton12bec712010-06-28 21:30:43 +0000377 num_matches = symbol_vendor->FindFunctions(function_name, eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000378 }
379
380 if (num_matches)
381 {
382 strm.Indent ();
383 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
384 DumpFullpath (strm, &module->GetFileSpec(), 0);
385 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000386 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000387 }
388 return num_matches;
389 }
390 }
391 return 0;
392}
393
394static uint32_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000395LookupTypeInModule
396(
397 CommandInterpreter &interpreter,
398 Stream &strm,
399 Module *module,
400 const char *name_cstr,
401 bool name_is_regex
402)
403{
404 if (module && name_cstr && name_cstr[0])
405 {
406 SymbolContextList sc_list;
407
408 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
409 if (symbol_vendor)
410 {
411 TypeList type_list;
412 uint32_t num_matches = 0;
413 SymbolContext sc;
414// if (name_is_regex)
415// {
416// RegularExpression name_regex (name_cstr);
417// num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list);
418// }
419// else
420// {
421 ConstString name(name_cstr);
422 num_matches = symbol_vendor->FindTypes(sc, name, true, UINT32_MAX, type_list);
423// }
424
425 if (num_matches)
426 {
427 strm.Indent ();
428 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
429 DumpFullpath (strm, &module->GetFileSpec(), 0);
430 strm.PutCString(":\n");
431 const uint32_t num_types = type_list.GetSize();
432 for (uint32_t i=0; i<num_types; ++i)
433 {
434 TypeSP type_sp (type_list.GetTypeAtIndex(i));
435 if (type_sp)
436 {
437 // Resolve the clang type so that any forward references
438 // to types that haven't yet been parsed will get parsed.
Greg Clayton462d4142010-09-29 01:12:09 +0000439 type_sp->GetClangType ();
Greg Clayton960d6a42010-08-03 00:35:52 +0000440 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
441 }
442 strm.EOL();
443 }
444 }
445 return num_matches;
446 }
447 }
448 return 0;
449}
450
451static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000452LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines)
Chris Lattner24943d22010-06-08 16:52:24 +0000453{
454 if (module && file_spec)
455 {
456 SymbolContextList sc_list;
457 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
458 eSymbolContextEverything, sc_list);
459 if (num_matches > 0)
460 {
461 strm.Indent ();
462 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
463 strm << file_spec;
464 if (line > 0)
465 strm.Printf (":%u", line);
466 strm << " in ";
467 DumpFullpath (strm, &module->GetFileSpec(), 0);
468 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000469 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000470 return num_matches;
471 }
472 }
473 return 0;
474
475}
476
477
478//----------------------------------------------------------------------
479// Image symbol table dumping command
480//----------------------------------------------------------------------
481
482class CommandObjectImageDumpModuleList : public CommandObject
483{
484public:
485
Greg Clayton238c0a12010-09-18 01:14:36 +0000486 CommandObjectImageDumpModuleList (CommandInterpreter &interpreter,
487 const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000488 const char *help,
489 const char *syntax) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000490 CommandObject (interpreter, name, help, syntax)
Chris Lattner24943d22010-06-08 16:52:24 +0000491 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000492 CommandArgumentEntry arg;
493 CommandArgumentData file_arg;
494
495 // Define the first (and only) variant of this arg.
496 file_arg.arg_type = eArgTypeFilename;
497 file_arg.arg_repetition = eArgRepeatStar;
498
499 // There is only one variant this argument could be; put it into the argument entry.
500 arg.push_back (file_arg);
501
502 // Push the data for the first argument into the m_arguments vector.
503 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000504 }
505
506 virtual
507 ~CommandObjectImageDumpModuleList ()
508 {
509 }
510
511 virtual int
Greg Clayton238c0a12010-09-18 01:14:36 +0000512 HandleArgumentCompletion (Args &input,
Greg Clayton63094e02010-06-23 01:19:29 +0000513 int &cursor_index,
514 int &cursor_char_position,
515 OptionElementVector &opt_element_vector,
516 int match_start_point,
517 int max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000518 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000519 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000520 {
521 // Arguments are the standard module completer.
522 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
523 completion_str.erase (cursor_char_position);
524
Greg Clayton238c0a12010-09-18 01:14:36 +0000525 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +0000526 CommandCompletions::eModuleCompletion,
527 completion_str.c_str(),
528 match_start_point,
529 max_return_elements,
530 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000531 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000532 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000533 return matches.GetSize();
534 }
535};
536
537class CommandObjectImageDumpSourceFileList : public CommandObject
538{
539public:
540
Greg Clayton238c0a12010-09-18 01:14:36 +0000541 CommandObjectImageDumpSourceFileList (CommandInterpreter &interpreter,
542 const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000543 const char *help,
544 const char *syntax) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000545 CommandObject (interpreter, name, help, syntax)
Chris Lattner24943d22010-06-08 16:52:24 +0000546 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000547 CommandArgumentEntry arg;
548 CommandArgumentData source_file_arg;
549
550 // Define the first (and only) variant of this arg.
551 source_file_arg.arg_type = eArgTypeSourceFile;
552 source_file_arg.arg_repetition = eArgRepeatPlus;
553
554 // There is only one variant this argument could be; put it into the argument entry.
555 arg.push_back (source_file_arg);
556
557 // Push the data for the first argument into the m_arguments vector.
558 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000559 }
560
561 virtual
562 ~CommandObjectImageDumpSourceFileList ()
563 {
564 }
565
566 virtual int
Greg Clayton238c0a12010-09-18 01:14:36 +0000567 HandleArgumentCompletion (Args &input,
Greg Clayton63094e02010-06-23 01:19:29 +0000568 int &cursor_index,
569 int &cursor_char_position,
570 OptionElementVector &opt_element_vector,
571 int match_start_point,
572 int max_return_elements,
Greg Clayton54e7afa2010-07-09 20:39:50 +0000573 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000574 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000575 {
576 // Arguments are the standard source file completer.
577 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
578 completion_str.erase (cursor_char_position);
579
Greg Clayton238c0a12010-09-18 01:14:36 +0000580 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +0000581 CommandCompletions::eSourceFileCompletion,
582 completion_str.c_str(),
583 match_start_point,
584 max_return_elements,
585 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000586 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000587 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000588 return matches.GetSize();
589 }
590};
591
592
593class CommandObjectImageDumpSymtab : public CommandObjectImageDumpModuleList
594{
595public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000596 CommandObjectImageDumpSymtab (CommandInterpreter &interpreter) :
597 CommandObjectImageDumpModuleList (interpreter,
598 "image dump symtab",
599 "Dump the symbol table from one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000600 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000601 {
602 }
603
604 virtual
605 ~CommandObjectImageDumpSymtab ()
606 {
607 }
608
609 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000610 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000611 CommandReturnObject &result)
612 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000613 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000614 if (target == NULL)
615 {
616 result.AppendError ("invalid target, set executable file using 'file' command");
617 result.SetStatus (eReturnStatusFailed);
618 return false;
619 }
620 else
621 {
622 uint32_t num_dumped = 0;
623
624 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
625 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
626 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
627
628 if (command.GetArgumentCount() == 0)
629 {
630 // Dump all sections for all modules images
631 const uint32_t num_modules = target->GetImages().GetSize();
632 if (num_modules > 0)
633 {
634 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
635 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
636 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000637 if (num_dumped > 0)
638 {
639 result.GetOutputStream().EOL();
640 result.GetOutputStream().EOL();
641 }
Chris Lattner24943d22010-06-08 16:52:24 +0000642 num_dumped++;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000643 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
Chris Lattner24943d22010-06-08 16:52:24 +0000644 }
645 }
646 else
647 {
648 result.AppendError ("the target has no associated executable images");
649 result.SetStatus (eReturnStatusFailed);
650 return false;
651 }
652 }
653 else
654 {
655 // Dump specified images (by basename or fullpath)
656 const char *arg_cstr;
657 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
658 {
659 FileSpec image_file(arg_cstr);
660 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000661 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000662
Greg Clayton661825b2010-06-28 23:51:11 +0000663 // Not found in our module list for our target, check the main
664 // shared module list in case it is a extra file used somewhere
665 // else
666 if (num_matching_modules == 0)
667 num_matching_modules = ModuleList::FindSharedModules (image_file,
668 target->GetArchitecture(),
669 NULL,
670 NULL,
671 matching_modules);
672
Chris Lattner24943d22010-06-08 16:52:24 +0000673 if (num_matching_modules > 0)
674 {
675 for (size_t i=0; i<num_matching_modules; ++i)
676 {
677 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
678 if (image_module)
679 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000680 if (num_dumped > 0)
681 {
682 result.GetOutputStream().EOL();
683 result.GetOutputStream().EOL();
684 }
Chris Lattner24943d22010-06-08 16:52:24 +0000685 num_dumped++;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000686 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order);
Chris Lattner24943d22010-06-08 16:52:24 +0000687 }
688 }
689 }
690 else
691 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
692 }
693 }
694
695 if (num_dumped > 0)
696 result.SetStatus (eReturnStatusSuccessFinishResult);
697 else
698 {
699 result.AppendError ("no matching executable images found");
700 result.SetStatus (eReturnStatusFailed);
701 }
702 }
703 return result.Succeeded();
704 }
Greg Clayton8d3802d2010-10-08 04:20:14 +0000705
706 virtual Options *
707 GetOptions ()
708 {
709 return &m_options;
710 }
711
712 class CommandOptions : public Options
713 {
714 public:
Chris Lattner24943d22010-06-08 16:52:24 +0000715
Greg Clayton8d3802d2010-10-08 04:20:14 +0000716 CommandOptions () :
717 Options(),
718 m_sort_order (eSortOrderNone)
719 {
720 }
721
722 virtual
723 ~CommandOptions ()
724 {
725 }
726
727 virtual Error
728 SetOptionValue (int option_idx, const char *option_arg)
729 {
730 Error error;
731 char short_option = (char) m_getopt_table[option_idx].val;
732
733 switch (short_option)
734 {
735 case 's':
736 {
737 bool found_one = false;
738 m_sort_order = (lldb::SortOrder) Args::StringToOptionEnum (option_arg,
739 g_option_table[option_idx].enum_values,
740 eSortOrderNone,
741 &found_one);
742 if (!found_one)
743 error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n",
744 option_arg,
745 short_option);
746 }
747 break;
748
749 default:
750 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
751 break;
752
753 }
754 return error;
755 }
756
757 void
758 ResetOptionValues ()
759 {
760 Options::ResetOptionValues();
761 m_sort_order = eSortOrderNone;
762 }
763
764 const lldb::OptionDefinition*
765 GetDefinitions ()
766 {
767 return g_option_table;
768 }
769
770 // Options table: Required for subclasses of Options.
771 static lldb::OptionDefinition g_option_table[];
772
773 SortOrder m_sort_order;
774 };
775
776protected:
777
778 CommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000779};
780
Greg Clayton8d3802d2010-10-08 04:20:14 +0000781lldb::OptionEnumValueElement
782g_sort_option_enumeration[4] =
783{
784 { eSortOrderNone, "none", "No sorting, use the original symbol table order."},
785 { eSortOrderByAddress, "address", "Sort output by symbol address."},
786 { eSortOrderByName, "name", "Sort output by symbol name."},
787 { 0, NULL, NULL }
788};
789
790
791lldb::OptionDefinition
792CommandObjectImageDumpSymtab::CommandOptions::g_option_table[] =
793{
794{ LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
795{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
796};
797
798
Chris Lattner24943d22010-06-08 16:52:24 +0000799//----------------------------------------------------------------------
800// Image section dumping command
801//----------------------------------------------------------------------
802class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList
803{
804public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000805 CommandObjectImageDumpSections (CommandInterpreter &interpreter) :
806 CommandObjectImageDumpModuleList (interpreter,
807 "image dump sections",
Greg Clayton63094e02010-06-23 01:19:29 +0000808 "Dump the sections from one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000809 //"image dump sections [<file1> ...]")
810 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000811 {
812 }
813
814 virtual
815 ~CommandObjectImageDumpSections ()
816 {
817 }
818
819 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000820 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000821 CommandReturnObject &result)
822 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000823 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000824 if (target == NULL)
825 {
826 result.AppendError ("invalid target, set executable file using 'file' command");
827 result.SetStatus (eReturnStatusFailed);
828 return false;
829 }
830 else
831 {
832 uint32_t num_dumped = 0;
833
834 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
835 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
836 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
837
838 if (command.GetArgumentCount() == 0)
839 {
840 // Dump all sections for all modules images
841 const uint32_t num_modules = target->GetImages().GetSize();
842 if (num_modules > 0)
843 {
844 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
845 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
846 {
847 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000848 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000849 }
850 }
851 else
852 {
853 result.AppendError ("the target has no associated executable images");
854 result.SetStatus (eReturnStatusFailed);
855 return false;
856 }
857 }
858 else
859 {
860 // Dump specified images (by basename or fullpath)
861 const char *arg_cstr;
862 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
863 {
864 FileSpec image_file(arg_cstr);
865 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000866 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000867
Greg Clayton661825b2010-06-28 23:51:11 +0000868 // Not found in our module list for our target, check the main
869 // shared module list in case it is a extra file used somewhere
870 // else
871 if (num_matching_modules == 0)
872 num_matching_modules = ModuleList::FindSharedModules (image_file,
873 target->GetArchitecture(),
874 NULL,
875 NULL,
876 matching_modules);
877
Chris Lattner24943d22010-06-08 16:52:24 +0000878 if (num_matching_modules > 0)
879 {
880 for (size_t i=0; i<num_matching_modules; ++i)
881 {
882 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
883 if (image_module)
884 {
885 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000886 DumpModuleSections (m_interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000887 }
888 }
889 }
890 else
891 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
892 }
893 }
894
895 if (num_dumped > 0)
896 result.SetStatus (eReturnStatusSuccessFinishResult);
897 else
898 {
899 result.AppendError ("no matching executable images found");
900 result.SetStatus (eReturnStatusFailed);
901 }
902 }
903 return result.Succeeded();
904 }
905};
906
907//----------------------------------------------------------------------
908// Image debug symbol dumping command
909//----------------------------------------------------------------------
910class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList
911{
912public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000913 CommandObjectImageDumpSymfile (CommandInterpreter &interpreter) :
914 CommandObjectImageDumpModuleList (interpreter,
915 "image dump symfile",
916 "Dump the debug symbol file for one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000917 //"image dump symfile [<file1> ...]")
918 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000919 {
920 }
921
922 virtual
923 ~CommandObjectImageDumpSymfile ()
924 {
925 }
926
927 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000928 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000929 CommandReturnObject &result)
930 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000931 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000932 if (target == NULL)
933 {
934 result.AppendError ("invalid target, set executable file using 'file' command");
935 result.SetStatus (eReturnStatusFailed);
936 return false;
937 }
938 else
939 {
940 uint32_t num_dumped = 0;
941
942 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
943 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
944 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
945
946 if (command.GetArgumentCount() == 0)
947 {
948 // Dump all sections for all modules images
949 const uint32_t num_modules = target->GetImages().GetSize();
950 if (num_modules > 0)
951 {
952 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
953 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
954 {
955 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
956 num_dumped++;
957 }
958 }
959 else
960 {
961 result.AppendError ("the target has no associated executable images");
962 result.SetStatus (eReturnStatusFailed);
963 return false;
964 }
965 }
966 else
967 {
968 // Dump specified images (by basename or fullpath)
969 const char *arg_cstr;
970 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
971 {
972 FileSpec image_file(arg_cstr);
973 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000974 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000975
Greg Clayton661825b2010-06-28 23:51:11 +0000976 // Not found in our module list for our target, check the main
977 // shared module list in case it is a extra file used somewhere
978 // else
979 if (num_matching_modules == 0)
980 num_matching_modules = ModuleList::FindSharedModules (image_file,
981 target->GetArchitecture(),
982 NULL,
983 NULL,
984 matching_modules);
985
Chris Lattner24943d22010-06-08 16:52:24 +0000986 if (num_matching_modules > 0)
987 {
988 for (size_t i=0; i<num_matching_modules; ++i)
989 {
990 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
991 if (image_module)
992 {
993 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
994 num_dumped++;
995 }
996 }
997 }
998 else
999 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1000 }
1001 }
1002
1003 if (num_dumped > 0)
1004 result.SetStatus (eReturnStatusSuccessFinishResult);
1005 else
1006 {
1007 result.AppendError ("no matching executable images found");
1008 result.SetStatus (eReturnStatusFailed);
1009 }
1010 }
1011 return result.Succeeded();
1012 }
1013};
1014
1015//----------------------------------------------------------------------
1016// Image debug symbol dumping command
1017//----------------------------------------------------------------------
1018class CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList
1019{
1020public:
Greg Clayton238c0a12010-09-18 01:14:36 +00001021 CommandObjectImageDumpLineTable (CommandInterpreter &interpreter) :
1022 CommandObjectImageDumpSourceFileList (interpreter,
1023 "image dump line-table",
1024 "Dump the debug symbol file for one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001025 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001026 {
1027 }
1028
1029 virtual
1030 ~CommandObjectImageDumpLineTable ()
1031 {
1032 }
1033
1034 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001035 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001036 CommandReturnObject &result)
1037 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001038 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001039 if (target == NULL)
1040 {
1041 result.AppendError ("invalid target, set executable file using 'file' command");
1042 result.SetStatus (eReturnStatusFailed);
1043 return false;
1044 }
1045 else
1046 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001047 ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +00001048 uint32_t total_num_dumped = 0;
1049
1050 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1051 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1052 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1053
1054 if (command.GetArgumentCount() == 0)
1055 {
1056 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
1057 result.SetStatus (eReturnStatusFailed);
1058 }
1059 else
1060 {
1061 // Dump specified images (by basename or fullpath)
1062 const char *arg_cstr;
1063 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1064 {
1065 FileSpec file_spec(arg_cstr);
1066 const uint32_t num_modules = target->GetImages().GetSize();
1067 if (num_modules > 0)
1068 {
1069 uint32_t num_dumped = 0;
1070 for (uint32_t i = 0; i<num_modules; ++i)
1071 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001072 if (DumpCompileUnitLineTable (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001073 result.GetOutputStream(),
1074 target->GetImages().GetModulePointerAtIndex(i),
1075 file_spec,
1076 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
1077 num_dumped++;
1078 }
1079 if (num_dumped == 0)
1080 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
1081 else
1082 total_num_dumped += num_dumped;
1083 }
1084 }
1085 }
1086
1087 if (total_num_dumped > 0)
1088 result.SetStatus (eReturnStatusSuccessFinishResult);
1089 else
1090 {
1091 result.AppendError ("no source filenames matched any command arguments");
1092 result.SetStatus (eReturnStatusFailed);
1093 }
1094 }
1095 return result.Succeeded();
1096 }
1097};
1098
1099//----------------------------------------------------------------------
1100// Dump multi-word command
1101//----------------------------------------------------------------------
1102class CommandObjectImageDump : public CommandObjectMultiword
1103{
1104public:
1105
1106 //------------------------------------------------------------------
1107 // Constructors and Destructors
1108 //------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001109 CommandObjectImageDump(CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001110 CommandObjectMultiword (interpreter,
1111 "image dump",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001112 "A set of commands for dumping information about one or more executable images; 'line-table' expects a source file name",
Greg Clayton63094e02010-06-23 01:19:29 +00001113 "image dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +00001114 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001115 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectImageDumpSymtab (interpreter)));
1116 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectImageDumpSections (interpreter)));
1117 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectImageDumpSymfile (interpreter)));
1118 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectImageDumpLineTable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001119 }
1120
1121 virtual
1122 ~CommandObjectImageDump()
1123 {
1124 }
1125};
1126
1127//----------------------------------------------------------------------
1128// List images with associated information
1129//----------------------------------------------------------------------
1130class CommandObjectImageList : public CommandObject
1131{
1132public:
1133
1134 class CommandOptions : public Options
1135 {
1136 public:
1137
1138 CommandOptions () :
1139 Options(),
1140 m_format_array()
1141 {
1142 }
1143
1144 virtual
1145 ~CommandOptions ()
1146 {
1147 }
1148
1149 virtual Error
1150 SetOptionValue (int option_idx, const char *option_arg)
1151 {
1152 char short_option = (char) m_getopt_table[option_idx].val;
1153 uint32_t width = 0;
1154 if (option_arg)
1155 width = strtoul (option_arg, NULL, 0);
1156 m_format_array.push_back(std::make_pair(short_option, width));
1157 Error error;
1158 return error;
1159 }
1160
1161 void
1162 ResetOptionValues ()
1163 {
1164 Options::ResetOptionValues();
1165 m_format_array.clear();
1166 }
1167
1168 const lldb::OptionDefinition*
1169 GetDefinitions ()
1170 {
1171 return g_option_table;
1172 }
1173
1174 // Options table: Required for subclasses of Options.
1175
1176 static lldb::OptionDefinition g_option_table[];
1177
1178 // Instance variables to hold the values for command options.
1179 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
1180 FormatWidthCollection m_format_array;
1181 };
1182
Greg Clayton238c0a12010-09-18 01:14:36 +00001183 CommandObjectImageList (CommandInterpreter &interpreter) :
1184 CommandObject (interpreter,
1185 "image list",
1186 "List current executable and dependent shared library images.",
1187 "image list [<cmd-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00001188 {
1189 }
1190
1191 virtual
1192 ~CommandObjectImageList ()
1193 {
1194 }
1195
1196 virtual
1197 Options *
1198 GetOptions ()
1199 {
1200 return &m_options;
1201 }
1202
1203 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001204 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001205 CommandReturnObject &result)
1206 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001207 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001208 if (target == NULL)
1209 {
1210 result.AppendError ("invalid target, set executable file using 'file' command");
1211 result.SetStatus (eReturnStatusFailed);
1212 return false;
1213 }
1214 else
1215 {
1216 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1217 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1218 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1219 // Dump all sections for all modules images
1220 const uint32_t num_modules = target->GetImages().GetSize();
1221 if (num_modules > 0)
1222 {
1223 Stream &strm = result.GetOutputStream();
1224
1225 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1226 {
1227 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
1228 strm.Printf("[%3u] ", image_idx);
1229
1230 if (m_options.m_format_array.empty())
1231 {
1232 DumpFullpath(strm, &module->GetFileSpec(), 0);
1233 }
1234 else
1235 {
1236 const size_t num_entries = m_options.m_format_array.size();
1237 for (size_t i=0; i<num_entries; ++i)
1238 {
1239 if (i > 0)
1240 strm.PutChar(' ');
1241 char format_char = m_options.m_format_array[i].first;
1242 uint32_t width = m_options.m_format_array[i].second;
1243 switch (format_char)
1244 {
1245 case 'a':
1246 DumpModuleArchitecture (strm, module, width);
1247 break;
1248
1249 case 'f':
1250 DumpFullpath (strm, &module->GetFileSpec(), width);
1251 break;
1252
1253 case 'd':
1254 DumpDirectory (strm, &module->GetFileSpec(), width);
1255 break;
1256
1257 case 'b':
1258 DumpBasename (strm, &module->GetFileSpec(), width);
1259 break;
1260
1261 case 's':
1262 case 'S':
1263 {
1264 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1265 if (symbol_vendor)
1266 {
1267 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
1268 if (symbol_file)
1269 {
1270 if (format_char == 'S')
1271 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1272 else
1273 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1274 break;
1275 }
1276 }
1277 strm.Printf("%.*s", width, "<NONE>");
1278 }
1279 break;
1280
1281 case 'u':
1282 DumpModuleUUID(strm, module);
1283 break;
1284
1285 default:
1286 break;
1287 }
1288 }
1289 }
1290 strm.EOL();
1291 }
1292 result.SetStatus (eReturnStatusSuccessFinishResult);
1293 }
1294 else
1295 {
1296 result.AppendError ("the target has no associated executable images");
1297 result.SetStatus (eReturnStatusFailed);
1298 return false;
1299 }
1300 }
1301 return result.Succeeded();
1302 }
1303protected:
1304
1305 CommandOptions m_options;
1306};
1307
1308lldb::OptionDefinition
1309CommandObjectImageList::CommandOptions::g_option_table[] =
1310{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001311{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
1312{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
1313{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
1314{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
1315{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
1316{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
1317{ LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."},
1318{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001319};
1320
1321
1322
1323//----------------------------------------------------------------------
1324// Lookup information in images
1325//----------------------------------------------------------------------
1326class CommandObjectImageLookup : public CommandObject
1327{
1328public:
1329
1330 enum
1331 {
1332 eLookupTypeInvalid = -1,
1333 eLookupTypeAddress = 0,
1334 eLookupTypeSymbol,
1335 eLookupTypeFileLine, // Line is optional
1336 eLookupTypeFunction,
Greg Clayton960d6a42010-08-03 00:35:52 +00001337 eLookupTypeType,
Chris Lattner24943d22010-06-08 16:52:24 +00001338 kNumLookupTypes
1339 };
1340
1341 class CommandOptions : public Options
1342 {
1343 public:
1344
1345 CommandOptions () :
1346 Options()
1347 {
1348 ResetOptionValues();
1349 }
1350
1351 virtual
1352 ~CommandOptions ()
1353 {
1354 }
1355
1356 virtual Error
1357 SetOptionValue (int option_idx, const char *option_arg)
1358 {
1359 Error error;
1360
1361 char short_option = (char) m_getopt_table[option_idx].val;
1362
1363 switch (short_option)
1364 {
1365 case 'a':
1366 m_type = eLookupTypeAddress;
1367 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1368 if (m_addr == LLDB_INVALID_ADDRESS)
1369 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
1370 break;
1371
1372 case 'o':
1373 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1374 if (m_offset == LLDB_INVALID_ADDRESS)
1375 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
1376 break;
1377
1378 case 's':
1379 m_str = option_arg;
1380 m_type = eLookupTypeSymbol;
1381 break;
1382
1383 case 'f':
1384 m_file.SetFile (option_arg);
1385 m_type = eLookupTypeFileLine;
1386 break;
1387
1388 case 'i':
1389 m_check_inlines = false;
1390 break;
1391
1392 case 'l':
1393 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
1394 if (m_line_number == UINT32_MAX)
1395 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
1396 else if (m_line_number == 0)
1397 error.SetErrorString ("Zero is an invalid line number.");
1398 m_type = eLookupTypeFileLine;
1399 break;
1400
1401 case 'n':
1402 m_str = option_arg;
1403 m_type = eLookupTypeFunction;
1404 break;
1405
Greg Clayton960d6a42010-08-03 00:35:52 +00001406 case 't':
1407 m_str = option_arg;
1408 m_type = eLookupTypeType;
1409 break;
1410
1411 case 'v':
1412 m_verbose = 1;
1413 break;
1414
Chris Lattner24943d22010-06-08 16:52:24 +00001415 case 'r':
1416 m_use_regex = true;
1417 break;
1418 }
1419
1420 return error;
1421 }
1422
1423 void
1424 ResetOptionValues ()
1425 {
1426 Options::ResetOptionValues();
1427 m_type = eLookupTypeInvalid;
1428 m_str.clear();
1429 m_file.Clear();
1430 m_addr = LLDB_INVALID_ADDRESS;
1431 m_offset = 0;
1432 m_line_number = 0;
1433 m_use_regex = false;
1434 m_check_inlines = true;
Greg Clayton960d6a42010-08-03 00:35:52 +00001435 m_verbose = false;
Chris Lattner24943d22010-06-08 16:52:24 +00001436 }
1437
1438 const lldb::OptionDefinition*
1439 GetDefinitions ()
1440 {
1441 return g_option_table;
1442 }
1443
1444 // Options table: Required for subclasses of Options.
1445
1446 static lldb::OptionDefinition g_option_table[];
1447 int m_type; // Should be a eLookupTypeXXX enum after parsing options
1448 std::string m_str; // Holds name lookup
1449 FileSpec m_file; // Files for file lookups
1450 lldb::addr_t m_addr; // Holds the address to lookup
1451 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
1452 uint32_t m_line_number; // Line number for file+line lookups
1453 bool m_use_regex; // Name lookups in m_str are regular expressions.
1454 bool m_check_inlines;// Check for inline entries when looking up by file/line.
Greg Clayton960d6a42010-08-03 00:35:52 +00001455 bool m_verbose; // Enable verbose lookup info
1456
Chris Lattner24943d22010-06-08 16:52:24 +00001457 };
1458
Greg Clayton238c0a12010-09-18 01:14:36 +00001459 CommandObjectImageLookup (CommandInterpreter &interpreter) :
1460 CommandObject (interpreter,
1461 "image lookup",
1462 "Look up information within executable and dependent shared library images.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001463 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001464 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001465 CommandArgumentEntry arg;
1466 CommandArgumentData file_arg;
1467
1468 // Define the first (and only) variant of this arg.
1469 file_arg.arg_type = eArgTypeFilename;
1470 file_arg.arg_repetition = eArgRepeatStar;
1471
1472 // There is only one variant this argument could be; put it into the argument entry.
1473 arg.push_back (file_arg);
1474
1475 // Push the data for the first argument into the m_arguments vector.
1476 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001477 }
1478
1479 virtual
1480 ~CommandObjectImageLookup ()
1481 {
1482 }
1483
Greg Clayton8d3802d2010-10-08 04:20:14 +00001484 virtual Options *
Chris Lattner24943d22010-06-08 16:52:24 +00001485 GetOptions ()
1486 {
1487 return &m_options;
1488 }
1489
1490
1491 bool
Greg Clayton63094e02010-06-23 01:19:29 +00001492 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
Chris Lattner24943d22010-06-08 16:52:24 +00001493 {
1494 switch (m_options.m_type)
1495 {
1496 case eLookupTypeAddress:
1497 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
1498 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001499 if (LookupAddressInModule (m_interpreter,
Greg Clayton960d6a42010-08-03 00:35:52 +00001500 result.GetOutputStream(),
1501 module,
1502 eSymbolContextEverything,
1503 m_options.m_addr,
1504 m_options.m_offset,
1505 m_options.m_verbose))
Chris Lattner24943d22010-06-08 16:52:24 +00001506 {
1507 result.SetStatus(eReturnStatusSuccessFinishResult);
1508 return true;
1509 }
1510 }
1511 break;
1512
1513 case eLookupTypeSymbol:
1514 if (!m_options.m_str.empty())
1515 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001516 if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
Chris Lattner24943d22010-06-08 16:52:24 +00001517 {
1518 result.SetStatus(eReturnStatusSuccessFinishResult);
1519 return true;
1520 }
1521 }
1522 break;
1523
1524 case eLookupTypeFileLine:
1525 if (m_options.m_file)
1526 {
1527
Greg Clayton238c0a12010-09-18 01:14:36 +00001528 if (LookupFileAndLineInModule (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001529 result.GetOutputStream(),
1530 module,
1531 m_options.m_file,
1532 m_options.m_line_number,
1533 m_options.m_check_inlines))
1534 {
1535 result.SetStatus(eReturnStatusSuccessFinishResult);
1536 return true;
1537 }
1538 }
1539 break;
1540
1541 case eLookupTypeFunction:
1542 if (!m_options.m_str.empty())
1543 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001544 if (LookupFunctionInModule (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001545 result.GetOutputStream(),
1546 module,
1547 m_options.m_str.c_str(),
1548 m_options.m_use_regex))
1549 {
1550 result.SetStatus(eReturnStatusSuccessFinishResult);
1551 return true;
1552 }
1553 }
1554 break;
1555
Greg Clayton960d6a42010-08-03 00:35:52 +00001556 case eLookupTypeType:
1557 if (!m_options.m_str.empty())
1558 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001559 if (LookupTypeInModule (m_interpreter,
Greg Clayton960d6a42010-08-03 00:35:52 +00001560 result.GetOutputStream(),
1561 module,
1562 m_options.m_str.c_str(),
1563 m_options.m_use_regex))
1564 {
1565 result.SetStatus(eReturnStatusSuccessFinishResult);
1566 return true;
1567 }
1568 }
1569 break;
1570
Chris Lattner24943d22010-06-08 16:52:24 +00001571 default:
Greg Clayton238c0a12010-09-18 01:14:36 +00001572 m_options.GenerateOptionUsage (m_interpreter, result.GetErrorStream(), this);
Chris Lattner24943d22010-06-08 16:52:24 +00001573 syntax_error = true;
1574 break;
1575 }
1576
1577 result.SetStatus (eReturnStatusFailed);
1578 return false;
1579 }
1580
1581 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001582 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001583 CommandReturnObject &result)
1584 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001585 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001586 if (target == NULL)
1587 {
1588 result.AppendError ("invalid target, set executable file using 'file' command");
1589 result.SetStatus (eReturnStatusFailed);
1590 return false;
1591 }
1592 else
1593 {
1594 bool syntax_error = false;
1595 uint32_t i;
1596 uint32_t num_successful_lookups = 0;
1597 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1598 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1599 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1600 // Dump all sections for all modules images
1601
1602 if (command.GetArgumentCount() == 0)
1603 {
1604 // Dump all sections for all modules images
1605 const uint32_t num_modules = target->GetImages().GetSize();
1606 if (num_modules > 0)
1607 {
1608 for (i = 0; i<num_modules && syntax_error == false; ++i)
1609 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001610 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001611 {
1612 result.GetOutputStream().EOL();
1613 num_successful_lookups++;
1614 }
1615 }
1616 }
1617 else
1618 {
1619 result.AppendError ("the target has no associated executable images");
1620 result.SetStatus (eReturnStatusFailed);
1621 return false;
1622 }
1623 }
1624 else
1625 {
1626 // Dump specified images (by basename or fullpath)
1627 const char *arg_cstr;
1628 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
1629 {
1630 FileSpec image_file(arg_cstr);
1631 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +00001632 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +00001633
Greg Clayton661825b2010-06-28 23:51:11 +00001634 // Not found in our module list for our target, check the main
1635 // shared module list in case it is a extra file used somewhere
1636 // else
1637 if (num_matching_modules == 0)
1638 num_matching_modules = ModuleList::FindSharedModules (image_file,
1639 target->GetArchitecture(),
1640 NULL,
1641 NULL,
1642 matching_modules);
1643
Chris Lattner24943d22010-06-08 16:52:24 +00001644 if (num_matching_modules > 0)
1645 {
Greg Claytonbef15832010-07-14 00:18:15 +00001646 for (size_t j=0; j<num_matching_modules; ++j)
Chris Lattner24943d22010-06-08 16:52:24 +00001647 {
Greg Claytonbef15832010-07-14 00:18:15 +00001648 Module * image_module = matching_modules.GetModulePointerAtIndex(j);
Chris Lattner24943d22010-06-08 16:52:24 +00001649 if (image_module)
1650 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001651 if (LookupInModule (m_interpreter, image_module, result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001652 {
1653 result.GetOutputStream().EOL();
1654 num_successful_lookups++;
1655 }
1656 }
1657 }
1658 }
1659 else
1660 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1661 }
1662 }
1663
1664 if (num_successful_lookups > 0)
1665 result.SetStatus (eReturnStatusSuccessFinishResult);
1666 else
1667 result.SetStatus (eReturnStatusFailed);
1668 }
1669 return result.Succeeded();
1670 }
1671protected:
1672
1673 CommandOptions m_options;
1674};
1675
1676lldb::OptionDefinition
1677CommandObjectImageLookup::CommandOptions::g_option_table[] =
1678{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001679{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more executable images."},
1680{ LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup."},
1681{ LLDB_OPT_SET_2, true, "symbol", 's', required_argument, NULL, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more executable images."},
1682{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
1683{ LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more executable images."},
1684{ LLDB_OPT_SET_3, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."},
1685{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."},
1686{ LLDB_OPT_SET_4, true, "function", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more executable images."},
1687{ LLDB_OPT_SET_5, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more executable images."},
1688{ LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
1689{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001690};
1691
1692
1693
1694
1695
1696//----------------------------------------------------------------------
1697// CommandObjectImage constructor
1698//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001699CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001700 CommandObjectMultiword (interpreter,
1701 "image",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001702 "A set of commands for accessing information for one or more executable images.",
1703 "image <sub-command> ...")
Chris Lattner24943d22010-06-08 16:52:24 +00001704{
Greg Clayton238c0a12010-09-18 01:14:36 +00001705 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectImageDump (interpreter)));
1706 LoadSubCommand ("list", CommandObjectSP (new CommandObjectImageList (interpreter)));
1707 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectImageLookup (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001708}
1709
1710//----------------------------------------------------------------------
1711// Destructor
1712//----------------------------------------------------------------------
1713CommandObjectImage::~CommandObjectImage()
1714{
1715}
1716