blob: b8c92ae123b2091abae129b80ed022a1f4f6f6ba [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 {
485 }
486
487 virtual
488 ~CommandObjectImageDumpModuleList ()
489 {
490 }
491
492 virtual int
Greg Clayton238c0a12010-09-18 01:14:36 +0000493 HandleArgumentCompletion (Args &input,
Greg Clayton63094e02010-06-23 01:19:29 +0000494 int &cursor_index,
495 int &cursor_char_position,
496 OptionElementVector &opt_element_vector,
497 int match_start_point,
498 int max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000499 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000500 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000501 {
502 // Arguments are the standard module completer.
503 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
504 completion_str.erase (cursor_char_position);
505
Greg Clayton238c0a12010-09-18 01:14:36 +0000506 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +0000507 CommandCompletions::eModuleCompletion,
508 completion_str.c_str(),
509 match_start_point,
510 max_return_elements,
511 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000512 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000513 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000514 return matches.GetSize();
515 }
516};
517
518class CommandObjectImageDumpSourceFileList : public CommandObject
519{
520public:
521
Greg Clayton238c0a12010-09-18 01:14:36 +0000522 CommandObjectImageDumpSourceFileList (CommandInterpreter &interpreter,
523 const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000524 const char *help,
525 const char *syntax) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000526 CommandObject (interpreter, name, help, syntax)
Chris Lattner24943d22010-06-08 16:52:24 +0000527 {
528 }
529
530 virtual
531 ~CommandObjectImageDumpSourceFileList ()
532 {
533 }
534
535 virtual int
Greg Clayton238c0a12010-09-18 01:14:36 +0000536 HandleArgumentCompletion (Args &input,
Greg Clayton63094e02010-06-23 01:19:29 +0000537 int &cursor_index,
538 int &cursor_char_position,
539 OptionElementVector &opt_element_vector,
540 int match_start_point,
541 int max_return_elements,
Greg Clayton54e7afa2010-07-09 20:39:50 +0000542 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000543 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000544 {
545 // Arguments are the standard source file completer.
546 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
547 completion_str.erase (cursor_char_position);
548
Greg Clayton238c0a12010-09-18 01:14:36 +0000549 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +0000550 CommandCompletions::eSourceFileCompletion,
551 completion_str.c_str(),
552 match_start_point,
553 max_return_elements,
554 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000555 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000556 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000557 return matches.GetSize();
558 }
559};
560
561
562class CommandObjectImageDumpSymtab : public CommandObjectImageDumpModuleList
563{
564public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000565 CommandObjectImageDumpSymtab (CommandInterpreter &interpreter) :
566 CommandObjectImageDumpModuleList (interpreter,
567 "image dump symtab",
568 "Dump the symbol table from one or more executable images.",
569 "image dump symtab [<file1> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000570 {
571 }
572
573 virtual
574 ~CommandObjectImageDumpSymtab ()
575 {
576 }
577
578 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000579 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000580 CommandReturnObject &result)
581 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000582 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000583 if (target == NULL)
584 {
585 result.AppendError ("invalid target, set executable file using 'file' command");
586 result.SetStatus (eReturnStatusFailed);
587 return false;
588 }
589 else
590 {
591 uint32_t num_dumped = 0;
592
593 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
594 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
595 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
596
597 if (command.GetArgumentCount() == 0)
598 {
599 // Dump all sections for all modules images
600 const uint32_t num_modules = target->GetImages().GetSize();
601 if (num_modules > 0)
602 {
603 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
604 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
605 {
606 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000607 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000608 }
609 }
610 else
611 {
612 result.AppendError ("the target has no associated executable images");
613 result.SetStatus (eReturnStatusFailed);
614 return false;
615 }
616 }
617 else
618 {
619 // Dump specified images (by basename or fullpath)
620 const char *arg_cstr;
621 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
622 {
623 FileSpec image_file(arg_cstr);
624 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000625 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000626
Greg Clayton661825b2010-06-28 23:51:11 +0000627 // Not found in our module list for our target, check the main
628 // shared module list in case it is a extra file used somewhere
629 // else
630 if (num_matching_modules == 0)
631 num_matching_modules = ModuleList::FindSharedModules (image_file,
632 target->GetArchitecture(),
633 NULL,
634 NULL,
635 matching_modules);
636
Chris Lattner24943d22010-06-08 16:52:24 +0000637 if (num_matching_modules > 0)
638 {
639 for (size_t i=0; i<num_matching_modules; ++i)
640 {
641 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
642 if (image_module)
643 {
644 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000645 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000646 }
647 }
648 }
649 else
650 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
651 }
652 }
653
654 if (num_dumped > 0)
655 result.SetStatus (eReturnStatusSuccessFinishResult);
656 else
657 {
658 result.AppendError ("no matching executable images found");
659 result.SetStatus (eReturnStatusFailed);
660 }
661 }
662 return result.Succeeded();
663 }
664
665};
666
667//----------------------------------------------------------------------
668// Image section dumping command
669//----------------------------------------------------------------------
670class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList
671{
672public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000673 CommandObjectImageDumpSections (CommandInterpreter &interpreter) :
674 CommandObjectImageDumpModuleList (interpreter,
675 "image dump sections",
Greg Clayton63094e02010-06-23 01:19:29 +0000676 "Dump the sections from one or more executable images.",
677 "image dump sections [<file1> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000678 {
679 }
680
681 virtual
682 ~CommandObjectImageDumpSections ()
683 {
684 }
685
686 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000687 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000688 CommandReturnObject &result)
689 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000690 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000691 if (target == NULL)
692 {
693 result.AppendError ("invalid target, set executable file using 'file' command");
694 result.SetStatus (eReturnStatusFailed);
695 return false;
696 }
697 else
698 {
699 uint32_t num_dumped = 0;
700
701 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
702 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
703 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
704
705 if (command.GetArgumentCount() == 0)
706 {
707 // Dump all sections for all modules images
708 const uint32_t num_modules = target->GetImages().GetSize();
709 if (num_modules > 0)
710 {
711 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
712 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
713 {
714 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000715 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000716 }
717 }
718 else
719 {
720 result.AppendError ("the target has no associated executable images");
721 result.SetStatus (eReturnStatusFailed);
722 return false;
723 }
724 }
725 else
726 {
727 // Dump specified images (by basename or fullpath)
728 const char *arg_cstr;
729 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
730 {
731 FileSpec image_file(arg_cstr);
732 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000733 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000734
Greg Clayton661825b2010-06-28 23:51:11 +0000735 // Not found in our module list for our target, check the main
736 // shared module list in case it is a extra file used somewhere
737 // else
738 if (num_matching_modules == 0)
739 num_matching_modules = ModuleList::FindSharedModules (image_file,
740 target->GetArchitecture(),
741 NULL,
742 NULL,
743 matching_modules);
744
Chris Lattner24943d22010-06-08 16:52:24 +0000745 if (num_matching_modules > 0)
746 {
747 for (size_t i=0; i<num_matching_modules; ++i)
748 {
749 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
750 if (image_module)
751 {
752 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000753 DumpModuleSections (m_interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000754 }
755 }
756 }
757 else
758 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
759 }
760 }
761
762 if (num_dumped > 0)
763 result.SetStatus (eReturnStatusSuccessFinishResult);
764 else
765 {
766 result.AppendError ("no matching executable images found");
767 result.SetStatus (eReturnStatusFailed);
768 }
769 }
770 return result.Succeeded();
771 }
772};
773
774//----------------------------------------------------------------------
775// Image debug symbol dumping command
776//----------------------------------------------------------------------
777class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList
778{
779public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000780 CommandObjectImageDumpSymfile (CommandInterpreter &interpreter) :
781 CommandObjectImageDumpModuleList (interpreter,
782 "image dump symfile",
783 "Dump the debug symbol file for one or more executable images.",
784 "image dump symfile [<file1> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000785 {
786 }
787
788 virtual
789 ~CommandObjectImageDumpSymfile ()
790 {
791 }
792
793 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000794 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000795 CommandReturnObject &result)
796 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000797 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000798 if (target == NULL)
799 {
800 result.AppendError ("invalid target, set executable file using 'file' command");
801 result.SetStatus (eReturnStatusFailed);
802 return false;
803 }
804 else
805 {
806 uint32_t num_dumped = 0;
807
808 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
809 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
810 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
811
812 if (command.GetArgumentCount() == 0)
813 {
814 // Dump all sections for all modules images
815 const uint32_t num_modules = target->GetImages().GetSize();
816 if (num_modules > 0)
817 {
818 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
819 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
820 {
821 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
822 num_dumped++;
823 }
824 }
825 else
826 {
827 result.AppendError ("the target has no associated executable images");
828 result.SetStatus (eReturnStatusFailed);
829 return false;
830 }
831 }
832 else
833 {
834 // Dump specified images (by basename or fullpath)
835 const char *arg_cstr;
836 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
837 {
838 FileSpec image_file(arg_cstr);
839 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000840 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000841
Greg Clayton661825b2010-06-28 23:51:11 +0000842 // Not found in our module list for our target, check the main
843 // shared module list in case it is a extra file used somewhere
844 // else
845 if (num_matching_modules == 0)
846 num_matching_modules = ModuleList::FindSharedModules (image_file,
847 target->GetArchitecture(),
848 NULL,
849 NULL,
850 matching_modules);
851
Chris Lattner24943d22010-06-08 16:52:24 +0000852 if (num_matching_modules > 0)
853 {
854 for (size_t i=0; i<num_matching_modules; ++i)
855 {
856 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
857 if (image_module)
858 {
859 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
860 num_dumped++;
861 }
862 }
863 }
864 else
865 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
866 }
867 }
868
869 if (num_dumped > 0)
870 result.SetStatus (eReturnStatusSuccessFinishResult);
871 else
872 {
873 result.AppendError ("no matching executable images found");
874 result.SetStatus (eReturnStatusFailed);
875 }
876 }
877 return result.Succeeded();
878 }
879};
880
881//----------------------------------------------------------------------
882// Image debug symbol dumping command
883//----------------------------------------------------------------------
884class CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList
885{
886public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000887 CommandObjectImageDumpLineTable (CommandInterpreter &interpreter) :
888 CommandObjectImageDumpSourceFileList (interpreter,
889 "image dump line-table",
890 "Dump the debug symbol file for one or more executable images.",
891 "image dump line-table <source-file1> [<source-file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000892 {
893 }
894
895 virtual
896 ~CommandObjectImageDumpLineTable ()
897 {
898 }
899
900 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000901 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000902 CommandReturnObject &result)
903 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000904 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000905 if (target == NULL)
906 {
907 result.AppendError ("invalid target, set executable file using 'file' command");
908 result.SetStatus (eReturnStatusFailed);
909 return false;
910 }
911 else
912 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000913 ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000914 uint32_t total_num_dumped = 0;
915
916 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
917 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
918 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
919
920 if (command.GetArgumentCount() == 0)
921 {
922 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
923 result.SetStatus (eReturnStatusFailed);
924 }
925 else
926 {
927 // Dump specified images (by basename or fullpath)
928 const char *arg_cstr;
929 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
930 {
931 FileSpec file_spec(arg_cstr);
932 const uint32_t num_modules = target->GetImages().GetSize();
933 if (num_modules > 0)
934 {
935 uint32_t num_dumped = 0;
936 for (uint32_t i = 0; i<num_modules; ++i)
937 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000938 if (DumpCompileUnitLineTable (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000939 result.GetOutputStream(),
940 target->GetImages().GetModulePointerAtIndex(i),
941 file_spec,
942 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
943 num_dumped++;
944 }
945 if (num_dumped == 0)
946 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
947 else
948 total_num_dumped += num_dumped;
949 }
950 }
951 }
952
953 if (total_num_dumped > 0)
954 result.SetStatus (eReturnStatusSuccessFinishResult);
955 else
956 {
957 result.AppendError ("no source filenames matched any command arguments");
958 result.SetStatus (eReturnStatusFailed);
959 }
960 }
961 return result.Succeeded();
962 }
963};
964
965//----------------------------------------------------------------------
966// Dump multi-word command
967//----------------------------------------------------------------------
968class CommandObjectImageDump : public CommandObjectMultiword
969{
970public:
971
972 //------------------------------------------------------------------
973 // Constructors and Destructors
974 //------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +0000975 CommandObjectImageDump(CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000976 CommandObjectMultiword (interpreter,
977 "image dump",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000978 "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 +0000979 "image dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +0000980 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000981 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectImageDumpSymtab (interpreter)));
982 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectImageDumpSections (interpreter)));
983 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectImageDumpSymfile (interpreter)));
984 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectImageDumpLineTable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +0000985 }
986
987 virtual
988 ~CommandObjectImageDump()
989 {
990 }
991};
992
993//----------------------------------------------------------------------
994// List images with associated information
995//----------------------------------------------------------------------
996class CommandObjectImageList : public CommandObject
997{
998public:
999
1000 class CommandOptions : public Options
1001 {
1002 public:
1003
1004 CommandOptions () :
1005 Options(),
1006 m_format_array()
1007 {
1008 }
1009
1010 virtual
1011 ~CommandOptions ()
1012 {
1013 }
1014
1015 virtual Error
1016 SetOptionValue (int option_idx, const char *option_arg)
1017 {
1018 char short_option = (char) m_getopt_table[option_idx].val;
1019 uint32_t width = 0;
1020 if (option_arg)
1021 width = strtoul (option_arg, NULL, 0);
1022 m_format_array.push_back(std::make_pair(short_option, width));
1023 Error error;
1024 return error;
1025 }
1026
1027 void
1028 ResetOptionValues ()
1029 {
1030 Options::ResetOptionValues();
1031 m_format_array.clear();
1032 }
1033
1034 const lldb::OptionDefinition*
1035 GetDefinitions ()
1036 {
1037 return g_option_table;
1038 }
1039
1040 // Options table: Required for subclasses of Options.
1041
1042 static lldb::OptionDefinition g_option_table[];
1043
1044 // Instance variables to hold the values for command options.
1045 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
1046 FormatWidthCollection m_format_array;
1047 };
1048
Greg Clayton238c0a12010-09-18 01:14:36 +00001049 CommandObjectImageList (CommandInterpreter &interpreter) :
1050 CommandObject (interpreter,
1051 "image list",
1052 "List current executable and dependent shared library images.",
1053 "image list [<cmd-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00001054 {
1055 }
1056
1057 virtual
1058 ~CommandObjectImageList ()
1059 {
1060 }
1061
1062 virtual
1063 Options *
1064 GetOptions ()
1065 {
1066 return &m_options;
1067 }
1068
1069 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001070 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001071 CommandReturnObject &result)
1072 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001073 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001074 if (target == NULL)
1075 {
1076 result.AppendError ("invalid target, set executable file using 'file' command");
1077 result.SetStatus (eReturnStatusFailed);
1078 return false;
1079 }
1080 else
1081 {
1082 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1083 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1084 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1085 // Dump all sections for all modules images
1086 const uint32_t num_modules = target->GetImages().GetSize();
1087 if (num_modules > 0)
1088 {
1089 Stream &strm = result.GetOutputStream();
1090
1091 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1092 {
1093 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
1094 strm.Printf("[%3u] ", image_idx);
1095
1096 if (m_options.m_format_array.empty())
1097 {
1098 DumpFullpath(strm, &module->GetFileSpec(), 0);
1099 }
1100 else
1101 {
1102 const size_t num_entries = m_options.m_format_array.size();
1103 for (size_t i=0; i<num_entries; ++i)
1104 {
1105 if (i > 0)
1106 strm.PutChar(' ');
1107 char format_char = m_options.m_format_array[i].first;
1108 uint32_t width = m_options.m_format_array[i].second;
1109 switch (format_char)
1110 {
1111 case 'a':
1112 DumpModuleArchitecture (strm, module, width);
1113 break;
1114
1115 case 'f':
1116 DumpFullpath (strm, &module->GetFileSpec(), width);
1117 break;
1118
1119 case 'd':
1120 DumpDirectory (strm, &module->GetFileSpec(), width);
1121 break;
1122
1123 case 'b':
1124 DumpBasename (strm, &module->GetFileSpec(), width);
1125 break;
1126
1127 case 's':
1128 case 'S':
1129 {
1130 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1131 if (symbol_vendor)
1132 {
1133 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
1134 if (symbol_file)
1135 {
1136 if (format_char == 'S')
1137 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1138 else
1139 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1140 break;
1141 }
1142 }
1143 strm.Printf("%.*s", width, "<NONE>");
1144 }
1145 break;
1146
1147 case 'u':
1148 DumpModuleUUID(strm, module);
1149 break;
1150
1151 default:
1152 break;
1153 }
1154 }
1155 }
1156 strm.EOL();
1157 }
1158 result.SetStatus (eReturnStatusSuccessFinishResult);
1159 }
1160 else
1161 {
1162 result.AppendError ("the target has no associated executable images");
1163 result.SetStatus (eReturnStatusFailed);
1164 return false;
1165 }
1166 }
1167 return result.Succeeded();
1168 }
1169protected:
1170
1171 CommandOptions m_options;
1172};
1173
1174lldb::OptionDefinition
1175CommandObjectImageList::CommandOptions::g_option_table[] =
1176{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001177{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
1178{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
1179{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
1180{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
1181{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
1182{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
1183{ LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."},
1184{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001185};
1186
1187
1188
1189//----------------------------------------------------------------------
1190// Lookup information in images
1191//----------------------------------------------------------------------
1192class CommandObjectImageLookup : public CommandObject
1193{
1194public:
1195
1196 enum
1197 {
1198 eLookupTypeInvalid = -1,
1199 eLookupTypeAddress = 0,
1200 eLookupTypeSymbol,
1201 eLookupTypeFileLine, // Line is optional
1202 eLookupTypeFunction,
Greg Clayton960d6a42010-08-03 00:35:52 +00001203 eLookupTypeType,
Chris Lattner24943d22010-06-08 16:52:24 +00001204 kNumLookupTypes
1205 };
1206
1207 class CommandOptions : public Options
1208 {
1209 public:
1210
1211 CommandOptions () :
1212 Options()
1213 {
1214 ResetOptionValues();
1215 }
1216
1217 virtual
1218 ~CommandOptions ()
1219 {
1220 }
1221
1222 virtual Error
1223 SetOptionValue (int option_idx, const char *option_arg)
1224 {
1225 Error error;
1226
1227 char short_option = (char) m_getopt_table[option_idx].val;
1228
1229 switch (short_option)
1230 {
1231 case 'a':
1232 m_type = eLookupTypeAddress;
1233 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1234 if (m_addr == LLDB_INVALID_ADDRESS)
1235 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
1236 break;
1237
1238 case 'o':
1239 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1240 if (m_offset == LLDB_INVALID_ADDRESS)
1241 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
1242 break;
1243
1244 case 's':
1245 m_str = option_arg;
1246 m_type = eLookupTypeSymbol;
1247 break;
1248
1249 case 'f':
1250 m_file.SetFile (option_arg);
1251 m_type = eLookupTypeFileLine;
1252 break;
1253
1254 case 'i':
1255 m_check_inlines = false;
1256 break;
1257
1258 case 'l':
1259 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
1260 if (m_line_number == UINT32_MAX)
1261 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
1262 else if (m_line_number == 0)
1263 error.SetErrorString ("Zero is an invalid line number.");
1264 m_type = eLookupTypeFileLine;
1265 break;
1266
1267 case 'n':
1268 m_str = option_arg;
1269 m_type = eLookupTypeFunction;
1270 break;
1271
Greg Clayton960d6a42010-08-03 00:35:52 +00001272 case 't':
1273 m_str = option_arg;
1274 m_type = eLookupTypeType;
1275 break;
1276
1277 case 'v':
1278 m_verbose = 1;
1279 break;
1280
Chris Lattner24943d22010-06-08 16:52:24 +00001281 case 'r':
1282 m_use_regex = true;
1283 break;
1284 }
1285
1286 return error;
1287 }
1288
1289 void
1290 ResetOptionValues ()
1291 {
1292 Options::ResetOptionValues();
1293 m_type = eLookupTypeInvalid;
1294 m_str.clear();
1295 m_file.Clear();
1296 m_addr = LLDB_INVALID_ADDRESS;
1297 m_offset = 0;
1298 m_line_number = 0;
1299 m_use_regex = false;
1300 m_check_inlines = true;
Greg Clayton960d6a42010-08-03 00:35:52 +00001301 m_verbose = false;
Chris Lattner24943d22010-06-08 16:52:24 +00001302 }
1303
1304 const lldb::OptionDefinition*
1305 GetDefinitions ()
1306 {
1307 return g_option_table;
1308 }
1309
1310 // Options table: Required for subclasses of Options.
1311
1312 static lldb::OptionDefinition g_option_table[];
1313 int m_type; // Should be a eLookupTypeXXX enum after parsing options
1314 std::string m_str; // Holds name lookup
1315 FileSpec m_file; // Files for file lookups
1316 lldb::addr_t m_addr; // Holds the address to lookup
1317 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
1318 uint32_t m_line_number; // Line number for file+line lookups
1319 bool m_use_regex; // Name lookups in m_str are regular expressions.
1320 bool m_check_inlines;// Check for inline entries when looking up by file/line.
Greg Clayton960d6a42010-08-03 00:35:52 +00001321 bool m_verbose; // Enable verbose lookup info
1322
Chris Lattner24943d22010-06-08 16:52:24 +00001323 };
1324
Greg Clayton238c0a12010-09-18 01:14:36 +00001325 CommandObjectImageLookup (CommandInterpreter &interpreter) :
1326 CommandObject (interpreter,
1327 "image lookup",
1328 "Look up information within executable and dependent shared library images.",
1329 "image lookup [<cmd-options>] [<file1>...]")
Chris Lattner24943d22010-06-08 16:52:24 +00001330 {
1331 }
1332
1333 virtual
1334 ~CommandObjectImageLookup ()
1335 {
1336 }
1337
1338 virtual
1339 Options *
1340 GetOptions ()
1341 {
1342 return &m_options;
1343 }
1344
1345
1346 bool
Greg Clayton63094e02010-06-23 01:19:29 +00001347 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
Chris Lattner24943d22010-06-08 16:52:24 +00001348 {
1349 switch (m_options.m_type)
1350 {
1351 case eLookupTypeAddress:
1352 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
1353 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001354 if (LookupAddressInModule (m_interpreter,
Greg Clayton960d6a42010-08-03 00:35:52 +00001355 result.GetOutputStream(),
1356 module,
1357 eSymbolContextEverything,
1358 m_options.m_addr,
1359 m_options.m_offset,
1360 m_options.m_verbose))
Chris Lattner24943d22010-06-08 16:52:24 +00001361 {
1362 result.SetStatus(eReturnStatusSuccessFinishResult);
1363 return true;
1364 }
1365 }
1366 break;
1367
1368 case eLookupTypeSymbol:
1369 if (!m_options.m_str.empty())
1370 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001371 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 +00001372 {
1373 result.SetStatus(eReturnStatusSuccessFinishResult);
1374 return true;
1375 }
1376 }
1377 break;
1378
1379 case eLookupTypeFileLine:
1380 if (m_options.m_file)
1381 {
1382
Greg Clayton238c0a12010-09-18 01:14:36 +00001383 if (LookupFileAndLineInModule (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001384 result.GetOutputStream(),
1385 module,
1386 m_options.m_file,
1387 m_options.m_line_number,
1388 m_options.m_check_inlines))
1389 {
1390 result.SetStatus(eReturnStatusSuccessFinishResult);
1391 return true;
1392 }
1393 }
1394 break;
1395
1396 case eLookupTypeFunction:
1397 if (!m_options.m_str.empty())
1398 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001399 if (LookupFunctionInModule (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001400 result.GetOutputStream(),
1401 module,
1402 m_options.m_str.c_str(),
1403 m_options.m_use_regex))
1404 {
1405 result.SetStatus(eReturnStatusSuccessFinishResult);
1406 return true;
1407 }
1408 }
1409 break;
1410
Greg Clayton960d6a42010-08-03 00:35:52 +00001411 case eLookupTypeType:
1412 if (!m_options.m_str.empty())
1413 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001414 if (LookupTypeInModule (m_interpreter,
Greg Clayton960d6a42010-08-03 00:35:52 +00001415 result.GetOutputStream(),
1416 module,
1417 m_options.m_str.c_str(),
1418 m_options.m_use_regex))
1419 {
1420 result.SetStatus(eReturnStatusSuccessFinishResult);
1421 return true;
1422 }
1423 }
1424 break;
1425
Chris Lattner24943d22010-06-08 16:52:24 +00001426 default:
Greg Clayton238c0a12010-09-18 01:14:36 +00001427 m_options.GenerateOptionUsage (m_interpreter, result.GetErrorStream(), this);
Chris Lattner24943d22010-06-08 16:52:24 +00001428 syntax_error = true;
1429 break;
1430 }
1431
1432 result.SetStatus (eReturnStatusFailed);
1433 return false;
1434 }
1435
1436 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001437 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001438 CommandReturnObject &result)
1439 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001440 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001441 if (target == NULL)
1442 {
1443 result.AppendError ("invalid target, set executable file using 'file' command");
1444 result.SetStatus (eReturnStatusFailed);
1445 return false;
1446 }
1447 else
1448 {
1449 bool syntax_error = false;
1450 uint32_t i;
1451 uint32_t num_successful_lookups = 0;
1452 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1453 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1454 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1455 // Dump all sections for all modules images
1456
1457 if (command.GetArgumentCount() == 0)
1458 {
1459 // Dump all sections for all modules images
1460 const uint32_t num_modules = target->GetImages().GetSize();
1461 if (num_modules > 0)
1462 {
1463 for (i = 0; i<num_modules && syntax_error == false; ++i)
1464 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001465 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001466 {
1467 result.GetOutputStream().EOL();
1468 num_successful_lookups++;
1469 }
1470 }
1471 }
1472 else
1473 {
1474 result.AppendError ("the target has no associated executable images");
1475 result.SetStatus (eReturnStatusFailed);
1476 return false;
1477 }
1478 }
1479 else
1480 {
1481 // Dump specified images (by basename or fullpath)
1482 const char *arg_cstr;
1483 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
1484 {
1485 FileSpec image_file(arg_cstr);
1486 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +00001487 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +00001488
Greg Clayton661825b2010-06-28 23:51:11 +00001489 // Not found in our module list for our target, check the main
1490 // shared module list in case it is a extra file used somewhere
1491 // else
1492 if (num_matching_modules == 0)
1493 num_matching_modules = ModuleList::FindSharedModules (image_file,
1494 target->GetArchitecture(),
1495 NULL,
1496 NULL,
1497 matching_modules);
1498
Chris Lattner24943d22010-06-08 16:52:24 +00001499 if (num_matching_modules > 0)
1500 {
Greg Claytonbef15832010-07-14 00:18:15 +00001501 for (size_t j=0; j<num_matching_modules; ++j)
Chris Lattner24943d22010-06-08 16:52:24 +00001502 {
Greg Claytonbef15832010-07-14 00:18:15 +00001503 Module * image_module = matching_modules.GetModulePointerAtIndex(j);
Chris Lattner24943d22010-06-08 16:52:24 +00001504 if (image_module)
1505 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001506 if (LookupInModule (m_interpreter, image_module, result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001507 {
1508 result.GetOutputStream().EOL();
1509 num_successful_lookups++;
1510 }
1511 }
1512 }
1513 }
1514 else
1515 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1516 }
1517 }
1518
1519 if (num_successful_lookups > 0)
1520 result.SetStatus (eReturnStatusSuccessFinishResult);
1521 else
1522 result.SetStatus (eReturnStatusFailed);
1523 }
1524 return result.Succeeded();
1525 }
1526protected:
1527
1528 CommandOptions m_options;
1529};
1530
1531lldb::OptionDefinition
1532CommandObjectImageLookup::CommandOptions::g_option_table[] =
1533{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001534{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more executable images."},
1535{ 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."},
1536{ 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."},
1537{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
1538{ 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."},
1539{ 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)."},
1540{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."},
1541{ 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."},
1542{ 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."},
1543{ LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
1544{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001545};
1546
1547
1548
1549
1550
1551//----------------------------------------------------------------------
1552// CommandObjectImage constructor
1553//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001554CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001555 CommandObjectMultiword (interpreter,
1556 "image",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001557 "A set of commands for accessing information for one or more executable images.",
1558 "image <sub-command> ...")
Chris Lattner24943d22010-06-08 16:52:24 +00001559{
Greg Clayton238c0a12010-09-18 01:14:36 +00001560 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectImageDump (interpreter)));
1561 LoadSubCommand ("list", CommandObjectSP (new CommandObjectImageList (interpreter)));
1562 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectImageLookup (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001563}
1564
1565//----------------------------------------------------------------------
1566// Destructor
1567//----------------------------------------------------------------------
1568CommandObjectImage::~CommandObjectImage()
1569{
1570}
1571