blob: b2ecef2396654a78caf411bc4f3ddf504af4bdf7 [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 Clayton63094e02010-06-23 01:19:29 +0000159DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module)
Chris Lattner24943d22010-06-08 16:52:24 +0000160{
161 if (module)
162 {
163 ObjectFile *objfile = module->GetObjectFile ();
164 if (objfile)
165 {
166 Symtab *symtab = objfile->GetSymtab();
167 if (symtab)
Greg Claytoneea26402010-09-14 23:36:40 +0000168 symtab->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target);
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 Claytoneea26402010-09-14 23:36:40 +0000183 section_list->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000184 }
185 }
186}
187
188static bool
189DumpModuleSymbolVendor (Stream &strm, Module *module)
190{
191 if (module)
192 {
193 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
194 if (symbol_vendor)
195 {
196 symbol_vendor->Dump(&strm);
197 return true;
198 }
199 }
200 return false;
201}
202
203static bool
Greg Clayton960d6a42010-08-03 00:35:52 +0000204LookupAddressInModule
205(
206 CommandInterpreter &interpreter,
207 Stream &strm,
208 Module *module,
209 uint32_t resolve_mask,
210 lldb::addr_t raw_addr,
211 lldb::addr_t offset,
212 bool verbose
213)
Chris Lattner24943d22010-06-08 16:52:24 +0000214{
215 if (module)
216 {
217 lldb::addr_t addr = raw_addr - offset;
218 Address so_addr;
219 SymbolContext sc;
Greg Claytoneea26402010-09-14 23:36:40 +0000220 Target *target = interpreter.GetDebugger().GetExecutionContext().target;
221 if (target && !target->GetSectionLoadList().IsEmpty())
Chris Lattner24943d22010-06-08 16:52:24 +0000222 {
Greg Claytoneea26402010-09-14 23:36:40 +0000223 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
Chris Lattner24943d22010-06-08 16:52:24 +0000224 return false;
225 else if (so_addr.GetModule() != module)
226 return false;
227 }
228 else
229 {
230 if (!module->ResolveFileAddress (addr, so_addr))
231 return false;
232 }
233
234 // If an offset was given, print out the address we ended up looking up
235 if (offset)
236 strm.Printf("0x%llx: ", addr);
237
Greg Clayton63094e02010-06-23 01:19:29 +0000238 ExecutionContextScope *exe_scope = interpreter.GetDebugger().GetExecutionContext().GetBestExecutionContextScope();
Greg Clayton12bec712010-06-28 21:30:43 +0000239 strm.IndentMore();
240 strm.Indent (" Address: ");
241 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
242 strm.EOL();
Greg Clayton70436352010-06-30 23:03:03 +0000243 strm.Indent (" Summary: ");
Chris Lattner24943d22010-06-08 16:52:24 +0000244 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
Greg Clayton70436352010-06-30 23:03:03 +0000245 strm.EOL();
Greg Clayton960d6a42010-08-03 00:35:52 +0000246 // Print out detailed address information when verbose is enabled
247 if (verbose)
248 {
249 if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext))
250 strm.EOL();
251 }
Greg Clayton12bec712010-06-28 21:30:43 +0000252 strm.IndentLess();
Chris Lattner24943d22010-06-08 16:52:24 +0000253 return true;
254 }
255
256 return false;
257}
258
259static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000260LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000261{
262 if (module)
263 {
264 SymbolContext sc;
265
266 ObjectFile *objfile = module->GetObjectFile ();
267 if (objfile)
268 {
269 Symtab *symtab = objfile->GetSymtab();
270 if (symtab)
271 {
272 uint32_t i;
273 std::vector<uint32_t> match_indexes;
274 ConstString symbol_name (name);
275 uint32_t num_matches = 0;
276 if (name_is_regex)
277 {
278 RegularExpression name_regexp(name);
Greg Clayton7c36fa02010-09-11 03:13:28 +0000279 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
280 eSymbolTypeAny,
Chris Lattner24943d22010-06-08 16:52:24 +0000281 match_indexes);
282 }
283 else
284 {
285 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
286 }
287
288
289 if (num_matches > 0)
290 {
291 strm.Indent ();
292 strm.Printf("%u symbols match %s'%s' in ", num_matches,
293 name_is_regex ? "the regular expression " : "", name);
294 DumpFullpath (strm, &module->GetFileSpec(), 0);
295 strm.PutCString(":\n");
296 strm.IndentMore ();
297 Symtab::DumpSymbolHeader (&strm);
298 for (i=0; i < num_matches; ++i)
299 {
300 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
301 strm.Indent ();
Greg Claytoneea26402010-09-14 23:36:40 +0000302 symbol->Dump (&strm, interpreter.GetDebugger().GetExecutionContext().target, i);
Chris Lattner24943d22010-06-08 16:52:24 +0000303 }
304 strm.IndentLess ();
305 return num_matches;
306 }
307 }
308 }
309 }
310 return 0;
311}
312
313
314static void
Greg Clayton63094e02010-06-23 01:19:29 +0000315DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000316{
317 strm.IndentMore ();
318 uint32_t i;
319 const uint32_t num_matches = sc_list.GetSize();
320
321 for (i=0; i<num_matches; ++i)
322 {
323 SymbolContext sc;
324 if (sc_list.GetContextAtIndex(i, sc))
325 {
326 strm.Indent();
327 if (prepend_addr)
328 {
329 if (sc.line_entry.range.GetBaseAddress().IsValid())
330 {
Greg Claytoneea26402010-09-14 23:36:40 +0000331 lldb::addr_t vm_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(interpreter.GetDebugger().GetExecutionContext().target);
Chris Lattner24943d22010-06-08 16:52:24 +0000332 int addr_size = sizeof (addr_t);
Greg Clayton63094e02010-06-23 01:19:29 +0000333 Process *process = interpreter.GetDebugger().GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000334 if (process)
335 addr_size = process->GetAddressByteSize();
336 if (vm_addr != LLDB_INVALID_ADDRESS)
337 strm.Address (vm_addr, addr_size);
338 else
339 sc.line_entry.range.GetBaseAddress().Dump (&strm, NULL, Address::DumpStyleSectionNameOffset);
340
341 strm.PutCString(" in ");
342 }
343 }
Greg Clayton72b71582010-09-02 21:44:10 +0000344 sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress(), true, true, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000345 }
346 }
347 strm.IndentLess ();
348}
349
350static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000351LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000352{
353 if (module && name && name[0])
354 {
355 SymbolContextList sc_list;
356
357 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
358 if (symbol_vendor)
359 {
360 uint32_t num_matches = 0;
361 if (name_is_regex)
362 {
363 RegularExpression function_name_regex (name);
364 num_matches = symbol_vendor->FindFunctions(function_name_regex, true, sc_list);
365
366 }
367 else
368 {
369 ConstString function_name(name);
Greg Clayton12bec712010-06-28 21:30:43 +0000370 num_matches = symbol_vendor->FindFunctions(function_name, eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000371 }
372
373 if (num_matches)
374 {
375 strm.Indent ();
376 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
377 DumpFullpath (strm, &module->GetFileSpec(), 0);
378 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000379 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000380 }
381 return num_matches;
382 }
383 }
384 return 0;
385}
386
387static uint32_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000388LookupTypeInModule
389(
390 CommandInterpreter &interpreter,
391 Stream &strm,
392 Module *module,
393 const char *name_cstr,
394 bool name_is_regex
395)
396{
397 if (module && name_cstr && name_cstr[0])
398 {
399 SymbolContextList sc_list;
400
401 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
402 if (symbol_vendor)
403 {
404 TypeList type_list;
405 uint32_t num_matches = 0;
406 SymbolContext sc;
407// if (name_is_regex)
408// {
409// RegularExpression name_regex (name_cstr);
410// num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list);
411// }
412// else
413// {
414 ConstString name(name_cstr);
415 num_matches = symbol_vendor->FindTypes(sc, name, true, UINT32_MAX, type_list);
416// }
417
418 if (num_matches)
419 {
420 strm.Indent ();
421 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
422 DumpFullpath (strm, &module->GetFileSpec(), 0);
423 strm.PutCString(":\n");
424 const uint32_t num_types = type_list.GetSize();
425 for (uint32_t i=0; i<num_types; ++i)
426 {
427 TypeSP type_sp (type_list.GetTypeAtIndex(i));
428 if (type_sp)
429 {
430 // Resolve the clang type so that any forward references
431 // to types that haven't yet been parsed will get parsed.
Greg Clayton462d4142010-09-29 01:12:09 +0000432 type_sp->GetClangType ();
Greg Clayton960d6a42010-08-03 00:35:52 +0000433 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
434 }
435 strm.EOL();
436 }
437 }
438 return num_matches;
439 }
440 }
441 return 0;
442}
443
444static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000445LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines)
Chris Lattner24943d22010-06-08 16:52:24 +0000446{
447 if (module && file_spec)
448 {
449 SymbolContextList sc_list;
450 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
451 eSymbolContextEverything, sc_list);
452 if (num_matches > 0)
453 {
454 strm.Indent ();
455 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
456 strm << file_spec;
457 if (line > 0)
458 strm.Printf (":%u", line);
459 strm << " in ";
460 DumpFullpath (strm, &module->GetFileSpec(), 0);
461 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000462 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000463 return num_matches;
464 }
465 }
466 return 0;
467
468}
469
470
471//----------------------------------------------------------------------
472// Image symbol table dumping command
473//----------------------------------------------------------------------
474
475class CommandObjectImageDumpModuleList : public CommandObject
476{
477public:
478
Greg Clayton238c0a12010-09-18 01:14:36 +0000479 CommandObjectImageDumpModuleList (CommandInterpreter &interpreter,
480 const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000481 const char *help,
482 const char *syntax) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000483 CommandObject (interpreter, name, help, syntax)
Chris Lattner24943d22010-06-08 16:52:24 +0000484 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000485 CommandArgumentEntry arg;
486 CommandArgumentData file_arg;
487
488 // Define the first (and only) variant of this arg.
489 file_arg.arg_type = eArgTypeFilename;
490 file_arg.arg_repetition = eArgRepeatStar;
491
492 // There is only one variant this argument could be; put it into the argument entry.
493 arg.push_back (file_arg);
494
495 // Push the data for the first argument into the m_arguments vector.
496 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000497 }
498
499 virtual
500 ~CommandObjectImageDumpModuleList ()
501 {
502 }
503
504 virtual int
Greg Clayton238c0a12010-09-18 01:14:36 +0000505 HandleArgumentCompletion (Args &input,
Greg Clayton63094e02010-06-23 01:19:29 +0000506 int &cursor_index,
507 int &cursor_char_position,
508 OptionElementVector &opt_element_vector,
509 int match_start_point,
510 int max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000511 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000512 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000513 {
514 // Arguments are the standard module completer.
515 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
516 completion_str.erase (cursor_char_position);
517
Greg Clayton238c0a12010-09-18 01:14:36 +0000518 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +0000519 CommandCompletions::eModuleCompletion,
520 completion_str.c_str(),
521 match_start_point,
522 max_return_elements,
523 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000524 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000525 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000526 return matches.GetSize();
527 }
528};
529
530class CommandObjectImageDumpSourceFileList : public CommandObject
531{
532public:
533
Greg Clayton238c0a12010-09-18 01:14:36 +0000534 CommandObjectImageDumpSourceFileList (CommandInterpreter &interpreter,
535 const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000536 const char *help,
537 const char *syntax) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000538 CommandObject (interpreter, name, help, syntax)
Chris Lattner24943d22010-06-08 16:52:24 +0000539 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000540 CommandArgumentEntry arg;
541 CommandArgumentData source_file_arg;
542
543 // Define the first (and only) variant of this arg.
544 source_file_arg.arg_type = eArgTypeSourceFile;
545 source_file_arg.arg_repetition = eArgRepeatPlus;
546
547 // There is only one variant this argument could be; put it into the argument entry.
548 arg.push_back (source_file_arg);
549
550 // Push the data for the first argument into the m_arguments vector.
551 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000552 }
553
554 virtual
555 ~CommandObjectImageDumpSourceFileList ()
556 {
557 }
558
559 virtual int
Greg Clayton238c0a12010-09-18 01:14:36 +0000560 HandleArgumentCompletion (Args &input,
Greg Clayton63094e02010-06-23 01:19:29 +0000561 int &cursor_index,
562 int &cursor_char_position,
563 OptionElementVector &opt_element_vector,
564 int match_start_point,
565 int max_return_elements,
Greg Clayton54e7afa2010-07-09 20:39:50 +0000566 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000567 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000568 {
569 // Arguments are the standard source file completer.
570 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
571 completion_str.erase (cursor_char_position);
572
Greg Clayton238c0a12010-09-18 01:14:36 +0000573 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +0000574 CommandCompletions::eSourceFileCompletion,
575 completion_str.c_str(),
576 match_start_point,
577 max_return_elements,
578 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000579 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000580 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000581 return matches.GetSize();
582 }
583};
584
585
586class CommandObjectImageDumpSymtab : public CommandObjectImageDumpModuleList
587{
588public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000589 CommandObjectImageDumpSymtab (CommandInterpreter &interpreter) :
590 CommandObjectImageDumpModuleList (interpreter,
591 "image dump symtab",
592 "Dump the symbol table from one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000593 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000594 {
595 }
596
597 virtual
598 ~CommandObjectImageDumpSymtab ()
599 {
600 }
601
602 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000603 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000604 CommandReturnObject &result)
605 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000606 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000607 if (target == NULL)
608 {
609 result.AppendError ("invalid target, set executable file using 'file' command");
610 result.SetStatus (eReturnStatusFailed);
611 return false;
612 }
613 else
614 {
615 uint32_t num_dumped = 0;
616
617 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
618 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
619 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
620
621 if (command.GetArgumentCount() == 0)
622 {
623 // Dump all sections for all modules images
624 const uint32_t num_modules = target->GetImages().GetSize();
625 if (num_modules > 0)
626 {
627 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
628 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
629 {
630 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000631 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000632 }
633 }
634 else
635 {
636 result.AppendError ("the target has no associated executable images");
637 result.SetStatus (eReturnStatusFailed);
638 return false;
639 }
640 }
641 else
642 {
643 // Dump specified images (by basename or fullpath)
644 const char *arg_cstr;
645 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
646 {
647 FileSpec image_file(arg_cstr);
648 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000649 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000650
Greg Clayton661825b2010-06-28 23:51:11 +0000651 // Not found in our module list for our target, check the main
652 // shared module list in case it is a extra file used somewhere
653 // else
654 if (num_matching_modules == 0)
655 num_matching_modules = ModuleList::FindSharedModules (image_file,
656 target->GetArchitecture(),
657 NULL,
658 NULL,
659 matching_modules);
660
Chris Lattner24943d22010-06-08 16:52:24 +0000661 if (num_matching_modules > 0)
662 {
663 for (size_t i=0; i<num_matching_modules; ++i)
664 {
665 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
666 if (image_module)
667 {
668 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000669 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000670 }
671 }
672 }
673 else
674 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
675 }
676 }
677
678 if (num_dumped > 0)
679 result.SetStatus (eReturnStatusSuccessFinishResult);
680 else
681 {
682 result.AppendError ("no matching executable images found");
683 result.SetStatus (eReturnStatusFailed);
684 }
685 }
686 return result.Succeeded();
687 }
688
689};
690
691//----------------------------------------------------------------------
692// Image section dumping command
693//----------------------------------------------------------------------
694class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList
695{
696public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000697 CommandObjectImageDumpSections (CommandInterpreter &interpreter) :
698 CommandObjectImageDumpModuleList (interpreter,
699 "image dump sections",
Greg Clayton63094e02010-06-23 01:19:29 +0000700 "Dump the sections from one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000701 //"image dump sections [<file1> ...]")
702 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000703 {
704 }
705
706 virtual
707 ~CommandObjectImageDumpSections ()
708 {
709 }
710
711 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000712 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000713 CommandReturnObject &result)
714 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000715 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000716 if (target == NULL)
717 {
718 result.AppendError ("invalid target, set executable file using 'file' command");
719 result.SetStatus (eReturnStatusFailed);
720 return false;
721 }
722 else
723 {
724 uint32_t num_dumped = 0;
725
726 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
727 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
728 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
729
730 if (command.GetArgumentCount() == 0)
731 {
732 // Dump all sections for all modules images
733 const uint32_t num_modules = target->GetImages().GetSize();
734 if (num_modules > 0)
735 {
736 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
737 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
738 {
739 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000740 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000741 }
742 }
743 else
744 {
745 result.AppendError ("the target has no associated executable images");
746 result.SetStatus (eReturnStatusFailed);
747 return false;
748 }
749 }
750 else
751 {
752 // Dump specified images (by basename or fullpath)
753 const char *arg_cstr;
754 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
755 {
756 FileSpec image_file(arg_cstr);
757 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000758 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000759
Greg Clayton661825b2010-06-28 23:51:11 +0000760 // Not found in our module list for our target, check the main
761 // shared module list in case it is a extra file used somewhere
762 // else
763 if (num_matching_modules == 0)
764 num_matching_modules = ModuleList::FindSharedModules (image_file,
765 target->GetArchitecture(),
766 NULL,
767 NULL,
768 matching_modules);
769
Chris Lattner24943d22010-06-08 16:52:24 +0000770 if (num_matching_modules > 0)
771 {
772 for (size_t i=0; i<num_matching_modules; ++i)
773 {
774 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
775 if (image_module)
776 {
777 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000778 DumpModuleSections (m_interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000779 }
780 }
781 }
782 else
783 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
784 }
785 }
786
787 if (num_dumped > 0)
788 result.SetStatus (eReturnStatusSuccessFinishResult);
789 else
790 {
791 result.AppendError ("no matching executable images found");
792 result.SetStatus (eReturnStatusFailed);
793 }
794 }
795 return result.Succeeded();
796 }
797};
798
799//----------------------------------------------------------------------
800// Image debug symbol dumping command
801//----------------------------------------------------------------------
802class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList
803{
804public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000805 CommandObjectImageDumpSymfile (CommandInterpreter &interpreter) :
806 CommandObjectImageDumpModuleList (interpreter,
807 "image dump symfile",
808 "Dump the debug symbol file for one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000809 //"image dump symfile [<file1> ...]")
810 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000811 {
812 }
813
814 virtual
815 ~CommandObjectImageDumpSymfile ()
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 debug symbols for %u modules.\n", num_modules);
845 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
846 {
847 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
848 num_dumped++;
849 }
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 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
886 num_dumped++;
887 }
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 CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList
911{
912public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000913 CommandObjectImageDumpLineTable (CommandInterpreter &interpreter) :
914 CommandObjectImageDumpSourceFileList (interpreter,
915 "image dump line-table",
916 "Dump the debug symbol file for one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000917 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000918 {
919 }
920
921 virtual
922 ~CommandObjectImageDumpLineTable ()
923 {
924 }
925
926 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000927 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000928 CommandReturnObject &result)
929 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000930 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000931 if (target == NULL)
932 {
933 result.AppendError ("invalid target, set executable file using 'file' command");
934 result.SetStatus (eReturnStatusFailed);
935 return false;
936 }
937 else
938 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000939 ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000940 uint32_t total_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 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
949 result.SetStatus (eReturnStatusFailed);
950 }
951 else
952 {
953 // Dump specified images (by basename or fullpath)
954 const char *arg_cstr;
955 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
956 {
957 FileSpec file_spec(arg_cstr);
958 const uint32_t num_modules = target->GetImages().GetSize();
959 if (num_modules > 0)
960 {
961 uint32_t num_dumped = 0;
962 for (uint32_t i = 0; i<num_modules; ++i)
963 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000964 if (DumpCompileUnitLineTable (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000965 result.GetOutputStream(),
966 target->GetImages().GetModulePointerAtIndex(i),
967 file_spec,
968 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
969 num_dumped++;
970 }
971 if (num_dumped == 0)
972 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
973 else
974 total_num_dumped += num_dumped;
975 }
976 }
977 }
978
979 if (total_num_dumped > 0)
980 result.SetStatus (eReturnStatusSuccessFinishResult);
981 else
982 {
983 result.AppendError ("no source filenames matched any command arguments");
984 result.SetStatus (eReturnStatusFailed);
985 }
986 }
987 return result.Succeeded();
988 }
989};
990
991//----------------------------------------------------------------------
992// Dump multi-word command
993//----------------------------------------------------------------------
994class CommandObjectImageDump : public CommandObjectMultiword
995{
996public:
997
998 //------------------------------------------------------------------
999 // Constructors and Destructors
1000 //------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001001 CommandObjectImageDump(CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001002 CommandObjectMultiword (interpreter,
1003 "image dump",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001004 "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 +00001005 "image dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +00001006 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001007 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectImageDumpSymtab (interpreter)));
1008 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectImageDumpSections (interpreter)));
1009 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectImageDumpSymfile (interpreter)));
1010 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectImageDumpLineTable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001011 }
1012
1013 virtual
1014 ~CommandObjectImageDump()
1015 {
1016 }
1017};
1018
1019//----------------------------------------------------------------------
1020// List images with associated information
1021//----------------------------------------------------------------------
1022class CommandObjectImageList : public CommandObject
1023{
1024public:
1025
1026 class CommandOptions : public Options
1027 {
1028 public:
1029
1030 CommandOptions () :
1031 Options(),
1032 m_format_array()
1033 {
1034 }
1035
1036 virtual
1037 ~CommandOptions ()
1038 {
1039 }
1040
1041 virtual Error
1042 SetOptionValue (int option_idx, const char *option_arg)
1043 {
1044 char short_option = (char) m_getopt_table[option_idx].val;
1045 uint32_t width = 0;
1046 if (option_arg)
1047 width = strtoul (option_arg, NULL, 0);
1048 m_format_array.push_back(std::make_pair(short_option, width));
1049 Error error;
1050 return error;
1051 }
1052
1053 void
1054 ResetOptionValues ()
1055 {
1056 Options::ResetOptionValues();
1057 m_format_array.clear();
1058 }
1059
1060 const lldb::OptionDefinition*
1061 GetDefinitions ()
1062 {
1063 return g_option_table;
1064 }
1065
1066 // Options table: Required for subclasses of Options.
1067
1068 static lldb::OptionDefinition g_option_table[];
1069
1070 // Instance variables to hold the values for command options.
1071 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
1072 FormatWidthCollection m_format_array;
1073 };
1074
Greg Clayton238c0a12010-09-18 01:14:36 +00001075 CommandObjectImageList (CommandInterpreter &interpreter) :
1076 CommandObject (interpreter,
1077 "image list",
1078 "List current executable and dependent shared library images.",
1079 "image list [<cmd-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00001080 {
1081 }
1082
1083 virtual
1084 ~CommandObjectImageList ()
1085 {
1086 }
1087
1088 virtual
1089 Options *
1090 GetOptions ()
1091 {
1092 return &m_options;
1093 }
1094
1095 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001096 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001097 CommandReturnObject &result)
1098 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001099 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001100 if (target == NULL)
1101 {
1102 result.AppendError ("invalid target, set executable file using 'file' command");
1103 result.SetStatus (eReturnStatusFailed);
1104 return false;
1105 }
1106 else
1107 {
1108 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1109 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1110 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1111 // Dump all sections for all modules images
1112 const uint32_t num_modules = target->GetImages().GetSize();
1113 if (num_modules > 0)
1114 {
1115 Stream &strm = result.GetOutputStream();
1116
1117 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1118 {
1119 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
1120 strm.Printf("[%3u] ", image_idx);
1121
1122 if (m_options.m_format_array.empty())
1123 {
1124 DumpFullpath(strm, &module->GetFileSpec(), 0);
1125 }
1126 else
1127 {
1128 const size_t num_entries = m_options.m_format_array.size();
1129 for (size_t i=0; i<num_entries; ++i)
1130 {
1131 if (i > 0)
1132 strm.PutChar(' ');
1133 char format_char = m_options.m_format_array[i].first;
1134 uint32_t width = m_options.m_format_array[i].second;
1135 switch (format_char)
1136 {
1137 case 'a':
1138 DumpModuleArchitecture (strm, module, width);
1139 break;
1140
1141 case 'f':
1142 DumpFullpath (strm, &module->GetFileSpec(), width);
1143 break;
1144
1145 case 'd':
1146 DumpDirectory (strm, &module->GetFileSpec(), width);
1147 break;
1148
1149 case 'b':
1150 DumpBasename (strm, &module->GetFileSpec(), width);
1151 break;
1152
1153 case 's':
1154 case 'S':
1155 {
1156 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1157 if (symbol_vendor)
1158 {
1159 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
1160 if (symbol_file)
1161 {
1162 if (format_char == 'S')
1163 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1164 else
1165 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1166 break;
1167 }
1168 }
1169 strm.Printf("%.*s", width, "<NONE>");
1170 }
1171 break;
1172
1173 case 'u':
1174 DumpModuleUUID(strm, module);
1175 break;
1176
1177 default:
1178 break;
1179 }
1180 }
1181 }
1182 strm.EOL();
1183 }
1184 result.SetStatus (eReturnStatusSuccessFinishResult);
1185 }
1186 else
1187 {
1188 result.AppendError ("the target has no associated executable images");
1189 result.SetStatus (eReturnStatusFailed);
1190 return false;
1191 }
1192 }
1193 return result.Succeeded();
1194 }
1195protected:
1196
1197 CommandOptions m_options;
1198};
1199
1200lldb::OptionDefinition
1201CommandObjectImageList::CommandOptions::g_option_table[] =
1202{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001203{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
1204{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
1205{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
1206{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
1207{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
1208{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
1209{ LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."},
1210{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001211};
1212
1213
1214
1215//----------------------------------------------------------------------
1216// Lookup information in images
1217//----------------------------------------------------------------------
1218class CommandObjectImageLookup : public CommandObject
1219{
1220public:
1221
1222 enum
1223 {
1224 eLookupTypeInvalid = -1,
1225 eLookupTypeAddress = 0,
1226 eLookupTypeSymbol,
1227 eLookupTypeFileLine, // Line is optional
1228 eLookupTypeFunction,
Greg Clayton960d6a42010-08-03 00:35:52 +00001229 eLookupTypeType,
Chris Lattner24943d22010-06-08 16:52:24 +00001230 kNumLookupTypes
1231 };
1232
1233 class CommandOptions : public Options
1234 {
1235 public:
1236
1237 CommandOptions () :
1238 Options()
1239 {
1240 ResetOptionValues();
1241 }
1242
1243 virtual
1244 ~CommandOptions ()
1245 {
1246 }
1247
1248 virtual Error
1249 SetOptionValue (int option_idx, const char *option_arg)
1250 {
1251 Error error;
1252
1253 char short_option = (char) m_getopt_table[option_idx].val;
1254
1255 switch (short_option)
1256 {
1257 case 'a':
1258 m_type = eLookupTypeAddress;
1259 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1260 if (m_addr == LLDB_INVALID_ADDRESS)
1261 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
1262 break;
1263
1264 case 'o':
1265 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1266 if (m_offset == LLDB_INVALID_ADDRESS)
1267 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
1268 break;
1269
1270 case 's':
1271 m_str = option_arg;
1272 m_type = eLookupTypeSymbol;
1273 break;
1274
1275 case 'f':
1276 m_file.SetFile (option_arg);
1277 m_type = eLookupTypeFileLine;
1278 break;
1279
1280 case 'i':
1281 m_check_inlines = false;
1282 break;
1283
1284 case 'l':
1285 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
1286 if (m_line_number == UINT32_MAX)
1287 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
1288 else if (m_line_number == 0)
1289 error.SetErrorString ("Zero is an invalid line number.");
1290 m_type = eLookupTypeFileLine;
1291 break;
1292
1293 case 'n':
1294 m_str = option_arg;
1295 m_type = eLookupTypeFunction;
1296 break;
1297
Greg Clayton960d6a42010-08-03 00:35:52 +00001298 case 't':
1299 m_str = option_arg;
1300 m_type = eLookupTypeType;
1301 break;
1302
1303 case 'v':
1304 m_verbose = 1;
1305 break;
1306
Chris Lattner24943d22010-06-08 16:52:24 +00001307 case 'r':
1308 m_use_regex = true;
1309 break;
1310 }
1311
1312 return error;
1313 }
1314
1315 void
1316 ResetOptionValues ()
1317 {
1318 Options::ResetOptionValues();
1319 m_type = eLookupTypeInvalid;
1320 m_str.clear();
1321 m_file.Clear();
1322 m_addr = LLDB_INVALID_ADDRESS;
1323 m_offset = 0;
1324 m_line_number = 0;
1325 m_use_regex = false;
1326 m_check_inlines = true;
Greg Clayton960d6a42010-08-03 00:35:52 +00001327 m_verbose = false;
Chris Lattner24943d22010-06-08 16:52:24 +00001328 }
1329
1330 const lldb::OptionDefinition*
1331 GetDefinitions ()
1332 {
1333 return g_option_table;
1334 }
1335
1336 // Options table: Required for subclasses of Options.
1337
1338 static lldb::OptionDefinition g_option_table[];
1339 int m_type; // Should be a eLookupTypeXXX enum after parsing options
1340 std::string m_str; // Holds name lookup
1341 FileSpec m_file; // Files for file lookups
1342 lldb::addr_t m_addr; // Holds the address to lookup
1343 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
1344 uint32_t m_line_number; // Line number for file+line lookups
1345 bool m_use_regex; // Name lookups in m_str are regular expressions.
1346 bool m_check_inlines;// Check for inline entries when looking up by file/line.
Greg Clayton960d6a42010-08-03 00:35:52 +00001347 bool m_verbose; // Enable verbose lookup info
1348
Chris Lattner24943d22010-06-08 16:52:24 +00001349 };
1350
Greg Clayton238c0a12010-09-18 01:14:36 +00001351 CommandObjectImageLookup (CommandInterpreter &interpreter) :
1352 CommandObject (interpreter,
1353 "image lookup",
1354 "Look up information within executable and dependent shared library images.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001355 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001356 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001357 CommandArgumentEntry arg;
1358 CommandArgumentData file_arg;
1359
1360 // Define the first (and only) variant of this arg.
1361 file_arg.arg_type = eArgTypeFilename;
1362 file_arg.arg_repetition = eArgRepeatStar;
1363
1364 // There is only one variant this argument could be; put it into the argument entry.
1365 arg.push_back (file_arg);
1366
1367 // Push the data for the first argument into the m_arguments vector.
1368 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001369 }
1370
1371 virtual
1372 ~CommandObjectImageLookup ()
1373 {
1374 }
1375
1376 virtual
1377 Options *
1378 GetOptions ()
1379 {
1380 return &m_options;
1381 }
1382
1383
1384 bool
Greg Clayton63094e02010-06-23 01:19:29 +00001385 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
Chris Lattner24943d22010-06-08 16:52:24 +00001386 {
1387 switch (m_options.m_type)
1388 {
1389 case eLookupTypeAddress:
1390 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
1391 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001392 if (LookupAddressInModule (m_interpreter,
Greg Clayton960d6a42010-08-03 00:35:52 +00001393 result.GetOutputStream(),
1394 module,
1395 eSymbolContextEverything,
1396 m_options.m_addr,
1397 m_options.m_offset,
1398 m_options.m_verbose))
Chris Lattner24943d22010-06-08 16:52:24 +00001399 {
1400 result.SetStatus(eReturnStatusSuccessFinishResult);
1401 return true;
1402 }
1403 }
1404 break;
1405
1406 case eLookupTypeSymbol:
1407 if (!m_options.m_str.empty())
1408 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001409 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 +00001410 {
1411 result.SetStatus(eReturnStatusSuccessFinishResult);
1412 return true;
1413 }
1414 }
1415 break;
1416
1417 case eLookupTypeFileLine:
1418 if (m_options.m_file)
1419 {
1420
Greg Clayton238c0a12010-09-18 01:14:36 +00001421 if (LookupFileAndLineInModule (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001422 result.GetOutputStream(),
1423 module,
1424 m_options.m_file,
1425 m_options.m_line_number,
1426 m_options.m_check_inlines))
1427 {
1428 result.SetStatus(eReturnStatusSuccessFinishResult);
1429 return true;
1430 }
1431 }
1432 break;
1433
1434 case eLookupTypeFunction:
1435 if (!m_options.m_str.empty())
1436 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001437 if (LookupFunctionInModule (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001438 result.GetOutputStream(),
1439 module,
1440 m_options.m_str.c_str(),
1441 m_options.m_use_regex))
1442 {
1443 result.SetStatus(eReturnStatusSuccessFinishResult);
1444 return true;
1445 }
1446 }
1447 break;
1448
Greg Clayton960d6a42010-08-03 00:35:52 +00001449 case eLookupTypeType:
1450 if (!m_options.m_str.empty())
1451 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001452 if (LookupTypeInModule (m_interpreter,
Greg Clayton960d6a42010-08-03 00:35:52 +00001453 result.GetOutputStream(),
1454 module,
1455 m_options.m_str.c_str(),
1456 m_options.m_use_regex))
1457 {
1458 result.SetStatus(eReturnStatusSuccessFinishResult);
1459 return true;
1460 }
1461 }
1462 break;
1463
Chris Lattner24943d22010-06-08 16:52:24 +00001464 default:
Greg Clayton238c0a12010-09-18 01:14:36 +00001465 m_options.GenerateOptionUsage (m_interpreter, result.GetErrorStream(), this);
Chris Lattner24943d22010-06-08 16:52:24 +00001466 syntax_error = true;
1467 break;
1468 }
1469
1470 result.SetStatus (eReturnStatusFailed);
1471 return false;
1472 }
1473
1474 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001475 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001476 CommandReturnObject &result)
1477 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001478 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001479 if (target == NULL)
1480 {
1481 result.AppendError ("invalid target, set executable file using 'file' command");
1482 result.SetStatus (eReturnStatusFailed);
1483 return false;
1484 }
1485 else
1486 {
1487 bool syntax_error = false;
1488 uint32_t i;
1489 uint32_t num_successful_lookups = 0;
1490 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1491 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1492 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1493 // Dump all sections for all modules images
1494
1495 if (command.GetArgumentCount() == 0)
1496 {
1497 // Dump all sections for all modules images
1498 const uint32_t num_modules = target->GetImages().GetSize();
1499 if (num_modules > 0)
1500 {
1501 for (i = 0; i<num_modules && syntax_error == false; ++i)
1502 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001503 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001504 {
1505 result.GetOutputStream().EOL();
1506 num_successful_lookups++;
1507 }
1508 }
1509 }
1510 else
1511 {
1512 result.AppendError ("the target has no associated executable images");
1513 result.SetStatus (eReturnStatusFailed);
1514 return false;
1515 }
1516 }
1517 else
1518 {
1519 // Dump specified images (by basename or fullpath)
1520 const char *arg_cstr;
1521 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
1522 {
1523 FileSpec image_file(arg_cstr);
1524 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +00001525 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +00001526
Greg Clayton661825b2010-06-28 23:51:11 +00001527 // Not found in our module list for our target, check the main
1528 // shared module list in case it is a extra file used somewhere
1529 // else
1530 if (num_matching_modules == 0)
1531 num_matching_modules = ModuleList::FindSharedModules (image_file,
1532 target->GetArchitecture(),
1533 NULL,
1534 NULL,
1535 matching_modules);
1536
Chris Lattner24943d22010-06-08 16:52:24 +00001537 if (num_matching_modules > 0)
1538 {
Greg Claytonbef15832010-07-14 00:18:15 +00001539 for (size_t j=0; j<num_matching_modules; ++j)
Chris Lattner24943d22010-06-08 16:52:24 +00001540 {
Greg Claytonbef15832010-07-14 00:18:15 +00001541 Module * image_module = matching_modules.GetModulePointerAtIndex(j);
Chris Lattner24943d22010-06-08 16:52:24 +00001542 if (image_module)
1543 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001544 if (LookupInModule (m_interpreter, image_module, result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001545 {
1546 result.GetOutputStream().EOL();
1547 num_successful_lookups++;
1548 }
1549 }
1550 }
1551 }
1552 else
1553 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1554 }
1555 }
1556
1557 if (num_successful_lookups > 0)
1558 result.SetStatus (eReturnStatusSuccessFinishResult);
1559 else
1560 result.SetStatus (eReturnStatusFailed);
1561 }
1562 return result.Succeeded();
1563 }
1564protected:
1565
1566 CommandOptions m_options;
1567};
1568
1569lldb::OptionDefinition
1570CommandObjectImageLookup::CommandOptions::g_option_table[] =
1571{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001572{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more executable images."},
1573{ 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."},
1574{ 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."},
1575{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
1576{ 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."},
1577{ 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)."},
1578{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."},
1579{ 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."},
1580{ 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."},
1581{ LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
1582{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001583};
1584
1585
1586
1587
1588
1589//----------------------------------------------------------------------
1590// CommandObjectImage constructor
1591//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001592CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001593 CommandObjectMultiword (interpreter,
1594 "image",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001595 "A set of commands for accessing information for one or more executable images.",
1596 "image <sub-command> ...")
Chris Lattner24943d22010-06-08 16:52:24 +00001597{
Greg Clayton238c0a12010-09-18 01:14:36 +00001598 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectImageDump (interpreter)));
1599 LoadSubCommand ("list", CommandObjectSP (new CommandObjectImageList (interpreter)));
1600 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectImageLookup (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001601}
1602
1603//----------------------------------------------------------------------
1604// Destructor
1605//----------------------------------------------------------------------
1606CommandObjectImage::~CommandObjectImage()
1607{
1608}
1609