blob: d684bb2df98b078d554bd7b225a2012548c8bb4c [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"
Greg Clayton5f54ac32011-02-08 05:05:52 +000017#include "lldb/Host/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)
Greg Clayton940b1032011-02-23 00:35:02 +000045 strm.Printf("%-*s", width, module->GetArchitecture().GetArchitectureName());
Chris Lattner24943d22010-06-08 16:52:24 +000046 else
Greg Clayton940b1032011-02-23 00:35:02 +000047 strm.PutCString(module->GetArchitecture().GetArchitectureName());
Chris Lattner24943d22010-06-08 16:52:24 +000048 }
49}
50
51static void
52DumpModuleUUID (Stream &strm, Module *module)
53{
54 module->GetUUID().Dump (&strm);
55}
56
57static uint32_t
58DumpCompileUnitLineTable
59(
Greg Clayton63094e02010-06-23 01:19:29 +000060 CommandInterpreter &interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +000061 Stream &strm,
62 Module *module,
63 const FileSpec &file_spec,
64 bool load_addresses
65)
66{
67 uint32_t num_matches = 0;
68 if (module)
69 {
70 SymbolContextList sc_list;
71 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
72 0,
73 false,
74 eSymbolContextCompUnit,
75 sc_list);
76
77 for (uint32_t i=0; i<num_matches; ++i)
78 {
79 SymbolContext sc;
80 if (sc_list.GetContextAtIndex(i, sc))
81 {
82 if (i > 0)
83 strm << "\n\n";
84
Johnny Chencff44fd2010-10-29 22:18:43 +000085 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
Chris Lattner24943d22010-06-08 16:52:24 +000086 << module->GetFileSpec().GetFilename() << "\n";
87 LineTable *line_table = sc.comp_unit->GetLineTable();
88 if (line_table)
Greg Clayton63094e02010-06-23 01:19:29 +000089 line_table->GetDescription (&strm,
Greg Claytoneea26402010-09-14 23:36:40 +000090 interpreter.GetDebugger().GetExecutionContext().target,
Greg Clayton63094e02010-06-23 01:19:29 +000091 lldb::eDescriptionLevelBrief);
Chris Lattner24943d22010-06-08 16:52:24 +000092 else
93 strm << "No line table";
94 }
95 }
96 }
97 return num_matches;
98}
99
100static void
101DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
102{
103 if (file_spec_ptr)
104 {
105 if (width > 0)
106 {
107 char fullpath[PATH_MAX];
108 if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath)))
109 {
110 strm.Printf("%-*s", width, fullpath);
111 return;
112 }
113 }
114 else
115 {
116 file_spec_ptr->Dump(&strm);
117 return;
118 }
119 }
120 // Keep the width spacing correct if things go wrong...
121 if (width > 0)
122 strm.Printf("%-*s", width, "");
123}
124
125static void
126DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
127{
128 if (file_spec_ptr)
129 {
130 if (width > 0)
131 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
132 else
133 file_spec_ptr->GetDirectory().Dump(&strm);
134 return;
135 }
136 // Keep the width spacing correct if things go wrong...
137 if (width > 0)
138 strm.Printf("%-*s", width, "");
139}
140
141static void
142DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
143{
144 if (file_spec_ptr)
145 {
146 if (width > 0)
147 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
148 else
149 file_spec_ptr->GetFilename().Dump(&strm);
150 return;
151 }
152 // Keep the width spacing correct if things go wrong...
153 if (width > 0)
154 strm.Printf("%-*s", width, "");
155}
156
157
158static void
Greg Claytonb3448432011-03-24 21:19:54 +0000159DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
Chris Lattner24943d22010-06-08 16:52:24 +0000160{
161 if (module)
162 {
163 ObjectFile *objfile = module->GetObjectFile ();
164 if (objfile)
165 {
166 Symtab *symtab = objfile->GetSymtab();
167 if (symtab)
Greg Clayton8d3802d2010-10-08 04:20:14 +0000168 symtab->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, sort_order);
Chris Lattner24943d22010-06-08 16:52:24 +0000169 }
170 }
171}
172
173static void
Greg Clayton63094e02010-06-23 01:19:29 +0000174DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
Chris Lattner24943d22010-06-08 16:52:24 +0000175{
176 if (module)
177 {
178 ObjectFile *objfile = module->GetObjectFile ();
179 if (objfile)
180 {
181 SectionList *section_list = objfile->GetSectionList();
182 if (section_list)
Greg Clayton3fed8b92010-10-08 00:21:05 +0000183 {
184 strm.PutCString ("Sections for '");
185 strm << module->GetFileSpec();
Greg Clayton940b1032011-02-23 00:35:02 +0000186 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName());
Greg Clayton3fed8b92010-10-08 00:21:05 +0000187 strm.IndentMore();
Greg Clayton58e844b2010-12-08 05:08:21 +0000188 section_list->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, true, UINT32_MAX);
Greg Clayton3fed8b92010-10-08 00:21:05 +0000189 strm.IndentLess();
190 }
Chris Lattner24943d22010-06-08 16:52:24 +0000191 }
192 }
193}
194
195static bool
196DumpModuleSymbolVendor (Stream &strm, Module *module)
197{
198 if (module)
199 {
200 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
201 if (symbol_vendor)
202 {
203 symbol_vendor->Dump(&strm);
204 return true;
205 }
206 }
207 return false;
208}
209
210static bool
Greg Clayton960d6a42010-08-03 00:35:52 +0000211LookupAddressInModule
212(
213 CommandInterpreter &interpreter,
214 Stream &strm,
215 Module *module,
216 uint32_t resolve_mask,
217 lldb::addr_t raw_addr,
218 lldb::addr_t offset,
219 bool verbose
220)
Chris Lattner24943d22010-06-08 16:52:24 +0000221{
222 if (module)
223 {
224 lldb::addr_t addr = raw_addr - offset;
225 Address so_addr;
226 SymbolContext sc;
Greg Claytoneea26402010-09-14 23:36:40 +0000227 Target *target = interpreter.GetDebugger().GetExecutionContext().target;
228 if (target && !target->GetSectionLoadList().IsEmpty())
Chris Lattner24943d22010-06-08 16:52:24 +0000229 {
Greg Claytoneea26402010-09-14 23:36:40 +0000230 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
Chris Lattner24943d22010-06-08 16:52:24 +0000231 return false;
232 else if (so_addr.GetModule() != module)
233 return false;
234 }
235 else
236 {
237 if (!module->ResolveFileAddress (addr, so_addr))
238 return false;
239 }
240
241 // If an offset was given, print out the address we ended up looking up
242 if (offset)
Greg Clayton7e2f91c2011-01-29 07:10:55 +0000243 strm.Printf("File Address: 0x%llx\n", addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000244
Greg Clayton63094e02010-06-23 01:19:29 +0000245 ExecutionContextScope *exe_scope = interpreter.GetDebugger().GetExecutionContext().GetBestExecutionContextScope();
Greg Clayton12bec712010-06-28 21:30:43 +0000246 strm.IndentMore();
247 strm.Indent (" Address: ");
248 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
249 strm.EOL();
Greg Clayton70436352010-06-30 23:03:03 +0000250 strm.Indent (" Summary: ");
Greg Clayton3c126042011-02-08 02:40:32 +0000251 const uint32_t save_indent = strm.GetIndentLevel ();
252 strm.SetIndentLevel (save_indent + 11);
Chris Lattner24943d22010-06-08 16:52:24 +0000253 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
Greg Clayton3c126042011-02-08 02:40:32 +0000254 strm.SetIndentLevel (save_indent);
Greg Clayton70436352010-06-30 23:03:03 +0000255 strm.EOL();
Greg Clayton960d6a42010-08-03 00:35:52 +0000256 // Print out detailed address information when verbose is enabled
257 if (verbose)
258 {
259 if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext))
260 strm.EOL();
261 }
Greg Clayton12bec712010-06-28 21:30:43 +0000262 strm.IndentLess();
Chris Lattner24943d22010-06-08 16:52:24 +0000263 return true;
264 }
265
266 return false;
267}
268
269static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000270LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000271{
272 if (module)
273 {
274 SymbolContext sc;
275
276 ObjectFile *objfile = module->GetObjectFile ();
277 if (objfile)
278 {
279 Symtab *symtab = objfile->GetSymtab();
280 if (symtab)
281 {
282 uint32_t i;
283 std::vector<uint32_t> match_indexes;
284 ConstString symbol_name (name);
285 uint32_t num_matches = 0;
286 if (name_is_regex)
287 {
288 RegularExpression name_regexp(name);
Greg Clayton7c36fa02010-09-11 03:13:28 +0000289 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
290 eSymbolTypeAny,
Chris Lattner24943d22010-06-08 16:52:24 +0000291 match_indexes);
292 }
293 else
294 {
295 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
296 }
297
298
299 if (num_matches > 0)
300 {
301 strm.Indent ();
302 strm.Printf("%u symbols match %s'%s' in ", num_matches,
303 name_is_regex ? "the regular expression " : "", name);
304 DumpFullpath (strm, &module->GetFileSpec(), 0);
305 strm.PutCString(":\n");
306 strm.IndentMore ();
307 Symtab::DumpSymbolHeader (&strm);
308 for (i=0; i < num_matches; ++i)
309 {
310 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
311 strm.Indent ();
Greg Claytoneea26402010-09-14 23:36:40 +0000312 symbol->Dump (&strm, interpreter.GetDebugger().GetExecutionContext().target, i);
Chris Lattner24943d22010-06-08 16:52:24 +0000313 }
314 strm.IndentLess ();
315 return num_matches;
316 }
317 }
318 }
319 }
320 return 0;
321}
322
323
324static void
Greg Clayton63094e02010-06-23 01:19:29 +0000325DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000326{
327 strm.IndentMore ();
328 uint32_t i;
329 const uint32_t num_matches = sc_list.GetSize();
330
331 for (i=0; i<num_matches; ++i)
332 {
333 SymbolContext sc;
334 if (sc_list.GetContextAtIndex(i, sc))
335 {
336 strm.Indent();
337 if (prepend_addr)
338 {
339 if (sc.line_entry.range.GetBaseAddress().IsValid())
340 {
Greg Claytoneea26402010-09-14 23:36:40 +0000341 lldb::addr_t vm_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(interpreter.GetDebugger().GetExecutionContext().target);
Chris Lattner24943d22010-06-08 16:52:24 +0000342 int addr_size = sizeof (addr_t);
Greg Clayton63094e02010-06-23 01:19:29 +0000343 Process *process = interpreter.GetDebugger().GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000344 if (process)
Greg Clayton395fc332011-02-15 21:59:32 +0000345 addr_size = process->GetTarget().GetArchitecture().GetAddressByteSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000346 if (vm_addr != LLDB_INVALID_ADDRESS)
347 strm.Address (vm_addr, addr_size);
348 else
349 sc.line_entry.range.GetBaseAddress().Dump (&strm, NULL, Address::DumpStyleSectionNameOffset);
350
351 strm.PutCString(" in ");
352 }
353 }
Greg Clayton72b71582010-09-02 21:44:10 +0000354 sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress(), true, true, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000355 }
356 }
357 strm.IndentLess ();
358}
359
360static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000361LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000362{
363 if (module && name && name[0])
364 {
365 SymbolContextList sc_list;
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000366 const bool include_symbols = false;
367 const bool append = true;
368 uint32_t num_matches = 0;
369 if (name_is_regex)
Chris Lattner24943d22010-06-08 16:52:24 +0000370 {
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000371 RegularExpression function_name_regex (name);
372 num_matches = module->FindFunctions (function_name_regex,
373 include_symbols,
374 append,
375 sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000376 }
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000377 else
378 {
379 ConstString function_name (name);
380 num_matches = module->FindFunctions (function_name,
381 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
382 include_symbols,
383 append,
384 sc_list);
385 }
386
387 if (num_matches)
388 {
389 strm.Indent ();
390 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
391 DumpFullpath (strm, &module->GetFileSpec(), 0);
392 strm.PutCString(":\n");
393 DumpSymbolContextList (interpreter, strm, sc_list, true);
394 }
395 return num_matches;
Chris Lattner24943d22010-06-08 16:52:24 +0000396 }
397 return 0;
398}
399
400static uint32_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000401LookupTypeInModule
402(
403 CommandInterpreter &interpreter,
404 Stream &strm,
405 Module *module,
406 const char *name_cstr,
407 bool name_is_regex
408)
409{
410 if (module && name_cstr && name_cstr[0])
411 {
412 SymbolContextList sc_list;
413
414 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
415 if (symbol_vendor)
416 {
417 TypeList type_list;
418 uint32_t num_matches = 0;
419 SymbolContext sc;
420// if (name_is_regex)
421// {
422// RegularExpression name_regex (name_cstr);
423// num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list);
424// }
425// else
426// {
427 ConstString name(name_cstr);
428 num_matches = symbol_vendor->FindTypes(sc, name, true, UINT32_MAX, type_list);
429// }
430
431 if (num_matches)
432 {
433 strm.Indent ();
434 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
435 DumpFullpath (strm, &module->GetFileSpec(), 0);
436 strm.PutCString(":\n");
437 const uint32_t num_types = type_list.GetSize();
438 for (uint32_t i=0; i<num_types; ++i)
439 {
440 TypeSP type_sp (type_list.GetTypeAtIndex(i));
441 if (type_sp)
442 {
443 // Resolve the clang type so that any forward references
444 // to types that haven't yet been parsed will get parsed.
Greg Clayton04c9c7b2011-02-16 23:00:21 +0000445 type_sp->GetClangFullType ();
Greg Clayton960d6a42010-08-03 00:35:52 +0000446 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
447 }
448 strm.EOL();
449 }
450 }
451 return num_matches;
452 }
453 }
454 return 0;
455}
456
457static uint32_t
Greg Clayton63094e02010-06-23 01:19:29 +0000458LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines)
Chris Lattner24943d22010-06-08 16:52:24 +0000459{
460 if (module && file_spec)
461 {
462 SymbolContextList sc_list;
463 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
464 eSymbolContextEverything, sc_list);
465 if (num_matches > 0)
466 {
467 strm.Indent ();
468 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
469 strm << file_spec;
470 if (line > 0)
471 strm.Printf (":%u", line);
472 strm << " in ";
473 DumpFullpath (strm, &module->GetFileSpec(), 0);
474 strm.PutCString(":\n");
Greg Clayton63094e02010-06-23 01:19:29 +0000475 DumpSymbolContextList (interpreter, strm, sc_list, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000476 return num_matches;
477 }
478 }
479 return 0;
480
481}
482
483
484//----------------------------------------------------------------------
485// Image symbol table dumping command
486//----------------------------------------------------------------------
487
488class CommandObjectImageDumpModuleList : public CommandObject
489{
490public:
491
Greg Clayton238c0a12010-09-18 01:14:36 +0000492 CommandObjectImageDumpModuleList (CommandInterpreter &interpreter,
493 const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000494 const char *help,
495 const char *syntax) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000496 CommandObject (interpreter, name, help, syntax)
Chris Lattner24943d22010-06-08 16:52:24 +0000497 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000498 CommandArgumentEntry arg;
499 CommandArgumentData file_arg;
500
501 // Define the first (and only) variant of this arg.
502 file_arg.arg_type = eArgTypeFilename;
503 file_arg.arg_repetition = eArgRepeatStar;
504
505 // There is only one variant this argument could be; put it into the argument entry.
506 arg.push_back (file_arg);
507
508 // Push the data for the first argument into the m_arguments vector.
509 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000510 }
511
512 virtual
513 ~CommandObjectImageDumpModuleList ()
514 {
515 }
516
517 virtual int
Greg Clayton238c0a12010-09-18 01:14:36 +0000518 HandleArgumentCompletion (Args &input,
Greg Clayton63094e02010-06-23 01:19:29 +0000519 int &cursor_index,
520 int &cursor_char_position,
521 OptionElementVector &opt_element_vector,
522 int match_start_point,
523 int max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000524 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000525 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000526 {
527 // Arguments are the standard module completer.
528 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
529 completion_str.erase (cursor_char_position);
530
Greg Clayton238c0a12010-09-18 01:14:36 +0000531 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +0000532 CommandCompletions::eModuleCompletion,
533 completion_str.c_str(),
534 match_start_point,
535 max_return_elements,
536 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000537 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000538 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000539 return matches.GetSize();
540 }
541};
542
543class CommandObjectImageDumpSourceFileList : public CommandObject
544{
545public:
546
Greg Clayton238c0a12010-09-18 01:14:36 +0000547 CommandObjectImageDumpSourceFileList (CommandInterpreter &interpreter,
548 const char *name,
Greg Clayton63094e02010-06-23 01:19:29 +0000549 const char *help,
550 const char *syntax) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000551 CommandObject (interpreter, name, help, syntax)
Chris Lattner24943d22010-06-08 16:52:24 +0000552 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000553 CommandArgumentEntry arg;
554 CommandArgumentData source_file_arg;
555
556 // Define the first (and only) variant of this arg.
557 source_file_arg.arg_type = eArgTypeSourceFile;
558 source_file_arg.arg_repetition = eArgRepeatPlus;
559
560 // There is only one variant this argument could be; put it into the argument entry.
561 arg.push_back (source_file_arg);
562
563 // Push the data for the first argument into the m_arguments vector.
564 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000565 }
566
567 virtual
568 ~CommandObjectImageDumpSourceFileList ()
569 {
570 }
571
572 virtual int
Greg Clayton238c0a12010-09-18 01:14:36 +0000573 HandleArgumentCompletion (Args &input,
Greg Clayton63094e02010-06-23 01:19:29 +0000574 int &cursor_index,
575 int &cursor_char_position,
576 OptionElementVector &opt_element_vector,
577 int match_start_point,
578 int max_return_elements,
Greg Clayton54e7afa2010-07-09 20:39:50 +0000579 bool &word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000580 StringList &matches)
Chris Lattner24943d22010-06-08 16:52:24 +0000581 {
582 // Arguments are the standard source file completer.
583 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
584 completion_str.erase (cursor_char_position);
585
Greg Clayton238c0a12010-09-18 01:14:36 +0000586 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
Greg Clayton63094e02010-06-23 01:19:29 +0000587 CommandCompletions::eSourceFileCompletion,
588 completion_str.c_str(),
589 match_start_point,
590 max_return_elements,
591 NULL,
Jim Ingham802f8b02010-06-30 05:02:46 +0000592 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000593 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000594 return matches.GetSize();
595 }
596};
597
598
599class CommandObjectImageDumpSymtab : public CommandObjectImageDumpModuleList
600{
601public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000602 CommandObjectImageDumpSymtab (CommandInterpreter &interpreter) :
603 CommandObjectImageDumpModuleList (interpreter,
604 "image dump symtab",
605 "Dump the symbol table from one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000606 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000607 {
608 }
609
610 virtual
611 ~CommandObjectImageDumpSymtab ()
612 {
613 }
614
615 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000616 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000617 CommandReturnObject &result)
618 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000619 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000620 if (target == NULL)
621 {
622 result.AppendError ("invalid target, set executable file using 'file' command");
623 result.SetStatus (eReturnStatusFailed);
624 return false;
625 }
626 else
627 {
628 uint32_t num_dumped = 0;
629
630 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
631 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
632 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
633
634 if (command.GetArgumentCount() == 0)
635 {
636 // Dump all sections for all modules images
637 const uint32_t num_modules = target->GetImages().GetSize();
638 if (num_modules > 0)
639 {
640 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
641 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
642 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000643 if (num_dumped > 0)
644 {
645 result.GetOutputStream().EOL();
646 result.GetOutputStream().EOL();
647 }
Chris Lattner24943d22010-06-08 16:52:24 +0000648 num_dumped++;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000649 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
Chris Lattner24943d22010-06-08 16:52:24 +0000650 }
651 }
652 else
653 {
654 result.AppendError ("the target has no associated executable images");
655 result.SetStatus (eReturnStatusFailed);
656 return false;
657 }
658 }
659 else
660 {
661 // Dump specified images (by basename or fullpath)
662 const char *arg_cstr;
663 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
664 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000665 FileSpec image_file(arg_cstr, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000666 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000667 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000668
Greg Clayton661825b2010-06-28 23:51:11 +0000669 // Not found in our module list for our target, check the main
670 // shared module list in case it is a extra file used somewhere
671 // else
672 if (num_matching_modules == 0)
673 num_matching_modules = ModuleList::FindSharedModules (image_file,
674 target->GetArchitecture(),
675 NULL,
676 NULL,
677 matching_modules);
678
Chris Lattner24943d22010-06-08 16:52:24 +0000679 if (num_matching_modules > 0)
680 {
681 for (size_t i=0; i<num_matching_modules; ++i)
682 {
683 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
684 if (image_module)
685 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000686 if (num_dumped > 0)
687 {
688 result.GetOutputStream().EOL();
689 result.GetOutputStream().EOL();
690 }
Chris Lattner24943d22010-06-08 16:52:24 +0000691 num_dumped++;
Greg Clayton8d3802d2010-10-08 04:20:14 +0000692 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order);
Chris Lattner24943d22010-06-08 16:52:24 +0000693 }
694 }
695 }
696 else
697 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
698 }
699 }
700
701 if (num_dumped > 0)
702 result.SetStatus (eReturnStatusSuccessFinishResult);
703 else
704 {
705 result.AppendError ("no matching executable images found");
706 result.SetStatus (eReturnStatusFailed);
707 }
708 }
709 return result.Succeeded();
710 }
Greg Clayton8d3802d2010-10-08 04:20:14 +0000711
712 virtual Options *
713 GetOptions ()
714 {
715 return &m_options;
716 }
717
718 class CommandOptions : public Options
719 {
720 public:
Chris Lattner24943d22010-06-08 16:52:24 +0000721
Greg Clayton8d3802d2010-10-08 04:20:14 +0000722 CommandOptions () :
723 Options(),
724 m_sort_order (eSortOrderNone)
725 {
726 }
727
728 virtual
729 ~CommandOptions ()
730 {
731 }
732
733 virtual Error
734 SetOptionValue (int option_idx, const char *option_arg)
735 {
736 Error error;
737 char short_option = (char) m_getopt_table[option_idx].val;
738
739 switch (short_option)
740 {
741 case 's':
742 {
743 bool found_one = false;
Greg Claytonb3448432011-03-24 21:19:54 +0000744 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
Greg Clayton8d3802d2010-10-08 04:20:14 +0000745 g_option_table[option_idx].enum_values,
746 eSortOrderNone,
747 &found_one);
748 if (!found_one)
749 error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n",
750 option_arg,
751 short_option);
752 }
753 break;
754
755 default:
756 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
757 break;
758
759 }
760 return error;
761 }
762
763 void
764 ResetOptionValues ()
765 {
Greg Clayton8d3802d2010-10-08 04:20:14 +0000766 m_sort_order = eSortOrderNone;
767 }
768
Greg Claytonb3448432011-03-24 21:19:54 +0000769 const OptionDefinition*
Greg Clayton8d3802d2010-10-08 04:20:14 +0000770 GetDefinitions ()
771 {
772 return g_option_table;
773 }
774
775 // Options table: Required for subclasses of Options.
Greg Claytonb3448432011-03-24 21:19:54 +0000776 static OptionDefinition g_option_table[];
Greg Clayton8d3802d2010-10-08 04:20:14 +0000777
778 SortOrder m_sort_order;
779 };
780
781protected:
782
783 CommandOptions m_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000784};
785
Greg Claytonb3448432011-03-24 21:19:54 +0000786static OptionEnumValueElement
Greg Clayton8d3802d2010-10-08 04:20:14 +0000787g_sort_option_enumeration[4] =
788{
789 { eSortOrderNone, "none", "No sorting, use the original symbol table order."},
790 { eSortOrderByAddress, "address", "Sort output by symbol address."},
791 { eSortOrderByName, "name", "Sort output by symbol name."},
792 { 0, NULL, NULL }
793};
794
795
Greg Claytonb3448432011-03-24 21:19:54 +0000796OptionDefinition
Greg Clayton8d3802d2010-10-08 04:20:14 +0000797CommandObjectImageDumpSymtab::CommandOptions::g_option_table[] =
798{
799{ LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
800{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
801};
802
803
Chris Lattner24943d22010-06-08 16:52:24 +0000804//----------------------------------------------------------------------
805// Image section dumping command
806//----------------------------------------------------------------------
807class CommandObjectImageDumpSections : public CommandObjectImageDumpModuleList
808{
809public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000810 CommandObjectImageDumpSections (CommandInterpreter &interpreter) :
811 CommandObjectImageDumpModuleList (interpreter,
812 "image dump sections",
Greg Clayton63094e02010-06-23 01:19:29 +0000813 "Dump the sections from one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000814 //"image dump sections [<file1> ...]")
815 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000816 {
817 }
818
819 virtual
820 ~CommandObjectImageDumpSections ()
821 {
822 }
823
824 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000825 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000826 CommandReturnObject &result)
827 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000828 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000829 if (target == NULL)
830 {
831 result.AppendError ("invalid target, set executable file using 'file' command");
832 result.SetStatus (eReturnStatusFailed);
833 return false;
834 }
835 else
836 {
837 uint32_t num_dumped = 0;
838
839 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
840 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
841 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
842
843 if (command.GetArgumentCount() == 0)
844 {
845 // Dump all sections for all modules images
846 const uint32_t num_modules = target->GetImages().GetSize();
847 if (num_modules > 0)
848 {
849 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
850 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
851 {
852 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000853 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000854 }
855 }
856 else
857 {
858 result.AppendError ("the target has no associated executable images");
859 result.SetStatus (eReturnStatusFailed);
860 return false;
861 }
862 }
863 else
864 {
865 // Dump specified images (by basename or fullpath)
866 const char *arg_cstr;
867 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
868 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000869 FileSpec image_file(arg_cstr, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000870 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000871 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000872
Greg Clayton661825b2010-06-28 23:51:11 +0000873 // Not found in our module list for our target, check the main
874 // shared module list in case it is a extra file used somewhere
875 // else
876 if (num_matching_modules == 0)
877 num_matching_modules = ModuleList::FindSharedModules (image_file,
878 target->GetArchitecture(),
879 NULL,
880 NULL,
881 matching_modules);
882
Chris Lattner24943d22010-06-08 16:52:24 +0000883 if (num_matching_modules > 0)
884 {
885 for (size_t i=0; i<num_matching_modules; ++i)
886 {
887 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
888 if (image_module)
889 {
890 num_dumped++;
Greg Clayton238c0a12010-09-18 01:14:36 +0000891 DumpModuleSections (m_interpreter, result.GetOutputStream(), image_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000892 }
893 }
894 }
895 else
896 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
897 }
898 }
899
900 if (num_dumped > 0)
901 result.SetStatus (eReturnStatusSuccessFinishResult);
902 else
903 {
904 result.AppendError ("no matching executable images found");
905 result.SetStatus (eReturnStatusFailed);
906 }
907 }
908 return result.Succeeded();
909 }
910};
911
912//----------------------------------------------------------------------
913// Image debug symbol dumping command
914//----------------------------------------------------------------------
915class CommandObjectImageDumpSymfile : public CommandObjectImageDumpModuleList
916{
917public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000918 CommandObjectImageDumpSymfile (CommandInterpreter &interpreter) :
919 CommandObjectImageDumpModuleList (interpreter,
920 "image dump symfile",
921 "Dump the debug symbol file for one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000922 //"image dump symfile [<file1> ...]")
923 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000924 {
925 }
926
927 virtual
928 ~CommandObjectImageDumpSymfile ()
929 {
930 }
931
932 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000933 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000934 CommandReturnObject &result)
935 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000936 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000937 if (target == NULL)
938 {
939 result.AppendError ("invalid target, set executable file using 'file' command");
940 result.SetStatus (eReturnStatusFailed);
941 return false;
942 }
943 else
944 {
945 uint32_t num_dumped = 0;
946
947 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
948 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
949 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
950
951 if (command.GetArgumentCount() == 0)
952 {
953 // Dump all sections for all modules images
954 const uint32_t num_modules = target->GetImages().GetSize();
955 if (num_modules > 0)
956 {
957 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
958 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
959 {
960 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
961 num_dumped++;
962 }
963 }
964 else
965 {
966 result.AppendError ("the target has no associated executable images");
967 result.SetStatus (eReturnStatusFailed);
968 return false;
969 }
970 }
971 else
972 {
973 // Dump specified images (by basename or fullpath)
974 const char *arg_cstr;
975 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
976 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000977 FileSpec image_file(arg_cstr, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000978 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +0000979 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +0000980
Greg Clayton661825b2010-06-28 23:51:11 +0000981 // Not found in our module list for our target, check the main
982 // shared module list in case it is a extra file used somewhere
983 // else
984 if (num_matching_modules == 0)
985 num_matching_modules = ModuleList::FindSharedModules (image_file,
986 target->GetArchitecture(),
987 NULL,
988 NULL,
989 matching_modules);
990
Chris Lattner24943d22010-06-08 16:52:24 +0000991 if (num_matching_modules > 0)
992 {
993 for (size_t i=0; i<num_matching_modules; ++i)
994 {
995 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
996 if (image_module)
997 {
998 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
999 num_dumped++;
1000 }
1001 }
1002 }
1003 else
1004 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1005 }
1006 }
1007
1008 if (num_dumped > 0)
1009 result.SetStatus (eReturnStatusSuccessFinishResult);
1010 else
1011 {
1012 result.AppendError ("no matching executable images found");
1013 result.SetStatus (eReturnStatusFailed);
1014 }
1015 }
1016 return result.Succeeded();
1017 }
1018};
1019
1020//----------------------------------------------------------------------
1021// Image debug symbol dumping command
1022//----------------------------------------------------------------------
1023class CommandObjectImageDumpLineTable : public CommandObjectImageDumpSourceFileList
1024{
1025public:
Greg Clayton238c0a12010-09-18 01:14:36 +00001026 CommandObjectImageDumpLineTable (CommandInterpreter &interpreter) :
1027 CommandObjectImageDumpSourceFileList (interpreter,
1028 "image dump line-table",
1029 "Dump the debug symbol file for one or more executable images.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001030 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001031 {
1032 }
1033
1034 virtual
1035 ~CommandObjectImageDumpLineTable ()
1036 {
1037 }
1038
1039 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001040 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001041 CommandReturnObject &result)
1042 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001043 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001044 if (target == NULL)
1045 {
1046 result.AppendError ("invalid target, set executable file using 'file' command");
1047 result.SetStatus (eReturnStatusFailed);
1048 return false;
1049 }
1050 else
1051 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001052 ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +00001053 uint32_t total_num_dumped = 0;
1054
1055 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1056 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1057 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1058
1059 if (command.GetArgumentCount() == 0)
1060 {
1061 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
1062 result.SetStatus (eReturnStatusFailed);
1063 }
1064 else
1065 {
1066 // Dump specified images (by basename or fullpath)
1067 const char *arg_cstr;
1068 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1069 {
Greg Clayton537a7a82010-10-20 20:54:39 +00001070 FileSpec file_spec(arg_cstr, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001071 const uint32_t num_modules = target->GetImages().GetSize();
1072 if (num_modules > 0)
1073 {
1074 uint32_t num_dumped = 0;
1075 for (uint32_t i = 0; i<num_modules; ++i)
1076 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001077 if (DumpCompileUnitLineTable (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001078 result.GetOutputStream(),
1079 target->GetImages().GetModulePointerAtIndex(i),
1080 file_spec,
1081 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
1082 num_dumped++;
1083 }
1084 if (num_dumped == 0)
1085 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
1086 else
1087 total_num_dumped += num_dumped;
1088 }
1089 }
1090 }
1091
1092 if (total_num_dumped > 0)
1093 result.SetStatus (eReturnStatusSuccessFinishResult);
1094 else
1095 {
1096 result.AppendError ("no source filenames matched any command arguments");
1097 result.SetStatus (eReturnStatusFailed);
1098 }
1099 }
1100 return result.Succeeded();
1101 }
1102};
1103
1104//----------------------------------------------------------------------
1105// Dump multi-word command
1106//----------------------------------------------------------------------
1107class CommandObjectImageDump : public CommandObjectMultiword
1108{
1109public:
1110
1111 //------------------------------------------------------------------
1112 // Constructors and Destructors
1113 //------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001114 CommandObjectImageDump(CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001115 CommandObjectMultiword (interpreter,
1116 "image dump",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001117 "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 +00001118 "image dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
Chris Lattner24943d22010-06-08 16:52:24 +00001119 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001120 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectImageDumpSymtab (interpreter)));
1121 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectImageDumpSections (interpreter)));
1122 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectImageDumpSymfile (interpreter)));
1123 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectImageDumpLineTable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001124 }
1125
1126 virtual
1127 ~CommandObjectImageDump()
1128 {
1129 }
1130};
1131
1132//----------------------------------------------------------------------
1133// List images with associated information
1134//----------------------------------------------------------------------
1135class CommandObjectImageList : public CommandObject
1136{
1137public:
1138
1139 class CommandOptions : public Options
1140 {
1141 public:
1142
1143 CommandOptions () :
1144 Options(),
1145 m_format_array()
1146 {
1147 }
1148
1149 virtual
1150 ~CommandOptions ()
1151 {
1152 }
1153
1154 virtual Error
1155 SetOptionValue (int option_idx, const char *option_arg)
1156 {
1157 char short_option = (char) m_getopt_table[option_idx].val;
1158 uint32_t width = 0;
1159 if (option_arg)
1160 width = strtoul (option_arg, NULL, 0);
1161 m_format_array.push_back(std::make_pair(short_option, width));
1162 Error error;
1163 return error;
1164 }
1165
1166 void
1167 ResetOptionValues ()
1168 {
Chris Lattner24943d22010-06-08 16:52:24 +00001169 m_format_array.clear();
1170 }
1171
Greg Claytonb3448432011-03-24 21:19:54 +00001172 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +00001173 GetDefinitions ()
1174 {
1175 return g_option_table;
1176 }
1177
1178 // Options table: Required for subclasses of Options.
1179
Greg Claytonb3448432011-03-24 21:19:54 +00001180 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +00001181
1182 // Instance variables to hold the values for command options.
1183 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
1184 FormatWidthCollection m_format_array;
1185 };
1186
Greg Clayton238c0a12010-09-18 01:14:36 +00001187 CommandObjectImageList (CommandInterpreter &interpreter) :
1188 CommandObject (interpreter,
1189 "image list",
1190 "List current executable and dependent shared library images.",
1191 "image list [<cmd-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00001192 {
1193 }
1194
1195 virtual
1196 ~CommandObjectImageList ()
1197 {
1198 }
1199
1200 virtual
1201 Options *
1202 GetOptions ()
1203 {
1204 return &m_options;
1205 }
1206
1207 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001208 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001209 CommandReturnObject &result)
1210 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001211 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001212 if (target == NULL)
1213 {
1214 result.AppendError ("invalid target, set executable file using 'file' command");
1215 result.SetStatus (eReturnStatusFailed);
1216 return false;
1217 }
1218 else
1219 {
1220 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1221 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1222 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1223 // Dump all sections for all modules images
1224 const uint32_t num_modules = target->GetImages().GetSize();
1225 if (num_modules > 0)
1226 {
1227 Stream &strm = result.GetOutputStream();
1228
1229 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1230 {
1231 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
1232 strm.Printf("[%3u] ", image_idx);
1233
1234 if (m_options.m_format_array.empty())
1235 {
1236 DumpFullpath(strm, &module->GetFileSpec(), 0);
1237 }
1238 else
1239 {
1240 const size_t num_entries = m_options.m_format_array.size();
1241 for (size_t i=0; i<num_entries; ++i)
1242 {
1243 if (i > 0)
1244 strm.PutChar(' ');
1245 char format_char = m_options.m_format_array[i].first;
1246 uint32_t width = m_options.m_format_array[i].second;
1247 switch (format_char)
1248 {
1249 case 'a':
1250 DumpModuleArchitecture (strm, module, width);
1251 break;
1252
1253 case 'f':
1254 DumpFullpath (strm, &module->GetFileSpec(), width);
1255 break;
1256
1257 case 'd':
1258 DumpDirectory (strm, &module->GetFileSpec(), width);
1259 break;
1260
1261 case 'b':
1262 DumpBasename (strm, &module->GetFileSpec(), width);
1263 break;
1264
1265 case 's':
1266 case 'S':
1267 {
1268 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1269 if (symbol_vendor)
1270 {
1271 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
1272 if (symbol_file)
1273 {
1274 if (format_char == 'S')
1275 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1276 else
1277 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
1278 break;
1279 }
1280 }
1281 strm.Printf("%.*s", width, "<NONE>");
1282 }
1283 break;
1284
1285 case 'u':
1286 DumpModuleUUID(strm, module);
1287 break;
1288
1289 default:
1290 break;
1291 }
1292 }
1293 }
1294 strm.EOL();
1295 }
1296 result.SetStatus (eReturnStatusSuccessFinishResult);
1297 }
1298 else
1299 {
1300 result.AppendError ("the target has no associated executable images");
1301 result.SetStatus (eReturnStatusFailed);
1302 return false;
1303 }
1304 }
1305 return result.Succeeded();
1306 }
1307protected:
1308
1309 CommandOptions m_options;
1310};
1311
Greg Claytonb3448432011-03-24 21:19:54 +00001312OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001313CommandObjectImageList::CommandOptions::g_option_table[] =
1314{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001315{ LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
Greg Clayton0467c782011-02-04 18:53:10 +00001316{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
Caroline Tice4d6675c2010-10-01 19:59:14 +00001317{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
1318{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
1319{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
1320{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
1321{ LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."},
1322{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001323};
1324
1325
1326
1327//----------------------------------------------------------------------
1328// Lookup information in images
1329//----------------------------------------------------------------------
1330class CommandObjectImageLookup : public CommandObject
1331{
1332public:
1333
1334 enum
1335 {
1336 eLookupTypeInvalid = -1,
1337 eLookupTypeAddress = 0,
1338 eLookupTypeSymbol,
1339 eLookupTypeFileLine, // Line is optional
1340 eLookupTypeFunction,
Greg Clayton960d6a42010-08-03 00:35:52 +00001341 eLookupTypeType,
Chris Lattner24943d22010-06-08 16:52:24 +00001342 kNumLookupTypes
1343 };
1344
1345 class CommandOptions : public Options
1346 {
1347 public:
1348
1349 CommandOptions () :
1350 Options()
1351 {
1352 ResetOptionValues();
1353 }
1354
1355 virtual
1356 ~CommandOptions ()
1357 {
1358 }
1359
1360 virtual Error
1361 SetOptionValue (int option_idx, const char *option_arg)
1362 {
1363 Error error;
1364
1365 char short_option = (char) m_getopt_table[option_idx].val;
1366
1367 switch (short_option)
1368 {
1369 case 'a':
1370 m_type = eLookupTypeAddress;
1371 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1372 if (m_addr == LLDB_INVALID_ADDRESS)
1373 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
1374 break;
1375
1376 case 'o':
1377 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
1378 if (m_offset == LLDB_INVALID_ADDRESS)
1379 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
1380 break;
1381
1382 case 's':
1383 m_str = option_arg;
1384 m_type = eLookupTypeSymbol;
1385 break;
1386
1387 case 'f':
Greg Clayton537a7a82010-10-20 20:54:39 +00001388 m_file.SetFile (option_arg, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001389 m_type = eLookupTypeFileLine;
1390 break;
1391
1392 case 'i':
1393 m_check_inlines = false;
1394 break;
1395
1396 case 'l':
1397 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
1398 if (m_line_number == UINT32_MAX)
1399 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
1400 else if (m_line_number == 0)
1401 error.SetErrorString ("Zero is an invalid line number.");
1402 m_type = eLookupTypeFileLine;
1403 break;
1404
1405 case 'n':
1406 m_str = option_arg;
1407 m_type = eLookupTypeFunction;
1408 break;
1409
Greg Clayton960d6a42010-08-03 00:35:52 +00001410 case 't':
1411 m_str = option_arg;
1412 m_type = eLookupTypeType;
1413 break;
1414
1415 case 'v':
1416 m_verbose = 1;
1417 break;
1418
Chris Lattner24943d22010-06-08 16:52:24 +00001419 case 'r':
1420 m_use_regex = true;
1421 break;
1422 }
1423
1424 return error;
1425 }
1426
1427 void
1428 ResetOptionValues ()
1429 {
Chris Lattner24943d22010-06-08 16:52:24 +00001430 m_type = eLookupTypeInvalid;
1431 m_str.clear();
1432 m_file.Clear();
1433 m_addr = LLDB_INVALID_ADDRESS;
1434 m_offset = 0;
1435 m_line_number = 0;
1436 m_use_regex = false;
1437 m_check_inlines = true;
Greg Clayton960d6a42010-08-03 00:35:52 +00001438 m_verbose = false;
Chris Lattner24943d22010-06-08 16:52:24 +00001439 }
1440
Greg Claytonb3448432011-03-24 21:19:54 +00001441 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +00001442 GetDefinitions ()
1443 {
1444 return g_option_table;
1445 }
1446
1447 // Options table: Required for subclasses of Options.
1448
Greg Claytonb3448432011-03-24 21:19:54 +00001449 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +00001450 int m_type; // Should be a eLookupTypeXXX enum after parsing options
1451 std::string m_str; // Holds name lookup
1452 FileSpec m_file; // Files for file lookups
1453 lldb::addr_t m_addr; // Holds the address to lookup
1454 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
1455 uint32_t m_line_number; // Line number for file+line lookups
1456 bool m_use_regex; // Name lookups in m_str are regular expressions.
1457 bool m_check_inlines;// Check for inline entries when looking up by file/line.
Greg Clayton960d6a42010-08-03 00:35:52 +00001458 bool m_verbose; // Enable verbose lookup info
1459
Chris Lattner24943d22010-06-08 16:52:24 +00001460 };
1461
Greg Clayton238c0a12010-09-18 01:14:36 +00001462 CommandObjectImageLookup (CommandInterpreter &interpreter) :
1463 CommandObject (interpreter,
1464 "image lookup",
1465 "Look up information within executable and dependent shared library images.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001466 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001467 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001468 CommandArgumentEntry arg;
1469 CommandArgumentData file_arg;
1470
1471 // Define the first (and only) variant of this arg.
1472 file_arg.arg_type = eArgTypeFilename;
1473 file_arg.arg_repetition = eArgRepeatStar;
1474
1475 // There is only one variant this argument could be; put it into the argument entry.
1476 arg.push_back (file_arg);
1477
1478 // Push the data for the first argument into the m_arguments vector.
1479 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001480 }
1481
1482 virtual
1483 ~CommandObjectImageLookup ()
1484 {
1485 }
1486
Greg Clayton8d3802d2010-10-08 04:20:14 +00001487 virtual Options *
Chris Lattner24943d22010-06-08 16:52:24 +00001488 GetOptions ()
1489 {
1490 return &m_options;
1491 }
1492
1493
1494 bool
Greg Clayton63094e02010-06-23 01:19:29 +00001495 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
Chris Lattner24943d22010-06-08 16:52:24 +00001496 {
1497 switch (m_options.m_type)
1498 {
1499 case eLookupTypeAddress:
1500 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
1501 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001502 if (LookupAddressInModule (m_interpreter,
Greg Clayton960d6a42010-08-03 00:35:52 +00001503 result.GetOutputStream(),
1504 module,
1505 eSymbolContextEverything,
1506 m_options.m_addr,
1507 m_options.m_offset,
1508 m_options.m_verbose))
Chris Lattner24943d22010-06-08 16:52:24 +00001509 {
1510 result.SetStatus(eReturnStatusSuccessFinishResult);
1511 return true;
1512 }
1513 }
1514 break;
1515
1516 case eLookupTypeSymbol:
1517 if (!m_options.m_str.empty())
1518 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001519 if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
Chris Lattner24943d22010-06-08 16:52:24 +00001520 {
1521 result.SetStatus(eReturnStatusSuccessFinishResult);
1522 return true;
1523 }
1524 }
1525 break;
1526
1527 case eLookupTypeFileLine:
1528 if (m_options.m_file)
1529 {
1530
Greg Clayton238c0a12010-09-18 01:14:36 +00001531 if (LookupFileAndLineInModule (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001532 result.GetOutputStream(),
1533 module,
1534 m_options.m_file,
1535 m_options.m_line_number,
1536 m_options.m_check_inlines))
1537 {
1538 result.SetStatus(eReturnStatusSuccessFinishResult);
1539 return true;
1540 }
1541 }
1542 break;
1543
1544 case eLookupTypeFunction:
1545 if (!m_options.m_str.empty())
1546 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001547 if (LookupFunctionInModule (m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +00001548 result.GetOutputStream(),
1549 module,
1550 m_options.m_str.c_str(),
1551 m_options.m_use_regex))
1552 {
1553 result.SetStatus(eReturnStatusSuccessFinishResult);
1554 return true;
1555 }
1556 }
1557 break;
1558
Greg Clayton960d6a42010-08-03 00:35:52 +00001559 case eLookupTypeType:
1560 if (!m_options.m_str.empty())
1561 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001562 if (LookupTypeInModule (m_interpreter,
Greg Clayton960d6a42010-08-03 00:35:52 +00001563 result.GetOutputStream(),
1564 module,
1565 m_options.m_str.c_str(),
1566 m_options.m_use_regex))
1567 {
1568 result.SetStatus(eReturnStatusSuccessFinishResult);
1569 return true;
1570 }
1571 }
1572 break;
1573
Chris Lattner24943d22010-06-08 16:52:24 +00001574 default:
Greg Clayton238c0a12010-09-18 01:14:36 +00001575 m_options.GenerateOptionUsage (m_interpreter, result.GetErrorStream(), this);
Chris Lattner24943d22010-06-08 16:52:24 +00001576 syntax_error = true;
1577 break;
1578 }
1579
1580 result.SetStatus (eReturnStatusFailed);
1581 return false;
1582 }
1583
1584 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001585 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001586 CommandReturnObject &result)
1587 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001588 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001589 if (target == NULL)
1590 {
1591 result.AppendError ("invalid target, set executable file using 'file' command");
1592 result.SetStatus (eReturnStatusFailed);
1593 return false;
1594 }
1595 else
1596 {
1597 bool syntax_error = false;
1598 uint32_t i;
1599 uint32_t num_successful_lookups = 0;
1600 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1601 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1602 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1603 // Dump all sections for all modules images
1604
1605 if (command.GetArgumentCount() == 0)
1606 {
1607 // Dump all sections for all modules images
1608 const uint32_t num_modules = target->GetImages().GetSize();
1609 if (num_modules > 0)
1610 {
1611 for (i = 0; i<num_modules && syntax_error == false; ++i)
1612 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001613 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001614 {
1615 result.GetOutputStream().EOL();
1616 num_successful_lookups++;
1617 }
1618 }
1619 }
1620 else
1621 {
1622 result.AppendError ("the target has no associated executable images");
1623 result.SetStatus (eReturnStatusFailed);
1624 return false;
1625 }
1626 }
1627 else
1628 {
1629 // Dump specified images (by basename or fullpath)
1630 const char *arg_cstr;
1631 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
1632 {
Greg Clayton537a7a82010-10-20 20:54:39 +00001633 FileSpec image_file(arg_cstr, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001634 ModuleList matching_modules;
Greg Clayton661825b2010-06-28 23:51:11 +00001635 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
Chris Lattner24943d22010-06-08 16:52:24 +00001636
Greg Clayton661825b2010-06-28 23:51:11 +00001637 // Not found in our module list for our target, check the main
1638 // shared module list in case it is a extra file used somewhere
1639 // else
1640 if (num_matching_modules == 0)
1641 num_matching_modules = ModuleList::FindSharedModules (image_file,
1642 target->GetArchitecture(),
1643 NULL,
1644 NULL,
1645 matching_modules);
1646
Chris Lattner24943d22010-06-08 16:52:24 +00001647 if (num_matching_modules > 0)
1648 {
Greg Claytonbef15832010-07-14 00:18:15 +00001649 for (size_t j=0; j<num_matching_modules; ++j)
Chris Lattner24943d22010-06-08 16:52:24 +00001650 {
Greg Claytonbef15832010-07-14 00:18:15 +00001651 Module * image_module = matching_modules.GetModulePointerAtIndex(j);
Chris Lattner24943d22010-06-08 16:52:24 +00001652 if (image_module)
1653 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001654 if (LookupInModule (m_interpreter, image_module, result, syntax_error))
Chris Lattner24943d22010-06-08 16:52:24 +00001655 {
1656 result.GetOutputStream().EOL();
1657 num_successful_lookups++;
1658 }
1659 }
1660 }
1661 }
1662 else
1663 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1664 }
1665 }
1666
1667 if (num_successful_lookups > 0)
1668 result.SetStatus (eReturnStatusSuccessFinishResult);
1669 else
1670 result.SetStatus (eReturnStatusFailed);
1671 }
1672 return result.Succeeded();
1673 }
1674protected:
1675
1676 CommandOptions m_options;
1677};
1678
Greg Claytonb3448432011-03-24 21:19:54 +00001679OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +00001680CommandObjectImageLookup::CommandOptions::g_option_table[] =
1681{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001682{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more executable images."},
1683{ LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup."},
1684{ LLDB_OPT_SET_2, true, "symbol", 's', required_argument, NULL, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more executable images."},
1685{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
1686{ LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more executable images."},
1687{ LLDB_OPT_SET_3, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."},
1688{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."},
1689{ LLDB_OPT_SET_4, true, "function", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more executable images."},
1690{ LLDB_OPT_SET_5, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more executable images."},
1691{ LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
1692{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +00001693};
1694
1695
1696
1697
1698
1699//----------------------------------------------------------------------
1700// CommandObjectImage constructor
1701//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +00001702CommandObjectImage::CommandObjectImage(CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001703 CommandObjectMultiword (interpreter,
1704 "image",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001705 "A set of commands for accessing information for one or more executable images.",
1706 "image <sub-command> ...")
Chris Lattner24943d22010-06-08 16:52:24 +00001707{
Greg Clayton238c0a12010-09-18 01:14:36 +00001708 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectImageDump (interpreter)));
1709 LoadSubCommand ("list", CommandObjectSP (new CommandObjectImageList (interpreter)));
1710 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectImageLookup (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001711}
1712
1713//----------------------------------------------------------------------
1714// Destructor
1715//----------------------------------------------------------------------
1716CommandObjectImage::~CommandObjectImage()
1717{
1718}
1719