1 //===-- 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> 14 15 // C++ Includes 16 // Other libraries and framework includes 17 // Project includes 18 #include "lldb/Interpreter/Args.h" 19 #include "lldb/Core/Debugger.h" 20 #include "lldb/Core/InputReader.h" 21 #include "lldb/Core/Module.h" 22 #include "lldb/Core/ModuleSpec.h" 23 #include "lldb/Core/Section.h" 24 #include "lldb/Core/State.h" 25 #include "lldb/Core/Timer.h" 26 #include "lldb/Core/ValueObjectVariable.h" 27 #include "lldb/Host/Symbols.h" 28 #include "lldb/Interpreter/CommandInterpreter.h" 29 #include "lldb/Interpreter/CommandReturnObject.h" 30 #include "lldb/Interpreter/Options.h" 31 #include "lldb/Interpreter/OptionGroupArchitecture.h" 32 #include "lldb/Interpreter/OptionGroupBoolean.h" 33 #include "lldb/Interpreter/OptionGroupFile.h" 34 #include "lldb/Interpreter/OptionGroupFormat.h" 35 #include "lldb/Interpreter/OptionGroupVariable.h" 36 #include "lldb/Interpreter/OptionGroupPlatform.h" 37 #include "lldb/Interpreter/OptionGroupUInt64.h" 38 #include "lldb/Interpreter/OptionGroupUUID.h" 39 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" 40 #include "lldb/Symbol/CompileUnit.h" 41 #include "lldb/Symbol/FuncUnwinders.h" 42 #include "lldb/Symbol/LineTable.h" 43 #include "lldb/Symbol/ObjectFile.h" 44 #include "lldb/Symbol/SymbolFile.h" 45 #include "lldb/Symbol/SymbolVendor.h" 46 #include "lldb/Symbol/UnwindPlan.h" 47 #include "lldb/Symbol/VariableList.h" 48 #include "lldb/Target/Process.h" 49 #include "lldb/Target/StackFrame.h" 50 #include "lldb/Target/Thread.h" 51 #include "lldb/Target/ThreadSpec.h" 52 53 using namespace lldb; 54 using namespace lldb_private; 55 56 57 58 static void 59 DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm) 60 { 61 const ArchSpec &target_arch = target->GetArchitecture(); 62 63 Module *exe_module = target->GetExecutableModulePointer(); 64 char exe_path[PATH_MAX]; 65 bool exe_valid = false; 66 if (exe_module) 67 exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path)); 68 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) 91 show_process_status = StateIsStoppedState(state, true); 92 const char *state_cstr = StateAsCString (state); 93 if (pid != LLDB_INVALID_PROCESS_ID) 94 strm.Printf ("%spid=%llu", properties++ > 0 ? ", " : " ( ", pid); 95 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 117 static uint32_t 118 DumpTargetList (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 147 class CommandObjectTargetCreate : public CommandObjectParsed 148 { 149 public: 150 CommandObjectTargetCreate(CommandInterpreter &interpreter) : 151 CommandObjectParsed (interpreter, 152 "target create", 153 "Create a target using the argument as the main executable.", 154 NULL), 155 m_option_group (interpreter), 156 m_arch_option (), 157 m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true 158 m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypePath, "Fullpath to a core file to use for this target.") 159 { 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 173 m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 174 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 175 m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 176 m_option_group.Finalize(); 177 } 178 179 ~CommandObjectTargetCreate () 180 { 181 } 182 183 Options * 184 GetOptions () 185 { 186 return &m_option_group; 187 } 188 189 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 213 protected: 214 bool 215 DoExecute (Args& command, CommandReturnObject &result) 216 { 217 const int argc = command.GetArgumentCount(); 218 FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue()); 219 220 if (argc == 1 || core_file) 221 { 222 const char *file_path = command.GetArgumentAtIndex(0); 223 Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path); 224 FileSpec file_spec; 225 226 if (file_path) 227 file_spec.SetFile (file_path, true); 228 229 TargetSP target_sp; 230 Debugger &debugger = m_interpreter.GetDebugger(); 231 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 240 if (target_sp) 241 { 242 debugger.GetTargetList().SetSelectedTarget(target_sp.get()); 243 if (core_file) 244 { 245 char core_path[PATH_MAX]; 246 core_file.GetPath(core_path, sizeof(core_path)); 247 if (core_file.Exists()) 248 { 249 FileSpec core_file_dir; 250 core_file_dir.GetDirectory() = core_file.GetDirectory(); 251 target_sp->GetExecutableSearchPaths ().Append (core_file_dir); 252 253 ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file)); 254 255 if (process_sp) 256 { 257 // 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 } 272 } 273 else 274 { 275 result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path); 276 result.SetStatus (eReturnStatusFailed); 277 } 278 } 279 else 280 { 281 result.AppendErrorWithFormat ("Core file '%s' does not exist\n", core_path); 282 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 } 290 } 291 else 292 { 293 result.AppendError(error.AsCString()); 294 result.SetStatus (eReturnStatusFailed); 295 } 296 } 297 else 298 { 299 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core-file option.\n", m_cmd_name.c_str()); 300 result.SetStatus (eReturnStatusFailed); 301 } 302 return result.Succeeded(); 303 304 } 305 306 private: 307 OptionGroupOptions m_option_group; 308 OptionGroupArchitecture m_arch_option; 309 OptionGroupPlatform m_platform_options; 310 OptionGroupFile m_core_file; 311 312 }; 313 314 #pragma mark CommandObjectTargetList 315 316 //---------------------------------------------------------------------- 317 // "target list" 318 //---------------------------------------------------------------------- 319 320 class CommandObjectTargetList : public CommandObjectParsed 321 { 322 public: 323 CommandObjectTargetList (CommandInterpreter &interpreter) : 324 CommandObjectParsed (interpreter, 325 "target list", 326 "List all current targets in the current debug session.", 327 NULL, 328 0) 329 { 330 } 331 332 virtual 333 ~CommandObjectTargetList () 334 { 335 } 336 337 protected: 338 virtual bool 339 DoExecute (Args& args, CommandReturnObject &result) 340 { 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 } 350 result.SetStatus (eReturnStatusSuccessFinishResult); 351 } 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 368 class CommandObjectTargetSelect : public CommandObjectParsed 369 { 370 public: 371 CommandObjectTargetSelect (CommandInterpreter &interpreter) : 372 CommandObjectParsed (interpreter, 373 "target select", 374 "Select a target as the current target by target index.", 375 NULL, 376 0) 377 { 378 } 379 380 virtual 381 ~CommandObjectTargetSelect () 382 { 383 } 384 385 protected: 386 virtual bool 387 DoExecute (Args& args, CommandReturnObject &result) 388 { 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); 407 result.SetStatus (eReturnStatusSuccessFinishResult); 408 } 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 438 #pragma mark CommandObjectTargetSelect 439 440 //---------------------------------------------------------------------- 441 // "target delete" 442 //---------------------------------------------------------------------- 443 444 class CommandObjectTargetDelete : public CommandObjectParsed 445 { 446 public: 447 CommandObjectTargetDelete (CommandInterpreter &interpreter) : 448 CommandObjectParsed (interpreter, 449 "target delete", 450 "Delete one or more targets by target index.", 451 NULL, 452 0), 453 m_option_group (interpreter), 454 m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', "Perform extra cleanup to minimize memory consumption after deleting the target.", false, false) 455 { 456 m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 457 m_option_group.Finalize(); 458 } 459 460 virtual 461 ~CommandObjectTargetDelete () 462 { 463 } 464 465 Options * 466 GetOptions () 467 { 468 return &m_option_group; 469 } 470 471 protected: 472 virtual bool 473 DoExecute (Args& args, CommandReturnObject &result) 474 { 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(); 483 // 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 490 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 } 505 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 513 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 } 548 // If "--clean" was specified, prune any orphaned shared modules from 549 // the global shared module list 550 if (m_cleanup_option.GetOptionValue ()) 551 { 552 const bool mandatory = true; 553 ModuleList::RemoveOrphanSharedModules(mandatory); 554 } 555 result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete); 556 result.SetStatus(eReturnStatusSuccessFinishResult); 557 } 558 559 return result.Succeeded(); 560 } 561 562 OptionGroupOptions m_option_group; 563 OptionGroupBoolean m_cleanup_option; 564 }; 565 566 567 #pragma mark CommandObjectTargetVariable 568 569 //---------------------------------------------------------------------- 570 // "target variable" 571 //---------------------------------------------------------------------- 572 573 class CommandObjectTargetVariable : public CommandObjectParsed 574 { 575 public: 576 CommandObjectTargetVariable (CommandInterpreter &interpreter) : 577 CommandObjectParsed (interpreter, 578 "target variable", 579 "Read global variable(s) prior to running your binary.", 580 NULL, 581 0), 582 m_option_group (interpreter), 583 m_option_variable (false), // Don't include frame options 584 m_option_format (eFormatDefault), 585 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 { 589 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 602 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 603 m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 604 m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1); 605 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 } 614 615 void 616 DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name) 617 { 618 ValueObject::DumpValueObjectOptions options; 619 620 options.SetMaximumPointerDepth(m_varobj_options.ptr_depth) 621 .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) 626 .SetUseSyntheticValue(m_varobj_options.use_synth) 627 .SetFlatOutput(m_varobj_options.flat_output) 628 .SetOmitSummaryDepth(m_varobj_options.no_summary_depth) 629 .SetIgnoreCap(m_varobj_options.ignore_cap); 630 631 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 657 if (m_option_variable.show_decl) 658 { 659 bool show_fullpaths = false; 660 bool show_module = true; 661 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module)) 662 s.PutCString (": "); 663 } 664 665 const Format format = m_option_format.GetFormat(); 666 if (format != eFormatDefault) 667 options.SetFormat(format); 668 669 options.SetRootValueObjectName(root_name); 670 671 ValueObject::DumpValueObject (s, 672 valobj_sp.get(), 673 options); 674 675 } 676 677 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 695 Options * 696 GetOptions () 697 { 698 return &m_option_group; 699 } 700 701 protected: 702 virtual bool 703 DoExecute (Args& args, CommandReturnObject &result) 704 { 705 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 706 Target *target = exe_ctx.GetTargetPtr(); 707 if (target) 708 { 709 const size_t argc = args.GetArgumentCount(); 710 Stream &s = result.GetOutputStream(); 711 if (argc > 0) 712 { 713 714 for (size_t idx = 0; idx < argc; ++idx) 715 { 716 VariableList variable_list; 717 ValueObjectList valobj_list; 718 719 const char *arg = args.GetArgumentAtIndex(idx); 720 uint32_t matches = 0; 721 bool use_var_name = false; 722 if (m_option_variable.use_regex) 723 { 724 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 } 731 use_var_name = true; 732 matches = target->GetImages().FindGlobalVariables (regex, 733 true, 734 UINT32_MAX, 735 variable_list); 736 } 737 else 738 { 739 Error error (Variable::GetValuesForVariableExpressionPath (arg, 740 exe_ctx.GetBestExecutionContextScope(), 741 GetVariableCallback, 742 target, 743 variable_list, 744 valobj_list)); 745 matches = variable_list.GetSize(); 746 } 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 { 756 for (uint32_t global_idx=0; global_idx<matches; ++global_idx) 757 { 758 VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx)); 759 if (var_sp) 760 { 761 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx)); 762 if (!valobj_sp) 763 valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp); 764 765 if (valobj_sp) 766 DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg); 767 } 768 } 769 } 770 } 771 } 772 else 773 { 774 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 { 789 s.Printf ("Global variables for %s/%s:\n", 790 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 } 824 } 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 } 832 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 840 return result.Succeeded(); 841 } 842 843 OptionGroupOptions m_option_group; 844 OptionGroupVariable m_option_variable; 845 OptionGroupFormat m_option_format; 846 OptionGroupFileList m_option_compile_units; 847 OptionGroupFileList m_option_shared_libraries; 848 OptionGroupValueObjectDisplay m_varobj_options; 849 850 }; 851 852 853 #pragma mark CommandObjectTargetModulesSearchPathsAdd 854 855 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed 856 { 857 public: 858 859 CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) : 860 CommandObjectParsed (interpreter, 861 "target modules search-paths add", 862 "Add new image search paths substitution pairs to the current target.", 863 NULL) 864 { 865 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); 885 } 886 887 ~CommandObjectTargetModulesSearchPathsAdd () 888 { 889 } 890 891 protected: 892 bool 893 DoExecute (Args& command, 894 CommandReturnObject &result) 895 { 896 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 897 if (target) 898 { 899 uint32_t argc = command.GetArgumentCount(); 900 if (argc & 1) 901 { 902 result.AppendError ("add requires an even number of arguments\n"); 903 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); 915 target->GetImageSearchPathList().Append (ConstString(from), 916 ConstString(to), 917 last_pair); // Notify if this is the last pair 918 result.SetStatus (eReturnStatusSuccessFinishNoResult); 919 } 920 else 921 { 922 if (from[0]) 923 result.AppendError ("<path-prefix> can't be empty\n"); 924 else 925 result.AppendError ("<new-path-prefix> can't be empty\n"); 926 result.SetStatus (eReturnStatusFailed); 927 } 928 } 929 } 930 } 931 else 932 { 933 result.AppendError ("invalid target\n"); 934 result.SetStatus (eReturnStatusFailed); 935 } 936 return result.Succeeded(); 937 } 938 }; 939 940 #pragma mark CommandObjectTargetModulesSearchPathsClear 941 942 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed 943 { 944 public: 945 946 CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) : 947 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") 951 { 952 } 953 954 ~CommandObjectTargetModulesSearchPathsClear () 955 { 956 } 957 958 protected: 959 bool 960 DoExecute (Args& command, 961 CommandReturnObject &result) 962 { 963 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 964 if (target) 965 { 966 bool notify = true; 967 target->GetImageSearchPathList().Clear(notify); 968 result.SetStatus (eReturnStatusSuccessFinishNoResult); 969 } 970 else 971 { 972 result.AppendError ("invalid target\n"); 973 result.SetStatus (eReturnStatusFailed); 974 } 975 return result.Succeeded(); 976 } 977 }; 978 979 #pragma mark CommandObjectTargetModulesSearchPathsInsert 980 981 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed 982 { 983 public: 984 985 CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) : 986 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) 990 { 991 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); 1022 } 1023 1024 ~CommandObjectTargetModulesSearchPathsInsert () 1025 { 1026 } 1027 1028 protected: 1029 bool 1030 DoExecute (Args& command, 1031 CommandReturnObject &result) 1032 { 1033 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1034 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); 1067 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1068 } 1069 else 1070 { 1071 if (from[0]) 1072 result.AppendError ("<path-prefix> can't be empty\n"); 1073 else 1074 result.AppendError ("<new-path-prefix> can't be empty\n"); 1075 result.SetStatus (eReturnStatusFailed); 1076 return false; 1077 } 1078 } 1079 } 1080 else 1081 { 1082 result.AppendError ("insert requires at least three arguments\n"); 1083 result.SetStatus (eReturnStatusFailed); 1084 return result.Succeeded(); 1085 } 1086 1087 } 1088 else 1089 { 1090 result.AppendError ("invalid target\n"); 1091 result.SetStatus (eReturnStatusFailed); 1092 } 1093 return result.Succeeded(); 1094 } 1095 }; 1096 1097 1098 #pragma mark CommandObjectTargetModulesSearchPathsList 1099 1100 1101 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed 1102 { 1103 public: 1104 1105 CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) : 1106 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") 1110 { 1111 } 1112 1113 ~CommandObjectTargetModulesSearchPathsList () 1114 { 1115 } 1116 1117 protected: 1118 bool 1119 DoExecute (Args& command, 1120 CommandReturnObject &result) 1121 { 1122 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1123 if (target) 1124 { 1125 if (command.GetArgumentCount() != 0) 1126 { 1127 result.AppendError ("list takes no arguments\n"); 1128 result.SetStatus (eReturnStatusFailed); 1129 return result.Succeeded(); 1130 } 1131 1132 target->GetImageSearchPathList().Dump(&result.GetOutputStream()); 1133 result.SetStatus (eReturnStatusSuccessFinishResult); 1134 } 1135 else 1136 { 1137 result.AppendError ("invalid target\n"); 1138 result.SetStatus (eReturnStatusFailed); 1139 } 1140 return result.Succeeded(); 1141 } 1142 }; 1143 1144 #pragma mark CommandObjectTargetModulesSearchPathsQuery 1145 1146 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed 1147 { 1148 public: 1149 1150 CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) : 1151 CommandObjectParsed (interpreter, 1152 "target modules search-paths query", 1153 "Transform a path using the first applicable image search path.", 1154 NULL) 1155 { 1156 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); 1168 } 1169 1170 ~CommandObjectTargetModulesSearchPathsQuery () 1171 { 1172 } 1173 1174 protected: 1175 bool 1176 DoExecute (Args& command, 1177 CommandReturnObject &result) 1178 { 1179 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1180 if (target) 1181 { 1182 if (command.GetArgumentCount() != 1) 1183 { 1184 result.AppendError ("query requires one argument\n"); 1185 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()); 1195 1196 result.SetStatus (eReturnStatusSuccessFinishResult); 1197 } 1198 else 1199 { 1200 result.AppendError ("invalid target\n"); 1201 result.SetStatus (eReturnStatusFailed); 1202 } 1203 return result.Succeeded(); 1204 } 1205 }; 1206 1207 //---------------------------------------------------------------------- 1208 // Static Helper functions 1209 //---------------------------------------------------------------------- 1210 static void 1211 DumpModuleArchitecture (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 1227 static void 1228 DumpModuleUUID (Stream &strm, Module *module) 1229 { 1230 if (module && module->GetUUID().IsValid()) 1231 module->GetUUID().Dump (&strm); 1232 else 1233 strm.PutCString(" "); 1234 } 1235 1236 static uint32_t 1237 DumpCompileUnitLineTable 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, 1269 interpreter.GetExecutionContext().GetTargetPtr(), 1270 lldb::eDescriptionLevelBrief); 1271 else 1272 strm << "No line table"; 1273 } 1274 } 1275 } 1276 return num_matches; 1277 } 1278 1279 static void 1280 DumpFullpath (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 1304 static void 1305 DumpDirectory (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 1320 static void 1321 DumpBasename (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 1337 static void 1338 DumpModuleSymtab (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) 1347 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order); 1348 } 1349 } 1350 } 1351 1352 static void 1353 DumpModuleSections (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(); 1369 section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX); 1370 strm.IndentLess(); 1371 } 1372 } 1373 } 1374 } 1375 1376 static bool 1377 DumpModuleSymbolVendor (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 1391 static void 1392 DumpAddress (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 1414 static bool 1415 LookupAddressInModule (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) 1422 { 1423 if (module) 1424 { 1425 lldb::addr_t addr = raw_addr - offset; 1426 Address so_addr; 1427 SymbolContext sc; 1428 Target *target = interpreter.GetExecutionContext().GetTargetPtr(); 1429 if (target && !target->GetSectionLoadList().IsEmpty()) 1430 { 1431 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr)) 1432 return false; 1433 else if (so_addr.GetModule().get() != module) 1434 return false; 1435 } 1436 else 1437 { 1438 if (!module->ResolveFileAddress (addr, so_addr)) 1439 return false; 1440 } 1441 1442 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); 1443 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(); 1462 return true; 1463 } 1464 1465 return false; 1466 } 1467 1468 static uint32_t 1469 LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose) 1470 { 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 (); 1506 //Symtab::DumpSymbolHeader (&strm); 1507 for (i=0; i < num_matches; ++i) 1508 { 1509 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); 1510 DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(), 1511 symbol->GetAddress(), 1512 verbose, 1513 strm); 1514 1515 // strm.Indent (); 1516 // symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i); 1517 } 1518 strm.IndentLess (); 1519 return num_matches; 1520 } 1521 } 1522 } 1523 } 1524 return 0; 1525 } 1526 1527 1528 static void 1529 DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose) 1530 { 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 { 1540 AddressRange range; 1541 1542 sc.GetAddressRange(eSymbolContextEverything, 1543 0, 1544 true, 1545 range); 1546 1547 DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm); 1548 } 1549 } 1550 strm.IndentLess (); 1551 } 1552 1553 static uint32_t 1554 LookupFunctionInModule (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) 1562 { 1563 if (module && name && name[0]) 1564 { 1565 SymbolContextList sc_list; 1566 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, 1573 include_inlines, 1574 append, 1575 sc_list); 1576 } 1577 else 1578 { 1579 ConstString function_name (name); 1580 num_matches = module->FindFunctions (function_name, 1581 NULL, 1582 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, 1583 include_symbols, 1584 include_inlines, 1585 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"); 1595 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose); 1596 } 1597 return num_matches; 1598 } 1599 return 0; 1600 } 1601 1602 static uint32_t 1603 LookupTypeInModule (CommandInterpreter &interpreter, 1604 Stream &strm, 1605 Module *module, 1606 const char *name_cstr, 1607 bool name_is_regex) 1608 { 1609 if (module && name_cstr && name_cstr[0]) 1610 { 1611 TypeList type_list; 1612 const uint32_t max_num_matches = UINT32_MAX; 1613 uint32_t num_matches = 0; 1614 bool name_is_fully_qualified = false; 1615 SymbolContext sc; 1616 1617 ConstString name(name_cstr); 1618 num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list); 1619 1620 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) 1628 { 1629 TypeSP type_sp (type_list.GetTypeAtIndex(i)); 1630 if (type_sp) 1631 { 1632 // 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); 1636 // 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 } 1648 } 1649 strm.EOL(); 1650 } 1651 } 1652 return num_matches; 1653 } 1654 return 0; 1655 } 1656 1657 static uint32_t 1658 LookupTypeHere (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 1707 static uint32_t 1708 LookupFileAndLineInModule (CommandInterpreter &interpreter, 1709 Stream &strm, 1710 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"); 1731 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose); 1732 return num_matches; 1733 } 1734 } 1735 return 0; 1736 1737 } 1738 1739 1740 static size_t 1741 FindModulesByName (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); 1748 ModuleSpec module_spec (module_file_spec); 1749 1750 const size_t initial_size = module_list.GetSize (); 1751 1752 if (check_global_list) 1753 { 1754 // Check the global list 1755 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 1756 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 { 1764 if (module->MatchesModuleSpec (module_spec)) 1765 { 1766 module_sp = module->shared_from_this(); 1767 module_list.AppendIfNeeded(module_sp); 1768 } 1769 } 1770 } 1771 } 1772 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 1793 return module_list.GetSize () - initial_size; 1794 } 1795 1796 #pragma mark CommandObjectTargetModulesModuleAutoComplete 1797 1798 //---------------------------------------------------------------------- 1799 // A base command object class that can auto complete with module file 1800 // paths 1801 //---------------------------------------------------------------------- 1802 1803 class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed 1804 { 1805 public: 1806 1807 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter, 1808 const char *name, 1809 const char *help, 1810 const char *syntax) : 1811 CommandObjectParsed (interpreter, name, help, syntax) 1812 { 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 1865 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed 1866 { 1867 public: 1868 1869 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, 1870 const char *name, 1871 const char *help, 1872 const char *syntax) : 1873 CommandObjectParsed (interpreter, name, help, syntax) 1874 { 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 1924 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete 1925 { 1926 public: 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 1941 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 2003 protected: 2004 virtual bool 2005 DoExecute (Args& command, 2006 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 2026 Mutex::Locker modules_locker(target->GetImages().GetMutex()); 2027 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++; 2039 DumpModuleSymtab (m_interpreter, 2040 result.GetOutputStream(), 2041 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx), 2042 m_options.m_sort_order); 2043 } 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 { 2058 ModuleList module_list; 2059 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2060 if (num_matches > 0) 2061 { 2062 for (size_t i=0; i<num_matches; ++i) 2063 { 2064 Module *module = module_list.GetModulePointerAtIndex(i); 2065 if (module) 2066 { 2067 if (num_dumped > 0) 2068 { 2069 result.GetOutputStream().EOL(); 2070 result.GetOutputStream().EOL(); 2071 } 2072 num_dumped++; 2073 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order); 2074 } 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 2093 2094 CommandOptions m_options; 2095 }; 2096 2097 static OptionEnumValueElement 2098 g_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 2107 OptionDefinition 2108 CommandObjectTargetModulesDumpSymtab::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 2120 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete 2121 { 2122 public: 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 2137 protected: 2138 virtual bool 2139 DoExecute (Args& command, 2140 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 { 2183 ModuleList module_list; 2184 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2185 if (num_matches > 0) 2186 { 2187 for (size_t i=0; i<num_matches; ++i) 2188 { 2189 Module *module = module_list.GetModulePointerAtIndex(i); 2190 if (module) 2191 { 2192 num_dumped++; 2193 DumpModuleSections (m_interpreter, result.GetOutputStream(), module); 2194 } 2195 } 2196 } 2197 else 2198 { 2199 // Check the global list 2200 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 2201 2202 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2203 } 2204 } 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 2226 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete 2227 { 2228 public: 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 2243 protected: 2244 virtual bool 2245 DoExecute (Args& command, 2246 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 2266 ModuleList &target_modules = target->GetImages(); 2267 Mutex::Locker modules_locker (target_modules.GetMutex()); 2268 const uint32_t num_modules = target_modules.GetSize(); 2269 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 { 2274 if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx))) 2275 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 { 2291 ModuleList module_list; 2292 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2293 if (num_matches > 0) 2294 { 2295 for (size_t i=0; i<num_matches; ++i) 2296 { 2297 Module *module = module_list.GetModulePointerAtIndex(i); 2298 if (module) 2299 { 2300 if (DumpModuleSymbolVendor (result.GetOutputStream(), module)) 2301 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 2329 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete 2330 { 2331 public: 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 2345 protected: 2346 virtual bool 2347 DoExecute (Args& command, 2348 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); 2378 2379 ModuleList &target_modules = target->GetImages(); 2380 Mutex::Locker modules_locker(target_modules.GetMutex()); 2381 const uint32_t num_modules = target_modules.GetSize(); 2382 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(), 2389 target_modules.GetModulePointerAtIndexUnlocked(i), 2390 file_spec, 2391 exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive())) 2392 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 2421 class CommandObjectTargetModulesDump : public CommandObjectMultiword 2422 { 2423 public: 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 2446 class CommandObjectTargetModulesAdd : public CommandObjectParsed 2447 { 2448 public: 2449 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) : 2450 CommandObjectParsed (interpreter, 2451 "target modules add", 2452 "Add a new module to the current target's modules.", 2453 "target modules add [<module>]") 2454 { 2455 } 2456 2457 virtual 2458 ~CommandObjectTargetModulesAdd () 2459 { 2460 } 2461 2462 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 2486 protected: 2487 virtual bool 2488 DoExecute (Args& args, 2489 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); 2515 if (file_spec.Exists()) 2516 { 2517 ModuleSpec module_spec (file_spec); 2518 ModuleSP module_sp (target->GetSharedModule (module_spec)); 2519 if (!module_sp) 2520 { 2521 result.AppendError ("one or more executable image paths must be specified"); 2522 result.SetStatus (eReturnStatusFailed); 2523 return false; 2524 } 2525 result.SetStatus (eReturnStatusSuccessFinishResult); 2526 } 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 2549 }; 2550 2551 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete 2552 { 2553 public: 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 2574 virtual Options * 2575 GetOptions () 2576 { 2577 return &m_option_group; 2578 } 2579 2580 protected: 2581 virtual bool 2582 DoExecute (Args& args, 2583 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(); 2595 ModuleSpec module_spec; 2596 bool search_using_module_spec = false; 2597 if (m_file_option.GetOptionValue().OptionWasSet()) 2598 { 2599 search_using_module_spec = true; 2600 module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 2601 } 2602 2603 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2604 { 2605 search_using_module_spec = true; 2606 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2607 } 2608 2609 if (search_using_module_spec) 2610 { 2611 2612 ModuleList matching_modules; 2613 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules); 2614 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 { 2627 bool changed = false; 2628 if (argc == 0) 2629 { 2630 if (m_slide_option.GetOptionValue().OptionWasSet()) 2631 { 2632 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue(); 2633 module->SetLoadAddress (*target, slide, changed); 2634 } 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 { 2665 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 { 2673 if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr)) 2674 changed = true; 2675 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr); 2676 } 2677 } 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 } 2703 2704 if (changed) 2705 target->ModulesDidLoad (matching_modules); 2706 } 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 FileSpec *module_spec_file = module_spec.GetFileSpecPtr(); 2724 if (module_spec_file) 2725 { 2726 module_spec_file->GetPath (path, sizeof(path)); 2727 result.AppendErrorWithFormat ("invalid module '%s'.\n", path); 2728 } 2729 else 2730 result.AppendError ("no module spec"); 2731 result.SetStatus (eReturnStatusFailed); 2732 } 2733 } 2734 else 2735 { 2736 char uuid_cstr[64]; 2737 2738 if (module_spec.GetFileSpec()) 2739 module_spec.GetFileSpec().GetPath (path, sizeof(path)); 2740 else 2741 path[0] = '\0'; 2742 2743 if (module_spec.GetUUIDPtr()) 2744 module_spec.GetUUID().GetAsCString(uuid_cstr, sizeof(uuid_cstr)); 2745 else 2746 uuid_cstr[0] = '\0'; 2747 if (num_matches > 1) 2748 { 2749 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", 2750 path[0] ? " file=" : "", 2751 path, 2752 uuid_cstr[0] ? " uuid=" : "", 2753 uuid_cstr); 2754 for (size_t i=0; i<num_matches; ++i) 2755 { 2756 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path))) 2757 result.AppendMessageWithFormat("%s\n", path); 2758 } 2759 } 2760 else 2761 { 2762 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n", 2763 path[0] ? " file=" : "", 2764 path, 2765 uuid_cstr[0] ? " uuid=" : "", 2766 uuid_cstr); 2767 } 2768 result.SetStatus (eReturnStatusFailed); 2769 } 2770 } 2771 else 2772 { 2773 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n"); 2774 result.SetStatus (eReturnStatusFailed); 2775 return false; 2776 } 2777 } 2778 return result.Succeeded(); 2779 } 2780 2781 OptionGroupOptions m_option_group; 2782 OptionGroupUUID m_uuid_option_group; 2783 OptionGroupFile m_file_option; 2784 OptionGroupUInt64 m_slide_option; 2785 }; 2786 2787 //---------------------------------------------------------------------- 2788 // List images with associated information 2789 //---------------------------------------------------------------------- 2790 class CommandObjectTargetModulesList : public CommandObjectParsed 2791 { 2792 public: 2793 2794 class CommandOptions : public Options 2795 { 2796 public: 2797 2798 CommandOptions (CommandInterpreter &interpreter) : 2799 Options(interpreter), 2800 m_format_array(), 2801 m_use_global_module_list (false), 2802 m_module_addr (LLDB_INVALID_ADDRESS) 2803 { 2804 } 2805 2806 virtual 2807 ~CommandOptions () 2808 { 2809 } 2810 2811 virtual Error 2812 SetOptionValue (uint32_t option_idx, const char *option_arg) 2813 { 2814 char short_option = (char) m_getopt_table[option_idx].val; 2815 if (short_option == 'g') 2816 { 2817 m_use_global_module_list = true; 2818 } 2819 else if (short_option == 'a') 2820 { 2821 bool success; 2822 m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success); 2823 if (!success) 2824 { 2825 Error error; 2826 error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg); 2827 } 2828 } 2829 else 2830 { 2831 uint32_t width = 0; 2832 if (option_arg) 2833 width = strtoul (option_arg, NULL, 0); 2834 m_format_array.push_back(std::make_pair(short_option, width)); 2835 } 2836 Error error; 2837 return error; 2838 } 2839 2840 void 2841 OptionParsingStarting () 2842 { 2843 m_format_array.clear(); 2844 m_use_global_module_list = false; 2845 m_module_addr = LLDB_INVALID_ADDRESS; 2846 } 2847 2848 const OptionDefinition* 2849 GetDefinitions () 2850 { 2851 return g_option_table; 2852 } 2853 2854 // Options table: Required for subclasses of Options. 2855 2856 static OptionDefinition g_option_table[]; 2857 2858 // Instance variables to hold the values for command options. 2859 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection; 2860 FormatWidthCollection m_format_array; 2861 bool m_use_global_module_list; 2862 lldb::addr_t m_module_addr; 2863 }; 2864 2865 CommandObjectTargetModulesList (CommandInterpreter &interpreter) : 2866 CommandObjectParsed (interpreter, 2867 "target modules list", 2868 "List current executable and dependent shared library images.", 2869 "target modules list [<cmd-options>]"), 2870 m_options (interpreter) 2871 { 2872 } 2873 2874 virtual 2875 ~CommandObjectTargetModulesList () 2876 { 2877 } 2878 2879 virtual 2880 Options * 2881 GetOptions () 2882 { 2883 return &m_options; 2884 } 2885 2886 protected: 2887 virtual bool 2888 DoExecute (Args& command, 2889 CommandReturnObject &result) 2890 { 2891 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2892 const bool use_global_module_list = m_options.m_use_global_module_list; 2893 // Define a local module list here to ensure it lives longer than any "locker" 2894 // object which might lock its contents below (through the "module_list_ptr" 2895 // variable). 2896 ModuleList module_list; 2897 if (target == NULL && use_global_module_list == false) 2898 { 2899 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2900 result.SetStatus (eReturnStatusFailed); 2901 return false; 2902 } 2903 else 2904 { 2905 if (target) 2906 { 2907 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2908 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2909 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2910 } 2911 // Dump all sections for all modules images 2912 Stream &strm = result.GetOutputStream(); 2913 2914 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) 2915 { 2916 if (target) 2917 { 2918 Address module_address; 2919 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) 2920 { 2921 ModuleSP module_sp (module_address.GetModule()); 2922 if (module_sp) 2923 { 2924 PrintModule (target, module_sp.get(), UINT32_MAX, 0, strm); 2925 result.SetStatus (eReturnStatusSuccessFinishResult); 2926 } 2927 else 2928 { 2929 result.AppendError ("Couldn't find module matching address: 0x%llx.", m_options.m_module_addr); 2930 result.SetStatus (eReturnStatusFailed); 2931 } 2932 } 2933 else 2934 { 2935 result.AppendError ("Couldn't find module containing address: 0x%llx.", m_options.m_module_addr); 2936 result.SetStatus (eReturnStatusFailed); 2937 } 2938 } 2939 else 2940 { 2941 result.AppendError ("Can only look up modules by address with a valid target."); 2942 result.SetStatus (eReturnStatusFailed); 2943 } 2944 return result.Succeeded(); 2945 } 2946 2947 uint32_t num_modules = 0; 2948 Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL. 2949 // Otherwise it will lock the AllocationModuleCollectionMutex when accessing 2950 // the global module list directly. 2951 ModuleList *module_list_ptr = NULL; 2952 const size_t argc = command.GetArgumentCount(); 2953 if (argc == 0) 2954 { 2955 if (use_global_module_list) 2956 { 2957 locker.Lock (Module::GetAllocationModuleCollectionMutex()); 2958 num_modules = Module::GetNumberAllocatedModules(); 2959 } 2960 else 2961 { 2962 module_list_ptr = &target->GetImages(); 2963 } 2964 } 2965 else 2966 { 2967 for (size_t i=0; i<argc; ++i) 2968 { 2969 // Dump specified images (by basename or fullpath) 2970 const char *arg_cstr = command.GetArgumentAtIndex(i); 2971 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list); 2972 if (num_matches == 0) 2973 { 2974 if (argc == 1) 2975 { 2976 result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr); 2977 result.SetStatus (eReturnStatusFailed); 2978 return false; 2979 } 2980 } 2981 } 2982 2983 module_list_ptr = &module_list; 2984 } 2985 2986 if (module_list_ptr != NULL) 2987 { 2988 locker.Lock(module_list_ptr->GetMutex()); 2989 num_modules = module_list_ptr->GetSize(); 2990 } 2991 2992 if (num_modules > 0) 2993 { 2994 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2995 { 2996 ModuleSP module_sp; 2997 Module *module; 2998 if (module_list_ptr) 2999 { 3000 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx); 3001 module = module_sp.get(); 3002 } 3003 else 3004 { 3005 module = Module::GetAllocatedModuleAtIndex(image_idx); 3006 module_sp = module->shared_from_this(); 3007 } 3008 3009 int indent = strm.Printf("[%3u] ", image_idx); 3010 PrintModule (target, module, image_idx, indent, strm); 3011 3012 } 3013 result.SetStatus (eReturnStatusSuccessFinishResult); 3014 } 3015 else 3016 { 3017 if (argc) 3018 { 3019 if (use_global_module_list) 3020 result.AppendError ("the global module list has no matching modules"); 3021 else 3022 result.AppendError ("the target has no matching modules"); 3023 } 3024 else 3025 { 3026 if (use_global_module_list) 3027 result.AppendError ("the global module list is empty"); 3028 else 3029 result.AppendError ("the target has no associated executable images"); 3030 } 3031 result.SetStatus (eReturnStatusFailed); 3032 return false; 3033 } 3034 } 3035 return result.Succeeded(); 3036 } 3037 3038 void 3039 PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm) 3040 { 3041 3042 if (module == NULL) 3043 { 3044 strm.PutCString("Null module"); 3045 return; 3046 } 3047 3048 bool dump_object_name = false; 3049 if (m_options.m_format_array.empty()) 3050 { 3051 m_options.m_format_array.push_back(std::make_pair('u', 0)); 3052 m_options.m_format_array.push_back(std::make_pair('h', 0)); 3053 m_options.m_format_array.push_back(std::make_pair('f', 0)); 3054 m_options.m_format_array.push_back(std::make_pair('S', 0)); 3055 } 3056 const size_t num_entries = m_options.m_format_array.size(); 3057 bool print_space = false; 3058 for (size_t i=0; i<num_entries; ++i) 3059 { 3060 if (print_space) 3061 strm.PutChar(' '); 3062 print_space = true; 3063 const char format_char = m_options.m_format_array[i].first; 3064 uint32_t width = m_options.m_format_array[i].second; 3065 switch (format_char) 3066 { 3067 case 'A': 3068 DumpModuleArchitecture (strm, module, false, width); 3069 break; 3070 3071 case 't': 3072 DumpModuleArchitecture (strm, module, true, width); 3073 break; 3074 3075 case 'f': 3076 DumpFullpath (strm, &module->GetFileSpec(), width); 3077 dump_object_name = true; 3078 break; 3079 3080 case 'd': 3081 DumpDirectory (strm, &module->GetFileSpec(), width); 3082 break; 3083 3084 case 'b': 3085 DumpBasename (strm, &module->GetFileSpec(), width); 3086 dump_object_name = true; 3087 break; 3088 3089 case 'h': 3090 case 'o': 3091 // Image header address 3092 { 3093 uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16; 3094 3095 ObjectFile *objfile = module->GetObjectFile (); 3096 if (objfile) 3097 { 3098 Address header_addr(objfile->GetHeaderAddress()); 3099 if (header_addr.IsValid()) 3100 { 3101 if (target && !target->GetSectionLoadList().IsEmpty()) 3102 { 3103 lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target); 3104 if (header_load_addr == LLDB_INVALID_ADDRESS) 3105 { 3106 header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress); 3107 } 3108 else 3109 { 3110 if (format_char == 'o') 3111 { 3112 // Show the offset of slide for the image 3113 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress()); 3114 } 3115 else 3116 { 3117 // Show the load address of the image 3118 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr); 3119 } 3120 } 3121 break; 3122 } 3123 // The address was valid, but the image isn't loaded, output the address in an appropriate format 3124 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress); 3125 break; 3126 } 3127 } 3128 strm.Printf ("%*s", addr_nibble_width + 2, ""); 3129 } 3130 break; 3131 case 'r': 3132 { 3133 uint32_t ref_count = 0; 3134 ModuleSP module_sp (module->shared_from_this()); 3135 if (module_sp) 3136 { 3137 // Take one away to make sure we don't count our local "module_sp" 3138 ref_count = module_sp.use_count() - 1; 3139 } 3140 if (width) 3141 strm.Printf("{%*u}", width, ref_count); 3142 else 3143 strm.Printf("{%u}", ref_count); 3144 } 3145 break; 3146 3147 case 's': 3148 case 'S': 3149 { 3150 SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 3151 if (symbol_vendor) 3152 { 3153 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 3154 if (symbol_file) 3155 { 3156 if (format_char == 'S') 3157 { 3158 FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec(); 3159 // Dump symbol file only if different from module file 3160 if (!symfile_spec || symfile_spec == module->GetFileSpec()) 3161 { 3162 print_space = false; 3163 break; 3164 } 3165 // Add a newline and indent past the index 3166 strm.Printf ("\n%*s", indent, ""); 3167 } 3168 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 3169 dump_object_name = true; 3170 break; 3171 } 3172 } 3173 strm.Printf("%.*s", width, "<NONE>"); 3174 } 3175 break; 3176 3177 case 'm': 3178 module->GetModificationTime().Dump(&strm, width); 3179 break; 3180 3181 case 'p': 3182 strm.Printf("%p", module); 3183 break; 3184 3185 case 'u': 3186 DumpModuleUUID(strm, module); 3187 break; 3188 3189 default: 3190 break; 3191 } 3192 3193 } 3194 if (dump_object_name) 3195 { 3196 const char *object_name = module->GetObjectName().GetCString(); 3197 if (object_name) 3198 strm.Printf ("(%s)", object_name); 3199 } 3200 strm.EOL(); 3201 } 3202 3203 CommandOptions m_options; 3204 }; 3205 3206 OptionDefinition 3207 CommandObjectTargetModulesList::CommandOptions::g_option_table[] = 3208 { 3209 { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."}, 3210 { LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, 3211 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, 3212 { 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."}, 3213 { 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)."}, 3214 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, 3215 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, 3216 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, 3217 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, 3218 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, 3219 { 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."}, 3220 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, 3221 { 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."}, 3222 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."}, 3223 { 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."}, 3224 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3225 }; 3226 3227 #pragma mark CommandObjectTargetModulesShowUnwind 3228 3229 //---------------------------------------------------------------------- 3230 // Lookup unwind information in images 3231 //---------------------------------------------------------------------- 3232 3233 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed 3234 { 3235 public: 3236 3237 enum 3238 { 3239 eLookupTypeInvalid = -1, 3240 eLookupTypeAddress = 0, 3241 eLookupTypeSymbol, 3242 eLookupTypeFunction, 3243 eLookupTypeFunctionOrSymbol, 3244 kNumLookupTypes 3245 }; 3246 3247 class CommandOptions : public Options 3248 { 3249 public: 3250 3251 CommandOptions (CommandInterpreter &interpreter) : 3252 Options(interpreter), 3253 m_type(eLookupTypeInvalid), 3254 m_str(), 3255 m_addr(LLDB_INVALID_ADDRESS) 3256 { 3257 } 3258 3259 virtual 3260 ~CommandOptions () 3261 { 3262 } 3263 3264 virtual Error 3265 SetOptionValue (uint32_t option_idx, const char *option_arg) 3266 { 3267 Error error; 3268 3269 char short_option = (char) m_getopt_table[option_idx].val; 3270 3271 switch (short_option) 3272 { 3273 case 'a': 3274 m_type = eLookupTypeAddress; 3275 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3276 if (m_addr == LLDB_INVALID_ADDRESS) 3277 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg); 3278 break; 3279 3280 case 'n': 3281 m_str = option_arg; 3282 m_type = eLookupTypeFunctionOrSymbol; 3283 break; 3284 } 3285 3286 return error; 3287 } 3288 3289 void 3290 OptionParsingStarting () 3291 { 3292 m_type = eLookupTypeInvalid; 3293 m_str.clear(); 3294 m_addr = LLDB_INVALID_ADDRESS; 3295 } 3296 3297 const OptionDefinition* 3298 GetDefinitions () 3299 { 3300 return g_option_table; 3301 } 3302 3303 // Options table: Required for subclasses of Options. 3304 3305 static OptionDefinition g_option_table[]; 3306 3307 // Instance variables to hold the values for command options. 3308 3309 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3310 std::string m_str; // Holds name lookup 3311 lldb::addr_t m_addr; // Holds the address to lookup 3312 }; 3313 3314 CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) : 3315 CommandObjectParsed (interpreter, 3316 "target modules show-unwind", 3317 "Show synthesized unwind instructions for a function.", 3318 NULL), 3319 m_options (interpreter) 3320 { 3321 } 3322 3323 virtual 3324 ~CommandObjectTargetModulesShowUnwind () 3325 { 3326 } 3327 3328 virtual 3329 Options * 3330 GetOptions () 3331 { 3332 return &m_options; 3333 } 3334 3335 protected: 3336 bool 3337 DoExecute (Args& command, 3338 CommandReturnObject &result) 3339 { 3340 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3341 if (!target) 3342 { 3343 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3344 result.SetStatus (eReturnStatusFailed); 3345 return false; 3346 } 3347 3348 ExecutionContext exe_ctx = m_interpreter.GetDebugger().GetSelectedExecutionContext(); 3349 Process *process = exe_ctx.GetProcessPtr(); 3350 ABI *abi = NULL; 3351 if (process) 3352 abi = process->GetABI().get(); 3353 3354 if (process == NULL) 3355 { 3356 result.AppendError ("You must have a process running to use this command."); 3357 result.SetStatus (eReturnStatusFailed); 3358 return false; 3359 } 3360 3361 ThreadList threads(process->GetThreadList()); 3362 if (threads.GetSize() == 0) 3363 { 3364 result.AppendError ("The process must be paused to use this command."); 3365 result.SetStatus (eReturnStatusFailed); 3366 return false; 3367 } 3368 3369 ThreadSP thread(threads.GetThreadAtIndex(0)); 3370 if (thread.get() == NULL) 3371 { 3372 result.AppendError ("The process must be paused to use this command."); 3373 result.SetStatus (eReturnStatusFailed); 3374 return false; 3375 } 3376 3377 if (m_options.m_type == eLookupTypeFunctionOrSymbol) 3378 { 3379 SymbolContextList sc_list; 3380 uint32_t num_matches; 3381 ConstString function_name (m_options.m_str.c_str()); 3382 num_matches = target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list); 3383 for (uint32_t idx = 0; idx < num_matches; idx++) 3384 { 3385 SymbolContext sc; 3386 sc_list.GetContextAtIndex(idx, sc); 3387 if (sc.symbol == NULL && sc.function == NULL) 3388 continue; 3389 if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL) 3390 continue; 3391 AddressRange range; 3392 if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range)) 3393 continue; 3394 if (!range.GetBaseAddress().IsValid()) 3395 continue; 3396 ConstString funcname(sc.GetFunctionName()); 3397 if (funcname.IsEmpty()) 3398 continue; 3399 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target); 3400 if (abi) 3401 start_addr = abi->FixCodeAddress(start_addr); 3402 3403 FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc)); 3404 if (func_unwinders_sp.get() == NULL) 3405 continue; 3406 3407 Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target)); 3408 if (first_non_prologue_insn.IsValid()) 3409 { 3410 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); 3411 result.GetOutputStream().Printf ("\n"); 3412 } 3413 3414 UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*thread.get()); 3415 if (non_callsite_unwind_plan.get()) 3416 { 3417 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); 3418 non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3419 result.GetOutputStream().Printf ("\n"); 3420 } 3421 3422 UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(-1); 3423 if (callsite_unwind_plan.get()) 3424 { 3425 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); 3426 callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3427 result.GetOutputStream().Printf ("\n"); 3428 } 3429 3430 UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get()); 3431 if (arch_default_unwind_plan.get()) 3432 { 3433 result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3434 arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3435 result.GetOutputStream().Printf ("\n"); 3436 } 3437 3438 UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get()); 3439 if (fast_unwind_plan.get()) 3440 { 3441 result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3442 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3443 result.GetOutputStream().Printf ("\n"); 3444 } 3445 3446 3447 result.GetOutputStream().Printf ("\n"); 3448 } 3449 } 3450 return result.Succeeded(); 3451 } 3452 3453 CommandOptions m_options; 3454 }; 3455 3456 OptionDefinition 3457 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] = 3458 { 3459 { 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."}, 3460 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3461 }; 3462 3463 //---------------------------------------------------------------------- 3464 // Lookup information in images 3465 //---------------------------------------------------------------------- 3466 class CommandObjectTargetModulesLookup : public CommandObjectParsed 3467 { 3468 public: 3469 3470 enum 3471 { 3472 eLookupTypeInvalid = -1, 3473 eLookupTypeAddress = 0, 3474 eLookupTypeSymbol, 3475 eLookupTypeFileLine, // Line is optional 3476 eLookupTypeFunction, 3477 eLookupTypeFunctionOrSymbol, 3478 eLookupTypeType, 3479 kNumLookupTypes 3480 }; 3481 3482 class CommandOptions : public Options 3483 { 3484 public: 3485 3486 CommandOptions (CommandInterpreter &interpreter) : 3487 Options(interpreter) 3488 { 3489 OptionParsingStarting(); 3490 } 3491 3492 virtual 3493 ~CommandOptions () 3494 { 3495 } 3496 3497 virtual Error 3498 SetOptionValue (uint32_t option_idx, const char *option_arg) 3499 { 3500 Error error; 3501 3502 char short_option = (char) m_getopt_table[option_idx].val; 3503 3504 switch (short_option) 3505 { 3506 case 'a': 3507 m_type = eLookupTypeAddress; 3508 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3509 if (m_addr == LLDB_INVALID_ADDRESS) 3510 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg); 3511 break; 3512 3513 case 'o': 3514 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3515 if (m_offset == LLDB_INVALID_ADDRESS) 3516 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg); 3517 break; 3518 3519 case 's': 3520 m_str = option_arg; 3521 m_type = eLookupTypeSymbol; 3522 break; 3523 3524 case 'f': 3525 m_file.SetFile (option_arg, false); 3526 m_type = eLookupTypeFileLine; 3527 break; 3528 3529 case 'i': 3530 m_include_inlines = false; 3531 break; 3532 3533 case 'l': 3534 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); 3535 if (m_line_number == UINT32_MAX) 3536 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg); 3537 else if (m_line_number == 0) 3538 error.SetErrorString ("zero is an invalid line number"); 3539 m_type = eLookupTypeFileLine; 3540 break; 3541 3542 case 'F': 3543 m_str = option_arg; 3544 m_type = eLookupTypeFunction; 3545 break; 3546 3547 case 'n': 3548 m_str = option_arg; 3549 m_type = eLookupTypeFunctionOrSymbol; 3550 break; 3551 3552 case 't': 3553 m_str = option_arg; 3554 m_type = eLookupTypeType; 3555 break; 3556 3557 case 'v': 3558 m_verbose = 1; 3559 break; 3560 3561 case 'A': 3562 m_print_all = true; 3563 break; 3564 3565 case 'r': 3566 m_use_regex = true; 3567 break; 3568 } 3569 3570 return error; 3571 } 3572 3573 void 3574 OptionParsingStarting () 3575 { 3576 m_type = eLookupTypeInvalid; 3577 m_str.clear(); 3578 m_file.Clear(); 3579 m_addr = LLDB_INVALID_ADDRESS; 3580 m_offset = 0; 3581 m_line_number = 0; 3582 m_use_regex = false; 3583 m_include_inlines = true; 3584 m_verbose = false; 3585 m_print_all = false; 3586 } 3587 3588 const OptionDefinition* 3589 GetDefinitions () 3590 { 3591 return g_option_table; 3592 } 3593 3594 // Options table: Required for subclasses of Options. 3595 3596 static OptionDefinition g_option_table[]; 3597 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3598 std::string m_str; // Holds name lookup 3599 FileSpec m_file; // Files for file lookups 3600 lldb::addr_t m_addr; // Holds the address to lookup 3601 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 3602 uint32_t m_line_number; // Line number for file+line lookups 3603 bool m_use_regex; // Name lookups in m_str are regular expressions. 3604 bool m_include_inlines;// Check for inline entries when looking up by file/line. 3605 bool m_verbose; // Enable verbose lookup info 3606 bool m_print_all; // Print all matches, even in cases where there's a best match. 3607 3608 }; 3609 3610 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 3611 CommandObjectParsed (interpreter, 3612 "target modules lookup", 3613 "Look up information within executable and dependent shared library images.", 3614 NULL), 3615 m_options (interpreter) 3616 { 3617 CommandArgumentEntry arg; 3618 CommandArgumentData file_arg; 3619 3620 // Define the first (and only) variant of this arg. 3621 file_arg.arg_type = eArgTypeFilename; 3622 file_arg.arg_repetition = eArgRepeatStar; 3623 3624 // There is only one variant this argument could be; put it into the argument entry. 3625 arg.push_back (file_arg); 3626 3627 // Push the data for the first argument into the m_arguments vector. 3628 m_arguments.push_back (arg); 3629 } 3630 3631 virtual 3632 ~CommandObjectTargetModulesLookup () 3633 { 3634 } 3635 3636 virtual Options * 3637 GetOptions () 3638 { 3639 return &m_options; 3640 } 3641 3642 bool 3643 LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error) 3644 { 3645 switch (m_options.m_type) 3646 { 3647 case eLookupTypeAddress: 3648 case eLookupTypeFileLine: 3649 case eLookupTypeFunction: 3650 case eLookupTypeFunctionOrSymbol: 3651 case eLookupTypeSymbol: 3652 default: 3653 return false; 3654 case eLookupTypeType: 3655 break; 3656 } 3657 3658 ExecutionContext exe_ctx = interpreter.GetDebugger().GetSelectedExecutionContext(); 3659 3660 StackFrameSP frame = exe_ctx.GetFrameSP(); 3661 3662 if (!frame) 3663 return false; 3664 3665 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule)); 3666 3667 if (!sym_ctx.module_sp) 3668 return false; 3669 3670 switch (m_options.m_type) 3671 { 3672 default: 3673 return false; 3674 case eLookupTypeType: 3675 if (!m_options.m_str.empty()) 3676 { 3677 if (LookupTypeHere (m_interpreter, 3678 result.GetOutputStream(), 3679 sym_ctx, 3680 m_options.m_str.c_str(), 3681 m_options.m_use_regex)) 3682 { 3683 result.SetStatus(eReturnStatusSuccessFinishResult); 3684 return true; 3685 } 3686 } 3687 break; 3688 } 3689 3690 return true; 3691 } 3692 3693 bool 3694 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 3695 { 3696 switch (m_options.m_type) 3697 { 3698 case eLookupTypeAddress: 3699 if (m_options.m_addr != LLDB_INVALID_ADDRESS) 3700 { 3701 if (LookupAddressInModule (m_interpreter, 3702 result.GetOutputStream(), 3703 module, 3704 eSymbolContextEverything, 3705 m_options.m_addr, 3706 m_options.m_offset, 3707 m_options.m_verbose)) 3708 { 3709 result.SetStatus(eReturnStatusSuccessFinishResult); 3710 return true; 3711 } 3712 } 3713 break; 3714 3715 case eLookupTypeSymbol: 3716 if (!m_options.m_str.empty()) 3717 { 3718 if (LookupSymbolInModule (m_interpreter, 3719 result.GetOutputStream(), 3720 module, 3721 m_options.m_str.c_str(), 3722 m_options.m_use_regex, 3723 m_options.m_verbose)) 3724 { 3725 result.SetStatus(eReturnStatusSuccessFinishResult); 3726 return true; 3727 } 3728 } 3729 break; 3730 3731 case eLookupTypeFileLine: 3732 if (m_options.m_file) 3733 { 3734 3735 if (LookupFileAndLineInModule (m_interpreter, 3736 result.GetOutputStream(), 3737 module, 3738 m_options.m_file, 3739 m_options.m_line_number, 3740 m_options.m_include_inlines, 3741 m_options.m_verbose)) 3742 { 3743 result.SetStatus(eReturnStatusSuccessFinishResult); 3744 return true; 3745 } 3746 } 3747 break; 3748 3749 case eLookupTypeFunctionOrSymbol: 3750 case eLookupTypeFunction: 3751 if (!m_options.m_str.empty()) 3752 { 3753 if (LookupFunctionInModule (m_interpreter, 3754 result.GetOutputStream(), 3755 module, 3756 m_options.m_str.c_str(), 3757 m_options.m_use_regex, 3758 m_options.m_include_inlines, 3759 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols 3760 m_options.m_verbose)) 3761 { 3762 result.SetStatus(eReturnStatusSuccessFinishResult); 3763 return true; 3764 } 3765 } 3766 break; 3767 3768 3769 case eLookupTypeType: 3770 if (!m_options.m_str.empty()) 3771 { 3772 if (LookupTypeInModule (m_interpreter, 3773 result.GetOutputStream(), 3774 module, 3775 m_options.m_str.c_str(), 3776 m_options.m_use_regex)) 3777 { 3778 result.SetStatus(eReturnStatusSuccessFinishResult); 3779 return true; 3780 } 3781 } 3782 break; 3783 3784 default: 3785 m_options.GenerateOptionUsage (result.GetErrorStream(), this); 3786 syntax_error = true; 3787 break; 3788 } 3789 3790 result.SetStatus (eReturnStatusFailed); 3791 return false; 3792 } 3793 3794 protected: 3795 virtual bool 3796 DoExecute (Args& command, 3797 CommandReturnObject &result) 3798 { 3799 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3800 if (target == NULL) 3801 { 3802 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3803 result.SetStatus (eReturnStatusFailed); 3804 return false; 3805 } 3806 else 3807 { 3808 bool syntax_error = false; 3809 uint32_t i; 3810 uint32_t num_successful_lookups = 0; 3811 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3812 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3813 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3814 // Dump all sections for all modules images 3815 3816 if (command.GetArgumentCount() == 0) 3817 { 3818 ModuleSP current_module; 3819 3820 // Where it is possible to look in the current symbol context 3821 // first, try that. If this search was successful and --all 3822 // was not passed, don't print anything else. 3823 if (LookupHere (m_interpreter, result, syntax_error)) 3824 { 3825 result.GetOutputStream().EOL(); 3826 num_successful_lookups++; 3827 if (!m_options.m_print_all) 3828 { 3829 result.SetStatus (eReturnStatusSuccessFinishResult); 3830 return result.Succeeded(); 3831 } 3832 } 3833 3834 // Dump all sections for all other modules 3835 3836 ModuleList &target_modules = target->GetImages(); 3837 Mutex::Locker modules_locker(target_modules.GetMutex()); 3838 const uint32_t num_modules = target_modules.GetSize(); 3839 if (num_modules > 0) 3840 { 3841 for (i = 0; i<num_modules && syntax_error == false; ++i) 3842 { 3843 Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i); 3844 3845 if (module_pointer != current_module.get() && 3846 LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error)) 3847 { 3848 result.GetOutputStream().EOL(); 3849 num_successful_lookups++; 3850 } 3851 } 3852 } 3853 else 3854 { 3855 result.AppendError ("the target has no associated executable images"); 3856 result.SetStatus (eReturnStatusFailed); 3857 return false; 3858 } 3859 } 3860 else 3861 { 3862 // Dump specified images (by basename or fullpath) 3863 const char *arg_cstr; 3864 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 3865 { 3866 ModuleList module_list; 3867 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false); 3868 if (num_matches > 0) 3869 { 3870 for (size_t j=0; j<num_matches; ++j) 3871 { 3872 Module *module = module_list.GetModulePointerAtIndex(j); 3873 if (module) 3874 { 3875 if (LookupInModule (m_interpreter, module, result, syntax_error)) 3876 { 3877 result.GetOutputStream().EOL(); 3878 num_successful_lookups++; 3879 } 3880 } 3881 } 3882 } 3883 else 3884 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 3885 } 3886 } 3887 3888 if (num_successful_lookups > 0) 3889 result.SetStatus (eReturnStatusSuccessFinishResult); 3890 else 3891 result.SetStatus (eReturnStatusFailed); 3892 } 3893 return result.Succeeded(); 3894 } 3895 3896 CommandOptions m_options; 3897 }; 3898 3899 OptionDefinition 3900 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 3901 { 3902 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."}, 3903 { 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."}, 3904 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5 3905 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ , 3906 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 3907 { 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."}, 3908 { 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."}, 3909 { 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)."}, 3910 { LLDB_OPT_SET_FROM_TO(3,5), 3911 false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."}, 3912 { 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."}, 3913 { 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."}, 3914 { 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."}, 3915 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 3916 { 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."}, 3917 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3918 }; 3919 3920 3921 #pragma mark CommandObjectMultiwordImageSearchPaths 3922 3923 //------------------------------------------------------------------------- 3924 // CommandObjectMultiwordImageSearchPaths 3925 //------------------------------------------------------------------------- 3926 3927 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 3928 { 3929 public: 3930 3931 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 3932 CommandObjectMultiword (interpreter, 3933 "target modules search-paths", 3934 "A set of commands for operating on debugger target image search paths.", 3935 "target modules search-paths <subcommand> [<subcommand-options>]") 3936 { 3937 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 3938 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 3939 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 3940 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 3941 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 3942 } 3943 3944 ~CommandObjectTargetModulesImageSearchPaths() 3945 { 3946 } 3947 }; 3948 3949 3950 3951 #pragma mark CommandObjectTargetModules 3952 3953 //------------------------------------------------------------------------- 3954 // CommandObjectTargetModules 3955 //------------------------------------------------------------------------- 3956 3957 class CommandObjectTargetModules : public CommandObjectMultiword 3958 { 3959 public: 3960 //------------------------------------------------------------------ 3961 // Constructors and Destructors 3962 //------------------------------------------------------------------ 3963 CommandObjectTargetModules(CommandInterpreter &interpreter) : 3964 CommandObjectMultiword (interpreter, 3965 "target modules", 3966 "A set of commands for accessing information for one or more target modules.", 3967 "target modules <sub-command> ...") 3968 { 3969 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 3970 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 3971 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter))); 3972 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 3973 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 3974 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 3975 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 3976 LoadSubCommand ("show-unwind", CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter))); 3977 3978 } 3979 virtual 3980 ~CommandObjectTargetModules() 3981 { 3982 } 3983 3984 private: 3985 //------------------------------------------------------------------ 3986 // For CommandObjectTargetModules only 3987 //------------------------------------------------------------------ 3988 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 3989 }; 3990 3991 3992 3993 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed 3994 { 3995 public: 3996 CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) : 3997 CommandObjectParsed (interpreter, 3998 "target symbols add", 3999 "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.", 4000 "target symbols add [<symfile>]"), 4001 m_option_group (interpreter), 4002 m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."), 4003 m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true) 4004 4005 { 4006 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4007 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4008 m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2); 4009 m_option_group.Finalize(); 4010 } 4011 4012 virtual 4013 ~CommandObjectTargetSymbolsAdd () 4014 { 4015 } 4016 4017 int 4018 HandleArgumentCompletion (Args &input, 4019 int &cursor_index, 4020 int &cursor_char_position, 4021 OptionElementVector &opt_element_vector, 4022 int match_start_point, 4023 int max_return_elements, 4024 bool &word_complete, 4025 StringList &matches) 4026 { 4027 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 4028 completion_str.erase (cursor_char_position); 4029 4030 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 4031 CommandCompletions::eDiskFileCompletion, 4032 completion_str.c_str(), 4033 match_start_point, 4034 max_return_elements, 4035 NULL, 4036 word_complete, 4037 matches); 4038 return matches.GetSize(); 4039 } 4040 4041 virtual Options * 4042 GetOptions () 4043 { 4044 return &m_option_group; 4045 } 4046 4047 4048 protected: 4049 4050 bool 4051 AddModuleSymbols (Target *target, 4052 const FileSpec &symfile_spec, 4053 bool &flush, 4054 CommandReturnObject &result) 4055 { 4056 ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture())); 4057 const UUID &symfile_uuid = symfile_module_sp->GetUUID(); 4058 StreamString ss_symfile_uuid; 4059 symfile_uuid.Dump(&ss_symfile_uuid); 4060 4061 if (symfile_module_sp) 4062 { 4063 char symfile_path[PATH_MAX]; 4064 symfile_spec.GetPath (symfile_path, sizeof(symfile_path)); 4065 // We now have a module that represents a symbol file 4066 // that can be used for a module that might exist in the 4067 // current target, so we need to find that module in the 4068 // target 4069 4070 ModuleSP old_module_sp (target->GetImages().FindModule (symfile_uuid)); 4071 if (old_module_sp) 4072 { 4073 // The module has not yet created its symbol vendor, we can just 4074 // give the existing target module the symfile path to use for 4075 // when it decides to create it! 4076 old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec()); 4077 4078 // Provide feedback that the symfile has been successfully added. 4079 const FileSpec &module_fs = old_module_sp->GetFileSpec(); 4080 result.AppendMessageWithFormat("symbol file '%s' with UUID %s has been successfully added to the '%s/%s' module\n", 4081 symfile_path, ss_symfile_uuid.GetData(), 4082 module_fs.GetDirectory().AsCString(), module_fs.GetFilename().AsCString()); 4083 4084 // Let clients know something changed in the module 4085 // if it is currently loaded 4086 ModuleList module_list; 4087 module_list.Append (old_module_sp); 4088 target->ModulesDidLoad (module_list); 4089 flush = true; 4090 } 4091 else 4092 { 4093 result.AppendErrorWithFormat ("symbol file '%s' with UUID %s does not match any existing module%s\n", 4094 symfile_path, ss_symfile_uuid.GetData(), 4095 (symfile_spec.GetFileType() != FileSpec::eFileTypeRegular) 4096 ? "\n please specify the full path to the symbol file" 4097 : ""); 4098 return false; 4099 } 4100 } 4101 else 4102 { 4103 result.AppendError ("one or more executable image paths must be specified"); 4104 result.SetStatus (eReturnStatusFailed); 4105 return false; 4106 } 4107 result.SetStatus (eReturnStatusSuccessFinishResult); 4108 return true; 4109 } 4110 4111 virtual bool 4112 DoExecute (Args& args, 4113 CommandReturnObject &result) 4114 { 4115 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 4116 Target *target = exe_ctx.GetTargetPtr(); 4117 result.SetStatus (eReturnStatusFailed); 4118 if (target == NULL) 4119 { 4120 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 4121 } 4122 else 4123 { 4124 bool flush = false; 4125 ModuleSpec sym_spec; 4126 const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet(); 4127 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); 4128 const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet(); 4129 4130 const size_t argc = args.GetArgumentCount(); 4131 if (argc == 0) 4132 { 4133 if (uuid_option_set || file_option_set || frame_option_set) 4134 { 4135 bool success = false; 4136 bool error_set = false; 4137 if (frame_option_set) 4138 { 4139 Process *process = exe_ctx.GetProcessPtr(); 4140 if (process) 4141 { 4142 const StateType process_state = process->GetState(); 4143 if (StateIsStoppedState (process_state, true)) 4144 { 4145 StackFrame *frame = exe_ctx.GetFramePtr(); 4146 if (frame) 4147 { 4148 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp); 4149 if (frame_module_sp) 4150 { 4151 if (frame_module_sp->GetPlatformFileSpec().Exists()) 4152 { 4153 sym_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); 4154 sym_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); 4155 } 4156 sym_spec.GetUUID() = frame_module_sp->GetUUID(); 4157 success = sym_spec.GetUUID().IsValid() || sym_spec.GetFileSpec(); 4158 } 4159 else 4160 { 4161 result.AppendError ("frame has no module"); 4162 error_set = true; 4163 } 4164 } 4165 else 4166 { 4167 result.AppendError ("invalid current frame"); 4168 error_set = true; 4169 } 4170 } 4171 else 4172 { 4173 result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state)); 4174 error_set = true; 4175 } 4176 } 4177 else 4178 { 4179 result.AppendError ("a process must exist in order to use the --frame option"); 4180 error_set = true; 4181 } 4182 } 4183 else 4184 { 4185 if (uuid_option_set) 4186 { 4187 sym_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 4188 success |= sym_spec.GetUUID().IsValid(); 4189 } 4190 else if (file_option_set) 4191 { 4192 sym_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 4193 ModuleSP module_sp (target->GetImages().FindFirstModule(sym_spec)); 4194 if (module_sp) 4195 { 4196 sym_spec.GetFileSpec() = module_sp->GetFileSpec(); 4197 sym_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); 4198 sym_spec.GetUUID() = module_sp->GetUUID(); 4199 sym_spec.GetArchitecture() = module_sp->GetArchitecture(); 4200 } 4201 else 4202 { 4203 sym_spec.GetArchitecture() = target->GetArchitecture(); 4204 } 4205 success |= sym_spec.GetFileSpec().Exists(); 4206 } 4207 } 4208 4209 if (success) 4210 { 4211 if (Symbols::DownloadObjectAndSymbolFile (sym_spec)) 4212 { 4213 if (sym_spec.GetSymbolFileSpec()) 4214 success = AddModuleSymbols (target, sym_spec.GetSymbolFileSpec(), flush, result); 4215 } 4216 } 4217 4218 if (!success && !error_set) 4219 { 4220 StreamString error_strm; 4221 if (uuid_option_set) 4222 { 4223 error_strm.PutCString("unable to find debug symbols for UUID "); 4224 sym_spec.GetUUID().Dump (&error_strm); 4225 } 4226 else if (file_option_set) 4227 { 4228 error_strm.PutCString("unable to find debug symbols for the executable file "); 4229 error_strm << sym_spec.GetFileSpec(); 4230 } 4231 else if (frame_option_set) 4232 { 4233 error_strm.PutCString("unable to find debug symbols for the current frame"); 4234 } 4235 result.AppendError (error_strm.GetData()); 4236 } 4237 } 4238 else 4239 { 4240 result.AppendError ("one or more symbol file paths must be specified, or options must be specified"); 4241 } 4242 } 4243 else 4244 { 4245 if (uuid_option_set) 4246 { 4247 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments"); 4248 } 4249 else if (file_option_set) 4250 { 4251 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments"); 4252 } 4253 else if (frame_option_set) 4254 { 4255 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments"); 4256 } 4257 else 4258 { 4259 PlatformSP platform_sp (target->GetPlatform()); 4260 4261 for (size_t i=0; i<argc; ++i) 4262 { 4263 const char *symfile_path = args.GetArgumentAtIndex(i); 4264 if (symfile_path) 4265 { 4266 FileSpec symfile_spec; 4267 sym_spec.GetSymbolFileSpec().SetFile(symfile_path, true); 4268 if (platform_sp) 4269 platform_sp->ResolveSymbolFile(*target, sym_spec, symfile_spec); 4270 else 4271 symfile_spec.SetFile(symfile_path, true); 4272 4273 ArchSpec arch; 4274 bool symfile_exists = symfile_spec.Exists(); 4275 4276 if (symfile_exists) 4277 { 4278 if (!AddModuleSymbols (target, symfile_spec, flush, result)) 4279 break; 4280 } 4281 else 4282 { 4283 char resolved_symfile_path[PATH_MAX]; 4284 if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path))) 4285 { 4286 if (strcmp (resolved_symfile_path, symfile_path) != 0) 4287 { 4288 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path); 4289 break; 4290 } 4291 } 4292 result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path); 4293 break; 4294 } 4295 } 4296 } 4297 } 4298 } 4299 4300 if (flush) 4301 { 4302 Process *process = exe_ctx.GetProcessPtr(); 4303 if (process) 4304 process->Flush(); 4305 } 4306 } 4307 return result.Succeeded(); 4308 } 4309 4310 OptionGroupOptions m_option_group; 4311 OptionGroupUUID m_uuid_option_group; 4312 OptionGroupFile m_file_option; 4313 OptionGroupBoolean m_current_frame_option; 4314 4315 4316 }; 4317 4318 4319 #pragma mark CommandObjectTargetSymbols 4320 4321 //------------------------------------------------------------------------- 4322 // CommandObjectTargetSymbols 4323 //------------------------------------------------------------------------- 4324 4325 class CommandObjectTargetSymbols : public CommandObjectMultiword 4326 { 4327 public: 4328 //------------------------------------------------------------------ 4329 // Constructors and Destructors 4330 //------------------------------------------------------------------ 4331 CommandObjectTargetSymbols(CommandInterpreter &interpreter) : 4332 CommandObjectMultiword (interpreter, 4333 "target symbols", 4334 "A set of commands for adding and managing debug symbol files.", 4335 "target symbols <sub-command> ...") 4336 { 4337 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter))); 4338 4339 } 4340 virtual 4341 ~CommandObjectTargetSymbols() 4342 { 4343 } 4344 4345 private: 4346 //------------------------------------------------------------------ 4347 // For CommandObjectTargetModules only 4348 //------------------------------------------------------------------ 4349 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols); 4350 }; 4351 4352 4353 #pragma mark CommandObjectTargetStopHookAdd 4354 4355 //------------------------------------------------------------------------- 4356 // CommandObjectTargetStopHookAdd 4357 //------------------------------------------------------------------------- 4358 4359 class CommandObjectTargetStopHookAdd : public CommandObjectParsed 4360 { 4361 public: 4362 4363 class CommandOptions : public Options 4364 { 4365 public: 4366 CommandOptions (CommandInterpreter &interpreter) : 4367 Options(interpreter), 4368 m_line_start(0), 4369 m_line_end (UINT_MAX), 4370 m_func_name_type_mask (eFunctionNameTypeAuto), 4371 m_sym_ctx_specified (false), 4372 m_thread_specified (false), 4373 m_use_one_liner (false), 4374 m_one_liner() 4375 { 4376 } 4377 4378 ~CommandOptions () {} 4379 4380 const OptionDefinition* 4381 GetDefinitions () 4382 { 4383 return g_option_table; 4384 } 4385 4386 virtual Error 4387 SetOptionValue (uint32_t option_idx, const char *option_arg) 4388 { 4389 Error error; 4390 char short_option = (char) m_getopt_table[option_idx].val; 4391 bool success; 4392 4393 switch (short_option) 4394 { 4395 case 'c': 4396 m_class_name = option_arg; 4397 m_sym_ctx_specified = true; 4398 break; 4399 4400 case 'e': 4401 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success); 4402 if (!success) 4403 { 4404 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg); 4405 break; 4406 } 4407 m_sym_ctx_specified = true; 4408 break; 4409 4410 case 'l': 4411 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 4412 if (!success) 4413 { 4414 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg); 4415 break; 4416 } 4417 m_sym_ctx_specified = true; 4418 break; 4419 4420 case 'i': 4421 m_no_inlines = true; 4422 break; 4423 4424 case 'n': 4425 m_function_name = option_arg; 4426 m_func_name_type_mask |= eFunctionNameTypeAuto; 4427 m_sym_ctx_specified = true; 4428 break; 4429 4430 case 'f': 4431 m_file_name = option_arg; 4432 m_sym_ctx_specified = true; 4433 break; 4434 case 's': 4435 m_module_name = option_arg; 4436 m_sym_ctx_specified = true; 4437 break; 4438 case 't' : 4439 { 4440 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 4441 if (m_thread_id == LLDB_INVALID_THREAD_ID) 4442 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 4443 m_thread_specified = true; 4444 } 4445 break; 4446 case 'T': 4447 m_thread_name = option_arg; 4448 m_thread_specified = true; 4449 break; 4450 case 'q': 4451 m_queue_name = option_arg; 4452 m_thread_specified = true; 4453 break; 4454 case 'x': 4455 { 4456 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 4457 if (m_thread_id == UINT32_MAX) 4458 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 4459 m_thread_specified = true; 4460 } 4461 break; 4462 case 'o': 4463 m_use_one_liner = true; 4464 m_one_liner = option_arg; 4465 break; 4466 default: 4467 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option); 4468 break; 4469 } 4470 return error; 4471 } 4472 4473 void 4474 OptionParsingStarting () 4475 { 4476 m_class_name.clear(); 4477 m_function_name.clear(); 4478 m_line_start = 0; 4479 m_line_end = UINT_MAX; 4480 m_file_name.clear(); 4481 m_module_name.clear(); 4482 m_func_name_type_mask = eFunctionNameTypeAuto; 4483 m_thread_id = LLDB_INVALID_THREAD_ID; 4484 m_thread_index = UINT32_MAX; 4485 m_thread_name.clear(); 4486 m_queue_name.clear(); 4487 4488 m_no_inlines = false; 4489 m_sym_ctx_specified = false; 4490 m_thread_specified = false; 4491 4492 m_use_one_liner = false; 4493 m_one_liner.clear(); 4494 } 4495 4496 4497 static OptionDefinition g_option_table[]; 4498 4499 std::string m_class_name; 4500 std::string m_function_name; 4501 uint32_t m_line_start; 4502 uint32_t m_line_end; 4503 std::string m_file_name; 4504 std::string m_module_name; 4505 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 4506 lldb::tid_t m_thread_id; 4507 uint32_t m_thread_index; 4508 std::string m_thread_name; 4509 std::string m_queue_name; 4510 bool m_sym_ctx_specified; 4511 bool m_no_inlines; 4512 bool m_thread_specified; 4513 // Instance variables to hold the values for one_liner options. 4514 bool m_use_one_liner; 4515 std::string m_one_liner; 4516 }; 4517 4518 Options * 4519 GetOptions () 4520 { 4521 return &m_options; 4522 } 4523 4524 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 4525 CommandObjectParsed (interpreter, 4526 "target stop-hook add ", 4527 "Add a hook to be executed when the target stops.", 4528 "target stop-hook add"), 4529 m_options (interpreter) 4530 { 4531 } 4532 4533 ~CommandObjectTargetStopHookAdd () 4534 { 4535 } 4536 4537 static size_t 4538 ReadCommandsCallbackFunction (void *baton, 4539 InputReader &reader, 4540 lldb::InputReaderAction notification, 4541 const char *bytes, 4542 size_t bytes_len) 4543 { 4544 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 4545 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton); 4546 static bool got_interrupted; 4547 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 4548 4549 switch (notification) 4550 { 4551 case eInputReaderActivate: 4552 if (!batch_mode) 4553 { 4554 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end."); 4555 if (reader.GetPrompt()) 4556 out_stream->Printf ("%s", reader.GetPrompt()); 4557 out_stream->Flush(); 4558 } 4559 got_interrupted = false; 4560 break; 4561 4562 case eInputReaderDeactivate: 4563 break; 4564 4565 case eInputReaderReactivate: 4566 if (reader.GetPrompt() && !batch_mode) 4567 { 4568 out_stream->Printf ("%s", reader.GetPrompt()); 4569 out_stream->Flush(); 4570 } 4571 got_interrupted = false; 4572 break; 4573 4574 case eInputReaderAsynchronousOutputWritten: 4575 break; 4576 4577 case eInputReaderGotToken: 4578 if (bytes && bytes_len && baton) 4579 { 4580 StringList *commands = new_stop_hook->GetCommandPointer(); 4581 if (commands) 4582 { 4583 commands->AppendString (bytes, bytes_len); 4584 } 4585 } 4586 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode) 4587 { 4588 out_stream->Printf ("%s", reader.GetPrompt()); 4589 out_stream->Flush(); 4590 } 4591 break; 4592 4593 case eInputReaderInterrupt: 4594 { 4595 // Finish, and cancel the stop hook. 4596 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID()); 4597 if (!batch_mode) 4598 { 4599 out_stream->Printf ("Stop hook cancelled.\n"); 4600 out_stream->Flush(); 4601 } 4602 4603 reader.SetIsDone (true); 4604 } 4605 got_interrupted = true; 4606 break; 4607 4608 case eInputReaderEndOfFile: 4609 reader.SetIsDone (true); 4610 break; 4611 4612 case eInputReaderDone: 4613 if (!got_interrupted && !batch_mode) 4614 { 4615 out_stream->Printf ("Stop hook #%llu added.\n", new_stop_hook->GetID()); 4616 out_stream->Flush(); 4617 } 4618 break; 4619 } 4620 4621 return bytes_len; 4622 } 4623 4624 protected: 4625 bool 4626 DoExecute (Args& command, CommandReturnObject &result) 4627 { 4628 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4629 if (target) 4630 { 4631 Target::StopHookSP new_hook_sp; 4632 target->AddStopHook (new_hook_sp); 4633 4634 // First step, make the specifier. 4635 std::auto_ptr<SymbolContextSpecifier> specifier_ap; 4636 if (m_options.m_sym_ctx_specified) 4637 { 4638 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 4639 4640 if (!m_options.m_module_name.empty()) 4641 { 4642 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 4643 } 4644 4645 if (!m_options.m_class_name.empty()) 4646 { 4647 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 4648 } 4649 4650 if (!m_options.m_file_name.empty()) 4651 { 4652 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 4653 } 4654 4655 if (m_options.m_line_start != 0) 4656 { 4657 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 4658 } 4659 4660 if (m_options.m_line_end != UINT_MAX) 4661 { 4662 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 4663 } 4664 4665 if (!m_options.m_function_name.empty()) 4666 { 4667 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 4668 } 4669 } 4670 4671 if (specifier_ap.get()) 4672 new_hook_sp->SetSpecifier (specifier_ap.release()); 4673 4674 // Next see if any of the thread options have been entered: 4675 4676 if (m_options.m_thread_specified) 4677 { 4678 ThreadSpec *thread_spec = new ThreadSpec(); 4679 4680 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 4681 { 4682 thread_spec->SetTID (m_options.m_thread_id); 4683 } 4684 4685 if (m_options.m_thread_index != UINT32_MAX) 4686 thread_spec->SetIndex (m_options.m_thread_index); 4687 4688 if (!m_options.m_thread_name.empty()) 4689 thread_spec->SetName (m_options.m_thread_name.c_str()); 4690 4691 if (!m_options.m_queue_name.empty()) 4692 thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 4693 4694 new_hook_sp->SetThreadSpecifier (thread_spec); 4695 4696 } 4697 if (m_options.m_use_one_liner) 4698 { 4699 // Use one-liner. 4700 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 4701 result.AppendMessageWithFormat("Stop hook #%llu added.\n", new_hook_sp->GetID()); 4702 } 4703 else 4704 { 4705 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into 4706 // the new stop hook's command string. 4707 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 4708 if (!reader_sp) 4709 { 4710 result.AppendError("out of memory\n"); 4711 result.SetStatus (eReturnStatusFailed); 4712 target->RemoveStopHookByID (new_hook_sp->GetID()); 4713 return false; 4714 } 4715 4716 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction, 4717 new_hook_sp.get(), // baton 4718 eInputReaderGranularityLine, // token size, to pass to callback function 4719 "DONE", // end token 4720 "> ", // prompt 4721 true)); // echo input 4722 if (!err.Success()) 4723 { 4724 result.AppendError (err.AsCString()); 4725 result.SetStatus (eReturnStatusFailed); 4726 target->RemoveStopHookByID (new_hook_sp->GetID()); 4727 return false; 4728 } 4729 m_interpreter.GetDebugger().PushInputReader (reader_sp); 4730 } 4731 result.SetStatus (eReturnStatusSuccessFinishNoResult); 4732 } 4733 else 4734 { 4735 result.AppendError ("invalid target\n"); 4736 result.SetStatus (eReturnStatusFailed); 4737 } 4738 4739 return result.Succeeded(); 4740 } 4741 private: 4742 CommandOptions m_options; 4743 }; 4744 4745 OptionDefinition 4746 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 4747 { 4748 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, 0, eArgTypeOneLiner, 4749 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 4750 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 4751 "Set the module within which the stop-hook is to be run."}, 4752 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex, 4753 "The stop hook is run only for the thread whose index matches this argument."}, 4754 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID, 4755 "The stop hook is run only for the thread whose TID matches this argument."}, 4756 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName, 4757 "The stop hook is run only for the thread whose thread name matches this argument."}, 4758 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName, 4759 "The stop hook is run only for threads in the queue whose name is given by this argument."}, 4760 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 4761 "Specify the source file within which the stop-hook is to be run." }, 4762 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 4763 "Set the start of the line range for which the stop-hook is to be run."}, 4764 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum, 4765 "Set the end of the line range for which the stop-hook is to be run."}, 4766 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, 0, eArgTypeClassName, 4767 "Specify the class within which the stop-hook is to be run." }, 4768 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 4769 "Set the function name within which the stop hook will be run." }, 4770 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 4771 }; 4772 4773 #pragma mark CommandObjectTargetStopHookDelete 4774 4775 //------------------------------------------------------------------------- 4776 // CommandObjectTargetStopHookDelete 4777 //------------------------------------------------------------------------- 4778 4779 class CommandObjectTargetStopHookDelete : public CommandObjectParsed 4780 { 4781 public: 4782 4783 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 4784 CommandObjectParsed (interpreter, 4785 "target stop-hook delete", 4786 "Delete a stop-hook.", 4787 "target stop-hook delete [<idx>]") 4788 { 4789 } 4790 4791 ~CommandObjectTargetStopHookDelete () 4792 { 4793 } 4794 4795 protected: 4796 bool 4797 DoExecute (Args& command, CommandReturnObject &result) 4798 { 4799 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4800 if (target) 4801 { 4802 // FIXME: see if we can use the breakpoint id style parser? 4803 size_t num_args = command.GetArgumentCount(); 4804 if (num_args == 0) 4805 { 4806 if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 4807 { 4808 result.SetStatus (eReturnStatusFailed); 4809 return false; 4810 } 4811 else 4812 { 4813 target->RemoveAllStopHooks(); 4814 } 4815 } 4816 else 4817 { 4818 bool success; 4819 for (size_t i = 0; i < num_args; i++) 4820 { 4821 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 4822 if (!success) 4823 { 4824 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4825 result.SetStatus(eReturnStatusFailed); 4826 return false; 4827 } 4828 success = target->RemoveStopHookByID (user_id); 4829 if (!success) 4830 { 4831 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4832 result.SetStatus(eReturnStatusFailed); 4833 return false; 4834 } 4835 } 4836 } 4837 result.SetStatus (eReturnStatusSuccessFinishNoResult); 4838 } 4839 else 4840 { 4841 result.AppendError ("invalid target\n"); 4842 result.SetStatus (eReturnStatusFailed); 4843 } 4844 4845 return result.Succeeded(); 4846 } 4847 }; 4848 #pragma mark CommandObjectTargetStopHookEnableDisable 4849 4850 //------------------------------------------------------------------------- 4851 // CommandObjectTargetStopHookEnableDisable 4852 //------------------------------------------------------------------------- 4853 4854 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed 4855 { 4856 public: 4857 4858 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 4859 CommandObjectParsed (interpreter, 4860 name, 4861 help, 4862 syntax), 4863 m_enable (enable) 4864 { 4865 } 4866 4867 ~CommandObjectTargetStopHookEnableDisable () 4868 { 4869 } 4870 4871 protected: 4872 bool 4873 DoExecute (Args& command, CommandReturnObject &result) 4874 { 4875 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4876 if (target) 4877 { 4878 // FIXME: see if we can use the breakpoint id style parser? 4879 size_t num_args = command.GetArgumentCount(); 4880 bool success; 4881 4882 if (num_args == 0) 4883 { 4884 target->SetAllStopHooksActiveState (m_enable); 4885 } 4886 else 4887 { 4888 for (size_t i = 0; i < num_args; i++) 4889 { 4890 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 4891 if (!success) 4892 { 4893 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4894 result.SetStatus(eReturnStatusFailed); 4895 return false; 4896 } 4897 success = target->SetStopHookActiveStateByID (user_id, m_enable); 4898 if (!success) 4899 { 4900 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4901 result.SetStatus(eReturnStatusFailed); 4902 return false; 4903 } 4904 } 4905 } 4906 result.SetStatus (eReturnStatusSuccessFinishNoResult); 4907 } 4908 else 4909 { 4910 result.AppendError ("invalid target\n"); 4911 result.SetStatus (eReturnStatusFailed); 4912 } 4913 return result.Succeeded(); 4914 } 4915 private: 4916 bool m_enable; 4917 }; 4918 4919 #pragma mark CommandObjectTargetStopHookList 4920 4921 //------------------------------------------------------------------------- 4922 // CommandObjectTargetStopHookList 4923 //------------------------------------------------------------------------- 4924 4925 class CommandObjectTargetStopHookList : public CommandObjectParsed 4926 { 4927 public: 4928 4929 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 4930 CommandObjectParsed (interpreter, 4931 "target stop-hook list", 4932 "List all stop-hooks.", 4933 "target stop-hook list [<type>]") 4934 { 4935 } 4936 4937 ~CommandObjectTargetStopHookList () 4938 { 4939 } 4940 4941 protected: 4942 bool 4943 DoExecute (Args& command, CommandReturnObject &result) 4944 { 4945 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4946 if (!target) 4947 { 4948 result.AppendError ("invalid target\n"); 4949 result.SetStatus (eReturnStatusFailed); 4950 return result.Succeeded(); 4951 } 4952 4953 size_t num_hooks = target->GetNumStopHooks (); 4954 if (num_hooks == 0) 4955 { 4956 result.GetOutputStream().PutCString ("No stop hooks.\n"); 4957 } 4958 else 4959 { 4960 for (size_t i = 0; i < num_hooks; i++) 4961 { 4962 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 4963 if (i > 0) 4964 result.GetOutputStream().PutCString ("\n"); 4965 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 4966 } 4967 } 4968 result.SetStatus (eReturnStatusSuccessFinishResult); 4969 return result.Succeeded(); 4970 } 4971 }; 4972 4973 #pragma mark CommandObjectMultiwordTargetStopHooks 4974 //------------------------------------------------------------------------- 4975 // CommandObjectMultiwordTargetStopHooks 4976 //------------------------------------------------------------------------- 4977 4978 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 4979 { 4980 public: 4981 4982 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 4983 CommandObjectMultiword (interpreter, 4984 "target stop-hook", 4985 "A set of commands for operating on debugger target stop-hooks.", 4986 "target stop-hook <subcommand> [<subcommand-options>]") 4987 { 4988 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 4989 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 4990 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 4991 false, 4992 "target stop-hook disable [<id>]", 4993 "Disable a stop-hook.", 4994 "target stop-hook disable"))); 4995 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 4996 true, 4997 "target stop-hook enable [<id>]", 4998 "Enable a stop-hook.", 4999 "target stop-hook enable"))); 5000 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 5001 } 5002 5003 ~CommandObjectMultiwordTargetStopHooks() 5004 { 5005 } 5006 }; 5007 5008 5009 5010 #pragma mark CommandObjectMultiwordTarget 5011 5012 //------------------------------------------------------------------------- 5013 // CommandObjectMultiwordTarget 5014 //------------------------------------------------------------------------- 5015 5016 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 5017 CommandObjectMultiword (interpreter, 5018 "target", 5019 "A set of commands for operating on debugger targets.", 5020 "target <subcommand> [<subcommand-options>]") 5021 { 5022 5023 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 5024 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 5025 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 5026 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 5027 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 5028 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 5029 LoadSubCommand ("symbols", CommandObjectSP (new CommandObjectTargetSymbols (interpreter))); 5030 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 5031 } 5032 5033 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 5034 { 5035 } 5036 5037 5038