blob: f71638c5c80aa86a62a947bf5934dadb60bb92b2 [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
Johnny Chencff44fd2010-10-29 22:18:43 +000085 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
Chris Lattner24943d22010-06-08 16:52:24 +000086 << 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 Clayton58e844b2010-12-08 05:08:21 +0000188 section_list->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, true, UINT32_MAX);
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)
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000243 strm.Printf("File Address: 0x%llx\n", addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000244
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;
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000363 const bool include_symbols = false;
364 const bool append = true;
365 uint32_t num_matches = 0;
366 if (name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000367 {
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000368 RegularExpression function_name_regex (name);
369 num_matches = module->FindFunctions (function_name_regex,
370 include_symbols,
371 append,
372 sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000373 }
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000374 else
375 {
376 ConstString function_name (name);
377 num_matches = module->FindFunctions (function_name,
378 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
379 include_symbols,
380 append,
381 sc_list);
382 }
383
384 if (num_matches)
385 {
386 strm.Indent ();
387 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
388 DumpFullpath (strm, &module->GetFileSpec(), 0);
389 strm.PutCString(":\n");
390 DumpSymbolContextList (interpreter, strm, sc_list, true);
391 }
392 return num_matches;
Chris Lattner24943d22010-06-08 16:52:24 +0000393 }
394 return 0;
395}
396
397static uint32_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000398LookupTypeInModule
399(
400 CommandInterpreter &interpreter,
401 Stream &strm,
402 Module *module,
403 const char *name_cstr,
404 bool name_is_regex
405)
406{
407 if (module && name_cstr && name_cstr[0])
408 {
409 SymbolContextList sc_list;
410
411 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
412 if (symbol_vendor)
413 {
414 TypeList type_list;
415 uint32_t num_matches = 0;
416 SymbolContext sc;
417// if (name_is_regex)
418// {
419// RegularExpression name_regex (name_cstr);
420// num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list);
421// }
422// else
423// {
424 ConstString name(name_cstr);
425 num_matches = symbol_vendor->FindTypes(sc, name, true, UINT32_MAX, type_list);
426// }
427
428 if (num_matches)
429 {
430 strm.Indent ();
431 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
432 DumpFullpath (strm, &module->GetFileSpec(), 0);
433 strm.PutCString(":\n");
434 const uint32_t num_types = type_list.GetSize();
435 for (uint32_t i=0; i<num_types; ++i)
436 {
437 TypeSP type_sp (type_list.GetTypeAtIndex(i));
438 if (type_sp)
439 {
440 // Resolve the clang type so that any forward references
441 // to types that haven't yet been parsed will get parsed.
Greg Clayton462d4142010-09-29 01:12:09 +0000442 type_sp->GetClangType ();
Greg Clayton960d6a42010-08-03 00:35:52 +0000443 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
444 }
445 strm.EOL();
446 }
447 }
448 return num_matches;
449 }
450 }
451 return 0;
452}
453
454static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000455LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines)
Chris Lattner24943d22010-06-08 16:52:24 +0000456{
457 if (module && file_spec)
458 {
459 SymbolContextList sc_list;
460 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
461 eSymbolContextEverything, sc_list);
462 if (num_matches > 0)
463 {
464 strm.Indent ();
465 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
466 strm << file_spec;
467 if (line > 0)
468 strm.Printf (":%u", line);
469 strm << " in ";
470 DumpFullpath (strm, &module->GetFileSpec(), 0);
471 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000472 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000473 return num_matches;
474 }
475 }
476 return 0;
477
478}
479
480
481//----------------------------------------------------------------------
482// Image symbol table dumping command
483//----------------------------------------------------------------------
484
485class CommandObjectImageDumpModuleList : public CommandObject
486{
487public:
488
Greg Clayton238c0a12010-09-18 01:14:36 +0000489 CommandObjectImageDumpModuleList (CommandInterpreter &interpreter,
490 const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000491 const char *help,
492 const char *syntax) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000493 CommandObject (interpreter, name, help, syntax)
Chris Lattner24943d22010-06-08 16:52:24 +0000494 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000495 CommandArgumentEntry arg;
496 CommandArgumentData file_arg;
497
498 // Define the first (and only) variant of this arg.
499 file_arg.arg_type = eArgTypeFilename;
500 file_arg.arg_repetition = eArgRepeatStar;
501
502 // There is only one variant this argument could be; put it into the argument entry.
503 arg.push_back (file_arg);
504
505 // Push the data for the first argument into the m_arguments vector.
506 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000507 }
508
509 virtual
510 ~CommandObjectImageDumpModuleList ()
511 {
512 }
513
514 virtual int
Greg Clayton238c0a12010-09-18 01:14:36 +0000515 HandleArgumentCompletion (Args &input,
Greg Clayton63094e02010-06-23 01:19:29 +0000516 int &cursor_index,
517 int &cursor_char_position,
518 OptionElementVector &opt_element_vector,
519 int match_start_point,
520 int max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000521 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000522 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000523 {
524 // Arguments are the standard module completer.
525 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
526 completion_str.erase (cursor_char_position);
527
Greg Clayton238c0a12010-09-18 01:14:36 +0000528 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +0000529 CommandCompletions::eModuleCompletion,
530 completion_str.c_str(),
531 match_start_point,
532 max_return_elements,
533 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000534 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000535 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000536 return matches.GetSize();
537 }
538};
539
540class CommandObjectImageDumpSourceFileList : public CommandObject
541{
542public:
543
Greg Clayton238c0a12010-09-18 01:14:36 +0000544 CommandObjectImageDumpSourceFileList (CommandInterpreter &interpreter,
545 const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000546 const char *help,
547 const char *syntax) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000548 CommandObject (interpreter, name, help, syntax)
Chris Lattner24943d22010-06-08 16:52:24 +0000549 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000550 CommandArgumentEntry arg;
551 CommandArgumentData source_file_arg;
552
553 // Define the first (and only) variant of this arg.
554 source_file_arg.arg_type = eArgTypeSourceFile;
555 source_file_arg.arg_repetition = eArgRepeatPlus;
556
557 // There is only one variant this argument could be; put it into the argument entry.
558 arg.push_back (source_file_arg);
559
560 // Push the data for the first argument into the m_arguments vector.
561 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000562 }
563
564 virtual
565 ~CommandObjectImageDumpSourceFileList ()
566 {
567 }
568
569 virtual int
Greg Clayton238c0a12010-09-18 01:14:36 +0000570 HandleArgumentCompletion (Args &input,
Greg Clayton63094e02010-06-23 01:19:29 +0000571 int &cursor_index,
572 int &cursor_char_position,
573 OptionElementVector &opt_element_vector,
574 int match_start_point,
575 int max_return_elements,
Greg Clayton54e7afa2010-07-09 20:39:50 +0000576 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000577 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000578 {
579 // Arguments are the standard source file completer.
580 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
581 completion_str.erase (cursor_char_position);
582
Greg Clayton238c0a12010-09-18 01:14:36 +0000583 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +0000584 CommandCompletions::eSourceFileCompletion,
585 completion_str.c_str(),
586 match_start_point,
587 max_return_elements,
588 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000589 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000590 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000591 return matches.GetSize();
592 }
593};
594
595
596class CommandObjectImageDumpSymtab : public CommandObjectImageDumpModuleList
597{
598public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000599 CommandObjectImageDumpSymtab (CommandInterpreter &interpreter) :
600 CommandObjectImageDumpModuleList (interpreter,
601 "image dump symtab",
602 "Dump the symbol table from one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000603 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000604 {
605 }
606
607 virtual
608 ~CommandObjectImageDumpSymtab ()
609 {
610 }
611
612 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000613 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000614 CommandReturnObject &result)
615 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000616 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000617 if (target == NULL)
618 {
619 result.AppendError ("invalid target, set executable file using 'file' command");
620 result.SetStatus (eReturnStatusFailed);
621 return false;
622 }
623 else
624 {
625 uint32_t num_dumped = 0;
626
627 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
628 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
629 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
630
631 if (command.GetArgumentCount() == 0)
632 {
633 // Dump all sections for all modules images
634 const uint32_t num_modules = target->GetImages().GetSize();
635 if (num_modules > 0)
636 {
637 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
638 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
639 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000640 if (num_dumped > 0)
641 {
642 result.GetOutputStream().EOL();
643 result.GetOutputStream().EOL();
644 }
Chris Lattner24943d22010-06-08 16:52:24 +0000645 num_dumped++;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000646 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
Chris Lattner24943d22010-06-08 16:52:24 +0000647 }
648 }
649 else
650 {
651 result.AppendError ("the target has no associated executable images");
652 result.SetStatus (eReturnStatusFailed);
653 return false;
654 }
655 }
656 else
657 {
658 // Dump specified images (by basename or fullpath)
659 const char *arg_cstr;
660 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
661 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000662 FileSpec image_file(arg_cstr, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000663 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000664 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000665
Greg Clayton661825b2010-06-28 23:51:11 +0000666 // Not found in our module list for our target, check the main
667 // shared module list in case it is a extra file used somewhere
668 // else
669 if (num_matching_modules == 0)
670 num_matching_modules = ModuleList::FindSharedModules (image_file,
671 target->GetArchitecture(),
672 NULL,
673 NULL,
674 matching_modules);
675
Chris Lattner24943d22010-06-08 16:52:24 +0000676 if (num_matching_modules > 0)
677 {
678 for (size_t i=0; i<num_matching_modules; ++i)
679 {
680 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
681 if (image_module)
682 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000683 if (num_dumped > 0)
684 {
685 result.GetOutputStream().EOL();
686 result.GetOutputStream().EOL();
687 }
Chris Lattner24943d22010-06-08 16:52:24 +0000688 num_dumped++;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000689 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order);
Chris Lattner24943d22010-06-08 16:52:24 +0000690 }
691 }
692 }
693 else
694 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
695 }
696 }
697
698 if (num_dumped > 0)
699 result.SetStatus (eReturnStatusSuccessFinishResult);
700 else
701 {
702 result.AppendError ("no matching executable images found");
703 result.SetStatus (eReturnStatusFailed);
704 }
705 }
706 return result.Succeeded();
707 }
Greg Clayton8d3802d2010-10-08 04:20:14 +0000708
709 virtual Options *
710 GetOptions ()
711 {
712 return &m_options;
713 }
714
715 class CommandOptions : public Options
716 {
717 public:
Chris Lattner24943d22010-06-08 16:52:24 +0000718
Greg Clayton8d3802d2010-10-08 04:20:14 +0000719 CommandOptions () :
720 Options(),
721 m_sort_order (eSortOrderNone)
722 {
723 }
724
725 virtual
726 ~CommandOptions ()
727 {
728 }
729
730 virtual Error
731 SetOptionValue (int option_idx, const char *option_arg)
732 {
733 Error error;
734 char short_option = (char) m_getopt_table[option_idx].val;
735
736 switch (short_option)
737 {
738 case 's':
739 {
740 bool found_one = false;
741 m_sort_order = (lldb::SortOrder) Args::StringToOptionEnum (option_arg,
742 g_option_table[option_idx].enum_values,
743 eSortOrderNone,
744 &found_one);
745 if (!found_one)
746 error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n",
747 option_arg,
748 short_option);
749 }
750 break;
751
752 default:
753 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
754 break;
755
756 }
757 return error;
758 }
759
760 void
761 ResetOptionValues ()
762 {
763 Options::ResetOptionValues();
764 m_sort_order = eSortOrderNone;
765 }
766
767 const lldb::OptionDefinition*
768 GetDefinitions ()
769 {
770 return g_option_table;
771 }
772
773 // Options table: Required for subclasses of Options.
774 static lldb::OptionDefinition g_option_table[];
775
776 SortOrder m_sort_order;
777 };
778
779protected:
780
781 CommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000782};
783
Greg Clayton8d3802d2010-10-08 04:20:14 +0000784lldb::OptionEnumValueElement
785g_sort_option_enumeration[4] =
786{
787 { eSortOrderNone, "none", "No sorting, use the original symbol table order."},
788 { eSortOrderByAddress, "address", "Sort output by symbol address."},
789 { eSortOrderByName, "name", "Sort output by symbol name."},
790 { 0, NULL, NULL }
791};
792
793
794lldb::OptionDefinition
795CommandObjectImageDumpSymtab::CommandOptions::g_option_table[] =
796{
797{ LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
798{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
799};
800
801
Chris Lattner24943d22010-06-08 16:52:24 +0000802//----------------------------------------------------------------------
803// Image section dumping command
804//----------------------------------------------------------------------
805class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList
806{
807public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000808 CommandObjectImageDumpSections (CommandInterpreter &interpreter) :
809 CommandObjectImageDumpModuleList (interpreter,
810 "image dump sections",
Greg Clayton63094e02010-06-23 01:19:29 +0000811 "Dump the sections from one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000812 //"image dump sections [<file1> ...]")
813 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000814 {
815 }
816
817 virtual
818 ~CommandObjectImageDumpSections ()
819 {
820 }
821
822 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000823 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000824 CommandReturnObject &result)
825 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000826 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000827 if (target == NULL)
828 {
829 result.AppendError ("invalid target, set executable file using 'file' command");
830 result.SetStatus (eReturnStatusFailed);
831 return false;
832 }
833 else
834 {
835 uint32_t num_dumped = 0;
836
837 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
838 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
839 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
840
841 if (command.GetArgumentCount() == 0)
842 {
843 // Dump all sections for all modules images
844 const uint32_t num_modules = target->GetImages().GetSize();
845 if (num_modules > 0)
846 {
847 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
848 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
849 {
850 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000851 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000852 }
853 }
854 else
855 {
856 result.AppendError ("the target has no associated executable images");
857 result.SetStatus (eReturnStatusFailed);
858 return false;
859 }
860 }
861 else
862 {
863 // Dump specified images (by basename or fullpath)
864 const char *arg_cstr;
865 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
866 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000867 FileSpec image_file(arg_cstr, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000868 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000869 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000870
Greg Clayton661825b2010-06-28 23:51:11 +0000871 // Not found in our module list for our target, check the main
872 // shared module list in case it is a extra file used somewhere
873 // else
874 if (num_matching_modules == 0)
875 num_matching_modules = ModuleList::FindSharedModules (image_file,
876 target->GetArchitecture(),
877 NULL,
878 NULL,
879 matching_modules);
880
Chris Lattner24943d22010-06-08 16:52:24 +0000881 if (num_matching_modules > 0)
882 {
883 for (size_t i=0; i<num_matching_modules; ++i)
884 {
885 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
886 if (image_module)
887 {
888 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000889 DumpModuleSections (m_interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000890 }
891 }
892 }
893 else
894 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
895 }
896 }
897
898 if (num_dumped > 0)
899 result.SetStatus (eReturnStatusSuccessFinishResult);
900 else
901 {
902 result.AppendError ("no matching executable images found");
903 result.SetStatus (eReturnStatusFailed);
904 }
905 }
906 return result.Succeeded();
907 }
908};
909
910//----------------------------------------------------------------------
911// Image debug symbol dumping command
912//----------------------------------------------------------------------
913class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList
914{
915public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000916 CommandObjectImageDumpSymfile (CommandInterpreter &interpreter) :
917 CommandObjectImageDumpModuleList (interpreter,
918 "image dump symfile",
919 "Dump the debug symbol file for one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000920 //"image dump symfile [<file1> ...]")
921 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000922 {
923 }
924
925 virtual
926 ~CommandObjectImageDumpSymfile ()
927 {
928 }
929
930 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000931 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000932 CommandReturnObject &result)
933 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000934 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000935 if (target == NULL)
936 {
937 result.AppendError ("invalid target, set executable file using 'file' command");
938 result.SetStatus (eReturnStatusFailed);
939 return false;
940 }
941 else
942 {
943 uint32_t num_dumped = 0;
944
945 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
946 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
947 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
948
949 if (command.GetArgumentCount() == 0)
950 {
951 // Dump all sections for all modules images
952 const uint32_t num_modules = target->GetImages().GetSize();
953 if (num_modules > 0)
954 {
955 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
956 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
957 {
958 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
959 num_dumped++;
960 }
961 }
962 else
963 {
964 result.AppendError ("the target has no associated executable images");
965 result.SetStatus (eReturnStatusFailed);
966 return false;
967 }
968 }
969 else
970 {
971 // Dump specified images (by basename or fullpath)
972 const char *arg_cstr;
973 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
974 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000975 FileSpec image_file(arg_cstr, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000976 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000977 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000978
Greg Clayton661825b2010-06-28 23:51:11 +0000979 // Not found in our module list for our target, check the main
980 // shared module list in case it is a extra file used somewhere
981 // else
982 if (num_matching_modules == 0)
983 num_matching_modules = ModuleList::FindSharedModules (image_file,
984 target->GetArchitecture(),
985 NULL,
986 NULL,
987 matching_modules);
988
Chris Lattner24943d22010-06-08 16:52:24 +0000989 if (num_matching_modules > 0)
990 {
991 for (size_t i=0; i<num_matching_modules; ++i)
992 {
993 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
994 if (image_module)
995 {
996 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
997 num_dumped++;
998 }
999 }
1000 }
1001 else
1002 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1003 }
1004 }
1005
1006 if (num_dumped > 0)
1007 result.SetStatus (eReturnStatusSuccessFinishResult);
1008 else
1009 {
1010 result.AppendError ("no matching executable images found");
1011 result.SetStatus (eReturnStatusFailed);
1012 }
1013 }
1014 return result.Succeeded();
1015 }
1016};
1017
1018//----------------------------------------------------------------------
1019// Image debug symbol dumping command
1020//----------------------------------------------------------------------
1021class CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList
1022{
1023public:
Greg Clayton238c0a12010-09-18 01:14:36 +00001024 CommandObjectImageDumpLineTable (CommandInterpreter &interpreter) :
1025 CommandObjectImageDumpSourceFileList (interpreter,
1026 "image dump line-table",
1027 "Dump the debug symbol file for one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001028 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001029 {
1030 }
1031
1032 virtual
1033 ~CommandObjectImageDumpLineTable ()
1034 {
1035 }
1036
1037 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001038 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001039 CommandReturnObject &result)
1040 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001041 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001042 if (target == NULL)
1043 {
1044 result.AppendError ("invalid target, set executable file using 'file' command");
1045 result.SetStatus (eReturnStatusFailed);
1046 return false;
1047 }
1048 else
1049 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001050 ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +00001051 uint32_t total_num_dumped = 0;
1052
1053 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1054 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1055 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1056
1057 if (command.GetArgumentCount() == 0)
1058 {
1059 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
1060 result.SetStatus (eReturnStatusFailed);
1061 }
1062 else
1063 {
1064 // Dump specified images (by basename or fullpath)
1065 const char *arg_cstr;
1066 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1067 {
Greg Clayton537a7a82010-10-20 20:54:39 +00001068 FileSpec file_spec(arg_cstr, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001069 const uint32_t num_modules = target->GetImages().GetSize();
1070 if (num_modules > 0)
1071 {
1072 uint32_t num_dumped = 0;
1073 for (uint32_t i = 0; i<num_modules; ++i)
1074 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001075 if (DumpCompileUnitLineTable (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001076 result.GetOutputStream(),
1077 target->GetImages().GetModulePointerAtIndex(i),
1078 file_spec,
1079 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
1080 num_dumped++;
1081 }
1082 if (num_dumped == 0)
1083 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
1084 else
1085 total_num_dumped += num_dumped;
1086 }
1087 }
1088 }
1089
1090 if (total_num_dumped > 0)
1091 result.SetStatus (eReturnStatusSuccessFinishResult);
1092 else
1093 {
1094 result.AppendError ("no source filenames matched any command arguments");
1095 result.SetStatus (eReturnStatusFailed);
1096 }
1097 }
1098 return result.Succeeded();
1099 }
1100};
1101
1102//----------------------------------------------------------------------
1103// Dump multi-word command
1104//----------------------------------------------------------------------
1105class CommandObjectImageDump : public CommandObjectMultiword
1106{
1107public:
1108
1109 //------------------------------------------------------------------
1110 // Constructors and Destructors
1111 //------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001112 CommandObjectImageDump(CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001113 CommandObjectMultiword (interpreter,
1114 "image dump",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001115 "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 +00001116 "image dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +00001117 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001118 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectImageDumpSymtab (interpreter)));
1119 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectImageDumpSections (interpreter)));
1120 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectImageDumpSymfile (interpreter)));
1121 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectImageDumpLineTable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001122 }
1123
1124 virtual
1125 ~CommandObjectImageDump()
1126 {
1127 }
1128};
1129
1130//----------------------------------------------------------------------
1131// List images with associated information
1132//----------------------------------------------------------------------
1133class CommandObjectImageList : public CommandObject
1134{
1135public:
1136
1137 class CommandOptions : public Options
1138 {
1139 public:
1140
1141 CommandOptions () :
1142 Options(),
1143 m_format_array()
1144 {
1145 }
1146
1147 virtual
1148 ~CommandOptions ()
1149 {
1150 }
1151
1152 virtual Error
1153 SetOptionValue (int option_idx, const char *option_arg)
1154 {
1155 char short_option = (char) m_getopt_table[option_idx].val;
1156 uint32_t width = 0;
1157 if (option_arg)
1158 width = strtoul (option_arg, NULL, 0);
1159 m_format_array.push_back(std::make_pair(short_option, width));
1160 Error error;
1161 return error;
1162 }
1163
1164 void
1165 ResetOptionValues ()
1166 {
1167 Options::ResetOptionValues();
1168 m_format_array.clear();
1169 }
1170
1171 const lldb::OptionDefinition*
1172 GetDefinitions ()
1173 {
1174 return g_option_table;
1175 }
1176
1177 // Options table: Required for subclasses of Options.
1178
1179 static lldb::OptionDefinition g_option_table[];
1180
1181 // Instance variables to hold the values for command options.
1182 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
1183 FormatWidthCollection m_format_array;
1184 };
1185
Greg Clayton238c0a12010-09-18 01:14:36 +00001186 CommandObjectImageList (CommandInterpreter &interpreter) :
1187 CommandObject (interpreter,
1188 "image list",
1189 "List current executable and dependent shared library images.",
1190 "image list [<cmd-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00001191 {
1192 }
1193
1194 virtual
1195 ~CommandObjectImageList ()
1196 {
1197 }
1198
1199 virtual
1200 Options *
1201 GetOptions ()
1202 {
1203 return &m_options;
1204 }
1205
1206 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001207 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001208 CommandReturnObject &result)
1209 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001210 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001211 if (target == NULL)
1212 {
1213 result.AppendError ("invalid target, set executable file using 'file' command");
1214 result.SetStatus (eReturnStatusFailed);
1215 return false;
1216 }
1217 else
1218 {
1219 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1220 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1221 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1222 // Dump all sections for all modules images
1223 const uint32_t num_modules = target->GetImages().GetSize();
1224 if (num_modules > 0)
1225 {
1226 Stream &strm = result.GetOutputStream();
1227
1228 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1229 {
1230 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
1231 strm.Printf("[%3u] ", image_idx);
1232
1233 if (m_options.m_format_array.empty())
1234 {
1235 DumpFullpath(strm, &module->GetFileSpec(), 0);
1236 }
1237 else
1238 {
1239 const size_t num_entries = m_options.m_format_array.size();
1240 for (size_t i=0; i<num_entries; ++i)
1241 {
1242 if (i > 0)
1243 strm.PutChar(' ');
1244 char format_char = m_options.m_format_array[i].first;
1245 uint32_t width = m_options.m_format_array[i].second;
1246 switch (format_char)
1247 {
1248 case 'a':
1249 DumpModuleArchitecture (strm, module, width);
1250 break;
1251
1252 case 'f':
1253 DumpFullpath (strm, &module->GetFileSpec(), width);
1254 break;
1255
1256 case 'd':
1257 DumpDirectory (strm, &module->GetFileSpec(), width);
1258 break;
1259
1260 case 'b':
1261 DumpBasename (strm, &module->GetFileSpec(), width);
1262 break;
1263
1264 case 's':
1265 case 'S':
1266 {
1267 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1268 if (symbol_vendor)
1269 {
1270 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
1271 if (symbol_file)
1272 {
1273 if (format_char == 'S')
1274 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1275 else
1276 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1277 break;
1278 }
1279 }
1280 strm.Printf("%.*s", width, "<NONE>");
1281 }
1282 break;
1283
1284 case 'u':
1285 DumpModuleUUID(strm, module);
1286 break;
1287
1288 default:
1289 break;
1290 }
1291 }
1292 }
1293 strm.EOL();
1294 }
1295 result.SetStatus (eReturnStatusSuccessFinishResult);
1296 }
1297 else
1298 {
1299 result.AppendError ("the target has no associated executable images");
1300 result.SetStatus (eReturnStatusFailed);
1301 return false;
1302 }
1303 }
1304 return result.Succeeded();
1305 }
1306protected:
1307
1308 CommandOptions m_options;
1309};
1310
1311lldb::OptionDefinition
1312CommandObjectImageList::CommandOptions::g_option_table[] =
1313{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001314{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
Greg Clayton0467c782011-02-04 18:53:10 +00001315{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
Caroline Tice4d6675c2010-10-01 19:59:14 +00001316{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
1317{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
1318{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
1319{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
1320{ LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."},
1321{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001322};
1323
1324
1325
1326//----------------------------------------------------------------------
1327// Lookup information in images
1328//----------------------------------------------------------------------
1329class CommandObjectImageLookup : public CommandObject
1330{
1331public:
1332
1333 enum
1334 {
1335 eLookupTypeInvalid = -1,
1336 eLookupTypeAddress = 0,
1337 eLookupTypeSymbol,
1338 eLookupTypeFileLine, // Line is optional
1339 eLookupTypeFunction,
Greg Clayton960d6a42010-08-03 00:35:52 +00001340 eLookupTypeType,
Chris Lattner24943d22010-06-08 16:52:24 +00001341 kNumLookupTypes
1342 };
1343
1344 class CommandOptions : public Options
1345 {
1346 public:
1347
1348 CommandOptions () :
1349 Options()
1350 {
1351 ResetOptionValues();
1352 }
1353
1354 virtual
1355 ~CommandOptions ()
1356 {
1357 }
1358
1359 virtual Error
1360 SetOptionValue (int option_idx, const char *option_arg)
1361 {
1362 Error error;
1363
1364 char short_option = (char) m_getopt_table[option_idx].val;
1365
1366 switch (short_option)
1367 {
1368 case 'a':
1369 m_type = eLookupTypeAddress;
1370 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1371 if (m_addr == LLDB_INVALID_ADDRESS)
1372 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
1373 break;
1374
1375 case 'o':
1376 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1377 if (m_offset == LLDB_INVALID_ADDRESS)
1378 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
1379 break;
1380
1381 case 's':
1382 m_str = option_arg;
1383 m_type = eLookupTypeSymbol;
1384 break;
1385
1386 case 'f':
Greg Clayton537a7a82010-10-20 20:54:39 +00001387 m_file.SetFile (option_arg, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001388 m_type = eLookupTypeFileLine;
1389 break;
1390
1391 case 'i':
1392 m_check_inlines = false;
1393 break;
1394
1395 case 'l':
1396 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
1397 if (m_line_number == UINT32_MAX)
1398 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
1399 else if (m_line_number == 0)
1400 error.SetErrorString ("Zero is an invalid line number.");
1401 m_type = eLookupTypeFileLine;
1402 break;
1403
1404 case 'n':
1405 m_str = option_arg;
1406 m_type = eLookupTypeFunction;
1407 break;
1408
Greg Clayton960d6a42010-08-03 00:35:52 +00001409 case 't':
1410 m_str = option_arg;
1411 m_type = eLookupTypeType;
1412 break;
1413
1414 case 'v':
1415 m_verbose = 1;
1416 break;
1417
Chris Lattner24943d22010-06-08 16:52:24 +00001418 case 'r':
1419 m_use_regex = true;
1420 break;
1421 }
1422
1423 return error;
1424 }
1425
1426 void
1427 ResetOptionValues ()
1428 {
1429 Options::ResetOptionValues();
1430 m_type = eLookupTypeInvalid;
1431 m_str.clear();
1432 m_file.Clear();
1433 m_addr = LLDB_INVALID_ADDRESS;
1434 m_offset = 0;
1435 m_line_number = 0;
1436 m_use_regex = false;
1437 m_check_inlines = true;
Greg Clayton960d6a42010-08-03 00:35:52 +00001438 m_verbose = false;
Chris Lattner24943d22010-06-08 16:52:24 +00001439 }
1440
1441 const lldb::OptionDefinition*
1442 GetDefinitions ()
1443 {
1444 return g_option_table;
1445 }
1446
1447 // Options table: Required for subclasses of Options.
1448
1449 static lldb::OptionDefinition g_option_table[];
1450 int m_type; // Should be a eLookupTypeXXX enum after parsing options
1451 std::string m_str; // Holds name lookup
1452 FileSpec m_file; // Files for file lookups
1453 lldb::addr_t m_addr; // Holds the address to lookup
1454 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
1455 uint32_t m_line_number; // Line number for file+line lookups
1456 bool m_use_regex; // Name lookups in m_str are regular expressions.
1457 bool m_check_inlines;// Check for inline entries when looking up by file/line.
Greg Clayton960d6a42010-08-03 00:35:52 +00001458 bool m_verbose; // Enable verbose lookup info
1459
Chris Lattner24943d22010-06-08 16:52:24 +00001460 };
1461
Greg Clayton238c0a12010-09-18 01:14:36 +00001462 CommandObjectImageLookup (CommandInterpreter &interpreter) :
1463 CommandObject (interpreter,
1464 "image lookup",
1465 "Look up information within executable and dependent shared library images.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001466 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001467 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001468 CommandArgumentEntry arg;
1469 CommandArgumentData file_arg;
1470
1471 // Define the first (and only) variant of this arg.
1472 file_arg.arg_type = eArgTypeFilename;
1473 file_arg.arg_repetition = eArgRepeatStar;
1474
1475 // There is only one variant this argument could be; put it into the argument entry.
1476 arg.push_back (file_arg);
1477
1478 // Push the data for the first argument into the m_arguments vector.
1479 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001480 }
1481
1482 virtual
1483 ~CommandObjectImageLookup ()
1484 {
1485 }
1486
Greg Clayton8d3802d2010-10-08 04:20:14 +00001487 virtual Options *
Chris Lattner24943d22010-06-08 16:52:24 +00001488 GetOptions ()
1489 {
1490 return &m_options;
1491 }
1492
1493
1494 bool
Greg Clayton63094e02010-06-23 01:19:29 +00001495 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
Chris Lattner24943d22010-06-08 16:52:24 +00001496 {
1497 switch (m_options.m_type)
1498 {
1499 case eLookupTypeAddress:
1500 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
1501 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001502 if (LookupAddressInModule (m_interpreter,
Greg Clayton960d6a42010-08-03 00:35:52 +00001503 result.GetOutputStream(),
1504 module,
1505 eSymbolContextEverything,
1506 m_options.m_addr,
1507 m_options.m_offset,
1508 m_options.m_verbose))
Chris Lattner24943d22010-06-08 16:52:24 +00001509 {
1510 result.SetStatus(eReturnStatusSuccessFinishResult);
1511 return true;
1512 }
1513 }
1514 break;
1515
1516 case eLookupTypeSymbol:
1517 if (!m_options.m_str.empty())
1518 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001519 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 +00001520 {
1521 result.SetStatus(eReturnStatusSuccessFinishResult);
1522 return true;
1523 }
1524 }
1525 break;
1526
1527 case eLookupTypeFileLine:
1528 if (m_options.m_file)
1529 {
1530
Greg Clayton238c0a12010-09-18 01:14:36 +00001531 if (LookupFileAndLineInModule (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001532 result.GetOutputStream(),
1533 module,
1534 m_options.m_file,
1535 m_options.m_line_number,
1536 m_options.m_check_inlines))
1537 {
1538 result.SetStatus(eReturnStatusSuccessFinishResult);
1539 return true;
1540 }
1541 }
1542 break;
1543
1544 case eLookupTypeFunction:
1545 if (!m_options.m_str.empty())
1546 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001547 if (LookupFunctionInModule (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001548 result.GetOutputStream(),
1549 module,
1550 m_options.m_str.c_str(),
1551 m_options.m_use_regex))
1552 {
1553 result.SetStatus(eReturnStatusSuccessFinishResult);
1554 return true;
1555 }
1556 }
1557 break;
1558
Greg Clayton960d6a42010-08-03 00:35:52 +00001559 case eLookupTypeType:
1560 if (!m_options.m_str.empty())
1561 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001562 if (LookupTypeInModule (m_interpreter,
Greg Clayton960d6a42010-08-03 00:35:52 +00001563 result.GetOutputStream(),
1564 module,
1565 m_options.m_str.c_str(),
1566 m_options.m_use_regex))
1567 {
1568 result.SetStatus(eReturnStatusSuccessFinishResult);
1569 return true;
1570 }
1571 }
1572 break;
1573
Chris Lattner24943d22010-06-08 16:52:24 +00001574 default:
Greg Clayton238c0a12010-09-18 01:14:36 +00001575 m_options.GenerateOptionUsage (m_interpreter, result.GetErrorStream(), this);
Chris Lattner24943d22010-06-08 16:52:24 +00001576 syntax_error = true;
1577 break;
1578 }
1579
1580 result.SetStatus (eReturnStatusFailed);
1581 return false;
1582 }
1583
1584 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001585 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001586 CommandReturnObject &result)
1587 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001588 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001589 if (target == NULL)
1590 {
1591 result.AppendError ("invalid target, set executable file using 'file' command");
1592 result.SetStatus (eReturnStatusFailed);
1593 return false;
1594 }
1595 else
1596 {
1597 bool syntax_error = false;
1598 uint32_t i;
1599 uint32_t num_successful_lookups = 0;
1600 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1601 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1602 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1603 // Dump all sections for all modules images
1604
1605 if (command.GetArgumentCount() == 0)
1606 {
1607 // Dump all sections for all modules images
1608 const uint32_t num_modules = target->GetImages().GetSize();
1609 if (num_modules > 0)
1610 {
1611 for (i = 0; i<num_modules && syntax_error == false; ++i)
1612 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001613 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001614 {
1615 result.GetOutputStream().EOL();
1616 num_successful_lookups++;
1617 }
1618 }
1619 }
1620 else
1621 {
1622 result.AppendError ("the target has no associated executable images");
1623 result.SetStatus (eReturnStatusFailed);
1624 return false;
1625 }
1626 }
1627 else
1628 {
1629 // Dump specified images (by basename or fullpath)
1630 const char *arg_cstr;
1631 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
1632 {
Greg Clayton537a7a82010-10-20 20:54:39 +00001633 FileSpec image_file(arg_cstr, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001634 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +00001635 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +00001636
Greg Clayton661825b2010-06-28 23:51:11 +00001637 // Not found in our module list for our target, check the main
1638 // shared module list in case it is a extra file used somewhere
1639 // else
1640 if (num_matching_modules == 0)
1641 num_matching_modules = ModuleList::FindSharedModules (image_file,
1642 target->GetArchitecture(),
1643 NULL,
1644 NULL,
1645 matching_modules);
1646
Chris Lattner24943d22010-06-08 16:52:24 +00001647 if (num_matching_modules > 0)
1648 {
Greg Claytonbef15832010-07-14 00:18:15 +00001649 for (size_t j=0; j<num_matching_modules; ++j)
Chris Lattner24943d22010-06-08 16:52:24 +00001650 {
Greg Claytonbef15832010-07-14 00:18:15 +00001651 Module * image_module = matching_modules.GetModulePointerAtIndex(j);
Chris Lattner24943d22010-06-08 16:52:24 +00001652 if (image_module)
1653 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001654 if (LookupInModule (m_interpreter, image_module, result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001655 {
1656 result.GetOutputStream().EOL();
1657 num_successful_lookups++;
1658 }
1659 }
1660 }
1661 }
1662 else
1663 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1664 }
1665 }
1666
1667 if (num_successful_lookups > 0)
1668 result.SetStatus (eReturnStatusSuccessFinishResult);
1669 else
1670 result.SetStatus (eReturnStatusFailed);
1671 }
1672 return result.Succeeded();
1673 }
1674protected:
1675
1676 CommandOptions m_options;
1677};
1678
1679lldb::OptionDefinition
1680CommandObjectImageLookup::CommandOptions::g_option_table[] =
1681{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001682{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more executable images."},
1683{ 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."},
1684{ 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."},
1685{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
1686{ 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."},
1687{ 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)."},
1688{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."},
1689{ 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."},
1690{ 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."},
1691{ LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
1692{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001693};
1694
1695
1696
1697
1698
1699//----------------------------------------------------------------------
1700// CommandObjectImage constructor
1701//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001702CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001703 CommandObjectMultiword (interpreter,
1704 "image",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001705 "A set of commands for accessing information for one or more executable images.",
1706 "image <sub-command> ...")
Chris Lattner24943d22010-06-08 16:52:24 +00001707{
Greg Clayton238c0a12010-09-18 01:14:36 +00001708 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectImageDump (interpreter)));
1709 LoadSubCommand ("list", CommandObjectSP (new CommandObjectImageList (interpreter)));
1710 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectImageLookup (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001711}
1712
1713//----------------------------------------------------------------------
1714// Destructor
1715//----------------------------------------------------------------------
1716CommandObjectImage::~CommandObjectImage()
1717{
1718}
1719