blob: 226c00ff9d5173a299f9c194826eadd148935b99 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectTarget.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 "CommandObjectTarget.h"
11
12// C Includes
13#include <errno.h>
Greg Clayton81040f42011-02-01 01:13:32 +000014
Chris Lattner24943d22010-06-08 16:52:24 +000015// C++ Includes
16// Other libraries and framework includes
17// Project includes
Jim Ingham84cdc152010-06-15 19:49:27 +000018#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Core/Debugger.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000020#include "lldb/Core/InputReader.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000021#include "lldb/Core/Module.h"
22#include "lldb/Core/ModuleSpec.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000023#include "lldb/Core/Section.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000024#include "lldb/Core/State.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Core/Timer.h"
Greg Clayton801417e2011-07-07 01:59:51 +000026#include "lldb/Core/ValueObjectVariable.h"
Greg Claytonb924eb62012-09-27 03:13:55 +000027#include "lldb/Host/Symbols.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028#include "lldb/Interpreter/CommandInterpreter.h"
29#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000030#include "lldb/Interpreter/Options.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000031#include "lldb/Interpreter/OptionGroupArchitecture.h"
Greg Clayton5beb99d2011-08-11 02:48:45 +000032#include "lldb/Interpreter/OptionGroupBoolean.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000033#include "lldb/Interpreter/OptionGroupFile.h"
Greg Claytona42880a2011-10-25 06:44:01 +000034#include "lldb/Interpreter/OptionGroupFormat.h"
Greg Clayton368f8222011-07-07 04:38:25 +000035#include "lldb/Interpreter/OptionGroupVariable.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000036#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000037#include "lldb/Interpreter/OptionGroupUInt64.h"
38#include "lldb/Interpreter/OptionGroupUUID.h"
Greg Clayton801417e2011-07-07 01:59:51 +000039#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000040#include "lldb/Symbol/CompileUnit.h"
Jason Molenda5b0afcc2012-07-12 00:20:07 +000041#include "lldb/Symbol/FuncUnwinders.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000042#include "lldb/Symbol/LineTable.h"
43#include "lldb/Symbol/ObjectFile.h"
44#include "lldb/Symbol/SymbolFile.h"
45#include "lldb/Symbol/SymbolVendor.h"
Jason Molenda5b0afcc2012-07-12 00:20:07 +000046#include "lldb/Symbol/UnwindPlan.h"
Greg Clayton801417e2011-07-07 01:59:51 +000047#include "lldb/Symbol/VariableList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000048#include "lldb/Target/Process.h"
49#include "lldb/Target/StackFrame.h"
50#include "lldb/Target/Thread.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000051#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000052
53using namespace lldb;
54using namespace lldb_private;
55
Greg Claytonabe0fed2011-04-18 08:33:37 +000056
57
58static void
59DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
60{
Greg Clayton52c8b6e2011-04-19 04:19:37 +000061 const ArchSpec &target_arch = target->GetArchitecture();
Greg Claytonabe0fed2011-04-18 08:33:37 +000062
Greg Clayton5beb99d2011-08-11 02:48:45 +000063 Module *exe_module = target->GetExecutableModulePointer();
Greg Claytonabe0fed2011-04-18 08:33:37 +000064 char exe_path[PATH_MAX];
65 bool exe_valid = false;
Greg Clayton5beb99d2011-08-11 02:48:45 +000066 if (exe_module)
67 exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path));
Greg Claytonabe0fed2011-04-18 08:33:37 +000068
69 if (!exe_valid)
70 ::strcpy (exe_path, "<none>");
71
72 strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);
73
74 uint32_t properties = 0;
75 if (target_arch.IsValid())
76 {
77 strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
78 properties++;
79 }
80 PlatformSP platform_sp (target->GetPlatform());
81 if (platform_sp)
82 strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName());
83
84 ProcessSP process_sp (target->GetProcessSP());
85 bool show_process_status = false;
86 if (process_sp)
87 {
88 lldb::pid_t pid = process_sp->GetID();
89 StateType state = process_sp->GetState();
90 if (show_stopped_process_status)
Greg Clayton20206082011-11-17 01:23:07 +000091 show_process_status = StateIsStoppedState(state, true);
Greg Claytonabe0fed2011-04-18 08:33:37 +000092 const char *state_cstr = StateAsCString (state);
93 if (pid != LLDB_INVALID_PROCESS_ID)
Greg Claytond9919d32011-12-01 23:28:38 +000094 strm.Printf ("%spid=%llu", properties++ > 0 ? ", " : " ( ", pid);
Greg Claytonabe0fed2011-04-18 08:33:37 +000095 strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
96 }
97 if (properties > 0)
98 strm.PutCString (" )\n");
99 else
100 strm.EOL();
101 if (show_process_status)
102 {
103 const bool only_threads_with_stop_reason = true;
104 const uint32_t start_frame = 0;
105 const uint32_t num_frames = 1;
106 const uint32_t num_frames_with_source = 1;
107 process_sp->GetStatus (strm);
108 process_sp->GetThreadStatus (strm,
109 only_threads_with_stop_reason,
110 start_frame,
111 num_frames,
112 num_frames_with_source);
113
114 }
115}
116
117static uint32_t
118DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
119{
120 const uint32_t num_targets = target_list.GetNumTargets();
121 if (num_targets)
122 {
123 TargetSP selected_target_sp (target_list.GetSelectedTarget());
124 strm.PutCString ("Current targets:\n");
125 for (uint32_t i=0; i<num_targets; ++i)
126 {
127 TargetSP target_sp (target_list.GetTargetAtIndex (i));
128 if (target_sp)
129 {
130 bool is_selected = target_sp.get() == selected_target_sp.get();
131 DumpTargetInfo (i,
132 target_sp.get(),
133 is_selected ? "* " : " ",
134 show_stopped_process_status,
135 strm);
136 }
137 }
138 }
139 return num_targets;
140}
141#pragma mark CommandObjectTargetCreate
142
143//-------------------------------------------------------------------------
144// "target create"
145//-------------------------------------------------------------------------
146
Jim Inghamda26bd22012-06-08 21:56:10 +0000147class CommandObjectTargetCreate : public CommandObjectParsed
Greg Claytonabe0fed2011-04-18 08:33:37 +0000148{
149public:
150 CommandObjectTargetCreate(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000151 CommandObjectParsed (interpreter,
152 "target create",
153 "Create a target using the argument as the main executable.",
154 NULL),
Greg Claytonabe0fed2011-04-18 08:33:37 +0000155 m_option_group (interpreter),
Greg Clayton801417e2011-07-07 01:59:51 +0000156 m_arch_option (),
Greg Clayton46c9a352012-02-09 06:16:32 +0000157 m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true
Johnny Chen6c061be2012-08-15 22:10:42 +0000158 m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypePath, "Fullpath to a core file to use for this target.")
Greg Claytonabe0fed2011-04-18 08:33:37 +0000159 {
160 CommandArgumentEntry arg;
161 CommandArgumentData file_arg;
162
163 // Define the first (and only) variant of this arg.
164 file_arg.arg_type = eArgTypeFilename;
165 file_arg.arg_repetition = eArgRepeatPlain;
166
167 // There is only one variant this argument could be; put it into the argument entry.
168 arg.push_back (file_arg);
169
170 // Push the data for the first argument into the m_arguments vector.
171 m_arguments.push_back (arg);
172
Greg Clayton801417e2011-07-07 01:59:51 +0000173 m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000174 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton46c9a352012-02-09 06:16:32 +0000175 m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000176 m_option_group.Finalize();
177 }
178
179 ~CommandObjectTargetCreate ()
180 {
181 }
182
183 Options *
184 GetOptions ()
185 {
186 return &m_option_group;
187 }
188
Jim Inghamda26bd22012-06-08 21:56:10 +0000189 int
190 HandleArgumentCompletion (Args &input,
191 int &cursor_index,
192 int &cursor_char_position,
193 OptionElementVector &opt_element_vector,
194 int match_start_point,
195 int max_return_elements,
196 bool &word_complete,
197 StringList &matches)
198 {
199 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
200 completion_str.erase (cursor_char_position);
201
202 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
203 CommandCompletions::eDiskFileCompletion,
204 completion_str.c_str(),
205 match_start_point,
206 max_return_elements,
207 NULL,
208 word_complete,
209 matches);
210 return matches.GetSize();
211 }
212
213protected:
Greg Claytonabe0fed2011-04-18 08:33:37 +0000214 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000215 DoExecute (Args& command, CommandReturnObject &result)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000216 {
217 const int argc = command.GetArgumentCount();
Greg Clayton46c9a352012-02-09 06:16:32 +0000218 FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue());
219
220 if (argc == 1 || core_file)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000221 {
222 const char *file_path = command.GetArgumentAtIndex(0);
223 Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
Greg Clayton46c9a352012-02-09 06:16:32 +0000224 FileSpec file_spec;
225
226 if (file_path)
227 file_spec.SetFile (file_path, true);
Greg Clayton3e8c25f2011-09-24 00:52:29 +0000228
Greg Claytonabe0fed2011-04-18 08:33:37 +0000229 TargetSP target_sp;
230 Debugger &debugger = m_interpreter.GetDebugger();
Greg Clayton3e8c25f2011-09-24 00:52:29 +0000231 const char *arch_cstr = m_arch_option.GetArchitectureName();
232 const bool get_dependent_files = true;
233 Error error (debugger.GetTargetList().CreateTarget (debugger,
234 file_spec,
235 arch_cstr,
236 get_dependent_files,
237 &m_platform_options,
238 target_sp));
239
Greg Claytonabe0fed2011-04-18 08:33:37 +0000240 if (target_sp)
241 {
242 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
Greg Clayton46c9a352012-02-09 06:16:32 +0000243 if (core_file)
244 {
Greg Clayton46c9a352012-02-09 06:16:32 +0000245 char core_path[PATH_MAX];
246 core_file.GetPath(core_path, sizeof(core_path));
Greg Clayton9ce95382012-02-13 23:10:39 +0000247 if (core_file.Exists())
Greg Clayton46c9a352012-02-09 06:16:32 +0000248 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000249 FileSpec core_file_dir;
250 core_file_dir.GetDirectory() = core_file.GetDirectory();
251 target_sp->GetExecutableSearchPaths ().Append (core_file_dir);
Greg Clayton46c9a352012-02-09 06:16:32 +0000252
Greg Clayton9ce95382012-02-13 23:10:39 +0000253 ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file));
254
255 if (process_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +0000256 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000257 // Seems wierd that we Launch a core file, but that is
258 // what we do!
259 error = process_sp->LoadCore();
260
261 if (error.Fail())
262 {
263 result.AppendError(error.AsCString("can't find plug-in for core file"));
264 result.SetStatus (eReturnStatusFailed);
265 return false;
266 }
267 else
268 {
269 result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName());
270 result.SetStatus (eReturnStatusSuccessFinishNoResult);
271 }
Greg Clayton46c9a352012-02-09 06:16:32 +0000272 }
273 else
274 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000275 result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path);
276 result.SetStatus (eReturnStatusFailed);
Greg Clayton46c9a352012-02-09 06:16:32 +0000277 }
278 }
279 else
280 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000281 result.AppendErrorWithFormat ("Core file '%s' does not exist\n", core_path);
Greg Clayton46c9a352012-02-09 06:16:32 +0000282 result.SetStatus (eReturnStatusFailed);
283 }
284 }
285 else
286 {
287 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
288 result.SetStatus (eReturnStatusSuccessFinishNoResult);
289 }
Greg Claytonabe0fed2011-04-18 08:33:37 +0000290 }
291 else
292 {
293 result.AppendError(error.AsCString());
294 result.SetStatus (eReturnStatusFailed);
295 }
296 }
297 else
298 {
Greg Clayton46c9a352012-02-09 06:16:32 +0000299 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core-file option.\n", m_cmd_name.c_str());
Greg Claytonabe0fed2011-04-18 08:33:37 +0000300 result.SetStatus (eReturnStatusFailed);
301 }
302 return result.Succeeded();
303
304 }
305
Greg Claytonabe0fed2011-04-18 08:33:37 +0000306private:
307 OptionGroupOptions m_option_group;
Greg Clayton801417e2011-07-07 01:59:51 +0000308 OptionGroupArchitecture m_arch_option;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000309 OptionGroupPlatform m_platform_options;
Greg Clayton46c9a352012-02-09 06:16:32 +0000310 OptionGroupFile m_core_file;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000311
312};
313
314#pragma mark CommandObjectTargetList
315
316//----------------------------------------------------------------------
317// "target list"
318//----------------------------------------------------------------------
319
Jim Inghamda26bd22012-06-08 21:56:10 +0000320class CommandObjectTargetList : public CommandObjectParsed
Greg Claytonabe0fed2011-04-18 08:33:37 +0000321{
322public:
323 CommandObjectTargetList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000324 CommandObjectParsed (interpreter,
325 "target list",
326 "List all current targets in the current debug session.",
327 NULL,
328 0)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000329 {
330 }
331
332 virtual
333 ~CommandObjectTargetList ()
334 {
335 }
336
Jim Inghamda26bd22012-06-08 21:56:10 +0000337protected:
Greg Claytonabe0fed2011-04-18 08:33:37 +0000338 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000339 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000340 {
341 if (args.GetArgumentCount() == 0)
342 {
343 Stream &strm = result.GetOutputStream();
344
345 bool show_stopped_process_status = false;
346 if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
347 {
348 strm.PutCString ("No targets.\n");
349 }
Johnny Chen44dc9d32011-04-18 21:08:05 +0000350 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000351 }
352 else
353 {
354 result.AppendError ("the 'target list' command takes no arguments\n");
355 result.SetStatus (eReturnStatusFailed);
356 }
357 return result.Succeeded();
358 }
359};
360
361
362#pragma mark CommandObjectTargetSelect
363
364//----------------------------------------------------------------------
365// "target select"
366//----------------------------------------------------------------------
367
Jim Inghamda26bd22012-06-08 21:56:10 +0000368class CommandObjectTargetSelect : public CommandObjectParsed
Greg Claytonabe0fed2011-04-18 08:33:37 +0000369{
370public:
371 CommandObjectTargetSelect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000372 CommandObjectParsed (interpreter,
373 "target select",
374 "Select a target as the current target by target index.",
375 NULL,
376 0)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000377 {
378 }
379
380 virtual
381 ~CommandObjectTargetSelect ()
382 {
383 }
384
Jim Inghamda26bd22012-06-08 21:56:10 +0000385protected:
Greg Claytonabe0fed2011-04-18 08:33:37 +0000386 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000387 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000388 {
389 if (args.GetArgumentCount() == 1)
390 {
391 bool success = false;
392 const char *target_idx_arg = args.GetArgumentAtIndex(0);
393 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
394 if (success)
395 {
396 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
397 const uint32_t num_targets = target_list.GetNumTargets();
398 if (target_idx < num_targets)
399 {
400 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
401 if (target_sp)
402 {
403 Stream &strm = result.GetOutputStream();
404 target_list.SetSelectedTarget (target_sp.get());
405 bool show_stopped_process_status = false;
406 DumpTargetList (target_list, show_stopped_process_status, strm);
Johnny Chen44dc9d32011-04-18 21:08:05 +0000407 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000408 }
409 else
410 {
411 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
412 result.SetStatus (eReturnStatusFailed);
413 }
414 }
415 else
416 {
417 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
418 target_idx,
419 num_targets - 1);
420 result.SetStatus (eReturnStatusFailed);
421 }
422 }
423 else
424 {
425 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
426 result.SetStatus (eReturnStatusFailed);
427 }
428 }
429 else
430 {
431 result.AppendError ("'target select' takes a single argument: a target index\n");
432 result.SetStatus (eReturnStatusFailed);
433 }
434 return result.Succeeded();
435 }
436};
437
Greg Clayton153ccd72011-08-10 02:10:13 +0000438#pragma mark CommandObjectTargetSelect
439
440//----------------------------------------------------------------------
441// "target delete"
442//----------------------------------------------------------------------
443
Jim Inghamda26bd22012-06-08 21:56:10 +0000444class CommandObjectTargetDelete : public CommandObjectParsed
Greg Clayton153ccd72011-08-10 02:10:13 +0000445{
446public:
447 CommandObjectTargetDelete (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000448 CommandObjectParsed (interpreter,
449 "target delete",
450 "Delete one or more targets by target index.",
451 NULL,
452 0),
Greg Clayton5beb99d2011-08-11 02:48:45 +0000453 m_option_group (interpreter),
Greg Clayton437b5bc2012-09-27 22:26:11 +0000454 m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', "Perform extra cleanup to minimize memory consumption after deleting the target.", false, false)
Greg Clayton153ccd72011-08-10 02:10:13 +0000455 {
Greg Clayton5beb99d2011-08-11 02:48:45 +0000456 m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
457 m_option_group.Finalize();
Greg Clayton153ccd72011-08-10 02:10:13 +0000458 }
459
460 virtual
461 ~CommandObjectTargetDelete ()
462 {
463 }
464
Jim Inghamda26bd22012-06-08 21:56:10 +0000465 Options *
466 GetOptions ()
467 {
468 return &m_option_group;
469 }
470
471protected:
Greg Clayton153ccd72011-08-10 02:10:13 +0000472 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000473 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton153ccd72011-08-10 02:10:13 +0000474 {
475 const size_t argc = args.GetArgumentCount();
476 std::vector<TargetSP> delete_target_list;
477 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
478 bool success = true;
479 TargetSP target_sp;
480 if (argc > 0)
481 {
482 const uint32_t num_targets = target_list.GetNumTargets();
Filipe Cabecinhasaa3d89e2012-07-09 13:02:17 +0000483 // Bail out if don't have any targets.
484 if (num_targets == 0) {
485 result.AppendError("no targets to delete");
486 result.SetStatus(eReturnStatusFailed);
487 success = false;
488 }
489
Greg Clayton153ccd72011-08-10 02:10:13 +0000490 for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx)
491 {
492 const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx);
493 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
494 if (success)
495 {
496 if (target_idx < num_targets)
497 {
498 target_sp = target_list.GetTargetAtIndex (target_idx);
499 if (target_sp)
500 {
501 delete_target_list.push_back (target_sp);
502 continue;
503 }
504 }
Filipe Cabecinhasaa3d89e2012-07-09 13:02:17 +0000505 if (num_targets > 1)
506 result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n",
507 target_idx,
508 num_targets - 1);
509 else
510 result.AppendErrorWithFormat("target index %u is out of range, the only valid index is 0\n",
511 target_idx);
512
Greg Clayton153ccd72011-08-10 02:10:13 +0000513 result.SetStatus (eReturnStatusFailed);
514 success = false;
515 }
516 else
517 {
518 result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg);
519 result.SetStatus (eReturnStatusFailed);
520 success = false;
521 }
522 }
523
524 }
525 else
526 {
527 target_sp = target_list.GetSelectedTarget();
528 if (target_sp)
529 {
530 delete_target_list.push_back (target_sp);
531 }
532 else
533 {
534 result.AppendErrorWithFormat("no target is currently selected\n");
535 result.SetStatus (eReturnStatusFailed);
536 success = false;
537 }
538 }
539 if (success)
540 {
541 const size_t num_targets_to_delete = delete_target_list.size();
542 for (size_t idx = 0; idx < num_targets_to_delete; ++idx)
543 {
544 target_sp = delete_target_list[idx];
545 target_list.DeleteTarget(target_sp);
546 target_sp->Destroy();
547 }
Greg Clayton5beb99d2011-08-11 02:48:45 +0000548 // If "--clean" was specified, prune any orphaned shared modules from
549 // the global shared module list
550 if (m_cleanup_option.GetOptionValue ())
551 {
Greg Clayton860b9ea2012-04-09 20:22:01 +0000552 const bool mandatory = true;
553 ModuleList::RemoveOrphanSharedModules(mandatory);
Greg Clayton5beb99d2011-08-11 02:48:45 +0000554 }
Greg Clayton153ccd72011-08-10 02:10:13 +0000555 result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete);
556 result.SetStatus(eReturnStatusSuccessFinishResult);
557 }
558
559 return result.Succeeded();
560 }
Greg Clayton5beb99d2011-08-11 02:48:45 +0000561
Greg Clayton5beb99d2011-08-11 02:48:45 +0000562 OptionGroupOptions m_option_group;
563 OptionGroupBoolean m_cleanup_option;
Greg Clayton153ccd72011-08-10 02:10:13 +0000564};
565
Greg Claytonabe0fed2011-04-18 08:33:37 +0000566
Greg Clayton801417e2011-07-07 01:59:51 +0000567#pragma mark CommandObjectTargetVariable
568
569//----------------------------------------------------------------------
570// "target variable"
571//----------------------------------------------------------------------
572
Jim Inghamda26bd22012-06-08 21:56:10 +0000573class CommandObjectTargetVariable : public CommandObjectParsed
Greg Clayton801417e2011-07-07 01:59:51 +0000574{
575public:
576 CommandObjectTargetVariable (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000577 CommandObjectParsed (interpreter,
578 "target variable",
579 "Read global variable(s) prior to running your binary.",
580 NULL,
581 0),
Greg Clayton801417e2011-07-07 01:59:51 +0000582 m_option_group (interpreter),
Greg Clayton368f8222011-07-07 04:38:25 +0000583 m_option_variable (false), // Don't include frame options
Greg Claytona42880a2011-10-25 06:44:01 +0000584 m_option_format (eFormatDefault),
Greg Clayton801417e2011-07-07 01:59:51 +0000585 m_option_compile_units (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."),
586 m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",'s', 0, eArgTypePath, "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."),
587 m_varobj_options()
588 {
Johnny Chen24b81e32011-08-22 22:22:00 +0000589 CommandArgumentEntry arg;
590 CommandArgumentData var_name_arg;
591
592 // Define the first (and only) variant of this arg.
593 var_name_arg.arg_type = eArgTypeVarName;
594 var_name_arg.arg_repetition = eArgRepeatPlus;
595
596 // There is only one variant this argument could be; put it into the argument entry.
597 arg.push_back (var_name_arg);
598
599 // Push the data for the first argument into the m_arguments vector.
600 m_arguments.push_back (arg);
601
Greg Clayton801417e2011-07-07 01:59:51 +0000602 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton368f8222011-07-07 04:38:25 +0000603 m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton24a6bd92011-10-27 17:55:14 +0000604 m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
Greg Clayton801417e2011-07-07 01:59:51 +0000605 m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
606 m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
607 m_option_group.Finalize();
608 }
609
610 virtual
611 ~CommandObjectTargetVariable ()
612 {
613 }
Greg Clayton5d81f492011-07-08 21:46:14 +0000614
615 void
616 DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
617 {
Enrico Granata19030d82011-08-15 18:01:31 +0000618 ValueObject::DumpValueObjectOptions options;
619
Enrico Granata3069c622012-03-01 04:24:26 +0000620 options.SetMaximumPointerDepth(m_varobj_options.ptr_depth)
Enrico Granata19030d82011-08-15 18:01:31 +0000621 .SetMaximumDepth(m_varobj_options.max_depth)
622 .SetShowTypes(m_varobj_options.show_types)
623 .SetShowLocation(m_varobj_options.show_location)
624 .SetUseObjectiveC(m_varobj_options.use_objc)
625 .SetUseDynamicType(m_varobj_options.use_dynamic)
Enrico Granatacf09f882012-03-19 22:58:49 +0000626 .SetUseSyntheticValue(m_varobj_options.use_synth)
Enrico Granata19030d82011-08-15 18:01:31 +0000627 .SetFlatOutput(m_varobj_options.flat_output)
628 .SetOmitSummaryDepth(m_varobj_options.no_summary_depth)
629 .SetIgnoreCap(m_varobj_options.ignore_cap);
630
Greg Clayton5d81f492011-07-08 21:46:14 +0000631 switch (var_sp->GetScope())
632 {
633 case eValueTypeVariableGlobal:
634 if (m_option_variable.show_scope)
635 s.PutCString("GLOBAL: ");
636 break;
637
638 case eValueTypeVariableStatic:
639 if (m_option_variable.show_scope)
640 s.PutCString("STATIC: ");
641 break;
642
643 case eValueTypeVariableArgument:
644 if (m_option_variable.show_scope)
645 s.PutCString(" ARG: ");
646 break;
647
648 case eValueTypeVariableLocal:
649 if (m_option_variable.show_scope)
650 s.PutCString(" LOCAL: ");
651 break;
652
653 default:
654 break;
655 }
656
Greg Claytonfb816422011-07-10 19:21:23 +0000657 if (m_option_variable.show_decl)
Greg Clayton5d81f492011-07-08 21:46:14 +0000658 {
Greg Claytonfb816422011-07-10 19:21:23 +0000659 bool show_fullpaths = false;
660 bool show_module = true;
661 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
662 s.PutCString (": ");
Greg Clayton5d81f492011-07-08 21:46:14 +0000663 }
664
Greg Claytona42880a2011-10-25 06:44:01 +0000665 const Format format = m_option_format.GetFormat();
Greg Clayton5d81f492011-07-08 21:46:14 +0000666 if (format != eFormatDefault)
Enrico Granata3069c622012-03-01 04:24:26 +0000667 options.SetFormat(format);
668
669 options.SetRootValueObjectName(root_name);
Greg Clayton5d81f492011-07-08 21:46:14 +0000670
671 ValueObject::DumpValueObject (s,
672 valobj_sp.get(),
Enrico Granata3069c622012-03-01 04:24:26 +0000673 options);
Greg Clayton5d81f492011-07-08 21:46:14 +0000674
675 }
Greg Clayton801417e2011-07-07 01:59:51 +0000676
Greg Clayton5d81f492011-07-08 21:46:14 +0000677
678 static uint32_t GetVariableCallback (void *baton,
679 const char *name,
680 VariableList &variable_list)
681 {
682 Target *target = static_cast<Target *>(baton);
683 if (target)
684 {
685 return target->GetImages().FindGlobalVariables (ConstString(name),
686 true,
687 UINT32_MAX,
688 variable_list);
689 }
690 return 0;
691 }
692
693
694
Jim Inghamda26bd22012-06-08 21:56:10 +0000695 Options *
696 GetOptions ()
697 {
698 return &m_option_group;
699 }
700
701protected:
Greg Clayton801417e2011-07-07 01:59:51 +0000702 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000703 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton801417e2011-07-07 01:59:51 +0000704 {
705 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +0000706 Target *target = exe_ctx.GetTargetPtr();
707 if (target)
Greg Clayton801417e2011-07-07 01:59:51 +0000708 {
709 const size_t argc = args.GetArgumentCount();
Greg Claytonfac93882011-10-05 22:17:32 +0000710 Stream &s = result.GetOutputStream();
Greg Clayton801417e2011-07-07 01:59:51 +0000711 if (argc > 0)
712 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000713
Greg Clayton801417e2011-07-07 01:59:51 +0000714 for (size_t idx = 0; idx < argc; ++idx)
715 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000716 VariableList variable_list;
717 ValueObjectList valobj_list;
718
Greg Clayton368f8222011-07-07 04:38:25 +0000719 const char *arg = args.GetArgumentAtIndex(idx);
720 uint32_t matches = 0;
Greg Claytonfb816422011-07-10 19:21:23 +0000721 bool use_var_name = false;
Greg Clayton368f8222011-07-07 04:38:25 +0000722 if (m_option_variable.use_regex)
Greg Clayton801417e2011-07-07 01:59:51 +0000723 {
Greg Clayton368f8222011-07-07 04:38:25 +0000724 RegularExpression regex(arg);
725 if (!regex.IsValid ())
726 {
727 result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
728 result.SetStatus (eReturnStatusFailed);
729 return false;
730 }
Greg Claytonfb816422011-07-10 19:21:23 +0000731 use_var_name = true;
Greg Clayton567e7f32011-09-22 04:58:26 +0000732 matches = target->GetImages().FindGlobalVariables (regex,
733 true,
734 UINT32_MAX,
735 variable_list);
Greg Clayton801417e2011-07-07 01:59:51 +0000736 }
737 else
738 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000739 Error error (Variable::GetValuesForVariableExpressionPath (arg,
Greg Clayton24b03102011-07-09 20:12:33 +0000740 exe_ctx.GetBestExecutionContextScope(),
Greg Clayton5d81f492011-07-08 21:46:14 +0000741 GetVariableCallback,
Greg Clayton567e7f32011-09-22 04:58:26 +0000742 target,
Greg Clayton5d81f492011-07-08 21:46:14 +0000743 variable_list,
744 valobj_list));
Greg Clayton5d81f492011-07-08 21:46:14 +0000745 matches = variable_list.GetSize();
Greg Clayton368f8222011-07-07 04:38:25 +0000746 }
747
748 if (matches == 0)
749 {
750 result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
751 result.SetStatus (eReturnStatusFailed);
752 return false;
753 }
754 else
755 {
Greg Clayton801417e2011-07-07 01:59:51 +0000756 for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
757 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000758 VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
Greg Clayton801417e2011-07-07 01:59:51 +0000759 if (var_sp)
760 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000761 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
762 if (!valobj_sp)
Greg Claytonfb816422011-07-10 19:21:23 +0000763 valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp);
Greg Clayton801417e2011-07-07 01:59:51 +0000764
765 if (valobj_sp)
Greg Claytonb304a742011-10-13 18:31:02 +0000766 DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
Greg Clayton801417e2011-07-07 01:59:51 +0000767 }
768 }
769 }
770 }
771 }
772 else
773 {
Greg Claytonfac93882011-10-05 22:17:32 +0000774 bool success = false;
775 StackFrame *frame = exe_ctx.GetFramePtr();
776 CompileUnit *comp_unit = NULL;
777 if (frame)
778 {
779 comp_unit = frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit;
780 if (comp_unit)
781 {
782 const bool can_create = true;
783 VariableListSP comp_unit_varlist_sp (comp_unit->GetVariableList(can_create));
784 if (comp_unit_varlist_sp)
785 {
786 size_t count = comp_unit_varlist_sp->GetSize();
787 if (count > 0)
788 {
Greg Claytona1b9a902011-11-13 04:15:56 +0000789 s.Printf ("Global variables for %s/%s:\n",
Greg Claytonfac93882011-10-05 22:17:32 +0000790 comp_unit->GetDirectory().GetCString(),
791 comp_unit->GetFilename().GetCString());
792
793 success = true;
794 for (uint32_t i=0; i<count; ++i)
795 {
796 VariableSP var_sp (comp_unit_varlist_sp->GetVariableAtIndex(i));
797 if (var_sp)
798 {
799 ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp));
800
801 if (valobj_sp)
802 DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString());
803 }
804 }
805 }
806 }
807 }
808 }
809 if (!success)
810 {
811 if (frame)
812 {
813 if (comp_unit)
814 result.AppendErrorWithFormat ("no global variables in current compile unit: %s/%s\n",
815 comp_unit->GetDirectory().GetCString(),
816 comp_unit->GetFilename().GetCString());
817 else
818 result.AppendError ("no debug information for frame %u\n", frame->GetFrameIndex());
819 }
820 else
821 result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
822 result.SetStatus (eReturnStatusFailed);
823 }
Greg Clayton801417e2011-07-07 01:59:51 +0000824 }
825 }
826 else
827 {
828 result.AppendError ("invalid target, create a debug target using the 'target create' command");
829 result.SetStatus (eReturnStatusFailed);
830 return false;
831 }
Enrico Granatadb64d952011-08-12 16:42:31 +0000832
833 if (m_interpreter.TruncationWarningNecessary())
834 {
835 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
836 m_cmd_name.c_str());
837 m_interpreter.TruncationWarningGiven();
838 }
839
Greg Clayton801417e2011-07-07 01:59:51 +0000840 return result.Succeeded();
841 }
842
Greg Clayton801417e2011-07-07 01:59:51 +0000843 OptionGroupOptions m_option_group;
Greg Clayton368f8222011-07-07 04:38:25 +0000844 OptionGroupVariable m_option_variable;
Greg Claytona42880a2011-10-25 06:44:01 +0000845 OptionGroupFormat m_option_format;
Greg Clayton801417e2011-07-07 01:59:51 +0000846 OptionGroupFileList m_option_compile_units;
847 OptionGroupFileList m_option_shared_libraries;
848 OptionGroupValueObjectDisplay m_varobj_options;
849
850};
851
852
Greg Claytone1f50b92011-05-03 22:09:39 +0000853#pragma mark CommandObjectTargetModulesSearchPathsAdd
Chris Lattner24943d22010-06-08 16:52:24 +0000854
Jim Inghamda26bd22012-06-08 21:56:10 +0000855class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000856{
857public:
858
Greg Claytone1f50b92011-05-03 22:09:39 +0000859 CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000860 CommandObjectParsed (interpreter,
861 "target modules search-paths add",
862 "Add new image search paths substitution pairs to the current target.",
863 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000864 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000865 CommandArgumentEntry arg;
866 CommandArgumentData old_prefix_arg;
867 CommandArgumentData new_prefix_arg;
868
869 // Define the first variant of this arg pair.
870 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
871 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
872
873 // Define the first variant of this arg pair.
874 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
875 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
876
877 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
878 // must always occur together, they are treated as two variants of one argument rather than two independent
879 // arguments. Push them both into the first argument position for m_arguments...
880
881 arg.push_back (old_prefix_arg);
882 arg.push_back (new_prefix_arg);
883
884 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000885 }
886
Greg Claytone1f50b92011-05-03 22:09:39 +0000887 ~CommandObjectTargetModulesSearchPathsAdd ()
Chris Lattner24943d22010-06-08 16:52:24 +0000888 {
889 }
890
Jim Inghamda26bd22012-06-08 21:56:10 +0000891protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000892 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000893 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000894 CommandReturnObject &result)
895 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000896 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000897 if (target)
898 {
899 uint32_t argc = command.GetArgumentCount();
900 if (argc & 1)
901 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000902 result.AppendError ("add requires an even number of arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000903 result.SetStatus (eReturnStatusFailed);
904 }
905 else
906 {
907 for (uint32_t i=0; i<argc; i+=2)
908 {
909 const char *from = command.GetArgumentAtIndex(i);
910 const char *to = command.GetArgumentAtIndex(i+1);
911
912 if (from[0] && to[0])
913 {
914 bool last_pair = ((argc - i) == 2);
Greg Clayton63094e02010-06-23 01:19:29 +0000915 target->GetImageSearchPathList().Append (ConstString(from),
916 ConstString(to),
917 last_pair); // Notify if this is the last pair
Johnny Chen4d661352011-02-03 00:30:19 +0000918 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000919 }
920 else
921 {
922 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000923 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000924 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000925 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000926 result.SetStatus (eReturnStatusFailed);
927 }
928 }
929 }
930 }
931 else
932 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000933 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000934 result.SetStatus (eReturnStatusFailed);
935 }
936 return result.Succeeded();
937 }
938};
939
Greg Claytone1f50b92011-05-03 22:09:39 +0000940#pragma mark CommandObjectTargetModulesSearchPathsClear
941
Jim Inghamda26bd22012-06-08 21:56:10 +0000942class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000943{
944public:
945
Greg Claytone1f50b92011-05-03 22:09:39 +0000946 CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000947 CommandObjectParsed (interpreter,
948 "target modules search-paths clear",
949 "Clear all current image search path substitution pairs from the current target.",
950 "target modules search-paths clear")
Chris Lattner24943d22010-06-08 16:52:24 +0000951 {
952 }
953
Greg Claytone1f50b92011-05-03 22:09:39 +0000954 ~CommandObjectTargetModulesSearchPathsClear ()
Chris Lattner24943d22010-06-08 16:52:24 +0000955 {
956 }
957
Jim Inghamda26bd22012-06-08 21:56:10 +0000958protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000959 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000960 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000961 CommandReturnObject &result)
962 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000963 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000964 if (target)
965 {
966 bool notify = true;
967 target->GetImageSearchPathList().Clear(notify);
Johnny Chen4d661352011-02-03 00:30:19 +0000968 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000969 }
970 else
971 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000972 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000973 result.SetStatus (eReturnStatusFailed);
974 }
975 return result.Succeeded();
976 }
977};
978
Greg Claytone1f50b92011-05-03 22:09:39 +0000979#pragma mark CommandObjectTargetModulesSearchPathsInsert
980
Jim Inghamda26bd22012-06-08 21:56:10 +0000981class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000982{
983public:
984
Greg Claytone1f50b92011-05-03 22:09:39 +0000985 CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000986 CommandObjectParsed (interpreter,
987 "target modules search-paths insert",
988 "Insert a new image search path substitution pair into the current target at the specified index.",
989 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000990 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000991 CommandArgumentEntry arg1;
992 CommandArgumentEntry arg2;
993 CommandArgumentData index_arg;
994 CommandArgumentData old_prefix_arg;
995 CommandArgumentData new_prefix_arg;
996
997 // Define the first and only variant of this arg.
998 index_arg.arg_type = eArgTypeIndex;
999 index_arg.arg_repetition = eArgRepeatPlain;
1000
1001 // Put the one and only variant into the first arg for m_arguments:
1002 arg1.push_back (index_arg);
1003
1004 // Define the first variant of this arg pair.
1005 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1006 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1007
1008 // Define the first variant of this arg pair.
1009 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1010 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1011
1012 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
1013 // must always occur together, they are treated as two variants of one argument rather than two independent
1014 // arguments. Push them both into the same argument position for m_arguments...
1015
1016 arg2.push_back (old_prefix_arg);
1017 arg2.push_back (new_prefix_arg);
1018
1019 // Add arguments to m_arguments.
1020 m_arguments.push_back (arg1);
1021 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +00001022 }
1023
Greg Claytone1f50b92011-05-03 22:09:39 +00001024 ~CommandObjectTargetModulesSearchPathsInsert ()
Chris Lattner24943d22010-06-08 16:52:24 +00001025 {
1026 }
1027
Jim Inghamda26bd22012-06-08 21:56:10 +00001028protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001029 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001030 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001031 CommandReturnObject &result)
1032 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001033 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001034 if (target)
1035 {
1036 uint32_t argc = command.GetArgumentCount();
1037 // check for at least 3 arguments and an odd nubmer of parameters
1038 if (argc >= 3 && argc & 1)
1039 {
1040 bool success = false;
1041
1042 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1043
1044 if (!success)
1045 {
1046 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
1047 result.SetStatus (eReturnStatusFailed);
1048 return result.Succeeded();
1049 }
1050
1051 // shift off the index
1052 command.Shift();
1053 argc = command.GetArgumentCount();
1054
1055 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
1056 {
1057 const char *from = command.GetArgumentAtIndex(i);
1058 const char *to = command.GetArgumentAtIndex(i+1);
1059
1060 if (from[0] && to[0])
1061 {
1062 bool last_pair = ((argc - i) == 2);
1063 target->GetImageSearchPathList().Insert (ConstString(from),
1064 ConstString(to),
1065 insert_idx,
1066 last_pair);
Johnny Chen4d661352011-02-03 00:30:19 +00001067 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001068 }
1069 else
1070 {
1071 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +00001072 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001073 else
Greg Claytonabe0fed2011-04-18 08:33:37 +00001074 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001075 result.SetStatus (eReturnStatusFailed);
1076 return false;
1077 }
1078 }
1079 }
1080 else
1081 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001082 result.AppendError ("insert requires at least three arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001083 result.SetStatus (eReturnStatusFailed);
1084 return result.Succeeded();
1085 }
1086
1087 }
1088 else
1089 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001090 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001091 result.SetStatus (eReturnStatusFailed);
1092 }
1093 return result.Succeeded();
1094 }
1095};
1096
Greg Claytone1f50b92011-05-03 22:09:39 +00001097
1098#pragma mark CommandObjectTargetModulesSearchPathsList
1099
1100
Jim Inghamda26bd22012-06-08 21:56:10 +00001101class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001102{
1103public:
1104
Greg Claytone1f50b92011-05-03 22:09:39 +00001105 CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001106 CommandObjectParsed (interpreter,
1107 "target modules search-paths list",
1108 "List all current image search path substitution pairs in the current target.",
1109 "target modules search-paths list")
Chris Lattner24943d22010-06-08 16:52:24 +00001110 {
1111 }
1112
Greg Claytone1f50b92011-05-03 22:09:39 +00001113 ~CommandObjectTargetModulesSearchPathsList ()
Chris Lattner24943d22010-06-08 16:52:24 +00001114 {
1115 }
1116
Jim Inghamda26bd22012-06-08 21:56:10 +00001117protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001118 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001119 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001120 CommandReturnObject &result)
1121 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001122 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001123 if (target)
1124 {
1125 if (command.GetArgumentCount() != 0)
1126 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001127 result.AppendError ("list takes no arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001128 result.SetStatus (eReturnStatusFailed);
1129 return result.Succeeded();
1130 }
1131
1132 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
Johnny Chen4d661352011-02-03 00:30:19 +00001133 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001134 }
1135 else
1136 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001137 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001138 result.SetStatus (eReturnStatusFailed);
1139 }
1140 return result.Succeeded();
1141 }
1142};
1143
Greg Claytone1f50b92011-05-03 22:09:39 +00001144#pragma mark CommandObjectTargetModulesSearchPathsQuery
1145
Jim Inghamda26bd22012-06-08 21:56:10 +00001146class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001147{
1148public:
1149
Greg Claytone1f50b92011-05-03 22:09:39 +00001150 CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001151 CommandObjectParsed (interpreter,
1152 "target modules search-paths query",
1153 "Transform a path using the first applicable image search path.",
1154 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001155 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001156 CommandArgumentEntry arg;
1157 CommandArgumentData path_arg;
1158
1159 // Define the first (and only) variant of this arg.
1160 path_arg.arg_type = eArgTypePath;
1161 path_arg.arg_repetition = eArgRepeatPlain;
1162
1163 // There is only one variant this argument could be; put it into the argument entry.
1164 arg.push_back (path_arg);
1165
1166 // Push the data for the first argument into the m_arguments vector.
1167 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001168 }
1169
Greg Claytone1f50b92011-05-03 22:09:39 +00001170 ~CommandObjectTargetModulesSearchPathsQuery ()
Chris Lattner24943d22010-06-08 16:52:24 +00001171 {
1172 }
1173
Jim Inghamda26bd22012-06-08 21:56:10 +00001174protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001175 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001176 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001177 CommandReturnObject &result)
1178 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001179 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001180 if (target)
1181 {
1182 if (command.GetArgumentCount() != 1)
1183 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001184 result.AppendError ("query requires one argument\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001185 result.SetStatus (eReturnStatusFailed);
1186 return result.Succeeded();
1187 }
1188
1189 ConstString orig(command.GetArgumentAtIndex(0));
1190 ConstString transformed;
1191 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1192 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1193 else
1194 result.GetOutputStream().Printf("%s\n", orig.GetCString());
Johnny Chen4d661352011-02-03 00:30:19 +00001195
1196 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001197 }
1198 else
1199 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001200 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001201 result.SetStatus (eReturnStatusFailed);
1202 }
1203 return result.Succeeded();
1204 }
1205};
1206
Greg Claytone1f50b92011-05-03 22:09:39 +00001207//----------------------------------------------------------------------
1208// Static Helper functions
1209//----------------------------------------------------------------------
1210static void
1211DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
1212{
1213 if (module)
1214 {
1215 const char *arch_cstr;
1216 if (full_triple)
1217 arch_cstr = module->GetArchitecture().GetTriple().str().c_str();
1218 else
1219 arch_cstr = module->GetArchitecture().GetArchitectureName();
1220 if (width)
1221 strm.Printf("%-*s", width, arch_cstr);
1222 else
1223 strm.PutCString(arch_cstr);
1224 }
1225}
1226
1227static void
1228DumpModuleUUID (Stream &strm, Module *module)
1229{
Greg Clayton153ccd72011-08-10 02:10:13 +00001230 if (module->GetUUID().IsValid())
1231 module->GetUUID().Dump (&strm);
1232 else
1233 strm.PutCString(" ");
Greg Claytone1f50b92011-05-03 22:09:39 +00001234}
1235
1236static uint32_t
1237DumpCompileUnitLineTable
1238(
1239 CommandInterpreter &interpreter,
1240 Stream &strm,
1241 Module *module,
1242 const FileSpec &file_spec,
1243 bool load_addresses
1244 )
1245{
1246 uint32_t num_matches = 0;
1247 if (module)
1248 {
1249 SymbolContextList sc_list;
1250 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
1251 0,
1252 false,
1253 eSymbolContextCompUnit,
1254 sc_list);
1255
1256 for (uint32_t i=0; i<num_matches; ++i)
1257 {
1258 SymbolContext sc;
1259 if (sc_list.GetContextAtIndex(i, sc))
1260 {
1261 if (i > 0)
1262 strm << "\n\n";
1263
1264 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
1265 << module->GetFileSpec().GetFilename() << "\n";
1266 LineTable *line_table = sc.comp_unit->GetLineTable();
1267 if (line_table)
1268 line_table->GetDescription (&strm,
Greg Clayton567e7f32011-09-22 04:58:26 +00001269 interpreter.GetExecutionContext().GetTargetPtr(),
Greg Claytone1f50b92011-05-03 22:09:39 +00001270 lldb::eDescriptionLevelBrief);
1271 else
1272 strm << "No line table";
1273 }
1274 }
1275 }
1276 return num_matches;
1277}
1278
1279static void
1280DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1281{
1282 if (file_spec_ptr)
1283 {
1284 if (width > 0)
1285 {
1286 char fullpath[PATH_MAX];
1287 if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath)))
1288 {
1289 strm.Printf("%-*s", width, fullpath);
1290 return;
1291 }
1292 }
1293 else
1294 {
1295 file_spec_ptr->Dump(&strm);
1296 return;
1297 }
1298 }
1299 // Keep the width spacing correct if things go wrong...
1300 if (width > 0)
1301 strm.Printf("%-*s", width, "");
1302}
1303
1304static void
1305DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1306{
1307 if (file_spec_ptr)
1308 {
1309 if (width > 0)
1310 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1311 else
1312 file_spec_ptr->GetDirectory().Dump(&strm);
1313 return;
1314 }
1315 // Keep the width spacing correct if things go wrong...
1316 if (width > 0)
1317 strm.Printf("%-*s", width, "");
1318}
1319
1320static void
1321DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1322{
1323 if (file_spec_ptr)
1324 {
1325 if (width > 0)
1326 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1327 else
1328 file_spec_ptr->GetFilename().Dump(&strm);
1329 return;
1330 }
1331 // Keep the width spacing correct if things go wrong...
1332 if (width > 0)
1333 strm.Printf("%-*s", width, "");
1334}
1335
1336
1337static void
1338DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
1339{
1340 if (module)
1341 {
1342 ObjectFile *objfile = module->GetObjectFile ();
1343 if (objfile)
1344 {
1345 Symtab *symtab = objfile->GetSymtab();
1346 if (symtab)
Greg Clayton567e7f32011-09-22 04:58:26 +00001347 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order);
Greg Claytone1f50b92011-05-03 22:09:39 +00001348 }
1349 }
1350}
1351
1352static void
1353DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
1354{
1355 if (module)
1356 {
1357 ObjectFile *objfile = module->GetObjectFile ();
1358 if (objfile)
1359 {
1360 SectionList *section_list = objfile->GetSectionList();
1361 if (section_list)
1362 {
1363 strm.PutCString ("Sections for '");
1364 strm << module->GetFileSpec();
1365 if (module->GetObjectName())
1366 strm << '(' << module->GetObjectName() << ')';
1367 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName());
1368 strm.IndentMore();
Greg Clayton567e7f32011-09-22 04:58:26 +00001369 section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX);
Greg Claytone1f50b92011-05-03 22:09:39 +00001370 strm.IndentLess();
1371 }
1372 }
1373 }
1374}
1375
1376static bool
1377DumpModuleSymbolVendor (Stream &strm, Module *module)
1378{
1379 if (module)
1380 {
1381 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1382 if (symbol_vendor)
1383 {
1384 symbol_vendor->Dump(&strm);
1385 return true;
1386 }
1387 }
1388 return false;
1389}
1390
Greg Clayton2ad894b2012-05-15 18:43:44 +00001391static void
1392DumpAddress (ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, Stream &strm)
1393{
1394 strm.IndentMore();
1395 strm.Indent (" Address: ");
1396 so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1397 strm.PutCString (" (");
1398 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1399 strm.PutCString (")\n");
1400 strm.Indent (" Summary: ");
1401 const uint32_t save_indent = strm.GetIndentLevel ();
1402 strm.SetIndentLevel (save_indent + 13);
1403 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1404 strm.SetIndentLevel (save_indent);
1405 // Print out detailed address information when verbose is enabled
1406 if (verbose)
1407 {
1408 strm.EOL();
1409 so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1410 }
1411 strm.IndentLess();
1412}
1413
Greg Claytone1f50b92011-05-03 22:09:39 +00001414static bool
Greg Clayton3508c382012-02-24 01:59:29 +00001415LookupAddressInModule (CommandInterpreter &interpreter,
1416 Stream &strm,
1417 Module *module,
1418 uint32_t resolve_mask,
1419 lldb::addr_t raw_addr,
1420 lldb::addr_t offset,
1421 bool verbose)
Greg Claytone1f50b92011-05-03 22:09:39 +00001422{
1423 if (module)
1424 {
1425 lldb::addr_t addr = raw_addr - offset;
1426 Address so_addr;
1427 SymbolContext sc;
Greg Clayton567e7f32011-09-22 04:58:26 +00001428 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
Greg Claytone1f50b92011-05-03 22:09:39 +00001429 if (target && !target->GetSectionLoadList().IsEmpty())
1430 {
1431 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
1432 return false;
Greg Clayton3508c382012-02-24 01:59:29 +00001433 else if (so_addr.GetModule().get() != module)
Greg Claytone1f50b92011-05-03 22:09:39 +00001434 return false;
1435 }
1436 else
1437 {
1438 if (!module->ResolveFileAddress (addr, so_addr))
1439 return false;
1440 }
1441
Greg Claytone1f50b92011-05-03 22:09:39 +00001442 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
Greg Clayton2ad894b2012-05-15 18:43:44 +00001443 DumpAddress (exe_scope, so_addr, verbose, strm);
1444// strm.IndentMore();
1445// strm.Indent (" Address: ");
1446// so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1447// strm.PutCString (" (");
1448// so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1449// strm.PutCString (")\n");
1450// strm.Indent (" Summary: ");
1451// const uint32_t save_indent = strm.GetIndentLevel ();
1452// strm.SetIndentLevel (save_indent + 13);
1453// so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1454// strm.SetIndentLevel (save_indent);
1455// // Print out detailed address information when verbose is enabled
1456// if (verbose)
1457// {
1458// strm.EOL();
1459// so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1460// }
1461// strm.IndentLess();
Greg Claytone1f50b92011-05-03 22:09:39 +00001462 return true;
1463 }
1464
1465 return false;
1466}
1467
1468static uint32_t
Greg Clayton2ad894b2012-05-15 18:43:44 +00001469LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
Greg Claytone1f50b92011-05-03 22:09:39 +00001470{
1471 if (module)
1472 {
1473 SymbolContext sc;
1474
1475 ObjectFile *objfile = module->GetObjectFile ();
1476 if (objfile)
1477 {
1478 Symtab *symtab = objfile->GetSymtab();
1479 if (symtab)
1480 {
1481 uint32_t i;
1482 std::vector<uint32_t> match_indexes;
1483 ConstString symbol_name (name);
1484 uint32_t num_matches = 0;
1485 if (name_is_regex)
1486 {
1487 RegularExpression name_regexp(name);
1488 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
1489 eSymbolTypeAny,
1490 match_indexes);
1491 }
1492 else
1493 {
1494 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
1495 }
1496
1497
1498 if (num_matches > 0)
1499 {
1500 strm.Indent ();
1501 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1502 name_is_regex ? "the regular expression " : "", name);
1503 DumpFullpath (strm, &module->GetFileSpec(), 0);
1504 strm.PutCString(":\n");
1505 strm.IndentMore ();
Greg Clayton2ad894b2012-05-15 18:43:44 +00001506 //Symtab::DumpSymbolHeader (&strm);
Greg Claytone1f50b92011-05-03 22:09:39 +00001507 for (i=0; i < num_matches; ++i)
1508 {
1509 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
Greg Clayton2ad894b2012-05-15 18:43:44 +00001510 DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1511 symbol->GetAddress(),
1512 verbose,
1513 strm);
1514
1515// strm.Indent ();
1516// symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i);
Greg Claytone1f50b92011-05-03 22:09:39 +00001517 }
1518 strm.IndentLess ();
1519 return num_matches;
1520 }
1521 }
1522 }
1523 }
1524 return 0;
1525}
1526
1527
1528static void
Greg Clayton2ad894b2012-05-15 18:43:44 +00001529DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose)
Greg Claytone1f50b92011-05-03 22:09:39 +00001530{
1531 strm.IndentMore ();
1532 uint32_t i;
1533 const uint32_t num_matches = sc_list.GetSize();
1534
1535 for (i=0; i<num_matches; ++i)
1536 {
1537 SymbolContext sc;
1538 if (sc_list.GetContextAtIndex(i, sc))
1539 {
Sean Callanand7793d22012-02-11 00:24:04 +00001540 AddressRange range;
1541
1542 sc.GetAddressRange(eSymbolContextEverything,
1543 0,
1544 true,
1545 range);
1546
Greg Clayton2ad894b2012-05-15 18:43:44 +00001547 DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm);
Greg Claytone1f50b92011-05-03 22:09:39 +00001548 }
1549 }
1550 strm.IndentLess ();
1551}
1552
1553static uint32_t
Greg Clayton2ad894b2012-05-15 18:43:44 +00001554LookupFunctionInModule (CommandInterpreter &interpreter,
1555 Stream &strm,
1556 Module *module,
1557 const char *name,
1558 bool name_is_regex,
1559 bool include_inlines,
1560 bool include_symbols,
1561 bool verbose)
Greg Claytone1f50b92011-05-03 22:09:39 +00001562{
1563 if (module && name && name[0])
1564 {
1565 SymbolContextList sc_list;
Greg Claytone1f50b92011-05-03 22:09:39 +00001566 const bool append = true;
1567 uint32_t num_matches = 0;
1568 if (name_is_regex)
1569 {
1570 RegularExpression function_name_regex (name);
1571 num_matches = module->FindFunctions (function_name_regex,
1572 include_symbols,
Sean Callanan302d78c2012-02-10 22:52:19 +00001573 include_inlines,
Greg Claytone1f50b92011-05-03 22:09:39 +00001574 append,
1575 sc_list);
1576 }
1577 else
1578 {
1579 ConstString function_name (name);
Sean Callanan3e80cd92011-10-12 02:08:07 +00001580 num_matches = module->FindFunctions (function_name,
1581 NULL,
Greg Claytone1f50b92011-05-03 22:09:39 +00001582 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
1583 include_symbols,
Sean Callanan302d78c2012-02-10 22:52:19 +00001584 include_inlines,
Greg Claytone1f50b92011-05-03 22:09:39 +00001585 append,
1586 sc_list);
1587 }
1588
1589 if (num_matches)
1590 {
1591 strm.Indent ();
1592 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1593 DumpFullpath (strm, &module->GetFileSpec(), 0);
1594 strm.PutCString(":\n");
Greg Clayton2ad894b2012-05-15 18:43:44 +00001595 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
Greg Claytone1f50b92011-05-03 22:09:39 +00001596 }
1597 return num_matches;
1598 }
1599 return 0;
1600}
1601
1602static uint32_t
Greg Clayton0cbaacd2012-05-15 19:26:12 +00001603LookupTypeInModule (CommandInterpreter &interpreter,
Greg Clayton801417e2011-07-07 01:59:51 +00001604 Stream &strm,
1605 Module *module,
1606 const char *name_cstr,
1607 bool name_is_regex)
Greg Claytone1f50b92011-05-03 22:09:39 +00001608{
1609 if (module && name_cstr && name_cstr[0])
1610 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001611 TypeList type_list;
Greg Claytondc0a38c2012-03-26 23:03:23 +00001612 const uint32_t max_num_matches = UINT32_MAX;
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001613 uint32_t num_matches = 0;
Greg Claytondc0a38c2012-03-26 23:03:23 +00001614 bool name_is_fully_qualified = false;
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001615 SymbolContext sc;
1616
1617 ConstString name(name_cstr);
Greg Claytondc0a38c2012-03-26 23:03:23 +00001618 num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list);
Greg Claytone1f50b92011-05-03 22:09:39 +00001619
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001620 if (num_matches)
1621 {
1622 strm.Indent ();
1623 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1624 DumpFullpath (strm, &module->GetFileSpec(), 0);
1625 strm.PutCString(":\n");
1626 const uint32_t num_types = type_list.GetSize();
1627 for (uint32_t i=0; i<num_types; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00001628 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001629 TypeSP type_sp (type_list.GetTypeAtIndex(i));
1630 if (type_sp)
Greg Claytone1f50b92011-05-03 22:09:39 +00001631 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001632 // Resolve the clang type so that any forward references
1633 // to types that haven't yet been parsed will get parsed.
1634 type_sp->GetClangFullType ();
1635 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
Greg Clayton0cbaacd2012-05-15 19:26:12 +00001636 // Print all typedef chains
1637 TypeSP typedef_type_sp (type_sp);
1638 TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
1639 while (typedefed_type_sp)
1640 {
1641 strm.EOL();
1642 strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString());
1643 typedefed_type_sp->GetClangFullType ();
1644 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1645 typedef_type_sp = typedefed_type_sp;
1646 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1647 }
Greg Claytone1f50b92011-05-03 22:09:39 +00001648 }
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001649 strm.EOL();
Greg Claytone1f50b92011-05-03 22:09:39 +00001650 }
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001651 }
1652 return num_matches;
Greg Claytone1f50b92011-05-03 22:09:39 +00001653 }
1654 return 0;
1655}
1656
1657static uint32_t
Sean Callanan56d31ec2012-06-06 20:49:55 +00001658LookupTypeHere (CommandInterpreter &interpreter,
1659 Stream &strm,
1660 const SymbolContext &sym_ctx,
1661 const char *name_cstr,
1662 bool name_is_regex)
1663{
1664 if (!sym_ctx.module_sp)
1665 return 0;
1666
1667 TypeList type_list;
1668 const uint32_t max_num_matches = UINT32_MAX;
1669 uint32_t num_matches = 1;
1670 bool name_is_fully_qualified = false;
1671
1672 ConstString name(name_cstr);
1673 num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list);
1674
1675 if (num_matches)
1676 {
1677 strm.Indent ();
1678 strm.PutCString("Best match found in ");
1679 DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0);
1680 strm.PutCString(":\n");
1681
1682 TypeSP type_sp (type_list.GetTypeAtIndex(0));
1683 if (type_sp)
1684 {
1685 // Resolve the clang type so that any forward references
1686 // to types that haven't yet been parsed will get parsed.
1687 type_sp->GetClangFullType ();
1688 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1689 // Print all typedef chains
1690 TypeSP typedef_type_sp (type_sp);
1691 TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
1692 while (typedefed_type_sp)
1693 {
1694 strm.EOL();
1695 strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString());
1696 typedefed_type_sp->GetClangFullType ();
1697 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1698 typedef_type_sp = typedefed_type_sp;
1699 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1700 }
1701 }
1702 strm.EOL();
1703 }
1704 return num_matches;
1705}
1706
1707static uint32_t
Greg Claytone1f50b92011-05-03 22:09:39 +00001708LookupFileAndLineInModule (CommandInterpreter &interpreter,
Sean Callanan56d31ec2012-06-06 20:49:55 +00001709 Stream &strm,
Greg Claytone1f50b92011-05-03 22:09:39 +00001710 Module *module,
1711 const FileSpec &file_spec,
1712 uint32_t line,
1713 bool check_inlines,
1714 bool verbose)
1715{
1716 if (module && file_spec)
1717 {
1718 SymbolContextList sc_list;
1719 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1720 eSymbolContextEverything, sc_list);
1721 if (num_matches > 0)
1722 {
1723 strm.Indent ();
1724 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1725 strm << file_spec;
1726 if (line > 0)
1727 strm.Printf (":%u", line);
1728 strm << " in ";
1729 DumpFullpath (strm, &module->GetFileSpec(), 0);
1730 strm.PutCString(":\n");
Greg Clayton2ad894b2012-05-15 18:43:44 +00001731 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
Greg Claytone1f50b92011-05-03 22:09:39 +00001732 return num_matches;
1733 }
1734 }
1735 return 0;
1736
1737}
1738
Greg Clayton91048ef2011-11-10 01:18:58 +00001739
1740static size_t
1741FindModulesByName (Target *target,
1742 const char *module_name,
1743 ModuleList &module_list,
1744 bool check_global_list)
1745{
1746// Dump specified images (by basename or fullpath)
1747 FileSpec module_file_spec(module_name, false);
Greg Clayton444fe992012-02-26 05:51:37 +00001748 ModuleSpec module_spec (module_file_spec);
Greg Clayton91048ef2011-11-10 01:18:58 +00001749
1750 const size_t initial_size = module_list.GetSize ();
1751
Greg Clayton316f57f2012-07-11 20:46:47 +00001752 if (check_global_list)
Greg Clayton91048ef2011-11-10 01:18:58 +00001753 {
1754 // Check the global list
Greg Claytonc149c8b2012-01-27 18:08:35 +00001755 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
Greg Clayton91048ef2011-11-10 01:18:58 +00001756 const uint32_t num_modules = Module::GetNumberAllocatedModules();
1757 ModuleSP module_sp;
1758 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1759 {
1760 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1761
1762 if (module)
1763 {
Greg Clayton444fe992012-02-26 05:51:37 +00001764 if (module->MatchesModuleSpec (module_spec))
Greg Clayton91048ef2011-11-10 01:18:58 +00001765 {
Greg Clayton13d24fb2012-01-29 20:56:30 +00001766 module_sp = module->shared_from_this();
Greg Clayton91048ef2011-11-10 01:18:58 +00001767 module_list.AppendIfNeeded(module_sp);
1768 }
1769 }
1770 }
1771 }
Greg Clayton316f57f2012-07-11 20:46:47 +00001772 else
1773 {
1774 if (target)
1775 {
1776 const size_t num_matches = target->GetImages().FindModules (module_spec, module_list);
1777
1778 // Not found in our module list for our target, check the main
1779 // shared module list in case it is a extra file used somewhere
1780 // else
1781 if (num_matches == 0)
1782 {
1783 module_spec.GetArchitecture() = target->GetArchitecture();
1784 ModuleList::FindSharedModules (module_spec, module_list);
1785 }
1786 }
1787 else
1788 {
1789 ModuleList::FindSharedModules (module_spec,module_list);
1790 }
1791 }
1792
Greg Clayton91048ef2011-11-10 01:18:58 +00001793 return module_list.GetSize () - initial_size;
1794}
1795
Greg Claytone1f50b92011-05-03 22:09:39 +00001796#pragma mark CommandObjectTargetModulesModuleAutoComplete
1797
1798//----------------------------------------------------------------------
1799// A base command object class that can auto complete with module file
1800// paths
1801//----------------------------------------------------------------------
1802
Jim Inghamda26bd22012-06-08 21:56:10 +00001803class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed
Greg Claytone1f50b92011-05-03 22:09:39 +00001804{
1805public:
1806
1807 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
1808 const char *name,
1809 const char *help,
1810 const char *syntax) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001811 CommandObjectParsed (interpreter, name, help, syntax)
Greg Claytone1f50b92011-05-03 22:09:39 +00001812 {
1813 CommandArgumentEntry arg;
1814 CommandArgumentData file_arg;
1815
1816 // Define the first (and only) variant of this arg.
1817 file_arg.arg_type = eArgTypeFilename;
1818 file_arg.arg_repetition = eArgRepeatStar;
1819
1820 // There is only one variant this argument could be; put it into the argument entry.
1821 arg.push_back (file_arg);
1822
1823 // Push the data for the first argument into the m_arguments vector.
1824 m_arguments.push_back (arg);
1825 }
1826
1827 virtual
1828 ~CommandObjectTargetModulesModuleAutoComplete ()
1829 {
1830 }
1831
1832 virtual int
1833 HandleArgumentCompletion (Args &input,
1834 int &cursor_index,
1835 int &cursor_char_position,
1836 OptionElementVector &opt_element_vector,
1837 int match_start_point,
1838 int max_return_elements,
1839 bool &word_complete,
1840 StringList &matches)
1841 {
1842 // Arguments are the standard module completer.
1843 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1844 completion_str.erase (cursor_char_position);
1845
1846 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1847 CommandCompletions::eModuleCompletion,
1848 completion_str.c_str(),
1849 match_start_point,
1850 max_return_elements,
1851 NULL,
1852 word_complete,
1853 matches);
1854 return matches.GetSize();
1855 }
1856};
1857
1858#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1859
1860//----------------------------------------------------------------------
1861// A base command object class that can auto complete with module source
1862// file paths
1863//----------------------------------------------------------------------
1864
Jim Inghamda26bd22012-06-08 21:56:10 +00001865class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed
Greg Claytone1f50b92011-05-03 22:09:39 +00001866{
1867public:
1868
1869 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
1870 const char *name,
1871 const char *help,
1872 const char *syntax) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001873 CommandObjectParsed (interpreter, name, help, syntax)
Greg Claytone1f50b92011-05-03 22:09:39 +00001874 {
1875 CommandArgumentEntry arg;
1876 CommandArgumentData source_file_arg;
1877
1878 // Define the first (and only) variant of this arg.
1879 source_file_arg.arg_type = eArgTypeSourceFile;
1880 source_file_arg.arg_repetition = eArgRepeatPlus;
1881
1882 // There is only one variant this argument could be; put it into the argument entry.
1883 arg.push_back (source_file_arg);
1884
1885 // Push the data for the first argument into the m_arguments vector.
1886 m_arguments.push_back (arg);
1887 }
1888
1889 virtual
1890 ~CommandObjectTargetModulesSourceFileAutoComplete ()
1891 {
1892 }
1893
1894 virtual int
1895 HandleArgumentCompletion (Args &input,
1896 int &cursor_index,
1897 int &cursor_char_position,
1898 OptionElementVector &opt_element_vector,
1899 int match_start_point,
1900 int max_return_elements,
1901 bool &word_complete,
1902 StringList &matches)
1903 {
1904 // Arguments are the standard source file completer.
1905 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1906 completion_str.erase (cursor_char_position);
1907
1908 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1909 CommandCompletions::eSourceFileCompletion,
1910 completion_str.c_str(),
1911 match_start_point,
1912 max_return_elements,
1913 NULL,
1914 word_complete,
1915 matches);
1916 return matches.GetSize();
1917 }
1918};
1919
1920
1921#pragma mark CommandObjectTargetModulesDumpSymtab
1922
1923
1924class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
1925{
1926public:
1927 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
1928 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1929 "target modules dump symtab",
1930 "Dump the symbol table from one or more target modules.",
1931 NULL),
1932 m_options (interpreter)
1933 {
1934 }
1935
1936 virtual
1937 ~CommandObjectTargetModulesDumpSymtab ()
1938 {
1939 }
1940
Jim Inghamda26bd22012-06-08 21:56:10 +00001941 virtual Options *
1942 GetOptions ()
1943 {
1944 return &m_options;
1945 }
1946
1947 class CommandOptions : public Options
1948 {
1949 public:
1950
1951 CommandOptions (CommandInterpreter &interpreter) :
1952 Options(interpreter),
1953 m_sort_order (eSortOrderNone)
1954 {
1955 }
1956
1957 virtual
1958 ~CommandOptions ()
1959 {
1960 }
1961
1962 virtual Error
1963 SetOptionValue (uint32_t option_idx, const char *option_arg)
1964 {
1965 Error error;
1966 char short_option = (char) m_getopt_table[option_idx].val;
1967
1968 switch (short_option)
1969 {
1970 case 's':
1971 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
1972 g_option_table[option_idx].enum_values,
1973 eSortOrderNone,
1974 error);
1975 break;
1976
1977 default:
1978 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1979 break;
1980
1981 }
1982 return error;
1983 }
1984
1985 void
1986 OptionParsingStarting ()
1987 {
1988 m_sort_order = eSortOrderNone;
1989 }
1990
1991 const OptionDefinition*
1992 GetDefinitions ()
1993 {
1994 return g_option_table;
1995 }
1996
1997 // Options table: Required for subclasses of Options.
1998 static OptionDefinition g_option_table[];
1999
2000 SortOrder m_sort_order;
2001 };
2002
2003protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002004 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002005 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00002006 CommandReturnObject &result)
2007 {
2008 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2009 if (target == NULL)
2010 {
2011 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2012 result.SetStatus (eReturnStatusFailed);
2013 return false;
2014 }
2015 else
2016 {
2017 uint32_t num_dumped = 0;
2018
2019 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2020 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2021 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2022
2023 if (command.GetArgumentCount() == 0)
2024 {
2025 // Dump all sections for all modules images
Jim Ingham93367902012-05-30 02:19:25 +00002026 Mutex::Locker modules_locker(target->GetImages().GetMutex());
Greg Claytone1f50b92011-05-03 22:09:39 +00002027 const uint32_t num_modules = target->GetImages().GetSize();
2028 if (num_modules > 0)
2029 {
2030 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
2031 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2032 {
2033 if (num_dumped > 0)
2034 {
2035 result.GetOutputStream().EOL();
2036 result.GetOutputStream().EOL();
2037 }
2038 num_dumped++;
Jim Ingham93367902012-05-30 02:19:25 +00002039 DumpModuleSymtab (m_interpreter,
2040 result.GetOutputStream(),
2041 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2042 m_options.m_sort_order);
Greg Claytone1f50b92011-05-03 22:09:39 +00002043 }
2044 }
2045 else
2046 {
2047 result.AppendError ("the target has no associated executable images");
2048 result.SetStatus (eReturnStatusFailed);
2049 return false;
2050 }
2051 }
2052 else
2053 {
2054 // Dump specified images (by basename or fullpath)
2055 const char *arg_cstr;
2056 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2057 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002058 ModuleList module_list;
2059 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2060 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00002061 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002062 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00002063 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002064 Module *module = module_list.GetModulePointerAtIndex(i);
2065 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00002066 {
2067 if (num_dumped > 0)
2068 {
2069 result.GetOutputStream().EOL();
2070 result.GetOutputStream().EOL();
2071 }
2072 num_dumped++;
Greg Clayton91048ef2011-11-10 01:18:58 +00002073 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
Greg Claytone1f50b92011-05-03 22:09:39 +00002074 }
2075 }
2076 }
2077 else
2078 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2079 }
2080 }
2081
2082 if (num_dumped > 0)
2083 result.SetStatus (eReturnStatusSuccessFinishResult);
2084 else
2085 {
2086 result.AppendError ("no matching executable images found");
2087 result.SetStatus (eReturnStatusFailed);
2088 }
2089 }
2090 return result.Succeeded();
2091 }
2092
Greg Claytone1f50b92011-05-03 22:09:39 +00002093
2094 CommandOptions m_options;
2095};
2096
2097static OptionEnumValueElement
2098g_sort_option_enumeration[4] =
2099{
2100 { eSortOrderNone, "none", "No sorting, use the original symbol table order."},
2101 { eSortOrderByAddress, "address", "Sort output by symbol address."},
2102 { eSortOrderByName, "name", "Sort output by symbol name."},
2103 { 0, NULL, NULL }
2104};
2105
2106
2107OptionDefinition
2108CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
2109{
2110 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
2111 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2112};
2113
2114#pragma mark CommandObjectTargetModulesDumpSections
2115
2116//----------------------------------------------------------------------
2117// Image section dumping command
2118//----------------------------------------------------------------------
2119
2120class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
2121{
2122public:
2123 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
2124 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2125 "target modules dump sections",
2126 "Dump the sections from one or more target modules.",
2127 //"target modules dump sections [<file1> ...]")
2128 NULL)
2129 {
2130 }
2131
2132 virtual
2133 ~CommandObjectTargetModulesDumpSections ()
2134 {
2135 }
2136
Jim Inghamda26bd22012-06-08 21:56:10 +00002137protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002138 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002139 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00002140 CommandReturnObject &result)
2141 {
2142 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2143 if (target == NULL)
2144 {
2145 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2146 result.SetStatus (eReturnStatusFailed);
2147 return false;
2148 }
2149 else
2150 {
2151 uint32_t num_dumped = 0;
2152
2153 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2154 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2155 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2156
2157 if (command.GetArgumentCount() == 0)
2158 {
2159 // Dump all sections for all modules images
2160 const uint32_t num_modules = target->GetImages().GetSize();
2161 if (num_modules > 0)
2162 {
2163 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
2164 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2165 {
2166 num_dumped++;
2167 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
2168 }
2169 }
2170 else
2171 {
2172 result.AppendError ("the target has no associated executable images");
2173 result.SetStatus (eReturnStatusFailed);
2174 return false;
2175 }
2176 }
2177 else
2178 {
2179 // Dump specified images (by basename or fullpath)
2180 const char *arg_cstr;
2181 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2182 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002183 ModuleList module_list;
2184 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2185 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00002186 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002187 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00002188 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002189 Module *module = module_list.GetModulePointerAtIndex(i);
2190 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00002191 {
2192 num_dumped++;
Greg Clayton91048ef2011-11-10 01:18:58 +00002193 DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
Greg Claytone1f50b92011-05-03 22:09:39 +00002194 }
2195 }
2196 }
2197 else
Greg Clayton91048ef2011-11-10 01:18:58 +00002198 {
2199 // Check the global list
Greg Claytonc149c8b2012-01-27 18:08:35 +00002200 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
Greg Clayton91048ef2011-11-10 01:18:58 +00002201
Greg Claytone1f50b92011-05-03 22:09:39 +00002202 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Clayton91048ef2011-11-10 01:18:58 +00002203 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002204 }
2205 }
2206
2207 if (num_dumped > 0)
2208 result.SetStatus (eReturnStatusSuccessFinishResult);
2209 else
2210 {
2211 result.AppendError ("no matching executable images found");
2212 result.SetStatus (eReturnStatusFailed);
2213 }
2214 }
2215 return result.Succeeded();
2216 }
2217};
2218
2219
2220#pragma mark CommandObjectTargetModulesDumpSymfile
2221
2222//----------------------------------------------------------------------
2223// Image debug symbol dumping command
2224//----------------------------------------------------------------------
2225
2226class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2227{
2228public:
2229 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2230 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2231 "target modules dump symfile",
2232 "Dump the debug symbol file for one or more target modules.",
2233 //"target modules dump symfile [<file1> ...]")
2234 NULL)
2235 {
2236 }
2237
2238 virtual
2239 ~CommandObjectTargetModulesDumpSymfile ()
2240 {
2241 }
2242
Jim Inghamda26bd22012-06-08 21:56:10 +00002243protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002244 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002245 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00002246 CommandReturnObject &result)
2247 {
2248 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2249 if (target == NULL)
2250 {
2251 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2252 result.SetStatus (eReturnStatusFailed);
2253 return false;
2254 }
2255 else
2256 {
2257 uint32_t num_dumped = 0;
2258
2259 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2260 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2261 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2262
2263 if (command.GetArgumentCount() == 0)
2264 {
2265 // Dump all sections for all modules images
Jim Ingham93367902012-05-30 02:19:25 +00002266 ModuleList &target_modules = target->GetImages();
2267 Mutex::Locker modules_locker (target_modules.GetMutex());
2268 const uint32_t num_modules = target_modules.GetSize();
Greg Claytone1f50b92011-05-03 22:09:39 +00002269 if (num_modules > 0)
2270 {
2271 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
2272 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2273 {
Jim Ingham93367902012-05-30 02:19:25 +00002274 if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
Greg Claytone1f50b92011-05-03 22:09:39 +00002275 num_dumped++;
2276 }
2277 }
2278 else
2279 {
2280 result.AppendError ("the target has no associated executable images");
2281 result.SetStatus (eReturnStatusFailed);
2282 return false;
2283 }
2284 }
2285 else
2286 {
2287 // Dump specified images (by basename or fullpath)
2288 const char *arg_cstr;
2289 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2290 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002291 ModuleList module_list;
2292 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2293 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00002294 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002295 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00002296 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002297 Module *module = module_list.GetModulePointerAtIndex(i);
2298 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00002299 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002300 if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
Greg Claytone1f50b92011-05-03 22:09:39 +00002301 num_dumped++;
2302 }
2303 }
2304 }
2305 else
2306 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2307 }
2308 }
2309
2310 if (num_dumped > 0)
2311 result.SetStatus (eReturnStatusSuccessFinishResult);
2312 else
2313 {
2314 result.AppendError ("no matching executable images found");
2315 result.SetStatus (eReturnStatusFailed);
2316 }
2317 }
2318 return result.Succeeded();
2319 }
2320};
2321
2322
2323#pragma mark CommandObjectTargetModulesDumpLineTable
2324
2325//----------------------------------------------------------------------
2326// Image debug line table dumping command
2327//----------------------------------------------------------------------
2328
2329class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2330{
2331public:
2332 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2333 CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
2334 "target modules dump line-table",
2335 "Dump the debug symbol file for one or more target modules.",
2336 NULL)
2337 {
2338 }
2339
2340 virtual
2341 ~CommandObjectTargetModulesDumpLineTable ()
2342 {
2343 }
2344
Jim Inghamda26bd22012-06-08 21:56:10 +00002345protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002346 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002347 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00002348 CommandReturnObject &result)
2349 {
2350 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2351 if (target == NULL)
2352 {
2353 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2354 result.SetStatus (eReturnStatusFailed);
2355 return false;
2356 }
2357 else
2358 {
2359 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
2360 uint32_t total_num_dumped = 0;
2361
2362 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2363 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2364 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2365
2366 if (command.GetArgumentCount() == 0)
2367 {
2368 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
2369 result.SetStatus (eReturnStatusFailed);
2370 }
2371 else
2372 {
2373 // Dump specified images (by basename or fullpath)
2374 const char *arg_cstr;
2375 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2376 {
2377 FileSpec file_spec(arg_cstr, false);
Jim Ingham93367902012-05-30 02:19:25 +00002378
2379 ModuleList &target_modules = target->GetImages();
2380 Mutex::Locker modules_locker(target_modules.GetMutex());
2381 const uint32_t num_modules = target_modules.GetSize();
Greg Claytone1f50b92011-05-03 22:09:39 +00002382 if (num_modules > 0)
2383 {
2384 uint32_t num_dumped = 0;
2385 for (uint32_t i = 0; i<num_modules; ++i)
2386 {
2387 if (DumpCompileUnitLineTable (m_interpreter,
2388 result.GetOutputStream(),
Jim Ingham93367902012-05-30 02:19:25 +00002389 target_modules.GetModulePointerAtIndexUnlocked(i),
Greg Claytone1f50b92011-05-03 22:09:39 +00002390 file_spec,
Greg Clayton567e7f32011-09-22 04:58:26 +00002391 exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive()))
Greg Claytone1f50b92011-05-03 22:09:39 +00002392 num_dumped++;
2393 }
2394 if (num_dumped == 0)
2395 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2396 else
2397 total_num_dumped += num_dumped;
2398 }
2399 }
2400 }
2401
2402 if (total_num_dumped > 0)
2403 result.SetStatus (eReturnStatusSuccessFinishResult);
2404 else
2405 {
2406 result.AppendError ("no source filenames matched any command arguments");
2407 result.SetStatus (eReturnStatusFailed);
2408 }
2409 }
2410 return result.Succeeded();
2411 }
2412};
2413
2414
2415#pragma mark CommandObjectTargetModulesDump
2416
2417//----------------------------------------------------------------------
2418// Dump multi-word command for target modules
2419//----------------------------------------------------------------------
2420
2421class CommandObjectTargetModulesDump : public CommandObjectMultiword
2422{
2423public:
2424
2425 //------------------------------------------------------------------
2426 // Constructors and Destructors
2427 //------------------------------------------------------------------
2428 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2429 CommandObjectMultiword (interpreter,
2430 "target modules dump",
2431 "A set of commands for dumping information about one or more target modules.",
2432 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2433 {
2434 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2435 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2436 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2437 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2438 }
2439
2440 virtual
2441 ~CommandObjectTargetModulesDump()
2442 {
2443 }
2444};
2445
Jim Inghamda26bd22012-06-08 21:56:10 +00002446class CommandObjectTargetModulesAdd : public CommandObjectParsed
Greg Claytone1f50b92011-05-03 22:09:39 +00002447{
2448public:
2449 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00002450 CommandObjectParsed (interpreter,
2451 "target modules add",
2452 "Add a new module to the current target's modules.",
2453 "target modules add [<module>]")
Greg Claytone1f50b92011-05-03 22:09:39 +00002454 {
2455 }
2456
2457 virtual
2458 ~CommandObjectTargetModulesAdd ()
2459 {
2460 }
2461
Jim Inghamda26bd22012-06-08 21:56:10 +00002462 int
2463 HandleArgumentCompletion (Args &input,
2464 int &cursor_index,
2465 int &cursor_char_position,
2466 OptionElementVector &opt_element_vector,
2467 int match_start_point,
2468 int max_return_elements,
2469 bool &word_complete,
2470 StringList &matches)
2471 {
2472 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2473 completion_str.erase (cursor_char_position);
2474
2475 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2476 CommandCompletions::eDiskFileCompletion,
2477 completion_str.c_str(),
2478 match_start_point,
2479 max_return_elements,
2480 NULL,
2481 word_complete,
2482 matches);
2483 return matches.GetSize();
2484 }
2485
2486protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002487 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002488 DoExecute (Args& args,
Greg Claytone1f50b92011-05-03 22:09:39 +00002489 CommandReturnObject &result)
2490 {
2491 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2492 if (target == NULL)
2493 {
2494 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2495 result.SetStatus (eReturnStatusFailed);
2496 return false;
2497 }
2498 else
2499 {
2500 const size_t argc = args.GetArgumentCount();
2501 if (argc == 0)
2502 {
2503 result.AppendError ("one or more executable image paths must be specified");
2504 result.SetStatus (eReturnStatusFailed);
2505 return false;
2506 }
2507 else
2508 {
2509 for (size_t i=0; i<argc; ++i)
2510 {
2511 const char *path = args.GetArgumentAtIndex(i);
2512 if (path)
2513 {
2514 FileSpec file_spec(path, true);
Greg Claytone1f50b92011-05-03 22:09:39 +00002515 if (file_spec.Exists())
2516 {
Greg Clayton444fe992012-02-26 05:51:37 +00002517 ModuleSpec module_spec (file_spec);
2518 ModuleSP module_sp (target->GetSharedModule (module_spec));
Greg Claytone1f50b92011-05-03 22:09:39 +00002519 if (!module_sp)
2520 {
2521 result.AppendError ("one or more executable image paths must be specified");
2522 result.SetStatus (eReturnStatusFailed);
2523 return false;
2524 }
Jason Molenda36f6fb92011-08-02 23:28:55 +00002525 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytone1f50b92011-05-03 22:09:39 +00002526 }
2527 else
2528 {
2529 char resolved_path[PATH_MAX];
2530 result.SetStatus (eReturnStatusFailed);
2531 if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2532 {
2533 if (strcmp (resolved_path, path) != 0)
2534 {
2535 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2536 break;
2537 }
2538 }
2539 result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2540 break;
2541 }
2542 }
2543 }
2544 }
2545 }
2546 return result.Succeeded();
2547 }
2548
Greg Claytone1f50b92011-05-03 22:09:39 +00002549};
2550
2551class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2552{
2553public:
2554 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2555 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2556 "target modules load",
2557 "Set the load addresses for one or more sections in a target module.",
2558 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2559 m_option_group (interpreter),
2560 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."),
2561 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset, "Set the load address for all sections to be the virtual address in the file plus the offset.", 0)
2562 {
2563 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2564 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2565 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2566 m_option_group.Finalize();
2567 }
2568
2569 virtual
2570 ~CommandObjectTargetModulesLoad ()
2571 {
2572 }
2573
Jim Inghamda26bd22012-06-08 21:56:10 +00002574 virtual Options *
2575 GetOptions ()
2576 {
2577 return &m_option_group;
2578 }
2579
2580protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002581 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002582 DoExecute (Args& args,
Greg Claytone1f50b92011-05-03 22:09:39 +00002583 CommandReturnObject &result)
2584 {
2585 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2586 if (target == NULL)
2587 {
2588 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2589 result.SetStatus (eReturnStatusFailed);
2590 return false;
2591 }
2592 else
2593 {
2594 const size_t argc = args.GetArgumentCount();
Greg Clayton444fe992012-02-26 05:51:37 +00002595 ModuleSpec module_spec;
2596 bool search_using_module_spec = false;
Greg Claytone1f50b92011-05-03 22:09:39 +00002597 if (m_file_option.GetOptionValue().OptionWasSet())
Greg Clayton444fe992012-02-26 05:51:37 +00002598 {
2599 search_using_module_spec = true;
2600 module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
2601 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002602
2603 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
Greg Clayton444fe992012-02-26 05:51:37 +00002604 {
2605 search_using_module_spec = true;
2606 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
2607 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002608
Greg Clayton444fe992012-02-26 05:51:37 +00002609 if (search_using_module_spec)
Greg Claytone1f50b92011-05-03 22:09:39 +00002610 {
2611
2612 ModuleList matching_modules;
Greg Clayton444fe992012-02-26 05:51:37 +00002613 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules);
Greg Claytone1f50b92011-05-03 22:09:39 +00002614
2615 char path[PATH_MAX];
2616 if (num_matches == 1)
2617 {
2618 Module *module = matching_modules.GetModulePointerAtIndex(0);
2619 if (module)
2620 {
2621 ObjectFile *objfile = module->GetObjectFile();
2622 if (objfile)
2623 {
2624 SectionList *section_list = objfile->GetSectionList();
2625 if (section_list)
2626 {
Greg Clayton9ab696e2012-03-27 21:10:07 +00002627 bool changed = false;
Greg Claytone1f50b92011-05-03 22:09:39 +00002628 if (argc == 0)
2629 {
2630 if (m_slide_option.GetOptionValue().OptionWasSet())
2631 {
Greg Clayton9ab696e2012-03-27 21:10:07 +00002632 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2633 module->SetLoadAddress (*target, slide, changed);
Greg Claytone1f50b92011-05-03 22:09:39 +00002634 }
2635 else
2636 {
2637 result.AppendError ("one or more section name + load address pair must be specified");
2638 result.SetStatus (eReturnStatusFailed);
2639 return false;
2640 }
2641 }
2642 else
2643 {
2644 if (m_slide_option.GetOptionValue().OptionWasSet())
2645 {
2646 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2647 result.SetStatus (eReturnStatusFailed);
2648 return false;
2649 }
2650
2651 for (size_t i=0; i<argc; i += 2)
2652 {
2653 const char *sect_name = args.GetArgumentAtIndex(i);
2654 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2655 if (sect_name && load_addr_cstr)
2656 {
2657 ConstString const_sect_name(sect_name);
2658 bool success = false;
2659 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2660 if (success)
2661 {
2662 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
2663 if (section_sp)
2664 {
Greg Clayton9ab696e2012-03-27 21:10:07 +00002665 if (section_sp->IsThreadSpecific())
2666 {
2667 result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name);
2668 result.SetStatus (eReturnStatusFailed);
2669 break;
2670 }
2671 else
2672 {
Greg Clayton545762f2012-07-07 01:24:12 +00002673 if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
Greg Clayton9ab696e2012-03-27 21:10:07 +00002674 changed = true;
2675 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr);
2676 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002677 }
2678 else
2679 {
2680 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
2681 result.SetStatus (eReturnStatusFailed);
2682 break;
2683 }
2684 }
2685 else
2686 {
2687 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
2688 result.SetStatus (eReturnStatusFailed);
2689 break;
2690 }
2691 }
2692 else
2693 {
2694 if (sect_name)
2695 result.AppendError ("section names must be followed by a load address.\n");
2696 else
2697 result.AppendError ("one or more section name + load address pair must be specified.\n");
2698 result.SetStatus (eReturnStatusFailed);
2699 break;
2700 }
2701 }
2702 }
Greg Clayton9ab696e2012-03-27 21:10:07 +00002703
2704 if (changed)
2705 target->ModulesDidLoad (matching_modules);
Greg Claytone1f50b92011-05-03 22:09:39 +00002706 }
2707 else
2708 {
2709 module->GetFileSpec().GetPath (path, sizeof(path));
2710 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
2711 result.SetStatus (eReturnStatusFailed);
2712 }
2713 }
2714 else
2715 {
2716 module->GetFileSpec().GetPath (path, sizeof(path));
2717 result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
2718 result.SetStatus (eReturnStatusFailed);
2719 }
2720 }
2721 else
2722 {
2723 module->GetFileSpec().GetPath (path, sizeof(path));
2724 result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
2725 result.SetStatus (eReturnStatusFailed);
2726 }
2727 }
2728 else
2729 {
2730 char uuid_cstr[64];
Greg Clayton444fe992012-02-26 05:51:37 +00002731
2732 if (module_spec.GetFileSpec())
2733 module_spec.GetFileSpec().GetPath (path, sizeof(path));
Greg Claytone1f50b92011-05-03 22:09:39 +00002734 else
2735 path[0] = '\0';
2736
Greg Clayton444fe992012-02-26 05:51:37 +00002737 if (module_spec.GetUUIDPtr())
2738 module_spec.GetUUID().GetAsCString(uuid_cstr, sizeof(uuid_cstr));
Greg Claytone1f50b92011-05-03 22:09:39 +00002739 else
2740 uuid_cstr[0] = '\0';
2741 if (num_matches > 1)
2742 {
2743 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
2744 path[0] ? " file=" : "",
2745 path,
2746 uuid_cstr[0] ? " uuid=" : "",
2747 uuid_cstr);
2748 for (size_t i=0; i<num_matches; ++i)
2749 {
2750 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
2751 result.AppendMessageWithFormat("%s\n", path);
2752 }
2753 }
2754 else
2755 {
2756 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n",
2757 path[0] ? " file=" : "",
2758 path,
2759 uuid_cstr[0] ? " uuid=" : "",
2760 uuid_cstr);
2761 }
2762 result.SetStatus (eReturnStatusFailed);
2763 }
2764 }
2765 else
2766 {
2767 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
2768 result.SetStatus (eReturnStatusFailed);
2769 return false;
2770 }
2771 }
2772 return result.Succeeded();
2773 }
2774
Greg Claytone1f50b92011-05-03 22:09:39 +00002775 OptionGroupOptions m_option_group;
2776 OptionGroupUUID m_uuid_option_group;
2777 OptionGroupFile m_file_option;
2778 OptionGroupUInt64 m_slide_option;
2779};
2780
2781//----------------------------------------------------------------------
2782// List images with associated information
2783//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +00002784class CommandObjectTargetModulesList : public CommandObjectParsed
Greg Claytone1f50b92011-05-03 22:09:39 +00002785{
2786public:
2787
2788 class CommandOptions : public Options
2789 {
2790 public:
2791
2792 CommandOptions (CommandInterpreter &interpreter) :
Greg Clayton899025f2011-08-09 00:01:09 +00002793 Options(interpreter),
Jim Ingham6bdea822011-10-24 18:36:33 +00002794 m_format_array(),
Daniel Dunbar97c89572011-10-31 22:50:49 +00002795 m_use_global_module_list (false),
Jim Ingham6bdea822011-10-24 18:36:33 +00002796 m_module_addr (LLDB_INVALID_ADDRESS)
Greg Claytone1f50b92011-05-03 22:09:39 +00002797 {
2798 }
2799
2800 virtual
2801 ~CommandOptions ()
2802 {
2803 }
2804
2805 virtual Error
2806 SetOptionValue (uint32_t option_idx, const char *option_arg)
2807 {
2808 char short_option = (char) m_getopt_table[option_idx].val;
Greg Clayton899025f2011-08-09 00:01:09 +00002809 if (short_option == 'g')
2810 {
2811 m_use_global_module_list = true;
2812 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002813 else if (short_option == 'a')
2814 {
2815 bool success;
2816 m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success);
2817 if (!success)
2818 {
2819 Error error;
Greg Clayton9c236732011-10-26 00:56:27 +00002820 error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg);
Jim Ingham6bdea822011-10-24 18:36:33 +00002821 }
2822 }
Greg Clayton899025f2011-08-09 00:01:09 +00002823 else
2824 {
2825 uint32_t width = 0;
2826 if (option_arg)
2827 width = strtoul (option_arg, NULL, 0);
2828 m_format_array.push_back(std::make_pair(short_option, width));
2829 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002830 Error error;
2831 return error;
2832 }
2833
2834 void
2835 OptionParsingStarting ()
2836 {
2837 m_format_array.clear();
Greg Clayton899025f2011-08-09 00:01:09 +00002838 m_use_global_module_list = false;
Jim Ingham6bdea822011-10-24 18:36:33 +00002839 m_module_addr = LLDB_INVALID_ADDRESS;
Greg Claytone1f50b92011-05-03 22:09:39 +00002840 }
2841
2842 const OptionDefinition*
2843 GetDefinitions ()
2844 {
2845 return g_option_table;
2846 }
2847
2848 // Options table: Required for subclasses of Options.
2849
2850 static OptionDefinition g_option_table[];
2851
2852 // Instance variables to hold the values for command options.
2853 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
2854 FormatWidthCollection m_format_array;
Greg Clayton899025f2011-08-09 00:01:09 +00002855 bool m_use_global_module_list;
Jim Ingham6bdea822011-10-24 18:36:33 +00002856 lldb::addr_t m_module_addr;
Greg Claytone1f50b92011-05-03 22:09:39 +00002857 };
2858
2859 CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00002860 CommandObjectParsed (interpreter,
2861 "target modules list",
2862 "List current executable and dependent shared library images.",
2863 "target modules list [<cmd-options>]"),
Greg Claytone1f50b92011-05-03 22:09:39 +00002864 m_options (interpreter)
2865 {
2866 }
2867
2868 virtual
2869 ~CommandObjectTargetModulesList ()
2870 {
2871 }
2872
2873 virtual
2874 Options *
2875 GetOptions ()
2876 {
2877 return &m_options;
2878 }
2879
Jim Inghamda26bd22012-06-08 21:56:10 +00002880protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002881 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002882 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00002883 CommandReturnObject &result)
2884 {
2885 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Clayton153ccd72011-08-10 02:10:13 +00002886 const bool use_global_module_list = m_options.m_use_global_module_list;
Greg Clayton11fb9212012-06-27 20:26:19 +00002887 // Define a local module list here to ensure it lives longer than any "locker"
2888 // object which might lock its contents below (through the "module_list_ptr"
2889 // variable).
2890 ModuleList module_list;
Greg Clayton153ccd72011-08-10 02:10:13 +00002891 if (target == NULL && use_global_module_list == false)
Greg Claytone1f50b92011-05-03 22:09:39 +00002892 {
2893 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2894 result.SetStatus (eReturnStatusFailed);
2895 return false;
2896 }
2897 else
2898 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002899 if (target)
2900 {
2901 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2902 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2903 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2904 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002905 // Dump all sections for all modules images
Jim Ingham6bdea822011-10-24 18:36:33 +00002906 Stream &strm = result.GetOutputStream();
2907
2908 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
2909 {
2910 if (target)
2911 {
2912 Address module_address;
2913 if (module_address.SetLoadAddress(m_options.m_module_addr, target))
2914 {
Greg Clayton3508c382012-02-24 01:59:29 +00002915 ModuleSP module_sp (module_address.GetModule());
2916 if (module_sp)
Jim Ingham6bdea822011-10-24 18:36:33 +00002917 {
Greg Clayton3508c382012-02-24 01:59:29 +00002918 PrintModule (target, module_sp.get(), UINT32_MAX, 0, strm);
Jim Ingham6bdea822011-10-24 18:36:33 +00002919 result.SetStatus (eReturnStatusSuccessFinishResult);
2920 }
2921 else
2922 {
2923 result.AppendError ("Couldn't find module matching address: 0x%llx.", m_options.m_module_addr);
2924 result.SetStatus (eReturnStatusFailed);
2925 }
2926 }
2927 else
2928 {
2929 result.AppendError ("Couldn't find module containing address: 0x%llx.", m_options.m_module_addr);
2930 result.SetStatus (eReturnStatusFailed);
2931 }
2932 }
2933 else
2934 {
2935 result.AppendError ("Can only look up modules by address with a valid target.");
2936 result.SetStatus (eReturnStatusFailed);
2937 }
2938 return result.Succeeded();
2939 }
2940
Jim Ingham93367902012-05-30 02:19:25 +00002941 uint32_t num_modules = 0;
2942 Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL.
2943 // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
2944 // the global module list directly.
Greg Clayton2ad894b2012-05-15 18:43:44 +00002945 ModuleList *module_list_ptr = NULL;
2946 const size_t argc = command.GetArgumentCount();
2947 if (argc == 0)
Greg Clayton899025f2011-08-09 00:01:09 +00002948 {
Greg Clayton2ad894b2012-05-15 18:43:44 +00002949 if (use_global_module_list)
2950 {
2951 locker.Lock (Module::GetAllocationModuleCollectionMutex());
2952 num_modules = Module::GetNumberAllocatedModules();
2953 }
2954 else
2955 {
2956 module_list_ptr = &target->GetImages();
Greg Clayton2ad894b2012-05-15 18:43:44 +00002957 }
Greg Clayton899025f2011-08-09 00:01:09 +00002958 }
2959 else
Greg Clayton2ad894b2012-05-15 18:43:44 +00002960 {
2961 for (size_t i=0; i<argc; ++i)
2962 {
2963 // Dump specified images (by basename or fullpath)
2964 const char *arg_cstr = command.GetArgumentAtIndex(i);
2965 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
2966 if (num_matches == 0)
2967 {
2968 if (argc == 1)
2969 {
2970 result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr);
2971 result.SetStatus (eReturnStatusFailed);
2972 return false;
2973 }
2974 }
2975 }
2976
Greg Clayton2ad894b2012-05-15 18:43:44 +00002977 module_list_ptr = &module_list;
2978 }
Jim Ingham93367902012-05-30 02:19:25 +00002979
2980 if (module_list_ptr != NULL)
2981 {
2982 locker.Lock(module_list_ptr->GetMutex());
2983 num_modules = module_list_ptr->GetSize();
2984 }
Greg Clayton899025f2011-08-09 00:01:09 +00002985
Greg Claytone1f50b92011-05-03 22:09:39 +00002986 if (num_modules > 0)
Jim Ingham6bdea822011-10-24 18:36:33 +00002987 {
Greg Claytone1f50b92011-05-03 22:09:39 +00002988 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2989 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002990 ModuleSP module_sp;
Greg Clayton899025f2011-08-09 00:01:09 +00002991 Module *module;
Greg Clayton2ad894b2012-05-15 18:43:44 +00002992 if (module_list_ptr)
Greg Clayton899025f2011-08-09 00:01:09 +00002993 {
Jim Ingham93367902012-05-30 02:19:25 +00002994 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
Greg Clayton2ad894b2012-05-15 18:43:44 +00002995 module = module_sp.get();
Greg Clayton899025f2011-08-09 00:01:09 +00002996 }
2997 else
2998 {
Greg Clayton2ad894b2012-05-15 18:43:44 +00002999 module = Module::GetAllocatedModuleAtIndex(image_idx);
3000 module_sp = module->shared_from_this();
Greg Clayton899025f2011-08-09 00:01:09 +00003001 }
Jim Ingham6bdea822011-10-24 18:36:33 +00003002
Greg Claytonb5a8f142012-02-05 02:38:54 +00003003 int indent = strm.Printf("[%3u] ", image_idx);
3004 PrintModule (target, module, image_idx, indent, strm);
Greg Clayton153ccd72011-08-10 02:10:13 +00003005
Greg Claytone1f50b92011-05-03 22:09:39 +00003006 }
3007 result.SetStatus (eReturnStatusSuccessFinishResult);
3008 }
3009 else
3010 {
Greg Clayton2ad894b2012-05-15 18:43:44 +00003011 if (argc)
3012 {
3013 if (use_global_module_list)
3014 result.AppendError ("the global module list has no matching modules");
3015 else
3016 result.AppendError ("the target has no matching modules");
3017 }
Greg Clayton153ccd72011-08-10 02:10:13 +00003018 else
Greg Clayton2ad894b2012-05-15 18:43:44 +00003019 {
3020 if (use_global_module_list)
3021 result.AppendError ("the global module list is empty");
3022 else
3023 result.AppendError ("the target has no associated executable images");
3024 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003025 result.SetStatus (eReturnStatusFailed);
3026 return false;
3027 }
3028 }
3029 return result.Succeeded();
3030 }
Jim Ingham6bdea822011-10-24 18:36:33 +00003031
3032 void
Greg Claytonb5a8f142012-02-05 02:38:54 +00003033 PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm)
Jim Ingham6bdea822011-10-24 18:36:33 +00003034 {
3035
3036 bool dump_object_name = false;
3037 if (m_options.m_format_array.empty())
3038 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003039 m_options.m_format_array.push_back(std::make_pair('u', 0));
3040 m_options.m_format_array.push_back(std::make_pair('h', 0));
3041 m_options.m_format_array.push_back(std::make_pair('f', 0));
3042 m_options.m_format_array.push_back(std::make_pair('S', 0));
Jim Ingham6bdea822011-10-24 18:36:33 +00003043 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00003044 const size_t num_entries = m_options.m_format_array.size();
3045 bool print_space = false;
3046 for (size_t i=0; i<num_entries; ++i)
Jim Ingham6bdea822011-10-24 18:36:33 +00003047 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003048 if (print_space)
3049 strm.PutChar(' ');
3050 print_space = true;
3051 const char format_char = m_options.m_format_array[i].first;
3052 uint32_t width = m_options.m_format_array[i].second;
3053 switch (format_char)
Jim Ingham6bdea822011-10-24 18:36:33 +00003054 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003055 case 'A':
3056 DumpModuleArchitecture (strm, module, false, width);
3057 break;
3058
3059 case 't':
3060 DumpModuleArchitecture (strm, module, true, width);
3061 break;
3062
3063 case 'f':
3064 DumpFullpath (strm, &module->GetFileSpec(), width);
3065 dump_object_name = true;
3066 break;
3067
3068 case 'd':
3069 DumpDirectory (strm, &module->GetFileSpec(), width);
3070 break;
3071
3072 case 'b':
3073 DumpBasename (strm, &module->GetFileSpec(), width);
3074 dump_object_name = true;
3075 break;
3076
3077 case 'h':
3078 case 'o':
3079 // Image header address
3080 {
3081 uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
Jim Ingham6bdea822011-10-24 18:36:33 +00003082
Greg Claytonb5a8f142012-02-05 02:38:54 +00003083 ObjectFile *objfile = module->GetObjectFile ();
3084 if (objfile)
Jim Ingham6bdea822011-10-24 18:36:33 +00003085 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003086 Address header_addr(objfile->GetHeaderAddress());
3087 if (header_addr.IsValid())
Jim Ingham6bdea822011-10-24 18:36:33 +00003088 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003089 if (target && !target->GetSectionLoadList().IsEmpty())
Jim Ingham6bdea822011-10-24 18:36:33 +00003090 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003091 lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
3092 if (header_load_addr == LLDB_INVALID_ADDRESS)
3093 {
3094 header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
3095 }
Jim Ingham6bdea822011-10-24 18:36:33 +00003096 else
Greg Claytonb5a8f142012-02-05 02:38:54 +00003097 {
3098 if (format_char == 'o')
3099 {
3100 // Show the offset of slide for the image
3101 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
3102 }
3103 else
3104 {
3105 // Show the load address of the image
3106 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr);
3107 }
3108 }
Jim Ingham6bdea822011-10-24 18:36:33 +00003109 break;
3110 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00003111 // The address was valid, but the image isn't loaded, output the address in an appropriate format
3112 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
3113 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003114 }
Jim Ingham6bdea822011-10-24 18:36:33 +00003115 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00003116 strm.Printf ("%*s", addr_nibble_width + 2, "");
3117 }
3118 break;
3119 case 'r':
3120 {
3121 uint32_t ref_count = 0;
3122 ModuleSP module_sp (module->shared_from_this());
3123 if (module_sp)
3124 {
3125 // Take one away to make sure we don't count our local "module_sp"
3126 ref_count = module_sp.use_count() - 1;
3127 }
3128 if (width)
3129 strm.Printf("{%*u}", width, ref_count);
3130 else
3131 strm.Printf("{%u}", ref_count);
3132 }
3133 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003134
Greg Claytonb5a8f142012-02-05 02:38:54 +00003135 case 's':
3136 case 'S':
3137 {
3138 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3139 if (symbol_vendor)
3140 {
3141 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
3142 if (symbol_file)
3143 {
3144 if (format_char == 'S')
3145 {
3146 FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec();
3147 // Dump symbol file only if different from module file
3148 if (!symfile_spec || symfile_spec == module->GetFileSpec())
3149 {
3150 print_space = false;
3151 break;
3152 }
3153 // Add a newline and indent past the index
3154 strm.Printf ("\n%*s", indent, "");
3155 }
3156 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
3157 dump_object_name = true;
3158 break;
3159 }
3160 }
3161 strm.Printf("%.*s", width, "<NONE>");
3162 }
3163 break;
3164
3165 case 'm':
3166 module->GetModificationTime().Dump(&strm, width);
3167 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003168
Greg Claytonb5a8f142012-02-05 02:38:54 +00003169 case 'p':
3170 strm.Printf("%p", module);
3171 break;
3172
3173 case 'u':
3174 DumpModuleUUID(strm, module);
3175 break;
3176
3177 default:
3178 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003179 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00003180
3181 }
3182 if (dump_object_name)
3183 {
3184 const char *object_name = module->GetObjectName().GetCString();
3185 if (object_name)
3186 strm.Printf ("(%s)", object_name);
Jim Ingham6bdea822011-10-24 18:36:33 +00003187 }
3188 strm.EOL();
3189 }
3190
Greg Claytone1f50b92011-05-03 22:09:39 +00003191 CommandOptions m_options;
3192};
3193
3194OptionDefinition
3195CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
3196{
Jim Ingham6bdea822011-10-24 18:36:33 +00003197 { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."},
3198 { LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003199 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."},
Greg Claytonb5a8f142012-02-05 02:38:54 +00003200 { LLDB_OPT_SET_1, false, "header", 'h', no_argument, NULL, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."},
3201 { LLDB_OPT_SET_1, false, "offset", 'o', no_argument, NULL, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003202 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
3203 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
3204 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
3205 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
3206 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
Greg Claytonb5a8f142012-02-05 02:38:54 +00003207 { LLDB_OPT_SET_1, false, "symfile-unique", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."},
Greg Clayton153ccd72011-08-10 02:10:13 +00003208 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."},
3209 { LLDB_OPT_SET_1, false, "ref-count", 'r', optional_argument, NULL, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache."},
3210 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."},
Greg Clayton899025f2011-08-09 00:01:09 +00003211 { LLDB_OPT_SET_1, false, "global", 'g', no_argument, NULL, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003212 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3213};
3214
Jason Molenda5b0afcc2012-07-12 00:20:07 +00003215#pragma mark CommandObjectTargetModulesShowUnwind
Greg Claytone1f50b92011-05-03 22:09:39 +00003216
Jason Molenda5b0afcc2012-07-12 00:20:07 +00003217//----------------------------------------------------------------------
3218// Lookup unwind information in images
3219//----------------------------------------------------------------------
3220
3221class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
3222{
3223public:
3224
3225 enum
3226 {
3227 eLookupTypeInvalid = -1,
3228 eLookupTypeAddress = 0,
3229 eLookupTypeSymbol,
3230 eLookupTypeFunction,
3231 eLookupTypeFunctionOrSymbol,
3232 kNumLookupTypes
3233 };
3234
3235 class CommandOptions : public Options
3236 {
3237 public:
3238
3239 CommandOptions (CommandInterpreter &interpreter) :
3240 Options(interpreter),
3241 m_type(eLookupTypeInvalid),
3242 m_str(),
3243 m_addr(LLDB_INVALID_ADDRESS)
3244 {
3245 }
3246
3247 virtual
3248 ~CommandOptions ()
3249 {
3250 }
3251
3252 virtual Error
3253 SetOptionValue (uint32_t option_idx, const char *option_arg)
3254 {
3255 Error error;
3256
3257 char short_option = (char) m_getopt_table[option_idx].val;
3258
3259 switch (short_option)
3260 {
3261 case 'a':
3262 m_type = eLookupTypeAddress;
3263 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3264 if (m_addr == LLDB_INVALID_ADDRESS)
3265 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
3266 break;
3267
3268 case 'n':
3269 m_str = option_arg;
3270 m_type = eLookupTypeFunctionOrSymbol;
3271 break;
3272 }
3273
3274 return error;
3275 }
3276
3277 void
3278 OptionParsingStarting ()
3279 {
3280 m_type = eLookupTypeInvalid;
3281 m_str.clear();
3282 m_addr = LLDB_INVALID_ADDRESS;
3283 }
3284
3285 const OptionDefinition*
3286 GetDefinitions ()
3287 {
3288 return g_option_table;
3289 }
3290
3291 // Options table: Required for subclasses of Options.
3292
3293 static OptionDefinition g_option_table[];
3294
3295 // Instance variables to hold the values for command options.
3296
3297 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3298 std::string m_str; // Holds name lookup
3299 lldb::addr_t m_addr; // Holds the address to lookup
3300 };
3301
3302 CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
3303 CommandObjectParsed (interpreter,
3304 "target modules show-unwind",
3305 "Show synthesized unwind instructions for a function.",
3306 NULL),
3307 m_options (interpreter)
3308 {
3309 }
3310
3311 virtual
3312 ~CommandObjectTargetModulesShowUnwind ()
3313 {
3314 }
3315
3316 virtual
3317 Options *
3318 GetOptions ()
3319 {
3320 return &m_options;
3321 }
3322
3323protected:
3324 bool
3325 DoExecute (Args& command,
3326 CommandReturnObject &result)
3327 {
3328 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3329 if (!target)
3330 {
3331 result.AppendError ("invalid target, create a debug target using the 'target create' command");
3332 result.SetStatus (eReturnStatusFailed);
3333 return false;
3334 }
3335
3336 ExecutionContext exe_ctx = m_interpreter.GetDebugger().GetSelectedExecutionContext();
3337 Process *process = exe_ctx.GetProcessPtr();
3338 ABI *abi = NULL;
3339 if (process)
3340 abi = process->GetABI().get();
3341
3342 if (process == NULL)
3343 {
3344 result.AppendError ("You must have a process running to use this command.");
3345 result.SetStatus (eReturnStatusFailed);
3346 return false;
3347 }
3348
3349 ThreadList threads(process->GetThreadList());
3350 if (threads.GetSize() == 0)
3351 {
3352 result.AppendError ("The process must be paused to use this command.");
3353 result.SetStatus (eReturnStatusFailed);
3354 return false;
3355 }
3356
3357 ThreadSP thread(threads.GetThreadAtIndex(0));
3358 if (thread.get() == NULL)
3359 {
3360 result.AppendError ("The process must be paused to use this command.");
3361 result.SetStatus (eReturnStatusFailed);
3362 return false;
3363 }
3364
3365 if (m_options.m_type == eLookupTypeFunctionOrSymbol)
3366 {
3367 SymbolContextList sc_list;
3368 uint32_t num_matches;
3369 ConstString function_name (m_options.m_str.c_str());
3370 num_matches = target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
3371 for (uint32_t idx = 0; idx < num_matches; idx++)
3372 {
3373 SymbolContext sc;
3374 sc_list.GetContextAtIndex(idx, sc);
3375 if (sc.symbol == NULL && sc.function == NULL)
3376 continue;
3377 if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL)
3378 continue;
3379 AddressRange range;
3380 if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
3381 continue;
3382 if (!range.GetBaseAddress().IsValid())
3383 continue;
3384 ConstString funcname(sc.GetFunctionName());
3385 if (funcname.IsEmpty())
3386 continue;
3387 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3388 if (abi)
3389 start_addr = abi->FixCodeAddress(start_addr);
3390
3391 FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3392 if (func_unwinders_sp.get() == NULL)
3393 continue;
3394
3395 Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target));
3396 if (first_non_prologue_insn.IsValid())
3397 {
3398 result.GetOutputStream().Printf("First non-prologue instruction is at address 0x%llx or offset %lld into the function.\n", first_non_prologue_insn.GetLoadAddress(target), first_non_prologue_insn.GetLoadAddress(target) - start_addr);
3399 result.GetOutputStream().Printf ("\n");
3400 }
3401
3402 UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*thread.get());
3403 if (non_callsite_unwind_plan.get())
3404 {
3405 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3406 non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3407 result.GetOutputStream().Printf ("\n");
3408 }
3409
3410 UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(-1);
3411 if (callsite_unwind_plan.get())
3412 {
3413 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3414 callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3415 result.GetOutputStream().Printf ("\n");
3416 }
3417
3418 UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get());
3419 if (arch_default_unwind_plan.get())
3420 {
3421 result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3422 arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3423 result.GetOutputStream().Printf ("\n");
3424 }
3425
3426 UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
3427 if (fast_unwind_plan.get())
3428 {
3429 result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3430 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3431 result.GetOutputStream().Printf ("\n");
3432 }
3433
3434
3435 result.GetOutputStream().Printf ("\n");
3436 }
3437 }
3438 return result.Succeeded();
3439 }
3440
3441 CommandOptions m_options;
3442};
3443
3444OptionDefinition
3445CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
3446{
3447 { LLDB_OPT_SET_1, true, "name", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function or symbol by name in one or more target modules."},
3448 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3449};
Greg Claytone1f50b92011-05-03 22:09:39 +00003450
3451//----------------------------------------------------------------------
3452// Lookup information in images
3453//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +00003454class CommandObjectTargetModulesLookup : public CommandObjectParsed
Greg Claytone1f50b92011-05-03 22:09:39 +00003455{
3456public:
3457
3458 enum
3459 {
3460 eLookupTypeInvalid = -1,
3461 eLookupTypeAddress = 0,
3462 eLookupTypeSymbol,
3463 eLookupTypeFileLine, // Line is optional
3464 eLookupTypeFunction,
Greg Clayton2ad894b2012-05-15 18:43:44 +00003465 eLookupTypeFunctionOrSymbol,
Greg Claytone1f50b92011-05-03 22:09:39 +00003466 eLookupTypeType,
3467 kNumLookupTypes
3468 };
3469
3470 class CommandOptions : public Options
3471 {
3472 public:
3473
3474 CommandOptions (CommandInterpreter &interpreter) :
3475 Options(interpreter)
3476 {
3477 OptionParsingStarting();
3478 }
3479
3480 virtual
3481 ~CommandOptions ()
3482 {
3483 }
3484
3485 virtual Error
3486 SetOptionValue (uint32_t option_idx, const char *option_arg)
3487 {
3488 Error error;
3489
3490 char short_option = (char) m_getopt_table[option_idx].val;
3491
3492 switch (short_option)
3493 {
3494 case 'a':
3495 m_type = eLookupTypeAddress;
3496 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3497 if (m_addr == LLDB_INVALID_ADDRESS)
Greg Clayton9c236732011-10-26 00:56:27 +00003498 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003499 break;
3500
3501 case 'o':
3502 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3503 if (m_offset == LLDB_INVALID_ADDRESS)
Greg Clayton9c236732011-10-26 00:56:27 +00003504 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003505 break;
3506
3507 case 's':
3508 m_str = option_arg;
3509 m_type = eLookupTypeSymbol;
3510 break;
3511
3512 case 'f':
3513 m_file.SetFile (option_arg, false);
3514 m_type = eLookupTypeFileLine;
3515 break;
3516
3517 case 'i':
Sean Callanan9ad19532012-02-11 01:22:21 +00003518 m_include_inlines = false;
Greg Claytone1f50b92011-05-03 22:09:39 +00003519 break;
3520
3521 case 'l':
3522 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
3523 if (m_line_number == UINT32_MAX)
Greg Clayton9c236732011-10-26 00:56:27 +00003524 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003525 else if (m_line_number == 0)
Greg Clayton9c236732011-10-26 00:56:27 +00003526 error.SetErrorString ("zero is an invalid line number");
Greg Claytone1f50b92011-05-03 22:09:39 +00003527 m_type = eLookupTypeFileLine;
3528 break;
3529
Greg Clayton2ad894b2012-05-15 18:43:44 +00003530 case 'F':
Greg Claytone1f50b92011-05-03 22:09:39 +00003531 m_str = option_arg;
3532 m_type = eLookupTypeFunction;
3533 break;
Greg Clayton2ad894b2012-05-15 18:43:44 +00003534
3535 case 'n':
3536 m_str = option_arg;
3537 m_type = eLookupTypeFunctionOrSymbol;
3538 break;
3539
Greg Claytone1f50b92011-05-03 22:09:39 +00003540 case 't':
3541 m_str = option_arg;
3542 m_type = eLookupTypeType;
3543 break;
3544
3545 case 'v':
3546 m_verbose = 1;
3547 break;
Sean Callanan56d31ec2012-06-06 20:49:55 +00003548
3549 case 'A':
3550 m_print_all = true;
3551 break;
Greg Claytone1f50b92011-05-03 22:09:39 +00003552
3553 case 'r':
3554 m_use_regex = true;
3555 break;
3556 }
3557
3558 return error;
3559 }
3560
3561 void
3562 OptionParsingStarting ()
3563 {
3564 m_type = eLookupTypeInvalid;
3565 m_str.clear();
3566 m_file.Clear();
3567 m_addr = LLDB_INVALID_ADDRESS;
3568 m_offset = 0;
3569 m_line_number = 0;
3570 m_use_regex = false;
Sean Callanan9ad19532012-02-11 01:22:21 +00003571 m_include_inlines = true;
Greg Claytone1f50b92011-05-03 22:09:39 +00003572 m_verbose = false;
Sean Callanan56d31ec2012-06-06 20:49:55 +00003573 m_print_all = false;
Greg Claytone1f50b92011-05-03 22:09:39 +00003574 }
3575
3576 const OptionDefinition*
3577 GetDefinitions ()
3578 {
3579 return g_option_table;
3580 }
3581
3582 // Options table: Required for subclasses of Options.
3583
3584 static OptionDefinition g_option_table[];
3585 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3586 std::string m_str; // Holds name lookup
3587 FileSpec m_file; // Files for file lookups
3588 lldb::addr_t m_addr; // Holds the address to lookup
3589 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
3590 uint32_t m_line_number; // Line number for file+line lookups
3591 bool m_use_regex; // Name lookups in m_str are regular expressions.
Sean Callanan9ad19532012-02-11 01:22:21 +00003592 bool m_include_inlines;// Check for inline entries when looking up by file/line.
Greg Claytone1f50b92011-05-03 22:09:39 +00003593 bool m_verbose; // Enable verbose lookup info
Sean Callanan56d31ec2012-06-06 20:49:55 +00003594 bool m_print_all; // Print all matches, even in cases where there's a best match.
Greg Claytone1f50b92011-05-03 22:09:39 +00003595
3596 };
3597
3598 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00003599 CommandObjectParsed (interpreter,
3600 "target modules lookup",
3601 "Look up information within executable and dependent shared library images.",
3602 NULL),
3603 m_options (interpreter)
Greg Claytone1f50b92011-05-03 22:09:39 +00003604 {
3605 CommandArgumentEntry arg;
3606 CommandArgumentData file_arg;
3607
3608 // Define the first (and only) variant of this arg.
3609 file_arg.arg_type = eArgTypeFilename;
3610 file_arg.arg_repetition = eArgRepeatStar;
3611
3612 // There is only one variant this argument could be; put it into the argument entry.
3613 arg.push_back (file_arg);
3614
3615 // Push the data for the first argument into the m_arguments vector.
3616 m_arguments.push_back (arg);
3617 }
3618
3619 virtual
3620 ~CommandObjectTargetModulesLookup ()
3621 {
3622 }
3623
3624 virtual Options *
3625 GetOptions ()
3626 {
3627 return &m_options;
3628 }
3629
Sean Callanan56d31ec2012-06-06 20:49:55 +00003630 bool
3631 LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
3632 {
3633 switch (m_options.m_type)
3634 {
3635 case eLookupTypeAddress:
3636 case eLookupTypeFileLine:
3637 case eLookupTypeFunction:
3638 case eLookupTypeFunctionOrSymbol:
3639 case eLookupTypeSymbol:
3640 default:
3641 return false;
3642 case eLookupTypeType:
3643 break;
3644 }
3645
3646 ExecutionContext exe_ctx = interpreter.GetDebugger().GetSelectedExecutionContext();
3647
3648 StackFrameSP frame = exe_ctx.GetFrameSP();
3649
3650 if (!frame)
3651 return false;
3652
3653 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3654
3655 if (!sym_ctx.module_sp)
3656 return false;
3657
3658 switch (m_options.m_type)
3659 {
3660 default:
3661 return false;
3662 case eLookupTypeType:
3663 if (!m_options.m_str.empty())
3664 {
3665 if (LookupTypeHere (m_interpreter,
3666 result.GetOutputStream(),
3667 sym_ctx,
3668 m_options.m_str.c_str(),
3669 m_options.m_use_regex))
3670 {
3671 result.SetStatus(eReturnStatusSuccessFinishResult);
3672 return true;
3673 }
3674 }
3675 break;
3676 }
3677
3678 return true;
3679 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003680
3681 bool
3682 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
3683 {
3684 switch (m_options.m_type)
3685 {
3686 case eLookupTypeAddress:
3687 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
3688 {
3689 if (LookupAddressInModule (m_interpreter,
3690 result.GetOutputStream(),
3691 module,
3692 eSymbolContextEverything,
3693 m_options.m_addr,
3694 m_options.m_offset,
3695 m_options.m_verbose))
3696 {
3697 result.SetStatus(eReturnStatusSuccessFinishResult);
3698 return true;
3699 }
3700 }
3701 break;
3702
3703 case eLookupTypeSymbol:
3704 if (!m_options.m_str.empty())
3705 {
Greg Clayton2ad894b2012-05-15 18:43:44 +00003706 if (LookupSymbolInModule (m_interpreter,
3707 result.GetOutputStream(),
3708 module,
3709 m_options.m_str.c_str(),
3710 m_options.m_use_regex,
3711 m_options.m_verbose))
Greg Claytone1f50b92011-05-03 22:09:39 +00003712 {
3713 result.SetStatus(eReturnStatusSuccessFinishResult);
3714 return true;
3715 }
3716 }
3717 break;
3718
3719 case eLookupTypeFileLine:
3720 if (m_options.m_file)
3721 {
3722
3723 if (LookupFileAndLineInModule (m_interpreter,
3724 result.GetOutputStream(),
3725 module,
3726 m_options.m_file,
3727 m_options.m_line_number,
Sean Callanan9ad19532012-02-11 01:22:21 +00003728 m_options.m_include_inlines,
Greg Claytone1f50b92011-05-03 22:09:39 +00003729 m_options.m_verbose))
3730 {
3731 result.SetStatus(eReturnStatusSuccessFinishResult);
3732 return true;
3733 }
3734 }
3735 break;
Greg Clayton2ad894b2012-05-15 18:43:44 +00003736
3737 case eLookupTypeFunctionOrSymbol:
Greg Claytone1f50b92011-05-03 22:09:39 +00003738 case eLookupTypeFunction:
3739 if (!m_options.m_str.empty())
3740 {
3741 if (LookupFunctionInModule (m_interpreter,
3742 result.GetOutputStream(),
3743 module,
3744 m_options.m_str.c_str(),
3745 m_options.m_use_regex,
Sean Callanan9ad19532012-02-11 01:22:21 +00003746 m_options.m_include_inlines,
Greg Clayton2ad894b2012-05-15 18:43:44 +00003747 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
Greg Claytone1f50b92011-05-03 22:09:39 +00003748 m_options.m_verbose))
3749 {
3750 result.SetStatus(eReturnStatusSuccessFinishResult);
3751 return true;
3752 }
3753 }
3754 break;
3755
Greg Clayton2ad894b2012-05-15 18:43:44 +00003756
Greg Claytone1f50b92011-05-03 22:09:39 +00003757 case eLookupTypeType:
3758 if (!m_options.m_str.empty())
3759 {
3760 if (LookupTypeInModule (m_interpreter,
3761 result.GetOutputStream(),
3762 module,
3763 m_options.m_str.c_str(),
3764 m_options.m_use_regex))
3765 {
3766 result.SetStatus(eReturnStatusSuccessFinishResult);
3767 return true;
3768 }
3769 }
3770 break;
3771
3772 default:
3773 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
3774 syntax_error = true;
3775 break;
3776 }
3777
3778 result.SetStatus (eReturnStatusFailed);
3779 return false;
3780 }
3781
Jim Inghamda26bd22012-06-08 21:56:10 +00003782protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00003783 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00003784 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00003785 CommandReturnObject &result)
3786 {
3787 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3788 if (target == NULL)
3789 {
3790 result.AppendError ("invalid target, create a debug target using the 'target create' command");
3791 result.SetStatus (eReturnStatusFailed);
3792 return false;
3793 }
3794 else
3795 {
3796 bool syntax_error = false;
3797 uint32_t i;
3798 uint32_t num_successful_lookups = 0;
3799 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3800 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3801 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3802 // Dump all sections for all modules images
3803
3804 if (command.GetArgumentCount() == 0)
3805 {
Sean Callanan56d31ec2012-06-06 20:49:55 +00003806 ModuleSP current_module;
3807
3808 // Where it is possible to look in the current symbol context
3809 // first, try that. If this search was successful and --all
3810 // was not passed, don't print anything else.
3811 if (LookupHere (m_interpreter, result, syntax_error))
3812 {
3813 result.GetOutputStream().EOL();
3814 num_successful_lookups++;
3815 if (!m_options.m_print_all)
3816 {
3817 result.SetStatus (eReturnStatusSuccessFinishResult);
3818 return result.Succeeded();
3819 }
3820 }
3821
3822 // Dump all sections for all other modules
3823
Jim Ingham93367902012-05-30 02:19:25 +00003824 ModuleList &target_modules = target->GetImages();
3825 Mutex::Locker modules_locker(target_modules.GetMutex());
3826 const uint32_t num_modules = target_modules.GetSize();
Greg Claytone1f50b92011-05-03 22:09:39 +00003827 if (num_modules > 0)
3828 {
3829 for (i = 0; i<num_modules && syntax_error == false; ++i)
3830 {
Sean Callanan56d31ec2012-06-06 20:49:55 +00003831 Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
3832
3833 if (module_pointer != current_module.get() &&
3834 LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
Greg Claytone1f50b92011-05-03 22:09:39 +00003835 {
3836 result.GetOutputStream().EOL();
3837 num_successful_lookups++;
3838 }
3839 }
3840 }
3841 else
3842 {
3843 result.AppendError ("the target has no associated executable images");
3844 result.SetStatus (eReturnStatusFailed);
3845 return false;
3846 }
3847 }
3848 else
3849 {
3850 // Dump specified images (by basename or fullpath)
3851 const char *arg_cstr;
3852 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
3853 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003854 ModuleList module_list;
3855 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
3856 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00003857 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003858 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00003859 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003860 Module *module = module_list.GetModulePointerAtIndex(i);
3861 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00003862 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003863 if (LookupInModule (m_interpreter, module, result, syntax_error))
Greg Claytone1f50b92011-05-03 22:09:39 +00003864 {
3865 result.GetOutputStream().EOL();
3866 num_successful_lookups++;
3867 }
3868 }
3869 }
3870 }
3871 else
3872 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
3873 }
3874 }
3875
3876 if (num_successful_lookups > 0)
3877 result.SetStatus (eReturnStatusSuccessFinishResult);
3878 else
3879 result.SetStatus (eReturnStatusFailed);
3880 }
3881 return result.Succeeded();
3882 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003883
3884 CommandOptions m_options;
3885};
3886
3887OptionDefinition
3888CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
3889{
Sean Callanan3bfaad62012-09-13 21:11:40 +00003890 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."},
3891 { 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."},
Greg Clayton2ad894b2012-05-15 18:43:44 +00003892 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
3893 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
Sean Callanan3bfaad62012-09-13 21:11:40 +00003894 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
3895 { 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 target modules."},
3896 { LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules."},
3897 { 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)."},
Jim Inghamf081dab2012-06-04 22:47:34 +00003898 { LLDB_OPT_SET_FROM_TO(3,5),
Sean Callanan3bfaad62012-09-13 21:11:40 +00003899 false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."},
3900 { LLDB_OPT_SET_4, true, "function", 'F', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."},
3901 { LLDB_OPT_SET_5, true, "name", 'n', required_argument, NULL, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules."},
3902 { LLDB_OPT_SET_6, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."},
3903 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
3904 { LLDB_OPT_SET_ALL, false, "all", 'A', no_argument, NULL, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available."},
3905 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Greg Claytone1f50b92011-05-03 22:09:39 +00003906};
Chris Lattner24943d22010-06-08 16:52:24 +00003907
3908
Jim Inghamd60d94a2011-03-11 03:53:59 +00003909#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner24943d22010-06-08 16:52:24 +00003910
3911//-------------------------------------------------------------------------
3912// CommandObjectMultiwordImageSearchPaths
3913//-------------------------------------------------------------------------
3914
Greg Claytone1f50b92011-05-03 22:09:39 +00003915class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
Chris Lattner24943d22010-06-08 16:52:24 +00003916{
3917public:
Greg Claytone1f50b92011-05-03 22:09:39 +00003918
3919 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
3920 CommandObjectMultiword (interpreter,
3921 "target modules search-paths",
3922 "A set of commands for operating on debugger target image search paths.",
3923 "target modules search-paths <subcommand> [<subcommand-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00003924 {
Greg Claytone1f50b92011-05-03 22:09:39 +00003925 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
3926 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
3927 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
3928 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
3929 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00003930 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003931
3932 ~CommandObjectTargetModulesImageSearchPaths()
Chris Lattner24943d22010-06-08 16:52:24 +00003933 {
3934 }
3935};
3936
Greg Claytone1f50b92011-05-03 22:09:39 +00003937
3938
3939#pragma mark CommandObjectTargetModules
3940
3941//-------------------------------------------------------------------------
3942// CommandObjectTargetModules
3943//-------------------------------------------------------------------------
3944
3945class CommandObjectTargetModules : public CommandObjectMultiword
3946{
3947public:
3948 //------------------------------------------------------------------
3949 // Constructors and Destructors
3950 //------------------------------------------------------------------
3951 CommandObjectTargetModules(CommandInterpreter &interpreter) :
3952 CommandObjectMultiword (interpreter,
3953 "target modules",
3954 "A set of commands for accessing information for one or more target modules.",
3955 "target modules <sub-command> ...")
3956 {
3957 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
3958 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
3959 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter)));
3960 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
3961 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
3962 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
3963 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
Jason Molenda5b0afcc2012-07-12 00:20:07 +00003964 LoadSubCommand ("show-unwind", CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter)));
Greg Claytone1f50b92011-05-03 22:09:39 +00003965
3966 }
3967 virtual
3968 ~CommandObjectTargetModules()
3969 {
3970 }
3971
3972private:
3973 //------------------------------------------------------------------
3974 // For CommandObjectTargetModules only
3975 //------------------------------------------------------------------
3976 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
3977};
3978
3979
Greg Clayton3508c382012-02-24 01:59:29 +00003980
Jim Inghamda26bd22012-06-08 21:56:10 +00003981class CommandObjectTargetSymbolsAdd : public CommandObjectParsed
Greg Clayton3508c382012-02-24 01:59:29 +00003982{
3983public:
3984 CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00003985 CommandObjectParsed (interpreter,
3986 "target symbols add",
Greg Clayton437b5bc2012-09-27 22:26:11 +00003987 "Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for.",
3988 "target symbols add [<symfile>]"),
3989 m_option_group (interpreter),
3990 m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
3991 m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
3992
Greg Clayton3508c382012-02-24 01:59:29 +00003993 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00003994 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3995 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3996 m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
3997 m_option_group.Finalize();
Greg Clayton3508c382012-02-24 01:59:29 +00003998 }
3999
4000 virtual
4001 ~CommandObjectTargetSymbolsAdd ()
4002 {
4003 }
4004
Jim Inghamda26bd22012-06-08 21:56:10 +00004005 int
4006 HandleArgumentCompletion (Args &input,
4007 int &cursor_index,
4008 int &cursor_char_position,
4009 OptionElementVector &opt_element_vector,
4010 int match_start_point,
4011 int max_return_elements,
4012 bool &word_complete,
4013 StringList &matches)
4014 {
4015 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
4016 completion_str.erase (cursor_char_position);
4017
4018 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
4019 CommandCompletions::eDiskFileCompletion,
4020 completion_str.c_str(),
4021 match_start_point,
4022 max_return_elements,
4023 NULL,
4024 word_complete,
4025 matches);
4026 return matches.GetSize();
4027 }
4028
Greg Clayton437b5bc2012-09-27 22:26:11 +00004029 virtual Options *
4030 GetOptions ()
4031 {
4032 return &m_option_group;
4033 }
4034
4035
Jim Inghamda26bd22012-06-08 21:56:10 +00004036protected:
Greg Clayton437b5bc2012-09-27 22:26:11 +00004037
4038 bool
4039 AddModuleSymbols (Target *target,
4040 const FileSpec &symfile_spec,
4041 bool &flush,
4042 CommandReturnObject &result)
4043 {
4044 ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture()));
4045 const UUID &symfile_uuid = symfile_module_sp->GetUUID();
4046 StreamString ss_symfile_uuid;
4047 symfile_uuid.Dump(&ss_symfile_uuid);
4048
4049 if (symfile_module_sp)
4050 {
4051 char symfile_path[PATH_MAX];
4052 symfile_spec.GetPath (symfile_path, sizeof(symfile_path));
4053 // We now have a module that represents a symbol file
4054 // that can be used for a module that might exist in the
4055 // current target, so we need to find that module in the
4056 // target
4057
4058 ModuleSP old_module_sp (target->GetImages().FindModule (symfile_uuid));
4059 if (old_module_sp)
4060 {
4061 // The module has not yet created its symbol vendor, we can just
4062 // give the existing target module the symfile path to use for
4063 // when it decides to create it!
4064 old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec());
4065
4066 // Provide feedback that the symfile has been successfully added.
4067 const FileSpec &module_fs = old_module_sp->GetFileSpec();
4068 result.AppendMessageWithFormat("symbol file '%s' with UUID %s has been successfully added to the '%s/%s' module\n",
4069 symfile_path, ss_symfile_uuid.GetData(),
4070 module_fs.GetDirectory().AsCString(), module_fs.GetFilename().AsCString());
4071
4072 // Let clients know something changed in the module
4073 // if it is currently loaded
4074 ModuleList module_list;
4075 module_list.Append (old_module_sp);
4076 target->ModulesDidLoad (module_list);
4077 flush = true;
4078 }
4079 else
4080 {
4081 result.AppendErrorWithFormat ("symbol file '%s' with UUID %s does not match any existing module%s\n",
4082 symfile_path, ss_symfile_uuid.GetData(),
4083 (symfile_spec.GetFileType() != FileSpec::eFileTypeRegular)
4084 ? "\n please specify the full path to the symbol file"
4085 : "");
4086 return false;
4087 }
4088 }
4089 else
4090 {
4091 result.AppendError ("one or more executable image paths must be specified");
4092 result.SetStatus (eReturnStatusFailed);
4093 return false;
4094 }
4095 result.SetStatus (eReturnStatusSuccessFinishResult);
4096 return true;
4097 }
4098
Greg Clayton3508c382012-02-24 01:59:29 +00004099 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00004100 DoExecute (Args& args,
Greg Clayton3508c382012-02-24 01:59:29 +00004101 CommandReturnObject &result)
4102 {
Greg Claytoncf5927e2012-05-18 02:38:05 +00004103 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
4104 Target *target = exe_ctx.GetTargetPtr();
Greg Clayton437b5bc2012-09-27 22:26:11 +00004105 result.SetStatus (eReturnStatusFailed);
Greg Clayton3508c382012-02-24 01:59:29 +00004106 if (target == NULL)
4107 {
4108 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Greg Clayton3508c382012-02-24 01:59:29 +00004109 }
4110 else
4111 {
Greg Claytoncf5927e2012-05-18 02:38:05 +00004112 bool flush = false;
Greg Clayton437b5bc2012-09-27 22:26:11 +00004113 ModuleSpec sym_spec;
4114 const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
4115 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4116 const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
4117
Greg Clayton3508c382012-02-24 01:59:29 +00004118 const size_t argc = args.GetArgumentCount();
4119 if (argc == 0)
4120 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004121 if (uuid_option_set || file_option_set || frame_option_set)
Greg Clayton3508c382012-02-24 01:59:29 +00004122 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004123 bool success = false;
4124 bool error_set = false;
4125 if (frame_option_set)
Greg Clayton3508c382012-02-24 01:59:29 +00004126 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004127 Process *process = exe_ctx.GetProcessPtr();
4128 if (process)
Greg Clayton3508c382012-02-24 01:59:29 +00004129 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004130 const StateType process_state = process->GetState();
4131 if (StateIsStoppedState (process_state, true))
Greg Clayton3508c382012-02-24 01:59:29 +00004132 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004133 StackFrame *frame = exe_ctx.GetFramePtr();
4134 if (frame)
Greg Clayton3508c382012-02-24 01:59:29 +00004135 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004136 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
4137 if (frame_module_sp)
4138 {
4139 if (frame_module_sp->GetPlatformFileSpec().Exists())
4140 {
4141 sym_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4142 sym_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4143 }
4144 sym_spec.GetUUID() = frame_module_sp->GetUUID();
4145 success = sym_spec.GetUUID().IsValid() || sym_spec.GetFileSpec();
4146 }
4147 else
4148 {
4149 result.AppendError ("frame has no module");
4150 error_set = true;
4151 }
Greg Clayton3508c382012-02-24 01:59:29 +00004152 }
Johnny Chen9262cd52012-08-22 00:18:43 +00004153 else
4154 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004155 result.AppendError ("invalid current frame");
4156 error_set = true;
Johnny Chen9262cd52012-08-22 00:18:43 +00004157 }
Greg Clayton3508c382012-02-24 01:59:29 +00004158 }
4159 else
4160 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004161 result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
4162 error_set = true;
Greg Clayton3508c382012-02-24 01:59:29 +00004163 }
Greg Clayton3508c382012-02-24 01:59:29 +00004164 }
4165 else
4166 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004167 result.AppendError ("a process must exist in order to use the --frame option");
4168 error_set = true;
4169 }
4170 }
4171 else
4172 {
4173 if (uuid_option_set)
4174 {
4175 sym_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
4176 success |= sym_spec.GetUUID().IsValid();
4177 }
4178 else if (file_option_set)
4179 {
4180 sym_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
4181 ModuleSP module_sp (target->GetImages().FindFirstModule(sym_spec));
4182 if (module_sp)
Greg Clayton3508c382012-02-24 01:59:29 +00004183 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004184 sym_spec.GetFileSpec() = module_sp->GetFileSpec();
4185 sym_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4186 sym_spec.GetUUID() = module_sp->GetUUID();
4187 sym_spec.GetArchitecture() = module_sp->GetArchitecture();
Greg Clayton3508c382012-02-24 01:59:29 +00004188 }
Greg Clayton437b5bc2012-09-27 22:26:11 +00004189 else
4190 {
4191 sym_spec.GetArchitecture() = target->GetArchitecture();
4192 }
4193 success |= sym_spec.GetFileSpec().Exists();
4194 }
4195 }
4196
4197 if (success)
4198 {
4199 if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
4200 {
4201 if (sym_spec.GetSymbolFileSpec())
4202 success = AddModuleSymbols (target, sym_spec.GetSymbolFileSpec(), flush, result);
4203 }
4204 }
4205
4206 if (!success && !error_set)
4207 {
4208 StreamString error_strm;
4209 if (uuid_option_set)
4210 {
4211 error_strm.PutCString("unable to find debug symbols for UUID ");
4212 sym_spec.GetUUID().Dump (&error_strm);
4213 }
4214 else if (file_option_set)
4215 {
4216 error_strm.PutCString("unable to find debug symbols for the executable file ");
4217 error_strm << sym_spec.GetFileSpec();
4218 }
4219 else if (frame_option_set)
4220 {
4221 error_strm.PutCString("unable to find debug symbols for the current frame");
4222 }
4223 result.AppendError (error_strm.GetData());
4224 }
4225 }
4226 else
4227 {
4228 result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
4229 }
4230 }
4231 else
4232 {
4233 if (uuid_option_set)
4234 {
4235 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
4236 }
4237 else if (file_option_set)
4238 {
4239 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
4240 }
4241 else if (frame_option_set)
4242 {
4243 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
4244 }
4245 else
4246 {
4247 PlatformSP platform_sp (target->GetPlatform());
4248
4249 for (size_t i=0; i<argc; ++i)
4250 {
4251 const char *symfile_path = args.GetArgumentAtIndex(i);
4252 if (symfile_path)
4253 {
4254 FileSpec symfile_spec;
4255 sym_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
4256 if (platform_sp)
4257 platform_sp->ResolveSymbolFile(*target, sym_spec, symfile_spec);
4258 else
4259 symfile_spec.SetFile(symfile_path, true);
4260
4261 ArchSpec arch;
4262 bool symfile_exists = symfile_spec.Exists();
4263
4264 if (symfile_exists)
4265 {
4266 if (!AddModuleSymbols (target, symfile_spec, flush, result))
4267 break;
4268 }
4269 else
4270 {
4271 char resolved_symfile_path[PATH_MAX];
4272 if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
4273 {
4274 if (strcmp (resolved_symfile_path, symfile_path) != 0)
4275 {
4276 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
4277 break;
4278 }
4279 }
4280 result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
4281 break;
4282 }
Greg Clayton3508c382012-02-24 01:59:29 +00004283 }
4284 }
4285 }
4286 }
Greg Claytoncf5927e2012-05-18 02:38:05 +00004287
4288 if (flush)
4289 {
4290 Process *process = exe_ctx.GetProcessPtr();
4291 if (process)
4292 process->Flush();
4293 }
Greg Clayton3508c382012-02-24 01:59:29 +00004294 }
4295 return result.Succeeded();
4296 }
4297
Greg Clayton437b5bc2012-09-27 22:26:11 +00004298 OptionGroupOptions m_option_group;
4299 OptionGroupUUID m_uuid_option_group;
4300 OptionGroupFile m_file_option;
4301 OptionGroupBoolean m_current_frame_option;
4302
4303
Greg Clayton3508c382012-02-24 01:59:29 +00004304};
4305
4306
4307#pragma mark CommandObjectTargetSymbols
4308
4309//-------------------------------------------------------------------------
4310// CommandObjectTargetSymbols
4311//-------------------------------------------------------------------------
4312
4313class CommandObjectTargetSymbols : public CommandObjectMultiword
4314{
4315public:
4316 //------------------------------------------------------------------
4317 // Constructors and Destructors
4318 //------------------------------------------------------------------
4319 CommandObjectTargetSymbols(CommandInterpreter &interpreter) :
4320 CommandObjectMultiword (interpreter,
4321 "target symbols",
4322 "A set of commands for adding and managing debug symbol files.",
4323 "target symbols <sub-command> ...")
4324 {
4325 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
4326
4327 }
4328 virtual
4329 ~CommandObjectTargetSymbols()
4330 {
4331 }
4332
4333private:
4334 //------------------------------------------------------------------
4335 // For CommandObjectTargetModules only
4336 //------------------------------------------------------------------
4337 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
4338};
4339
4340
Jim Inghamd60d94a2011-03-11 03:53:59 +00004341#pragma mark CommandObjectTargetStopHookAdd
4342
4343//-------------------------------------------------------------------------
4344// CommandObjectTargetStopHookAdd
4345//-------------------------------------------------------------------------
4346
Jim Inghamda26bd22012-06-08 21:56:10 +00004347class CommandObjectTargetStopHookAdd : public CommandObjectParsed
Jim Inghamd60d94a2011-03-11 03:53:59 +00004348{
4349public:
4350
4351 class CommandOptions : public Options
4352 {
4353 public:
Greg Claytonf15996e2011-04-07 22:46:35 +00004354 CommandOptions (CommandInterpreter &interpreter) :
4355 Options(interpreter),
Jim Inghamd60d94a2011-03-11 03:53:59 +00004356 m_line_start(0),
4357 m_line_end (UINT_MAX),
4358 m_func_name_type_mask (eFunctionNameTypeAuto),
4359 m_sym_ctx_specified (false),
Johnny Chen60fe60e2011-05-02 23:47:55 +00004360 m_thread_specified (false),
4361 m_use_one_liner (false),
4362 m_one_liner()
Jim Inghamd60d94a2011-03-11 03:53:59 +00004363 {
4364 }
4365
4366 ~CommandOptions () {}
4367
Greg Claytonb3448432011-03-24 21:19:54 +00004368 const OptionDefinition*
Jim Inghamd60d94a2011-03-11 03:53:59 +00004369 GetDefinitions ()
4370 {
4371 return g_option_table;
4372 }
4373
4374 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +00004375 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004376 {
4377 Error error;
4378 char short_option = (char) m_getopt_table[option_idx].val;
4379 bool success;
4380
4381 switch (short_option)
4382 {
4383 case 'c':
4384 m_class_name = option_arg;
4385 m_sym_ctx_specified = true;
4386 break;
4387
4388 case 'e':
4389 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
4390 if (!success)
4391 {
Greg Clayton9c236732011-10-26 00:56:27 +00004392 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004393 break;
4394 }
4395 m_sym_ctx_specified = true;
4396 break;
4397
4398 case 'l':
4399 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
4400 if (!success)
4401 {
Greg Clayton9c236732011-10-26 00:56:27 +00004402 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004403 break;
4404 }
4405 m_sym_ctx_specified = true;
4406 break;
Sean Callanan9ad19532012-02-11 01:22:21 +00004407
4408 case 'i':
4409 m_no_inlines = true;
4410 break;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004411
4412 case 'n':
4413 m_function_name = option_arg;
4414 m_func_name_type_mask |= eFunctionNameTypeAuto;
4415 m_sym_ctx_specified = true;
4416 break;
4417
4418 case 'f':
4419 m_file_name = option_arg;
4420 m_sym_ctx_specified = true;
4421 break;
4422 case 's':
4423 m_module_name = option_arg;
4424 m_sym_ctx_specified = true;
4425 break;
4426 case 't' :
4427 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00004428 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004429 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Greg Clayton9c236732011-10-26 00:56:27 +00004430 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004431 m_thread_specified = true;
4432 }
4433 break;
4434 case 'T':
4435 m_thread_name = option_arg;
4436 m_thread_specified = true;
4437 break;
4438 case 'q':
4439 m_queue_name = option_arg;
4440 m_thread_specified = true;
4441 break;
4442 case 'x':
4443 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00004444 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004445 if (m_thread_id == UINT32_MAX)
Greg Clayton9c236732011-10-26 00:56:27 +00004446 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004447 m_thread_specified = true;
4448 }
4449 break;
Johnny Chen60fe60e2011-05-02 23:47:55 +00004450 case 'o':
4451 m_use_one_liner = true;
4452 m_one_liner = option_arg;
4453 break;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004454 default:
Greg Clayton9c236732011-10-26 00:56:27 +00004455 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004456 break;
4457 }
4458 return error;
4459 }
4460
4461 void
Greg Clayton143fcc32011-04-13 00:18:08 +00004462 OptionParsingStarting ()
Jim Inghamd60d94a2011-03-11 03:53:59 +00004463 {
4464 m_class_name.clear();
4465 m_function_name.clear();
4466 m_line_start = 0;
4467 m_line_end = UINT_MAX;
4468 m_file_name.clear();
4469 m_module_name.clear();
4470 m_func_name_type_mask = eFunctionNameTypeAuto;
4471 m_thread_id = LLDB_INVALID_THREAD_ID;
4472 m_thread_index = UINT32_MAX;
4473 m_thread_name.clear();
4474 m_queue_name.clear();
Sean Callanan9ad19532012-02-11 01:22:21 +00004475
4476 m_no_inlines = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004477 m_sym_ctx_specified = false;
4478 m_thread_specified = false;
Johnny Chen60fe60e2011-05-02 23:47:55 +00004479
4480 m_use_one_liner = false;
4481 m_one_liner.clear();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004482 }
4483
4484
Greg Claytonb3448432011-03-24 21:19:54 +00004485 static OptionDefinition g_option_table[];
Jim Inghamd60d94a2011-03-11 03:53:59 +00004486
4487 std::string m_class_name;
4488 std::string m_function_name;
4489 uint32_t m_line_start;
4490 uint32_t m_line_end;
4491 std::string m_file_name;
4492 std::string m_module_name;
4493 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4494 lldb::tid_t m_thread_id;
4495 uint32_t m_thread_index;
4496 std::string m_thread_name;
4497 std::string m_queue_name;
4498 bool m_sym_ctx_specified;
Sean Callanan9ad19532012-02-11 01:22:21 +00004499 bool m_no_inlines;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004500 bool m_thread_specified;
Johnny Chen60fe60e2011-05-02 23:47:55 +00004501 // Instance variables to hold the values for one_liner options.
4502 bool m_use_one_liner;
4503 std::string m_one_liner;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004504 };
4505
4506 Options *
4507 GetOptions ()
4508 {
4509 return &m_options;
4510 }
4511
4512 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00004513 CommandObjectParsed (interpreter,
4514 "target stop-hook add ",
4515 "Add a hook to be executed when the target stops.",
4516 "target stop-hook add"),
Greg Claytonf15996e2011-04-07 22:46:35 +00004517 m_options (interpreter)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004518 {
4519 }
4520
4521 ~CommandObjectTargetStopHookAdd ()
4522 {
4523 }
4524
4525 static size_t
4526 ReadCommandsCallbackFunction (void *baton,
4527 InputReader &reader,
4528 lldb::InputReaderAction notification,
4529 const char *bytes,
4530 size_t bytes_len)
4531 {
Caroline Tice892fadd2011-06-16 16:27:19 +00004532 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004533 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
Jim Inghame15511a2011-05-05 01:03:36 +00004534 static bool got_interrupted;
Caroline Tice892fadd2011-06-16 16:27:19 +00004535 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004536
4537 switch (notification)
4538 {
4539 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00004540 if (!batch_mode)
4541 {
4542 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
4543 if (reader.GetPrompt())
4544 out_stream->Printf ("%s", reader.GetPrompt());
4545 out_stream->Flush();
4546 }
Jim Inghame15511a2011-05-05 01:03:36 +00004547 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004548 break;
4549
4550 case eInputReaderDeactivate:
4551 break;
4552
4553 case eInputReaderReactivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00004554 if (reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004555 {
Caroline Tice892fadd2011-06-16 16:27:19 +00004556 out_stream->Printf ("%s", reader.GetPrompt());
4557 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004558 }
Jim Inghame15511a2011-05-05 01:03:36 +00004559 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004560 break;
4561
Caroline Tice4a348082011-05-02 20:41:46 +00004562 case eInputReaderAsynchronousOutputWritten:
4563 break;
4564
Jim Inghamd60d94a2011-03-11 03:53:59 +00004565 case eInputReaderGotToken:
4566 if (bytes && bytes_len && baton)
4567 {
4568 StringList *commands = new_stop_hook->GetCommandPointer();
4569 if (commands)
4570 {
4571 commands->AppendString (bytes, bytes_len);
4572 }
4573 }
Caroline Tice892fadd2011-06-16 16:27:19 +00004574 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004575 {
Caroline Tice892fadd2011-06-16 16:27:19 +00004576 out_stream->Printf ("%s", reader.GetPrompt());
4577 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004578 }
4579 break;
4580
4581 case eInputReaderInterrupt:
4582 {
4583 // Finish, and cancel the stop hook.
4584 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
Caroline Tice892fadd2011-06-16 16:27:19 +00004585 if (!batch_mode)
4586 {
4587 out_stream->Printf ("Stop hook cancelled.\n");
4588 out_stream->Flush();
4589 }
4590
Jim Inghamd60d94a2011-03-11 03:53:59 +00004591 reader.SetIsDone (true);
4592 }
Jim Inghame15511a2011-05-05 01:03:36 +00004593 got_interrupted = true;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004594 break;
4595
4596 case eInputReaderEndOfFile:
4597 reader.SetIsDone (true);
4598 break;
4599
4600 case eInputReaderDone:
Caroline Tice892fadd2011-06-16 16:27:19 +00004601 if (!got_interrupted && !batch_mode)
4602 {
Greg Clayton444e35b2011-10-19 18:09:39 +00004603 out_stream->Printf ("Stop hook #%llu added.\n", new_stop_hook->GetID());
Caroline Tice892fadd2011-06-16 16:27:19 +00004604 out_stream->Flush();
4605 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00004606 break;
4607 }
4608
4609 return bytes_len;
4610 }
4611
Jim Inghamda26bd22012-06-08 21:56:10 +00004612protected:
Jim Inghamd60d94a2011-03-11 03:53:59 +00004613 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00004614 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004615 {
4616 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4617 if (target)
4618 {
4619 Target::StopHookSP new_hook_sp;
4620 target->AddStopHook (new_hook_sp);
4621
4622 // First step, make the specifier.
4623 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
4624 if (m_options.m_sym_ctx_specified)
4625 {
4626 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
4627
4628 if (!m_options.m_module_name.empty())
4629 {
4630 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
4631 }
4632
4633 if (!m_options.m_class_name.empty())
4634 {
4635 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
4636 }
4637
4638 if (!m_options.m_file_name.empty())
4639 {
4640 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
4641 }
4642
4643 if (m_options.m_line_start != 0)
4644 {
4645 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
4646 }
4647
4648 if (m_options.m_line_end != UINT_MAX)
4649 {
4650 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4651 }
4652
4653 if (!m_options.m_function_name.empty())
4654 {
4655 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
4656 }
4657 }
4658
4659 if (specifier_ap.get())
4660 new_hook_sp->SetSpecifier (specifier_ap.release());
4661
4662 // Next see if any of the thread options have been entered:
4663
4664 if (m_options.m_thread_specified)
4665 {
4666 ThreadSpec *thread_spec = new ThreadSpec();
4667
4668 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
4669 {
4670 thread_spec->SetTID (m_options.m_thread_id);
4671 }
4672
4673 if (m_options.m_thread_index != UINT32_MAX)
4674 thread_spec->SetIndex (m_options.m_thread_index);
4675
4676 if (!m_options.m_thread_name.empty())
4677 thread_spec->SetName (m_options.m_thread_name.c_str());
4678
4679 if (!m_options.m_queue_name.empty())
4680 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
4681
4682 new_hook_sp->SetThreadSpecifier (thread_spec);
4683
4684 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00004685 if (m_options.m_use_one_liner)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004686 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00004687 // Use one-liner.
4688 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
Greg Clayton444e35b2011-10-19 18:09:39 +00004689 result.AppendMessageWithFormat("Stop hook #%llu added.\n", new_hook_sp->GetID());
Jim Inghamd60d94a2011-03-11 03:53:59 +00004690 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00004691 else
Jim Inghamd60d94a2011-03-11 03:53:59 +00004692 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00004693 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
4694 // the new stop hook's command string.
4695 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
4696 if (!reader_sp)
4697 {
4698 result.AppendError("out of memory\n");
4699 result.SetStatus (eReturnStatusFailed);
4700 target->RemoveStopHookByID (new_hook_sp->GetID());
4701 return false;
4702 }
4703
4704 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
4705 new_hook_sp.get(), // baton
4706 eInputReaderGranularityLine, // token size, to pass to callback function
4707 "DONE", // end token
4708 "> ", // prompt
4709 true)); // echo input
4710 if (!err.Success())
4711 {
4712 result.AppendError (err.AsCString());
4713 result.SetStatus (eReturnStatusFailed);
4714 target->RemoveStopHookByID (new_hook_sp->GetID());
4715 return false;
4716 }
4717 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004718 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00004719 result.SetStatus (eReturnStatusSuccessFinishNoResult);
4720 }
4721 else
4722 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004723 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004724 result.SetStatus (eReturnStatusFailed);
4725 }
4726
4727 return result.Succeeded();
4728 }
4729private:
4730 CommandOptions m_options;
4731};
4732
Greg Claytonb3448432011-03-24 21:19:54 +00004733OptionDefinition
Jim Inghamd60d94a2011-03-11 03:53:59 +00004734CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
4735{
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004736 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, 0, eArgTypeOneLiner,
Johnny Chen60fe60e2011-05-02 23:47:55 +00004737 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
Jim Inghamd60d94a2011-03-11 03:53:59 +00004738 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4739 "Set the module within which the stop-hook is to be run."},
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004740 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex,
Jim Inghamd60d94a2011-03-11 03:53:59 +00004741 "The stop hook is run only for the thread whose index matches this argument."},
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004742 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID,
Jim Inghamd60d94a2011-03-11 03:53:59 +00004743 "The stop hook is run only for the thread whose TID matches this argument."},
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004744 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName,
Jim Inghamd60d94a2011-03-11 03:53:59 +00004745 "The stop hook is run only for the thread whose thread name matches this argument."},
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004746 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName,
Jim Inghamd60d94a2011-03-11 03:53:59 +00004747 "The stop hook is run only for threads in the queue whose name is given by this argument."},
4748 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
4749 "Specify the source file within which the stop-hook is to be run." },
4750 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
4751 "Set the start of the line range for which the stop-hook is to be run."},
4752 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
4753 "Set the end of the line range for which the stop-hook is to be run."},
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004754 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, 0, eArgTypeClassName,
Jim Inghamd60d94a2011-03-11 03:53:59 +00004755 "Specify the class within which the stop-hook is to be run." },
4756 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
4757 "Set the function name within which the stop hook will be run." },
4758 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
4759};
4760
4761#pragma mark CommandObjectTargetStopHookDelete
4762
4763//-------------------------------------------------------------------------
4764// CommandObjectTargetStopHookDelete
4765//-------------------------------------------------------------------------
4766
Jim Inghamda26bd22012-06-08 21:56:10 +00004767class CommandObjectTargetStopHookDelete : public CommandObjectParsed
Jim Inghamd60d94a2011-03-11 03:53:59 +00004768{
4769public:
4770
4771 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00004772 CommandObjectParsed (interpreter,
4773 "target stop-hook delete",
4774 "Delete a stop-hook.",
4775 "target stop-hook delete [<idx>]")
Jim Inghamd60d94a2011-03-11 03:53:59 +00004776 {
4777 }
4778
4779 ~CommandObjectTargetStopHookDelete ()
4780 {
4781 }
4782
Jim Inghamda26bd22012-06-08 21:56:10 +00004783protected:
Jim Inghamd60d94a2011-03-11 03:53:59 +00004784 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00004785 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004786 {
4787 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4788 if (target)
4789 {
4790 // FIXME: see if we can use the breakpoint id style parser?
4791 size_t num_args = command.GetArgumentCount();
4792 if (num_args == 0)
4793 {
4794 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
4795 {
4796 result.SetStatus (eReturnStatusFailed);
4797 return false;
4798 }
4799 else
4800 {
4801 target->RemoveAllStopHooks();
4802 }
4803 }
4804 else
4805 {
4806 bool success;
4807 for (size_t i = 0; i < num_args; i++)
4808 {
4809 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
4810 if (!success)
4811 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004812 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004813 result.SetStatus(eReturnStatusFailed);
4814 return false;
4815 }
4816 success = target->RemoveStopHookByID (user_id);
4817 if (!success)
4818 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004819 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004820 result.SetStatus(eReturnStatusFailed);
4821 return false;
4822 }
4823 }
4824 }
4825 result.SetStatus (eReturnStatusSuccessFinishNoResult);
4826 }
4827 else
4828 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004829 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004830 result.SetStatus (eReturnStatusFailed);
4831 }
4832
4833 return result.Succeeded();
4834 }
4835};
4836#pragma mark CommandObjectTargetStopHookEnableDisable
4837
4838//-------------------------------------------------------------------------
4839// CommandObjectTargetStopHookEnableDisable
4840//-------------------------------------------------------------------------
4841
Jim Inghamda26bd22012-06-08 21:56:10 +00004842class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
Jim Inghamd60d94a2011-03-11 03:53:59 +00004843{
4844public:
4845
4846 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
Jim Inghamda26bd22012-06-08 21:56:10 +00004847 CommandObjectParsed (interpreter,
4848 name,
4849 help,
4850 syntax),
Jim Inghamd60d94a2011-03-11 03:53:59 +00004851 m_enable (enable)
4852 {
4853 }
4854
4855 ~CommandObjectTargetStopHookEnableDisable ()
4856 {
4857 }
4858
Jim Inghamda26bd22012-06-08 21:56:10 +00004859protected:
Jim Inghamd60d94a2011-03-11 03:53:59 +00004860 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00004861 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004862 {
4863 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4864 if (target)
4865 {
4866 // FIXME: see if we can use the breakpoint id style parser?
4867 size_t num_args = command.GetArgumentCount();
4868 bool success;
4869
4870 if (num_args == 0)
4871 {
4872 target->SetAllStopHooksActiveState (m_enable);
4873 }
4874 else
4875 {
4876 for (size_t i = 0; i < num_args; i++)
4877 {
4878 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
4879 if (!success)
4880 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004881 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004882 result.SetStatus(eReturnStatusFailed);
4883 return false;
4884 }
4885 success = target->SetStopHookActiveStateByID (user_id, m_enable);
4886 if (!success)
4887 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004888 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004889 result.SetStatus(eReturnStatusFailed);
4890 return false;
4891 }
4892 }
4893 }
4894 result.SetStatus (eReturnStatusSuccessFinishNoResult);
4895 }
4896 else
4897 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004898 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004899 result.SetStatus (eReturnStatusFailed);
4900 }
4901 return result.Succeeded();
4902 }
4903private:
4904 bool m_enable;
4905};
4906
4907#pragma mark CommandObjectTargetStopHookList
4908
4909//-------------------------------------------------------------------------
4910// CommandObjectTargetStopHookList
4911//-------------------------------------------------------------------------
4912
Jim Inghamda26bd22012-06-08 21:56:10 +00004913class CommandObjectTargetStopHookList : public CommandObjectParsed
Jim Inghamd60d94a2011-03-11 03:53:59 +00004914{
4915public:
4916
4917 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00004918 CommandObjectParsed (interpreter,
4919 "target stop-hook list",
4920 "List all stop-hooks.",
4921 "target stop-hook list [<type>]")
Jim Inghamd60d94a2011-03-11 03:53:59 +00004922 {
4923 }
4924
4925 ~CommandObjectTargetStopHookList ()
4926 {
4927 }
4928
Jim Inghamda26bd22012-06-08 21:56:10 +00004929protected:
Jim Inghamd60d94a2011-03-11 03:53:59 +00004930 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00004931 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004932 {
4933 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Johnny Chen9fc16922011-11-29 23:56:14 +00004934 if (!target)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004935 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004936 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004937 result.SetStatus (eReturnStatusFailed);
Jason Molenda6e3a2412011-09-23 21:15:42 +00004938 return result.Succeeded();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004939 }
4940
4941 size_t num_hooks = target->GetNumStopHooks ();
4942 if (num_hooks == 0)
4943 {
4944 result.GetOutputStream().PutCString ("No stop hooks.\n");
4945 }
4946 else
4947 {
4948 for (size_t i = 0; i < num_hooks; i++)
4949 {
4950 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
4951 if (i > 0)
4952 result.GetOutputStream().PutCString ("\n");
4953 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
4954 }
4955 }
Johnny Chen6c7c3902011-11-30 19:09:20 +00004956 result.SetStatus (eReturnStatusSuccessFinishResult);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004957 return result.Succeeded();
4958 }
4959};
4960
4961#pragma mark CommandObjectMultiwordTargetStopHooks
4962//-------------------------------------------------------------------------
4963// CommandObjectMultiwordTargetStopHooks
4964//-------------------------------------------------------------------------
4965
4966class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
4967{
4968public:
4969
4970 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
4971 CommandObjectMultiword (interpreter,
4972 "target stop-hook",
4973 "A set of commands for operating on debugger target stop-hooks.",
4974 "target stop-hook <subcommand> [<subcommand-options>]")
4975 {
4976 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
4977 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
4978 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4979 false,
4980 "target stop-hook disable [<id>]",
4981 "Disable a stop-hook.",
4982 "target stop-hook disable")));
4983 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4984 true,
4985 "target stop-hook enable [<id>]",
4986 "Enable a stop-hook.",
4987 "target stop-hook enable")));
4988 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
4989 }
4990
4991 ~CommandObjectMultiwordTargetStopHooks()
4992 {
4993 }
4994};
4995
4996
Chris Lattner24943d22010-06-08 16:52:24 +00004997
4998#pragma mark CommandObjectMultiwordTarget
4999
5000//-------------------------------------------------------------------------
5001// CommandObjectMultiwordTarget
5002//-------------------------------------------------------------------------
5003
Greg Clayton63094e02010-06-23 01:19:29 +00005004CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00005005 CommandObjectMultiword (interpreter,
5006 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00005007 "A set of commands for operating on debugger targets.",
5008 "target <subcommand> [<subcommand-options>]")
5009{
Greg Claytonabe0fed2011-04-18 08:33:37 +00005010
5011 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
Greg Clayton153ccd72011-08-10 02:10:13 +00005012 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
Greg Claytonabe0fed2011-04-18 08:33:37 +00005013 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
5014 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00005015 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Greg Claytone1f50b92011-05-03 22:09:39 +00005016 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter)));
Greg Clayton3508c382012-02-24 01:59:29 +00005017 LoadSubCommand ("symbols", CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
Greg Clayton801417e2011-07-07 01:59:51 +00005018 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00005019}
5020
5021CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
5022{
5023}
5024
Greg Claytonabe0fed2011-04-18 08:33:37 +00005025