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 if (file_path) 243 { 244 // Use exactly what the user typed as the first argument 245 // when we exec or posix_spawn 246 target_sp->SetArg0 (file_path); 247 } 248 249 debugger.GetTargetList().SetSelectedTarget(target_sp.get()); 250 if (core_file) 251 { 252 char core_path[PATH_MAX]; 253 core_file.GetPath(core_path, sizeof(core_path)); 254 if (core_file.Exists()) 255 { 256 FileSpec core_file_dir; 257 core_file_dir.GetDirectory() = core_file.GetDirectory(); 258 target_sp->GetExecutableSearchPaths ().Append (core_file_dir); 259 260 ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file)); 261 262 if (process_sp) 263 { 264 // Seems wierd that we Launch a core file, but that is 265 // what we do! 266 error = process_sp->LoadCore(); 267 268 if (error.Fail()) 269 { 270 result.AppendError(error.AsCString("can't find plug-in for core file")); 271 result.SetStatus (eReturnStatusFailed); 272 return false; 273 } 274 else 275 { 276 result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName()); 277 result.SetStatus (eReturnStatusSuccessFinishNoResult); 278 } 279 } 280 else 281 { 282 result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path); 283 result.SetStatus (eReturnStatusFailed); 284 } 285 } 286 else 287 { 288 result.AppendErrorWithFormat ("Core file '%s' does not exist\n", core_path); 289 result.SetStatus (eReturnStatusFailed); 290 } 291 } 292 else 293 { 294 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName()); 295 result.SetStatus (eReturnStatusSuccessFinishNoResult); 296 } 297 } 298 else 299 { 300 result.AppendError(error.AsCString()); 301 result.SetStatus (eReturnStatusFailed); 302 } 303 } 304 else 305 { 306 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core-file option.\n", m_cmd_name.c_str()); 307 result.SetStatus (eReturnStatusFailed); 308 } 309 return result.Succeeded(); 310 311 } 312 313 private: 314 OptionGroupOptions m_option_group; 315 OptionGroupArchitecture m_arch_option; 316 OptionGroupPlatform m_platform_options; 317 OptionGroupFile m_core_file; 318 319 }; 320 321 #pragma mark CommandObjectTargetList 322 323 //---------------------------------------------------------------------- 324 // "target list" 325 //---------------------------------------------------------------------- 326 327 class CommandObjectTargetList : public CommandObjectParsed 328 { 329 public: 330 CommandObjectTargetList (CommandInterpreter &interpreter) : 331 CommandObjectParsed (interpreter, 332 "target list", 333 "List all current targets in the current debug session.", 334 NULL, 335 0) 336 { 337 } 338 339 virtual 340 ~CommandObjectTargetList () 341 { 342 } 343 344 protected: 345 virtual bool 346 DoExecute (Args& args, CommandReturnObject &result) 347 { 348 if (args.GetArgumentCount() == 0) 349 { 350 Stream &strm = result.GetOutputStream(); 351 352 bool show_stopped_process_status = false; 353 if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0) 354 { 355 strm.PutCString ("No targets.\n"); 356 } 357 result.SetStatus (eReturnStatusSuccessFinishResult); 358 } 359 else 360 { 361 result.AppendError ("the 'target list' command takes no arguments\n"); 362 result.SetStatus (eReturnStatusFailed); 363 } 364 return result.Succeeded(); 365 } 366 }; 367 368 369 #pragma mark CommandObjectTargetSelect 370 371 //---------------------------------------------------------------------- 372 // "target select" 373 //---------------------------------------------------------------------- 374 375 class CommandObjectTargetSelect : public CommandObjectParsed 376 { 377 public: 378 CommandObjectTargetSelect (CommandInterpreter &interpreter) : 379 CommandObjectParsed (interpreter, 380 "target select", 381 "Select a target as the current target by target index.", 382 NULL, 383 0) 384 { 385 } 386 387 virtual 388 ~CommandObjectTargetSelect () 389 { 390 } 391 392 protected: 393 virtual bool 394 DoExecute (Args& args, CommandReturnObject &result) 395 { 396 if (args.GetArgumentCount() == 1) 397 { 398 bool success = false; 399 const char *target_idx_arg = args.GetArgumentAtIndex(0); 400 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success); 401 if (success) 402 { 403 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList(); 404 const uint32_t num_targets = target_list.GetNumTargets(); 405 if (target_idx < num_targets) 406 { 407 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx)); 408 if (target_sp) 409 { 410 Stream &strm = result.GetOutputStream(); 411 target_list.SetSelectedTarget (target_sp.get()); 412 bool show_stopped_process_status = false; 413 DumpTargetList (target_list, show_stopped_process_status, strm); 414 result.SetStatus (eReturnStatusSuccessFinishResult); 415 } 416 else 417 { 418 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx); 419 result.SetStatus (eReturnStatusFailed); 420 } 421 } 422 else 423 { 424 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n", 425 target_idx, 426 num_targets - 1); 427 result.SetStatus (eReturnStatusFailed); 428 } 429 } 430 else 431 { 432 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg); 433 result.SetStatus (eReturnStatusFailed); 434 } 435 } 436 else 437 { 438 result.AppendError ("'target select' takes a single argument: a target index\n"); 439 result.SetStatus (eReturnStatusFailed); 440 } 441 return result.Succeeded(); 442 } 443 }; 444 445 #pragma mark CommandObjectTargetSelect 446 447 //---------------------------------------------------------------------- 448 // "target delete" 449 //---------------------------------------------------------------------- 450 451 class CommandObjectTargetDelete : public CommandObjectParsed 452 { 453 public: 454 CommandObjectTargetDelete (CommandInterpreter &interpreter) : 455 CommandObjectParsed (interpreter, 456 "target delete", 457 "Delete one or more targets by target index.", 458 NULL, 459 0), 460 m_option_group (interpreter), 461 m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', "Perform extra cleanup to minimize memory consumption after deleting the target.", false, false) 462 { 463 m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 464 m_option_group.Finalize(); 465 } 466 467 virtual 468 ~CommandObjectTargetDelete () 469 { 470 } 471 472 Options * 473 GetOptions () 474 { 475 return &m_option_group; 476 } 477 478 protected: 479 virtual bool 480 DoExecute (Args& args, CommandReturnObject &result) 481 { 482 const size_t argc = args.GetArgumentCount(); 483 std::vector<TargetSP> delete_target_list; 484 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList(); 485 bool success = true; 486 TargetSP target_sp; 487 if (argc > 0) 488 { 489 const uint32_t num_targets = target_list.GetNumTargets(); 490 // Bail out if don't have any targets. 491 if (num_targets == 0) { 492 result.AppendError("no targets to delete"); 493 result.SetStatus(eReturnStatusFailed); 494 success = false; 495 } 496 497 for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx) 498 { 499 const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx); 500 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success); 501 if (success) 502 { 503 if (target_idx < num_targets) 504 { 505 target_sp = target_list.GetTargetAtIndex (target_idx); 506 if (target_sp) 507 { 508 delete_target_list.push_back (target_sp); 509 continue; 510 } 511 } 512 if (num_targets > 1) 513 result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n", 514 target_idx, 515 num_targets - 1); 516 else 517 result.AppendErrorWithFormat("target index %u is out of range, the only valid index is 0\n", 518 target_idx); 519 520 result.SetStatus (eReturnStatusFailed); 521 success = false; 522 } 523 else 524 { 525 result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg); 526 result.SetStatus (eReturnStatusFailed); 527 success = false; 528 } 529 } 530 531 } 532 else 533 { 534 target_sp = target_list.GetSelectedTarget(); 535 if (target_sp) 536 { 537 delete_target_list.push_back (target_sp); 538 } 539 else 540 { 541 result.AppendErrorWithFormat("no target is currently selected\n"); 542 result.SetStatus (eReturnStatusFailed); 543 success = false; 544 } 545 } 546 if (success) 547 { 548 const size_t num_targets_to_delete = delete_target_list.size(); 549 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) 550 { 551 target_sp = delete_target_list[idx]; 552 target_list.DeleteTarget(target_sp); 553 target_sp->Destroy(); 554 } 555 // If "--clean" was specified, prune any orphaned shared modules from 556 // the global shared module list 557 if (m_cleanup_option.GetOptionValue ()) 558 { 559 const bool mandatory = true; 560 ModuleList::RemoveOrphanSharedModules(mandatory); 561 } 562 result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete); 563 result.SetStatus(eReturnStatusSuccessFinishResult); 564 } 565 566 return result.Succeeded(); 567 } 568 569 OptionGroupOptions m_option_group; 570 OptionGroupBoolean m_cleanup_option; 571 }; 572 573 574 #pragma mark CommandObjectTargetVariable 575 576 //---------------------------------------------------------------------- 577 // "target variable" 578 //---------------------------------------------------------------------- 579 580 class CommandObjectTargetVariable : public CommandObjectParsed 581 { 582 public: 583 CommandObjectTargetVariable (CommandInterpreter &interpreter) : 584 CommandObjectParsed (interpreter, 585 "target variable", 586 "Read global variable(s) prior to running your binary.", 587 NULL, 588 0), 589 m_option_group (interpreter), 590 m_option_variable (false), // Don't include frame options 591 m_option_format (eFormatDefault), 592 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."), 593 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."), 594 m_varobj_options() 595 { 596 CommandArgumentEntry arg; 597 CommandArgumentData var_name_arg; 598 599 // Define the first (and only) variant of this arg. 600 var_name_arg.arg_type = eArgTypeVarName; 601 var_name_arg.arg_repetition = eArgRepeatPlus; 602 603 // There is only one variant this argument could be; put it into the argument entry. 604 arg.push_back (var_name_arg); 605 606 // Push the data for the first argument into the m_arguments vector. 607 m_arguments.push_back (arg); 608 609 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 610 m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 611 m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1); 612 m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 613 m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 614 m_option_group.Finalize(); 615 } 616 617 virtual 618 ~CommandObjectTargetVariable () 619 { 620 } 621 622 void 623 DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name) 624 { 625 ValueObject::DumpValueObjectOptions options; 626 627 options.SetMaximumPointerDepth(m_varobj_options.ptr_depth) 628 .SetMaximumDepth(m_varobj_options.max_depth) 629 .SetShowTypes(m_varobj_options.show_types) 630 .SetShowLocation(m_varobj_options.show_location) 631 .SetUseObjectiveC(m_varobj_options.use_objc) 632 .SetUseDynamicType(m_varobj_options.use_dynamic) 633 .SetUseSyntheticValue(m_varobj_options.use_synth) 634 .SetFlatOutput(m_varobj_options.flat_output) 635 .SetOmitSummaryDepth(m_varobj_options.no_summary_depth) 636 .SetIgnoreCap(m_varobj_options.ignore_cap); 637 638 switch (var_sp->GetScope()) 639 { 640 case eValueTypeVariableGlobal: 641 if (m_option_variable.show_scope) 642 s.PutCString("GLOBAL: "); 643 break; 644 645 case eValueTypeVariableStatic: 646 if (m_option_variable.show_scope) 647 s.PutCString("STATIC: "); 648 break; 649 650 case eValueTypeVariableArgument: 651 if (m_option_variable.show_scope) 652 s.PutCString(" ARG: "); 653 break; 654 655 case eValueTypeVariableLocal: 656 if (m_option_variable.show_scope) 657 s.PutCString(" LOCAL: "); 658 break; 659 660 default: 661 break; 662 } 663 664 if (m_option_variable.show_decl) 665 { 666 bool show_fullpaths = false; 667 bool show_module = true; 668 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module)) 669 s.PutCString (": "); 670 } 671 672 const Format format = m_option_format.GetFormat(); 673 if (format != eFormatDefault) 674 options.SetFormat(format); 675 676 options.SetRootValueObjectName(root_name); 677 678 ValueObject::DumpValueObject (s, 679 valobj_sp.get(), 680 options); 681 682 } 683 684 685 static uint32_t GetVariableCallback (void *baton, 686 const char *name, 687 VariableList &variable_list) 688 { 689 Target *target = static_cast<Target *>(baton); 690 if (target) 691 { 692 return target->GetImages().FindGlobalVariables (ConstString(name), 693 true, 694 UINT32_MAX, 695 variable_list); 696 } 697 return 0; 698 } 699 700 701 702 Options * 703 GetOptions () 704 { 705 return &m_option_group; 706 } 707 708 protected: 709 virtual bool 710 DoExecute (Args& args, CommandReturnObject &result) 711 { 712 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 713 Target *target = exe_ctx.GetTargetPtr(); 714 if (target) 715 { 716 const size_t argc = args.GetArgumentCount(); 717 Stream &s = result.GetOutputStream(); 718 if (argc > 0) 719 { 720 721 for (size_t idx = 0; idx < argc; ++idx) 722 { 723 VariableList variable_list; 724 ValueObjectList valobj_list; 725 726 const char *arg = args.GetArgumentAtIndex(idx); 727 uint32_t matches = 0; 728 bool use_var_name = false; 729 if (m_option_variable.use_regex) 730 { 731 RegularExpression regex(arg); 732 if (!regex.IsValid ()) 733 { 734 result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg); 735 result.SetStatus (eReturnStatusFailed); 736 return false; 737 } 738 use_var_name = true; 739 matches = target->GetImages().FindGlobalVariables (regex, 740 true, 741 UINT32_MAX, 742 variable_list); 743 } 744 else 745 { 746 Error error (Variable::GetValuesForVariableExpressionPath (arg, 747 exe_ctx.GetBestExecutionContextScope(), 748 GetVariableCallback, 749 target, 750 variable_list, 751 valobj_list)); 752 matches = variable_list.GetSize(); 753 } 754 755 if (matches == 0) 756 { 757 result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg); 758 result.SetStatus (eReturnStatusFailed); 759 return false; 760 } 761 else 762 { 763 for (uint32_t global_idx=0; global_idx<matches; ++global_idx) 764 { 765 VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx)); 766 if (var_sp) 767 { 768 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx)); 769 if (!valobj_sp) 770 valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp); 771 772 if (valobj_sp) 773 DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg); 774 } 775 } 776 } 777 } 778 } 779 else 780 { 781 bool success = false; 782 StackFrame *frame = exe_ctx.GetFramePtr(); 783 CompileUnit *comp_unit = NULL; 784 if (frame) 785 { 786 comp_unit = frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit; 787 if (comp_unit) 788 { 789 const bool can_create = true; 790 VariableListSP comp_unit_varlist_sp (comp_unit->GetVariableList(can_create)); 791 if (comp_unit_varlist_sp) 792 { 793 size_t count = comp_unit_varlist_sp->GetSize(); 794 if (count > 0) 795 { 796 s.Printf ("Global variables for %s/%s:\n", 797 comp_unit->GetDirectory().GetCString(), 798 comp_unit->GetFilename().GetCString()); 799 800 success = true; 801 for (uint32_t i=0; i<count; ++i) 802 { 803 VariableSP var_sp (comp_unit_varlist_sp->GetVariableAtIndex(i)); 804 if (var_sp) 805 { 806 ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp)); 807 808 if (valobj_sp) 809 DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString()); 810 } 811 } 812 } 813 } 814 } 815 } 816 if (!success) 817 { 818 if (frame) 819 { 820 if (comp_unit) 821 result.AppendErrorWithFormat ("no global variables in current compile unit: %s/%s\n", 822 comp_unit->GetDirectory().GetCString(), 823 comp_unit->GetFilename().GetCString()); 824 else 825 result.AppendError ("no debug information for frame %u\n", frame->GetFrameIndex()); 826 } 827 else 828 result.AppendError ("'target variable' takes one or more global variable names as arguments\n"); 829 result.SetStatus (eReturnStatusFailed); 830 } 831 } 832 } 833 else 834 { 835 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 836 result.SetStatus (eReturnStatusFailed); 837 return false; 838 } 839 840 if (m_interpreter.TruncationWarningNecessary()) 841 { 842 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(), 843 m_cmd_name.c_str()); 844 m_interpreter.TruncationWarningGiven(); 845 } 846 847 return result.Succeeded(); 848 } 849 850 OptionGroupOptions m_option_group; 851 OptionGroupVariable m_option_variable; 852 OptionGroupFormat m_option_format; 853 OptionGroupFileList m_option_compile_units; 854 OptionGroupFileList m_option_shared_libraries; 855 OptionGroupValueObjectDisplay m_varobj_options; 856 857 }; 858 859 860 #pragma mark CommandObjectTargetModulesSearchPathsAdd 861 862 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed 863 { 864 public: 865 866 CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) : 867 CommandObjectParsed (interpreter, 868 "target modules search-paths add", 869 "Add new image search paths substitution pairs to the current target.", 870 NULL) 871 { 872 CommandArgumentEntry arg; 873 CommandArgumentData old_prefix_arg; 874 CommandArgumentData new_prefix_arg; 875 876 // Define the first variant of this arg pair. 877 old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 878 old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 879 880 // Define the first variant of this arg pair. 881 new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 882 new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 883 884 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 885 // must always occur together, they are treated as two variants of one argument rather than two independent 886 // arguments. Push them both into the first argument position for m_arguments... 887 888 arg.push_back (old_prefix_arg); 889 arg.push_back (new_prefix_arg); 890 891 m_arguments.push_back (arg); 892 } 893 894 ~CommandObjectTargetModulesSearchPathsAdd () 895 { 896 } 897 898 protected: 899 bool 900 DoExecute (Args& command, 901 CommandReturnObject &result) 902 { 903 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 904 if (target) 905 { 906 uint32_t argc = command.GetArgumentCount(); 907 if (argc & 1) 908 { 909 result.AppendError ("add requires an even number of arguments\n"); 910 result.SetStatus (eReturnStatusFailed); 911 } 912 else 913 { 914 for (uint32_t i=0; i<argc; i+=2) 915 { 916 const char *from = command.GetArgumentAtIndex(i); 917 const char *to = command.GetArgumentAtIndex(i+1); 918 919 if (from[0] && to[0]) 920 { 921 bool last_pair = ((argc - i) == 2); 922 target->GetImageSearchPathList().Append (ConstString(from), 923 ConstString(to), 924 last_pair); // Notify if this is the last pair 925 result.SetStatus (eReturnStatusSuccessFinishNoResult); 926 } 927 else 928 { 929 if (from[0]) 930 result.AppendError ("<path-prefix> can't be empty\n"); 931 else 932 result.AppendError ("<new-path-prefix> can't be empty\n"); 933 result.SetStatus (eReturnStatusFailed); 934 } 935 } 936 } 937 } 938 else 939 { 940 result.AppendError ("invalid target\n"); 941 result.SetStatus (eReturnStatusFailed); 942 } 943 return result.Succeeded(); 944 } 945 }; 946 947 #pragma mark CommandObjectTargetModulesSearchPathsClear 948 949 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed 950 { 951 public: 952 953 CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) : 954 CommandObjectParsed (interpreter, 955 "target modules search-paths clear", 956 "Clear all current image search path substitution pairs from the current target.", 957 "target modules search-paths clear") 958 { 959 } 960 961 ~CommandObjectTargetModulesSearchPathsClear () 962 { 963 } 964 965 protected: 966 bool 967 DoExecute (Args& command, 968 CommandReturnObject &result) 969 { 970 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 971 if (target) 972 { 973 bool notify = true; 974 target->GetImageSearchPathList().Clear(notify); 975 result.SetStatus (eReturnStatusSuccessFinishNoResult); 976 } 977 else 978 { 979 result.AppendError ("invalid target\n"); 980 result.SetStatus (eReturnStatusFailed); 981 } 982 return result.Succeeded(); 983 } 984 }; 985 986 #pragma mark CommandObjectTargetModulesSearchPathsInsert 987 988 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed 989 { 990 public: 991 992 CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) : 993 CommandObjectParsed (interpreter, 994 "target modules search-paths insert", 995 "Insert a new image search path substitution pair into the current target at the specified index.", 996 NULL) 997 { 998 CommandArgumentEntry arg1; 999 CommandArgumentEntry arg2; 1000 CommandArgumentData index_arg; 1001 CommandArgumentData old_prefix_arg; 1002 CommandArgumentData new_prefix_arg; 1003 1004 // Define the first and only variant of this arg. 1005 index_arg.arg_type = eArgTypeIndex; 1006 index_arg.arg_repetition = eArgRepeatPlain; 1007 1008 // Put the one and only variant into the first arg for m_arguments: 1009 arg1.push_back (index_arg); 1010 1011 // Define the first variant of this arg pair. 1012 old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 1013 old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 1014 1015 // Define the first variant of this arg pair. 1016 new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 1017 new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 1018 1019 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 1020 // must always occur together, they are treated as two variants of one argument rather than two independent 1021 // arguments. Push them both into the same argument position for m_arguments... 1022 1023 arg2.push_back (old_prefix_arg); 1024 arg2.push_back (new_prefix_arg); 1025 1026 // Add arguments to m_arguments. 1027 m_arguments.push_back (arg1); 1028 m_arguments.push_back (arg2); 1029 } 1030 1031 ~CommandObjectTargetModulesSearchPathsInsert () 1032 { 1033 } 1034 1035 protected: 1036 bool 1037 DoExecute (Args& command, 1038 CommandReturnObject &result) 1039 { 1040 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1041 if (target) 1042 { 1043 uint32_t argc = command.GetArgumentCount(); 1044 // check for at least 3 arguments and an odd nubmer of parameters 1045 if (argc >= 3 && argc & 1) 1046 { 1047 bool success = false; 1048 1049 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success); 1050 1051 if (!success) 1052 { 1053 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0)); 1054 result.SetStatus (eReturnStatusFailed); 1055 return result.Succeeded(); 1056 } 1057 1058 // shift off the index 1059 command.Shift(); 1060 argc = command.GetArgumentCount(); 1061 1062 for (uint32_t i=0; i<argc; i+=2, ++insert_idx) 1063 { 1064 const char *from = command.GetArgumentAtIndex(i); 1065 const char *to = command.GetArgumentAtIndex(i+1); 1066 1067 if (from[0] && to[0]) 1068 { 1069 bool last_pair = ((argc - i) == 2); 1070 target->GetImageSearchPathList().Insert (ConstString(from), 1071 ConstString(to), 1072 insert_idx, 1073 last_pair); 1074 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1075 } 1076 else 1077 { 1078 if (from[0]) 1079 result.AppendError ("<path-prefix> can't be empty\n"); 1080 else 1081 result.AppendError ("<new-path-prefix> can't be empty\n"); 1082 result.SetStatus (eReturnStatusFailed); 1083 return false; 1084 } 1085 } 1086 } 1087 else 1088 { 1089 result.AppendError ("insert requires at least three arguments\n"); 1090 result.SetStatus (eReturnStatusFailed); 1091 return result.Succeeded(); 1092 } 1093 1094 } 1095 else 1096 { 1097 result.AppendError ("invalid target\n"); 1098 result.SetStatus (eReturnStatusFailed); 1099 } 1100 return result.Succeeded(); 1101 } 1102 }; 1103 1104 1105 #pragma mark CommandObjectTargetModulesSearchPathsList 1106 1107 1108 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed 1109 { 1110 public: 1111 1112 CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) : 1113 CommandObjectParsed (interpreter, 1114 "target modules search-paths list", 1115 "List all current image search path substitution pairs in the current target.", 1116 "target modules search-paths list") 1117 { 1118 } 1119 1120 ~CommandObjectTargetModulesSearchPathsList () 1121 { 1122 } 1123 1124 protected: 1125 bool 1126 DoExecute (Args& command, 1127 CommandReturnObject &result) 1128 { 1129 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1130 if (target) 1131 { 1132 if (command.GetArgumentCount() != 0) 1133 { 1134 result.AppendError ("list takes no arguments\n"); 1135 result.SetStatus (eReturnStatusFailed); 1136 return result.Succeeded(); 1137 } 1138 1139 target->GetImageSearchPathList().Dump(&result.GetOutputStream()); 1140 result.SetStatus (eReturnStatusSuccessFinishResult); 1141 } 1142 else 1143 { 1144 result.AppendError ("invalid target\n"); 1145 result.SetStatus (eReturnStatusFailed); 1146 } 1147 return result.Succeeded(); 1148 } 1149 }; 1150 1151 #pragma mark CommandObjectTargetModulesSearchPathsQuery 1152 1153 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed 1154 { 1155 public: 1156 1157 CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) : 1158 CommandObjectParsed (interpreter, 1159 "target modules search-paths query", 1160 "Transform a path using the first applicable image search path.", 1161 NULL) 1162 { 1163 CommandArgumentEntry arg; 1164 CommandArgumentData path_arg; 1165 1166 // Define the first (and only) variant of this arg. 1167 path_arg.arg_type = eArgTypePath; 1168 path_arg.arg_repetition = eArgRepeatPlain; 1169 1170 // There is only one variant this argument could be; put it into the argument entry. 1171 arg.push_back (path_arg); 1172 1173 // Push the data for the first argument into the m_arguments vector. 1174 m_arguments.push_back (arg); 1175 } 1176 1177 ~CommandObjectTargetModulesSearchPathsQuery () 1178 { 1179 } 1180 1181 protected: 1182 bool 1183 DoExecute (Args& command, 1184 CommandReturnObject &result) 1185 { 1186 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1187 if (target) 1188 { 1189 if (command.GetArgumentCount() != 1) 1190 { 1191 result.AppendError ("query requires one argument\n"); 1192 result.SetStatus (eReturnStatusFailed); 1193 return result.Succeeded(); 1194 } 1195 1196 ConstString orig(command.GetArgumentAtIndex(0)); 1197 ConstString transformed; 1198 if (target->GetImageSearchPathList().RemapPath(orig, transformed)) 1199 result.GetOutputStream().Printf("%s\n", transformed.GetCString()); 1200 else 1201 result.GetOutputStream().Printf("%s\n", orig.GetCString()); 1202 1203 result.SetStatus (eReturnStatusSuccessFinishResult); 1204 } 1205 else 1206 { 1207 result.AppendError ("invalid target\n"); 1208 result.SetStatus (eReturnStatusFailed); 1209 } 1210 return result.Succeeded(); 1211 } 1212 }; 1213 1214 //---------------------------------------------------------------------- 1215 // Static Helper functions 1216 //---------------------------------------------------------------------- 1217 static void 1218 DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width) 1219 { 1220 if (module) 1221 { 1222 const char *arch_cstr; 1223 if (full_triple) 1224 arch_cstr = module->GetArchitecture().GetTriple().str().c_str(); 1225 else 1226 arch_cstr = module->GetArchitecture().GetArchitectureName(); 1227 if (width) 1228 strm.Printf("%-*s", width, arch_cstr); 1229 else 1230 strm.PutCString(arch_cstr); 1231 } 1232 } 1233 1234 static void 1235 DumpModuleUUID (Stream &strm, Module *module) 1236 { 1237 if (module && module->GetUUID().IsValid()) 1238 module->GetUUID().Dump (&strm); 1239 else 1240 strm.PutCString(" "); 1241 } 1242 1243 static uint32_t 1244 DumpCompileUnitLineTable 1245 ( 1246 CommandInterpreter &interpreter, 1247 Stream &strm, 1248 Module *module, 1249 const FileSpec &file_spec, 1250 bool load_addresses 1251 ) 1252 { 1253 uint32_t num_matches = 0; 1254 if (module) 1255 { 1256 SymbolContextList sc_list; 1257 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec, 1258 0, 1259 false, 1260 eSymbolContextCompUnit, 1261 sc_list); 1262 1263 for (uint32_t i=0; i<num_matches; ++i) 1264 { 1265 SymbolContext sc; 1266 if (sc_list.GetContextAtIndex(i, sc)) 1267 { 1268 if (i > 0) 1269 strm << "\n\n"; 1270 1271 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `" 1272 << module->GetFileSpec().GetFilename() << "\n"; 1273 LineTable *line_table = sc.comp_unit->GetLineTable(); 1274 if (line_table) 1275 line_table->GetDescription (&strm, 1276 interpreter.GetExecutionContext().GetTargetPtr(), 1277 lldb::eDescriptionLevelBrief); 1278 else 1279 strm << "No line table"; 1280 } 1281 } 1282 } 1283 return num_matches; 1284 } 1285 1286 static void 1287 DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1288 { 1289 if (file_spec_ptr) 1290 { 1291 if (width > 0) 1292 { 1293 char fullpath[PATH_MAX]; 1294 if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath))) 1295 { 1296 strm.Printf("%-*s", width, fullpath); 1297 return; 1298 } 1299 } 1300 else 1301 { 1302 file_spec_ptr->Dump(&strm); 1303 return; 1304 } 1305 } 1306 // Keep the width spacing correct if things go wrong... 1307 if (width > 0) 1308 strm.Printf("%-*s", width, ""); 1309 } 1310 1311 static void 1312 DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1313 { 1314 if (file_spec_ptr) 1315 { 1316 if (width > 0) 1317 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString("")); 1318 else 1319 file_spec_ptr->GetDirectory().Dump(&strm); 1320 return; 1321 } 1322 // Keep the width spacing correct if things go wrong... 1323 if (width > 0) 1324 strm.Printf("%-*s", width, ""); 1325 } 1326 1327 static void 1328 DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1329 { 1330 if (file_spec_ptr) 1331 { 1332 if (width > 0) 1333 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString("")); 1334 else 1335 file_spec_ptr->GetFilename().Dump(&strm); 1336 return; 1337 } 1338 // Keep the width spacing correct if things go wrong... 1339 if (width > 0) 1340 strm.Printf("%-*s", width, ""); 1341 } 1342 1343 1344 static void 1345 DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order) 1346 { 1347 if (module) 1348 { 1349 ObjectFile *objfile = module->GetObjectFile (); 1350 if (objfile) 1351 { 1352 Symtab *symtab = objfile->GetSymtab(); 1353 if (symtab) 1354 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order); 1355 } 1356 } 1357 } 1358 1359 static void 1360 DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module) 1361 { 1362 if (module) 1363 { 1364 ObjectFile *objfile = module->GetObjectFile (); 1365 if (objfile) 1366 { 1367 SectionList *section_list = objfile->GetSectionList(); 1368 if (section_list) 1369 { 1370 strm.PutCString ("Sections for '"); 1371 strm << module->GetFileSpec(); 1372 if (module->GetObjectName()) 1373 strm << '(' << module->GetObjectName() << ')'; 1374 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName()); 1375 strm.IndentMore(); 1376 section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX); 1377 strm.IndentLess(); 1378 } 1379 } 1380 } 1381 } 1382 1383 static bool 1384 DumpModuleSymbolVendor (Stream &strm, Module *module) 1385 { 1386 if (module) 1387 { 1388 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true); 1389 if (symbol_vendor) 1390 { 1391 symbol_vendor->Dump(&strm); 1392 return true; 1393 } 1394 } 1395 return false; 1396 } 1397 1398 static void 1399 DumpAddress (ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, Stream &strm) 1400 { 1401 strm.IndentMore(); 1402 strm.Indent (" Address: "); 1403 so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress); 1404 strm.PutCString (" ("); 1405 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset); 1406 strm.PutCString (")\n"); 1407 strm.Indent (" Summary: "); 1408 const uint32_t save_indent = strm.GetIndentLevel (); 1409 strm.SetIndentLevel (save_indent + 13); 1410 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription); 1411 strm.SetIndentLevel (save_indent); 1412 // Print out detailed address information when verbose is enabled 1413 if (verbose) 1414 { 1415 strm.EOL(); 1416 so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext); 1417 } 1418 strm.IndentLess(); 1419 } 1420 1421 static bool 1422 LookupAddressInModule (CommandInterpreter &interpreter, 1423 Stream &strm, 1424 Module *module, 1425 uint32_t resolve_mask, 1426 lldb::addr_t raw_addr, 1427 lldb::addr_t offset, 1428 bool verbose) 1429 { 1430 if (module) 1431 { 1432 lldb::addr_t addr = raw_addr - offset; 1433 Address so_addr; 1434 SymbolContext sc; 1435 Target *target = interpreter.GetExecutionContext().GetTargetPtr(); 1436 if (target && !target->GetSectionLoadList().IsEmpty()) 1437 { 1438 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr)) 1439 return false; 1440 else if (so_addr.GetModule().get() != module) 1441 return false; 1442 } 1443 else 1444 { 1445 if (!module->ResolveFileAddress (addr, so_addr)) 1446 return false; 1447 } 1448 1449 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); 1450 DumpAddress (exe_scope, so_addr, verbose, strm); 1451 // strm.IndentMore(); 1452 // strm.Indent (" Address: "); 1453 // so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress); 1454 // strm.PutCString (" ("); 1455 // so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset); 1456 // strm.PutCString (")\n"); 1457 // strm.Indent (" Summary: "); 1458 // const uint32_t save_indent = strm.GetIndentLevel (); 1459 // strm.SetIndentLevel (save_indent + 13); 1460 // so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription); 1461 // strm.SetIndentLevel (save_indent); 1462 // // Print out detailed address information when verbose is enabled 1463 // if (verbose) 1464 // { 1465 // strm.EOL(); 1466 // so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext); 1467 // } 1468 // strm.IndentLess(); 1469 return true; 1470 } 1471 1472 return false; 1473 } 1474 1475 static uint32_t 1476 LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose) 1477 { 1478 if (module) 1479 { 1480 SymbolContext sc; 1481 1482 ObjectFile *objfile = module->GetObjectFile (); 1483 if (objfile) 1484 { 1485 Symtab *symtab = objfile->GetSymtab(); 1486 if (symtab) 1487 { 1488 uint32_t i; 1489 std::vector<uint32_t> match_indexes; 1490 ConstString symbol_name (name); 1491 uint32_t num_matches = 0; 1492 if (name_is_regex) 1493 { 1494 RegularExpression name_regexp(name); 1495 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp, 1496 eSymbolTypeAny, 1497 match_indexes); 1498 } 1499 else 1500 { 1501 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes); 1502 } 1503 1504 1505 if (num_matches > 0) 1506 { 1507 strm.Indent (); 1508 strm.Printf("%u symbols match %s'%s' in ", num_matches, 1509 name_is_regex ? "the regular expression " : "", name); 1510 DumpFullpath (strm, &module->GetFileSpec(), 0); 1511 strm.PutCString(":\n"); 1512 strm.IndentMore (); 1513 //Symtab::DumpSymbolHeader (&strm); 1514 for (i=0; i < num_matches; ++i) 1515 { 1516 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); 1517 DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(), 1518 symbol->GetAddress(), 1519 verbose, 1520 strm); 1521 1522 // strm.Indent (); 1523 // symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i); 1524 } 1525 strm.IndentLess (); 1526 return num_matches; 1527 } 1528 } 1529 } 1530 } 1531 return 0; 1532 } 1533 1534 1535 static void 1536 DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose) 1537 { 1538 strm.IndentMore (); 1539 uint32_t i; 1540 const uint32_t num_matches = sc_list.GetSize(); 1541 1542 for (i=0; i<num_matches; ++i) 1543 { 1544 SymbolContext sc; 1545 if (sc_list.GetContextAtIndex(i, sc)) 1546 { 1547 AddressRange range; 1548 1549 sc.GetAddressRange(eSymbolContextEverything, 1550 0, 1551 true, 1552 range); 1553 1554 DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm); 1555 } 1556 } 1557 strm.IndentLess (); 1558 } 1559 1560 static uint32_t 1561 LookupFunctionInModule (CommandInterpreter &interpreter, 1562 Stream &strm, 1563 Module *module, 1564 const char *name, 1565 bool name_is_regex, 1566 bool include_inlines, 1567 bool include_symbols, 1568 bool verbose) 1569 { 1570 if (module && name && name[0]) 1571 { 1572 SymbolContextList sc_list; 1573 const bool append = true; 1574 uint32_t num_matches = 0; 1575 if (name_is_regex) 1576 { 1577 RegularExpression function_name_regex (name); 1578 num_matches = module->FindFunctions (function_name_regex, 1579 include_symbols, 1580 include_inlines, 1581 append, 1582 sc_list); 1583 } 1584 else 1585 { 1586 ConstString function_name (name); 1587 num_matches = module->FindFunctions (function_name, 1588 NULL, 1589 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, 1590 include_symbols, 1591 include_inlines, 1592 append, 1593 sc_list); 1594 } 1595 1596 if (num_matches) 1597 { 1598 strm.Indent (); 1599 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1600 DumpFullpath (strm, &module->GetFileSpec(), 0); 1601 strm.PutCString(":\n"); 1602 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose); 1603 } 1604 return num_matches; 1605 } 1606 return 0; 1607 } 1608 1609 static uint32_t 1610 LookupTypeInModule (CommandInterpreter &interpreter, 1611 Stream &strm, 1612 Module *module, 1613 const char *name_cstr, 1614 bool name_is_regex) 1615 { 1616 if (module && name_cstr && name_cstr[0]) 1617 { 1618 TypeList type_list; 1619 const uint32_t max_num_matches = UINT32_MAX; 1620 uint32_t num_matches = 0; 1621 bool name_is_fully_qualified = false; 1622 SymbolContext sc; 1623 1624 ConstString name(name_cstr); 1625 num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list); 1626 1627 if (num_matches) 1628 { 1629 strm.Indent (); 1630 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1631 DumpFullpath (strm, &module->GetFileSpec(), 0); 1632 strm.PutCString(":\n"); 1633 const uint32_t num_types = type_list.GetSize(); 1634 for (uint32_t i=0; i<num_types; ++i) 1635 { 1636 TypeSP type_sp (type_list.GetTypeAtIndex(i)); 1637 if (type_sp) 1638 { 1639 // Resolve the clang type so that any forward references 1640 // to types that haven't yet been parsed will get parsed. 1641 type_sp->GetClangFullType (); 1642 type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1643 // Print all typedef chains 1644 TypeSP typedef_type_sp (type_sp); 1645 TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType()); 1646 while (typedefed_type_sp) 1647 { 1648 strm.EOL(); 1649 strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString()); 1650 typedefed_type_sp->GetClangFullType (); 1651 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1652 typedef_type_sp = typedefed_type_sp; 1653 typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1654 } 1655 } 1656 strm.EOL(); 1657 } 1658 } 1659 return num_matches; 1660 } 1661 return 0; 1662 } 1663 1664 static uint32_t 1665 LookupTypeHere (CommandInterpreter &interpreter, 1666 Stream &strm, 1667 const SymbolContext &sym_ctx, 1668 const char *name_cstr, 1669 bool name_is_regex) 1670 { 1671 if (!sym_ctx.module_sp) 1672 return 0; 1673 1674 TypeList type_list; 1675 const uint32_t max_num_matches = UINT32_MAX; 1676 uint32_t num_matches = 1; 1677 bool name_is_fully_qualified = false; 1678 1679 ConstString name(name_cstr); 1680 num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list); 1681 1682 if (num_matches) 1683 { 1684 strm.Indent (); 1685 strm.PutCString("Best match found in "); 1686 DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0); 1687 strm.PutCString(":\n"); 1688 1689 TypeSP type_sp (type_list.GetTypeAtIndex(0)); 1690 if (type_sp) 1691 { 1692 // Resolve the clang type so that any forward references 1693 // to types that haven't yet been parsed will get parsed. 1694 type_sp->GetClangFullType (); 1695 type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1696 // Print all typedef chains 1697 TypeSP typedef_type_sp (type_sp); 1698 TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType()); 1699 while (typedefed_type_sp) 1700 { 1701 strm.EOL(); 1702 strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString()); 1703 typedefed_type_sp->GetClangFullType (); 1704 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1705 typedef_type_sp = typedefed_type_sp; 1706 typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1707 } 1708 } 1709 strm.EOL(); 1710 } 1711 return num_matches; 1712 } 1713 1714 static uint32_t 1715 LookupFileAndLineInModule (CommandInterpreter &interpreter, 1716 Stream &strm, 1717 Module *module, 1718 const FileSpec &file_spec, 1719 uint32_t line, 1720 bool check_inlines, 1721 bool verbose) 1722 { 1723 if (module && file_spec) 1724 { 1725 SymbolContextList sc_list; 1726 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, 1727 eSymbolContextEverything, sc_list); 1728 if (num_matches > 0) 1729 { 1730 strm.Indent (); 1731 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1732 strm << file_spec; 1733 if (line > 0) 1734 strm.Printf (":%u", line); 1735 strm << " in "; 1736 DumpFullpath (strm, &module->GetFileSpec(), 0); 1737 strm.PutCString(":\n"); 1738 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose); 1739 return num_matches; 1740 } 1741 } 1742 return 0; 1743 1744 } 1745 1746 1747 static size_t 1748 FindModulesByName (Target *target, 1749 const char *module_name, 1750 ModuleList &module_list, 1751 bool check_global_list) 1752 { 1753 // Dump specified images (by basename or fullpath) 1754 FileSpec module_file_spec(module_name, false); 1755 ModuleSpec module_spec (module_file_spec); 1756 1757 const size_t initial_size = module_list.GetSize (); 1758 1759 if (check_global_list) 1760 { 1761 // Check the global list 1762 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 1763 const uint32_t num_modules = Module::GetNumberAllocatedModules(); 1764 ModuleSP module_sp; 1765 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 1766 { 1767 Module *module = Module::GetAllocatedModuleAtIndex(image_idx); 1768 1769 if (module) 1770 { 1771 if (module->MatchesModuleSpec (module_spec)) 1772 { 1773 module_sp = module->shared_from_this(); 1774 module_list.AppendIfNeeded(module_sp); 1775 } 1776 } 1777 } 1778 } 1779 else 1780 { 1781 if (target) 1782 { 1783 const size_t num_matches = target->GetImages().FindModules (module_spec, module_list); 1784 1785 // Not found in our module list for our target, check the main 1786 // shared module list in case it is a extra file used somewhere 1787 // else 1788 if (num_matches == 0) 1789 { 1790 module_spec.GetArchitecture() = target->GetArchitecture(); 1791 ModuleList::FindSharedModules (module_spec, module_list); 1792 } 1793 } 1794 else 1795 { 1796 ModuleList::FindSharedModules (module_spec,module_list); 1797 } 1798 } 1799 1800 return module_list.GetSize () - initial_size; 1801 } 1802 1803 #pragma mark CommandObjectTargetModulesModuleAutoComplete 1804 1805 //---------------------------------------------------------------------- 1806 // A base command object class that can auto complete with module file 1807 // paths 1808 //---------------------------------------------------------------------- 1809 1810 class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed 1811 { 1812 public: 1813 1814 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter, 1815 const char *name, 1816 const char *help, 1817 const char *syntax) : 1818 CommandObjectParsed (interpreter, name, help, syntax) 1819 { 1820 CommandArgumentEntry arg; 1821 CommandArgumentData file_arg; 1822 1823 // Define the first (and only) variant of this arg. 1824 file_arg.arg_type = eArgTypeFilename; 1825 file_arg.arg_repetition = eArgRepeatStar; 1826 1827 // There is only one variant this argument could be; put it into the argument entry. 1828 arg.push_back (file_arg); 1829 1830 // Push the data for the first argument into the m_arguments vector. 1831 m_arguments.push_back (arg); 1832 } 1833 1834 virtual 1835 ~CommandObjectTargetModulesModuleAutoComplete () 1836 { 1837 } 1838 1839 virtual int 1840 HandleArgumentCompletion (Args &input, 1841 int &cursor_index, 1842 int &cursor_char_position, 1843 OptionElementVector &opt_element_vector, 1844 int match_start_point, 1845 int max_return_elements, 1846 bool &word_complete, 1847 StringList &matches) 1848 { 1849 // Arguments are the standard module completer. 1850 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1851 completion_str.erase (cursor_char_position); 1852 1853 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1854 CommandCompletions::eModuleCompletion, 1855 completion_str.c_str(), 1856 match_start_point, 1857 max_return_elements, 1858 NULL, 1859 word_complete, 1860 matches); 1861 return matches.GetSize(); 1862 } 1863 }; 1864 1865 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete 1866 1867 //---------------------------------------------------------------------- 1868 // A base command object class that can auto complete with module source 1869 // file paths 1870 //---------------------------------------------------------------------- 1871 1872 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed 1873 { 1874 public: 1875 1876 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, 1877 const char *name, 1878 const char *help, 1879 const char *syntax) : 1880 CommandObjectParsed (interpreter, name, help, syntax) 1881 { 1882 CommandArgumentEntry arg; 1883 CommandArgumentData source_file_arg; 1884 1885 // Define the first (and only) variant of this arg. 1886 source_file_arg.arg_type = eArgTypeSourceFile; 1887 source_file_arg.arg_repetition = eArgRepeatPlus; 1888 1889 // There is only one variant this argument could be; put it into the argument entry. 1890 arg.push_back (source_file_arg); 1891 1892 // Push the data for the first argument into the m_arguments vector. 1893 m_arguments.push_back (arg); 1894 } 1895 1896 virtual 1897 ~CommandObjectTargetModulesSourceFileAutoComplete () 1898 { 1899 } 1900 1901 virtual int 1902 HandleArgumentCompletion (Args &input, 1903 int &cursor_index, 1904 int &cursor_char_position, 1905 OptionElementVector &opt_element_vector, 1906 int match_start_point, 1907 int max_return_elements, 1908 bool &word_complete, 1909 StringList &matches) 1910 { 1911 // Arguments are the standard source file completer. 1912 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1913 completion_str.erase (cursor_char_position); 1914 1915 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1916 CommandCompletions::eSourceFileCompletion, 1917 completion_str.c_str(), 1918 match_start_point, 1919 max_return_elements, 1920 NULL, 1921 word_complete, 1922 matches); 1923 return matches.GetSize(); 1924 } 1925 }; 1926 1927 1928 #pragma mark CommandObjectTargetModulesDumpSymtab 1929 1930 1931 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete 1932 { 1933 public: 1934 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) : 1935 CommandObjectTargetModulesModuleAutoComplete (interpreter, 1936 "target modules dump symtab", 1937 "Dump the symbol table from one or more target modules.", 1938 NULL), 1939 m_options (interpreter) 1940 { 1941 } 1942 1943 virtual 1944 ~CommandObjectTargetModulesDumpSymtab () 1945 { 1946 } 1947 1948 virtual Options * 1949 GetOptions () 1950 { 1951 return &m_options; 1952 } 1953 1954 class CommandOptions : public Options 1955 { 1956 public: 1957 1958 CommandOptions (CommandInterpreter &interpreter) : 1959 Options(interpreter), 1960 m_sort_order (eSortOrderNone) 1961 { 1962 } 1963 1964 virtual 1965 ~CommandOptions () 1966 { 1967 } 1968 1969 virtual Error 1970 SetOptionValue (uint32_t option_idx, const char *option_arg) 1971 { 1972 Error error; 1973 char short_option = (char) m_getopt_table[option_idx].val; 1974 1975 switch (short_option) 1976 { 1977 case 's': 1978 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg, 1979 g_option_table[option_idx].enum_values, 1980 eSortOrderNone, 1981 error); 1982 break; 1983 1984 default: 1985 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1986 break; 1987 1988 } 1989 return error; 1990 } 1991 1992 void 1993 OptionParsingStarting () 1994 { 1995 m_sort_order = eSortOrderNone; 1996 } 1997 1998 const OptionDefinition* 1999 GetDefinitions () 2000 { 2001 return g_option_table; 2002 } 2003 2004 // Options table: Required for subclasses of Options. 2005 static OptionDefinition g_option_table[]; 2006 2007 SortOrder m_sort_order; 2008 }; 2009 2010 protected: 2011 virtual bool 2012 DoExecute (Args& command, 2013 CommandReturnObject &result) 2014 { 2015 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2016 if (target == NULL) 2017 { 2018 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2019 result.SetStatus (eReturnStatusFailed); 2020 return false; 2021 } 2022 else 2023 { 2024 uint32_t num_dumped = 0; 2025 2026 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2027 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2028 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2029 2030 if (command.GetArgumentCount() == 0) 2031 { 2032 // Dump all sections for all modules images 2033 Mutex::Locker modules_locker(target->GetImages().GetMutex()); 2034 const uint32_t num_modules = target->GetImages().GetSize(); 2035 if (num_modules > 0) 2036 { 2037 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules); 2038 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2039 { 2040 if (num_dumped > 0) 2041 { 2042 result.GetOutputStream().EOL(); 2043 result.GetOutputStream().EOL(); 2044 } 2045 num_dumped++; 2046 DumpModuleSymtab (m_interpreter, 2047 result.GetOutputStream(), 2048 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx), 2049 m_options.m_sort_order); 2050 } 2051 } 2052 else 2053 { 2054 result.AppendError ("the target has no associated executable images"); 2055 result.SetStatus (eReturnStatusFailed); 2056 return false; 2057 } 2058 } 2059 else 2060 { 2061 // Dump specified images (by basename or fullpath) 2062 const char *arg_cstr; 2063 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2064 { 2065 ModuleList module_list; 2066 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2067 if (num_matches > 0) 2068 { 2069 for (size_t i=0; i<num_matches; ++i) 2070 { 2071 Module *module = module_list.GetModulePointerAtIndex(i); 2072 if (module) 2073 { 2074 if (num_dumped > 0) 2075 { 2076 result.GetOutputStream().EOL(); 2077 result.GetOutputStream().EOL(); 2078 } 2079 num_dumped++; 2080 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order); 2081 } 2082 } 2083 } 2084 else 2085 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2086 } 2087 } 2088 2089 if (num_dumped > 0) 2090 result.SetStatus (eReturnStatusSuccessFinishResult); 2091 else 2092 { 2093 result.AppendError ("no matching executable images found"); 2094 result.SetStatus (eReturnStatusFailed); 2095 } 2096 } 2097 return result.Succeeded(); 2098 } 2099 2100 2101 CommandOptions m_options; 2102 }; 2103 2104 static OptionEnumValueElement 2105 g_sort_option_enumeration[4] = 2106 { 2107 { eSortOrderNone, "none", "No sorting, use the original symbol table order."}, 2108 { eSortOrderByAddress, "address", "Sort output by symbol address."}, 2109 { eSortOrderByName, "name", "Sort output by symbol name."}, 2110 { 0, NULL, NULL } 2111 }; 2112 2113 2114 OptionDefinition 2115 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] = 2116 { 2117 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."}, 2118 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2119 }; 2120 2121 #pragma mark CommandObjectTargetModulesDumpSections 2122 2123 //---------------------------------------------------------------------- 2124 // Image section dumping command 2125 //---------------------------------------------------------------------- 2126 2127 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete 2128 { 2129 public: 2130 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) : 2131 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2132 "target modules dump sections", 2133 "Dump the sections from one or more target modules.", 2134 //"target modules dump sections [<file1> ...]") 2135 NULL) 2136 { 2137 } 2138 2139 virtual 2140 ~CommandObjectTargetModulesDumpSections () 2141 { 2142 } 2143 2144 protected: 2145 virtual bool 2146 DoExecute (Args& command, 2147 CommandReturnObject &result) 2148 { 2149 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2150 if (target == NULL) 2151 { 2152 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2153 result.SetStatus (eReturnStatusFailed); 2154 return false; 2155 } 2156 else 2157 { 2158 uint32_t num_dumped = 0; 2159 2160 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2161 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2162 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2163 2164 if (command.GetArgumentCount() == 0) 2165 { 2166 // Dump all sections for all modules images 2167 const uint32_t num_modules = target->GetImages().GetSize(); 2168 if (num_modules > 0) 2169 { 2170 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules); 2171 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2172 { 2173 num_dumped++; 2174 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)); 2175 } 2176 } 2177 else 2178 { 2179 result.AppendError ("the target has no associated executable images"); 2180 result.SetStatus (eReturnStatusFailed); 2181 return false; 2182 } 2183 } 2184 else 2185 { 2186 // Dump specified images (by basename or fullpath) 2187 const char *arg_cstr; 2188 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2189 { 2190 ModuleList module_list; 2191 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2192 if (num_matches > 0) 2193 { 2194 for (size_t i=0; i<num_matches; ++i) 2195 { 2196 Module *module = module_list.GetModulePointerAtIndex(i); 2197 if (module) 2198 { 2199 num_dumped++; 2200 DumpModuleSections (m_interpreter, result.GetOutputStream(), module); 2201 } 2202 } 2203 } 2204 else 2205 { 2206 // Check the global list 2207 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 2208 2209 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2210 } 2211 } 2212 } 2213 2214 if (num_dumped > 0) 2215 result.SetStatus (eReturnStatusSuccessFinishResult); 2216 else 2217 { 2218 result.AppendError ("no matching executable images found"); 2219 result.SetStatus (eReturnStatusFailed); 2220 } 2221 } 2222 return result.Succeeded(); 2223 } 2224 }; 2225 2226 2227 #pragma mark CommandObjectTargetModulesDumpSymfile 2228 2229 //---------------------------------------------------------------------- 2230 // Image debug symbol dumping command 2231 //---------------------------------------------------------------------- 2232 2233 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete 2234 { 2235 public: 2236 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) : 2237 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2238 "target modules dump symfile", 2239 "Dump the debug symbol file for one or more target modules.", 2240 //"target modules dump symfile [<file1> ...]") 2241 NULL) 2242 { 2243 } 2244 2245 virtual 2246 ~CommandObjectTargetModulesDumpSymfile () 2247 { 2248 } 2249 2250 protected: 2251 virtual bool 2252 DoExecute (Args& command, 2253 CommandReturnObject &result) 2254 { 2255 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2256 if (target == NULL) 2257 { 2258 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2259 result.SetStatus (eReturnStatusFailed); 2260 return false; 2261 } 2262 else 2263 { 2264 uint32_t num_dumped = 0; 2265 2266 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2267 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2268 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2269 2270 if (command.GetArgumentCount() == 0) 2271 { 2272 // Dump all sections for all modules images 2273 ModuleList &target_modules = target->GetImages(); 2274 Mutex::Locker modules_locker (target_modules.GetMutex()); 2275 const uint32_t num_modules = target_modules.GetSize(); 2276 if (num_modules > 0) 2277 { 2278 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules); 2279 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2280 { 2281 if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx))) 2282 num_dumped++; 2283 } 2284 } 2285 else 2286 { 2287 result.AppendError ("the target has no associated executable images"); 2288 result.SetStatus (eReturnStatusFailed); 2289 return false; 2290 } 2291 } 2292 else 2293 { 2294 // Dump specified images (by basename or fullpath) 2295 const char *arg_cstr; 2296 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2297 { 2298 ModuleList module_list; 2299 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2300 if (num_matches > 0) 2301 { 2302 for (size_t i=0; i<num_matches; ++i) 2303 { 2304 Module *module = module_list.GetModulePointerAtIndex(i); 2305 if (module) 2306 { 2307 if (DumpModuleSymbolVendor (result.GetOutputStream(), module)) 2308 num_dumped++; 2309 } 2310 } 2311 } 2312 else 2313 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2314 } 2315 } 2316 2317 if (num_dumped > 0) 2318 result.SetStatus (eReturnStatusSuccessFinishResult); 2319 else 2320 { 2321 result.AppendError ("no matching executable images found"); 2322 result.SetStatus (eReturnStatusFailed); 2323 } 2324 } 2325 return result.Succeeded(); 2326 } 2327 }; 2328 2329 2330 #pragma mark CommandObjectTargetModulesDumpLineTable 2331 2332 //---------------------------------------------------------------------- 2333 // Image debug line table dumping command 2334 //---------------------------------------------------------------------- 2335 2336 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete 2337 { 2338 public: 2339 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) : 2340 CommandObjectTargetModulesSourceFileAutoComplete (interpreter, 2341 "target modules dump line-table", 2342 "Dump the debug symbol file for one or more target modules.", 2343 NULL) 2344 { 2345 } 2346 2347 virtual 2348 ~CommandObjectTargetModulesDumpLineTable () 2349 { 2350 } 2351 2352 protected: 2353 virtual bool 2354 DoExecute (Args& command, 2355 CommandReturnObject &result) 2356 { 2357 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2358 if (target == NULL) 2359 { 2360 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2361 result.SetStatus (eReturnStatusFailed); 2362 return false; 2363 } 2364 else 2365 { 2366 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 2367 uint32_t total_num_dumped = 0; 2368 2369 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2370 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2371 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2372 2373 if (command.GetArgumentCount() == 0) 2374 { 2375 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); 2376 result.SetStatus (eReturnStatusFailed); 2377 } 2378 else 2379 { 2380 // Dump specified images (by basename or fullpath) 2381 const char *arg_cstr; 2382 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2383 { 2384 FileSpec file_spec(arg_cstr, false); 2385 2386 ModuleList &target_modules = target->GetImages(); 2387 Mutex::Locker modules_locker(target_modules.GetMutex()); 2388 const uint32_t num_modules = target_modules.GetSize(); 2389 if (num_modules > 0) 2390 { 2391 uint32_t num_dumped = 0; 2392 for (uint32_t i = 0; i<num_modules; ++i) 2393 { 2394 if (DumpCompileUnitLineTable (m_interpreter, 2395 result.GetOutputStream(), 2396 target_modules.GetModulePointerAtIndexUnlocked(i), 2397 file_spec, 2398 exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive())) 2399 num_dumped++; 2400 } 2401 if (num_dumped == 0) 2402 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); 2403 else 2404 total_num_dumped += num_dumped; 2405 } 2406 } 2407 } 2408 2409 if (total_num_dumped > 0) 2410 result.SetStatus (eReturnStatusSuccessFinishResult); 2411 else 2412 { 2413 result.AppendError ("no source filenames matched any command arguments"); 2414 result.SetStatus (eReturnStatusFailed); 2415 } 2416 } 2417 return result.Succeeded(); 2418 } 2419 }; 2420 2421 2422 #pragma mark CommandObjectTargetModulesDump 2423 2424 //---------------------------------------------------------------------- 2425 // Dump multi-word command for target modules 2426 //---------------------------------------------------------------------- 2427 2428 class CommandObjectTargetModulesDump : public CommandObjectMultiword 2429 { 2430 public: 2431 2432 //------------------------------------------------------------------ 2433 // Constructors and Destructors 2434 //------------------------------------------------------------------ 2435 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) : 2436 CommandObjectMultiword (interpreter, 2437 "target modules dump", 2438 "A set of commands for dumping information about one or more target modules.", 2439 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]") 2440 { 2441 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter))); 2442 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter))); 2443 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter))); 2444 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter))); 2445 } 2446 2447 virtual 2448 ~CommandObjectTargetModulesDump() 2449 { 2450 } 2451 }; 2452 2453 class CommandObjectTargetModulesAdd : public CommandObjectParsed 2454 { 2455 public: 2456 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) : 2457 CommandObjectParsed (interpreter, 2458 "target modules add", 2459 "Add a new module to the current target's modules.", 2460 "target modules add [<module>]") 2461 { 2462 } 2463 2464 virtual 2465 ~CommandObjectTargetModulesAdd () 2466 { 2467 } 2468 2469 int 2470 HandleArgumentCompletion (Args &input, 2471 int &cursor_index, 2472 int &cursor_char_position, 2473 OptionElementVector &opt_element_vector, 2474 int match_start_point, 2475 int max_return_elements, 2476 bool &word_complete, 2477 StringList &matches) 2478 { 2479 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2480 completion_str.erase (cursor_char_position); 2481 2482 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2483 CommandCompletions::eDiskFileCompletion, 2484 completion_str.c_str(), 2485 match_start_point, 2486 max_return_elements, 2487 NULL, 2488 word_complete, 2489 matches); 2490 return matches.GetSize(); 2491 } 2492 2493 protected: 2494 virtual bool 2495 DoExecute (Args& args, 2496 CommandReturnObject &result) 2497 { 2498 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2499 if (target == NULL) 2500 { 2501 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2502 result.SetStatus (eReturnStatusFailed); 2503 return false; 2504 } 2505 else 2506 { 2507 const size_t argc = args.GetArgumentCount(); 2508 if (argc == 0) 2509 { 2510 result.AppendError ("one or more executable image paths must be specified"); 2511 result.SetStatus (eReturnStatusFailed); 2512 return false; 2513 } 2514 else 2515 { 2516 for (size_t i=0; i<argc; ++i) 2517 { 2518 const char *path = args.GetArgumentAtIndex(i); 2519 if (path) 2520 { 2521 FileSpec file_spec(path, true); 2522 if (file_spec.Exists()) 2523 { 2524 ModuleSpec module_spec (file_spec); 2525 ModuleSP module_sp (target->GetSharedModule (module_spec)); 2526 if (!module_sp) 2527 { 2528 result.AppendError ("one or more executable image paths must be specified"); 2529 result.SetStatus (eReturnStatusFailed); 2530 return false; 2531 } 2532 result.SetStatus (eReturnStatusSuccessFinishResult); 2533 } 2534 else 2535 { 2536 char resolved_path[PATH_MAX]; 2537 result.SetStatus (eReturnStatusFailed); 2538 if (file_spec.GetPath (resolved_path, sizeof(resolved_path))) 2539 { 2540 if (strcmp (resolved_path, path) != 0) 2541 { 2542 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path); 2543 break; 2544 } 2545 } 2546 result.AppendErrorWithFormat ("invalid module path '%s'\n", path); 2547 break; 2548 } 2549 } 2550 } 2551 } 2552 } 2553 return result.Succeeded(); 2554 } 2555 2556 }; 2557 2558 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete 2559 { 2560 public: 2561 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) : 2562 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2563 "target modules load", 2564 "Set the load addresses for one or more sections in a target module.", 2565 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"), 2566 m_option_group (interpreter), 2567 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."), 2568 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) 2569 { 2570 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2571 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2572 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2573 m_option_group.Finalize(); 2574 } 2575 2576 virtual 2577 ~CommandObjectTargetModulesLoad () 2578 { 2579 } 2580 2581 virtual Options * 2582 GetOptions () 2583 { 2584 return &m_option_group; 2585 } 2586 2587 protected: 2588 virtual bool 2589 DoExecute (Args& args, 2590 CommandReturnObject &result) 2591 { 2592 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2593 if (target == NULL) 2594 { 2595 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2596 result.SetStatus (eReturnStatusFailed); 2597 return false; 2598 } 2599 else 2600 { 2601 const size_t argc = args.GetArgumentCount(); 2602 ModuleSpec module_spec; 2603 bool search_using_module_spec = false; 2604 if (m_file_option.GetOptionValue().OptionWasSet()) 2605 { 2606 search_using_module_spec = true; 2607 module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 2608 } 2609 2610 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2611 { 2612 search_using_module_spec = true; 2613 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2614 } 2615 2616 if (search_using_module_spec) 2617 { 2618 2619 ModuleList matching_modules; 2620 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules); 2621 2622 char path[PATH_MAX]; 2623 if (num_matches == 1) 2624 { 2625 Module *module = matching_modules.GetModulePointerAtIndex(0); 2626 if (module) 2627 { 2628 ObjectFile *objfile = module->GetObjectFile(); 2629 if (objfile) 2630 { 2631 SectionList *section_list = objfile->GetSectionList(); 2632 if (section_list) 2633 { 2634 bool changed = false; 2635 if (argc == 0) 2636 { 2637 if (m_slide_option.GetOptionValue().OptionWasSet()) 2638 { 2639 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue(); 2640 module->SetLoadAddress (*target, slide, changed); 2641 } 2642 else 2643 { 2644 result.AppendError ("one or more section name + load address pair must be specified"); 2645 result.SetStatus (eReturnStatusFailed); 2646 return false; 2647 } 2648 } 2649 else 2650 { 2651 if (m_slide_option.GetOptionValue().OptionWasSet()) 2652 { 2653 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n"); 2654 result.SetStatus (eReturnStatusFailed); 2655 return false; 2656 } 2657 2658 for (size_t i=0; i<argc; i += 2) 2659 { 2660 const char *sect_name = args.GetArgumentAtIndex(i); 2661 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1); 2662 if (sect_name && load_addr_cstr) 2663 { 2664 ConstString const_sect_name(sect_name); 2665 bool success = false; 2666 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); 2667 if (success) 2668 { 2669 SectionSP section_sp (section_list->FindSectionByName(const_sect_name)); 2670 if (section_sp) 2671 { 2672 if (section_sp->IsThreadSpecific()) 2673 { 2674 result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name); 2675 result.SetStatus (eReturnStatusFailed); 2676 break; 2677 } 2678 else 2679 { 2680 if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr)) 2681 changed = true; 2682 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr); 2683 } 2684 } 2685 else 2686 { 2687 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name); 2688 result.SetStatus (eReturnStatusFailed); 2689 break; 2690 } 2691 } 2692 else 2693 { 2694 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr); 2695 result.SetStatus (eReturnStatusFailed); 2696 break; 2697 } 2698 } 2699 else 2700 { 2701 if (sect_name) 2702 result.AppendError ("section names must be followed by a load address.\n"); 2703 else 2704 result.AppendError ("one or more section name + load address pair must be specified.\n"); 2705 result.SetStatus (eReturnStatusFailed); 2706 break; 2707 } 2708 } 2709 } 2710 2711 if (changed) 2712 target->ModulesDidLoad (matching_modules); 2713 } 2714 else 2715 { 2716 module->GetFileSpec().GetPath (path, sizeof(path)); 2717 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path); 2718 result.SetStatus (eReturnStatusFailed); 2719 } 2720 } 2721 else 2722 { 2723 module->GetFileSpec().GetPath (path, sizeof(path)); 2724 result.AppendErrorWithFormat ("no object file for module '%s'\n", path); 2725 result.SetStatus (eReturnStatusFailed); 2726 } 2727 } 2728 else 2729 { 2730 FileSpec *module_spec_file = module_spec.GetFileSpecPtr(); 2731 if (module_spec_file) 2732 { 2733 module_spec_file->GetPath (path, sizeof(path)); 2734 result.AppendErrorWithFormat ("invalid module '%s'.\n", path); 2735 } 2736 else 2737 result.AppendError ("no module spec"); 2738 result.SetStatus (eReturnStatusFailed); 2739 } 2740 } 2741 else 2742 { 2743 char uuid_cstr[64]; 2744 2745 if (module_spec.GetFileSpec()) 2746 module_spec.GetFileSpec().GetPath (path, sizeof(path)); 2747 else 2748 path[0] = '\0'; 2749 2750 if (module_spec.GetUUIDPtr()) 2751 module_spec.GetUUID().GetAsCString(uuid_cstr, sizeof(uuid_cstr)); 2752 else 2753 uuid_cstr[0] = '\0'; 2754 if (num_matches > 1) 2755 { 2756 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", 2757 path[0] ? " file=" : "", 2758 path, 2759 uuid_cstr[0] ? " uuid=" : "", 2760 uuid_cstr); 2761 for (size_t i=0; i<num_matches; ++i) 2762 { 2763 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path))) 2764 result.AppendMessageWithFormat("%s\n", path); 2765 } 2766 } 2767 else 2768 { 2769 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n", 2770 path[0] ? " file=" : "", 2771 path, 2772 uuid_cstr[0] ? " uuid=" : "", 2773 uuid_cstr); 2774 } 2775 result.SetStatus (eReturnStatusFailed); 2776 } 2777 } 2778 else 2779 { 2780 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n"); 2781 result.SetStatus (eReturnStatusFailed); 2782 return false; 2783 } 2784 } 2785 return result.Succeeded(); 2786 } 2787 2788 OptionGroupOptions m_option_group; 2789 OptionGroupUUID m_uuid_option_group; 2790 OptionGroupFile m_file_option; 2791 OptionGroupUInt64 m_slide_option; 2792 }; 2793 2794 //---------------------------------------------------------------------- 2795 // List images with associated information 2796 //---------------------------------------------------------------------- 2797 class CommandObjectTargetModulesList : public CommandObjectParsed 2798 { 2799 public: 2800 2801 class CommandOptions : public Options 2802 { 2803 public: 2804 2805 CommandOptions (CommandInterpreter &interpreter) : 2806 Options(interpreter), 2807 m_format_array(), 2808 m_use_global_module_list (false), 2809 m_module_addr (LLDB_INVALID_ADDRESS) 2810 { 2811 } 2812 2813 virtual 2814 ~CommandOptions () 2815 { 2816 } 2817 2818 virtual Error 2819 SetOptionValue (uint32_t option_idx, const char *option_arg) 2820 { 2821 char short_option = (char) m_getopt_table[option_idx].val; 2822 if (short_option == 'g') 2823 { 2824 m_use_global_module_list = true; 2825 } 2826 else if (short_option == 'a') 2827 { 2828 bool success; 2829 m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success); 2830 if (!success) 2831 { 2832 Error error; 2833 error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg); 2834 } 2835 } 2836 else 2837 { 2838 uint32_t width = 0; 2839 if (option_arg) 2840 width = strtoul (option_arg, NULL, 0); 2841 m_format_array.push_back(std::make_pair(short_option, width)); 2842 } 2843 Error error; 2844 return error; 2845 } 2846 2847 void 2848 OptionParsingStarting () 2849 { 2850 m_format_array.clear(); 2851 m_use_global_module_list = false; 2852 m_module_addr = LLDB_INVALID_ADDRESS; 2853 } 2854 2855 const OptionDefinition* 2856 GetDefinitions () 2857 { 2858 return g_option_table; 2859 } 2860 2861 // Options table: Required for subclasses of Options. 2862 2863 static OptionDefinition g_option_table[]; 2864 2865 // Instance variables to hold the values for command options. 2866 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection; 2867 FormatWidthCollection m_format_array; 2868 bool m_use_global_module_list; 2869 lldb::addr_t m_module_addr; 2870 }; 2871 2872 CommandObjectTargetModulesList (CommandInterpreter &interpreter) : 2873 CommandObjectParsed (interpreter, 2874 "target modules list", 2875 "List current executable and dependent shared library images.", 2876 "target modules list [<cmd-options>]"), 2877 m_options (interpreter) 2878 { 2879 } 2880 2881 virtual 2882 ~CommandObjectTargetModulesList () 2883 { 2884 } 2885 2886 virtual 2887 Options * 2888 GetOptions () 2889 { 2890 return &m_options; 2891 } 2892 2893 protected: 2894 virtual bool 2895 DoExecute (Args& command, 2896 CommandReturnObject &result) 2897 { 2898 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2899 const bool use_global_module_list = m_options.m_use_global_module_list; 2900 // Define a local module list here to ensure it lives longer than any "locker" 2901 // object which might lock its contents below (through the "module_list_ptr" 2902 // variable). 2903 ModuleList module_list; 2904 if (target == NULL && use_global_module_list == false) 2905 { 2906 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2907 result.SetStatus (eReturnStatusFailed); 2908 return false; 2909 } 2910 else 2911 { 2912 if (target) 2913 { 2914 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2915 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2916 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2917 } 2918 // Dump all sections for all modules images 2919 Stream &strm = result.GetOutputStream(); 2920 2921 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) 2922 { 2923 if (target) 2924 { 2925 Address module_address; 2926 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) 2927 { 2928 ModuleSP module_sp (module_address.GetModule()); 2929 if (module_sp) 2930 { 2931 PrintModule (target, module_sp.get(), UINT32_MAX, 0, strm); 2932 result.SetStatus (eReturnStatusSuccessFinishResult); 2933 } 2934 else 2935 { 2936 result.AppendError ("Couldn't find module matching address: 0x%llx.", m_options.m_module_addr); 2937 result.SetStatus (eReturnStatusFailed); 2938 } 2939 } 2940 else 2941 { 2942 result.AppendError ("Couldn't find module containing address: 0x%llx.", m_options.m_module_addr); 2943 result.SetStatus (eReturnStatusFailed); 2944 } 2945 } 2946 else 2947 { 2948 result.AppendError ("Can only look up modules by address with a valid target."); 2949 result.SetStatus (eReturnStatusFailed); 2950 } 2951 return result.Succeeded(); 2952 } 2953 2954 uint32_t num_modules = 0; 2955 Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL. 2956 // Otherwise it will lock the AllocationModuleCollectionMutex when accessing 2957 // the global module list directly. 2958 ModuleList *module_list_ptr = NULL; 2959 const size_t argc = command.GetArgumentCount(); 2960 if (argc == 0) 2961 { 2962 if (use_global_module_list) 2963 { 2964 locker.Lock (Module::GetAllocationModuleCollectionMutex()); 2965 num_modules = Module::GetNumberAllocatedModules(); 2966 } 2967 else 2968 { 2969 module_list_ptr = &target->GetImages(); 2970 } 2971 } 2972 else 2973 { 2974 for (size_t i=0; i<argc; ++i) 2975 { 2976 // Dump specified images (by basename or fullpath) 2977 const char *arg_cstr = command.GetArgumentAtIndex(i); 2978 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list); 2979 if (num_matches == 0) 2980 { 2981 if (argc == 1) 2982 { 2983 result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr); 2984 result.SetStatus (eReturnStatusFailed); 2985 return false; 2986 } 2987 } 2988 } 2989 2990 module_list_ptr = &module_list; 2991 } 2992 2993 if (module_list_ptr != NULL) 2994 { 2995 locker.Lock(module_list_ptr->GetMutex()); 2996 num_modules = module_list_ptr->GetSize(); 2997 } 2998 2999 if (num_modules > 0) 3000 { 3001 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 3002 { 3003 ModuleSP module_sp; 3004 Module *module; 3005 if (module_list_ptr) 3006 { 3007 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx); 3008 module = module_sp.get(); 3009 } 3010 else 3011 { 3012 module = Module::GetAllocatedModuleAtIndex(image_idx); 3013 module_sp = module->shared_from_this(); 3014 } 3015 3016 int indent = strm.Printf("[%3u] ", image_idx); 3017 PrintModule (target, module, image_idx, indent, strm); 3018 3019 } 3020 result.SetStatus (eReturnStatusSuccessFinishResult); 3021 } 3022 else 3023 { 3024 if (argc) 3025 { 3026 if (use_global_module_list) 3027 result.AppendError ("the global module list has no matching modules"); 3028 else 3029 result.AppendError ("the target has no matching modules"); 3030 } 3031 else 3032 { 3033 if (use_global_module_list) 3034 result.AppendError ("the global module list is empty"); 3035 else 3036 result.AppendError ("the target has no associated executable images"); 3037 } 3038 result.SetStatus (eReturnStatusFailed); 3039 return false; 3040 } 3041 } 3042 return result.Succeeded(); 3043 } 3044 3045 void 3046 PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm) 3047 { 3048 3049 if (module == NULL) 3050 { 3051 strm.PutCString("Null module"); 3052 return; 3053 } 3054 3055 bool dump_object_name = false; 3056 if (m_options.m_format_array.empty()) 3057 { 3058 m_options.m_format_array.push_back(std::make_pair('u', 0)); 3059 m_options.m_format_array.push_back(std::make_pair('h', 0)); 3060 m_options.m_format_array.push_back(std::make_pair('f', 0)); 3061 m_options.m_format_array.push_back(std::make_pair('S', 0)); 3062 } 3063 const size_t num_entries = m_options.m_format_array.size(); 3064 bool print_space = false; 3065 for (size_t i=0; i<num_entries; ++i) 3066 { 3067 if (print_space) 3068 strm.PutChar(' '); 3069 print_space = true; 3070 const char format_char = m_options.m_format_array[i].first; 3071 uint32_t width = m_options.m_format_array[i].second; 3072 switch (format_char) 3073 { 3074 case 'A': 3075 DumpModuleArchitecture (strm, module, false, width); 3076 break; 3077 3078 case 't': 3079 DumpModuleArchitecture (strm, module, true, width); 3080 break; 3081 3082 case 'f': 3083 DumpFullpath (strm, &module->GetFileSpec(), width); 3084 dump_object_name = true; 3085 break; 3086 3087 case 'd': 3088 DumpDirectory (strm, &module->GetFileSpec(), width); 3089 break; 3090 3091 case 'b': 3092 DumpBasename (strm, &module->GetFileSpec(), width); 3093 dump_object_name = true; 3094 break; 3095 3096 case 'h': 3097 case 'o': 3098 // Image header address 3099 { 3100 uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16; 3101 3102 ObjectFile *objfile = module->GetObjectFile (); 3103 if (objfile) 3104 { 3105 Address header_addr(objfile->GetHeaderAddress()); 3106 if (header_addr.IsValid()) 3107 { 3108 if (target && !target->GetSectionLoadList().IsEmpty()) 3109 { 3110 lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target); 3111 if (header_load_addr == LLDB_INVALID_ADDRESS) 3112 { 3113 header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress); 3114 } 3115 else 3116 { 3117 if (format_char == 'o') 3118 { 3119 // Show the offset of slide for the image 3120 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress()); 3121 } 3122 else 3123 { 3124 // Show the load address of the image 3125 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr); 3126 } 3127 } 3128 break; 3129 } 3130 // The address was valid, but the image isn't loaded, output the address in an appropriate format 3131 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress); 3132 break; 3133 } 3134 } 3135 strm.Printf ("%*s", addr_nibble_width + 2, ""); 3136 } 3137 break; 3138 case 'r': 3139 { 3140 uint32_t ref_count = 0; 3141 ModuleSP module_sp (module->shared_from_this()); 3142 if (module_sp) 3143 { 3144 // Take one away to make sure we don't count our local "module_sp" 3145 ref_count = module_sp.use_count() - 1; 3146 } 3147 if (width) 3148 strm.Printf("{%*u}", width, ref_count); 3149 else 3150 strm.Printf("{%u}", ref_count); 3151 } 3152 break; 3153 3154 case 's': 3155 case 'S': 3156 { 3157 SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 3158 if (symbol_vendor) 3159 { 3160 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 3161 if (symbol_file) 3162 { 3163 if (format_char == 'S') 3164 { 3165 FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec(); 3166 // Dump symbol file only if different from module file 3167 if (!symfile_spec || symfile_spec == module->GetFileSpec()) 3168 { 3169 print_space = false; 3170 break; 3171 } 3172 // Add a newline and indent past the index 3173 strm.Printf ("\n%*s", indent, ""); 3174 } 3175 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 3176 dump_object_name = true; 3177 break; 3178 } 3179 } 3180 strm.Printf("%.*s", width, "<NONE>"); 3181 } 3182 break; 3183 3184 case 'm': 3185 module->GetModificationTime().Dump(&strm, width); 3186 break; 3187 3188 case 'p': 3189 strm.Printf("%p", module); 3190 break; 3191 3192 case 'u': 3193 DumpModuleUUID(strm, module); 3194 break; 3195 3196 default: 3197 break; 3198 } 3199 3200 } 3201 if (dump_object_name) 3202 { 3203 const char *object_name = module->GetObjectName().GetCString(); 3204 if (object_name) 3205 strm.Printf ("(%s)", object_name); 3206 } 3207 strm.EOL(); 3208 } 3209 3210 CommandOptions m_options; 3211 }; 3212 3213 OptionDefinition 3214 CommandObjectTargetModulesList::CommandOptions::g_option_table[] = 3215 { 3216 { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."}, 3217 { LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, 3218 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, 3219 { 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."}, 3220 { 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)."}, 3221 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, 3222 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, 3223 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, 3224 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, 3225 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, 3226 { 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."}, 3227 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, 3228 { 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."}, 3229 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."}, 3230 { 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."}, 3231 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3232 }; 3233 3234 #pragma mark CommandObjectTargetModulesShowUnwind 3235 3236 //---------------------------------------------------------------------- 3237 // Lookup unwind information in images 3238 //---------------------------------------------------------------------- 3239 3240 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed 3241 { 3242 public: 3243 3244 enum 3245 { 3246 eLookupTypeInvalid = -1, 3247 eLookupTypeAddress = 0, 3248 eLookupTypeSymbol, 3249 eLookupTypeFunction, 3250 eLookupTypeFunctionOrSymbol, 3251 kNumLookupTypes 3252 }; 3253 3254 class CommandOptions : public Options 3255 { 3256 public: 3257 3258 CommandOptions (CommandInterpreter &interpreter) : 3259 Options(interpreter), 3260 m_type(eLookupTypeInvalid), 3261 m_str(), 3262 m_addr(LLDB_INVALID_ADDRESS) 3263 { 3264 } 3265 3266 virtual 3267 ~CommandOptions () 3268 { 3269 } 3270 3271 virtual Error 3272 SetOptionValue (uint32_t option_idx, const char *option_arg) 3273 { 3274 Error error; 3275 3276 char short_option = (char) m_getopt_table[option_idx].val; 3277 3278 switch (short_option) 3279 { 3280 case 'a': 3281 m_type = eLookupTypeAddress; 3282 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3283 if (m_addr == LLDB_INVALID_ADDRESS) 3284 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg); 3285 break; 3286 3287 case 'n': 3288 m_str = option_arg; 3289 m_type = eLookupTypeFunctionOrSymbol; 3290 break; 3291 } 3292 3293 return error; 3294 } 3295 3296 void 3297 OptionParsingStarting () 3298 { 3299 m_type = eLookupTypeInvalid; 3300 m_str.clear(); 3301 m_addr = LLDB_INVALID_ADDRESS; 3302 } 3303 3304 const OptionDefinition* 3305 GetDefinitions () 3306 { 3307 return g_option_table; 3308 } 3309 3310 // Options table: Required for subclasses of Options. 3311 3312 static OptionDefinition g_option_table[]; 3313 3314 // Instance variables to hold the values for command options. 3315 3316 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3317 std::string m_str; // Holds name lookup 3318 lldb::addr_t m_addr; // Holds the address to lookup 3319 }; 3320 3321 CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) : 3322 CommandObjectParsed (interpreter, 3323 "target modules show-unwind", 3324 "Show synthesized unwind instructions for a function.", 3325 NULL), 3326 m_options (interpreter) 3327 { 3328 } 3329 3330 virtual 3331 ~CommandObjectTargetModulesShowUnwind () 3332 { 3333 } 3334 3335 virtual 3336 Options * 3337 GetOptions () 3338 { 3339 return &m_options; 3340 } 3341 3342 protected: 3343 bool 3344 DoExecute (Args& command, 3345 CommandReturnObject &result) 3346 { 3347 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3348 if (!target) 3349 { 3350 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3351 result.SetStatus (eReturnStatusFailed); 3352 return false; 3353 } 3354 3355 ExecutionContext exe_ctx = m_interpreter.GetDebugger().GetSelectedExecutionContext(); 3356 Process *process = exe_ctx.GetProcessPtr(); 3357 ABI *abi = NULL; 3358 if (process) 3359 abi = process->GetABI().get(); 3360 3361 if (process == NULL) 3362 { 3363 result.AppendError ("You must have a process running to use this command."); 3364 result.SetStatus (eReturnStatusFailed); 3365 return false; 3366 } 3367 3368 ThreadList threads(process->GetThreadList()); 3369 if (threads.GetSize() == 0) 3370 { 3371 result.AppendError ("The process must be paused to use this command."); 3372 result.SetStatus (eReturnStatusFailed); 3373 return false; 3374 } 3375 3376 ThreadSP thread(threads.GetThreadAtIndex(0)); 3377 if (thread.get() == NULL) 3378 { 3379 result.AppendError ("The process must be paused to use this command."); 3380 result.SetStatus (eReturnStatusFailed); 3381 return false; 3382 } 3383 3384 if (m_options.m_type == eLookupTypeFunctionOrSymbol) 3385 { 3386 SymbolContextList sc_list; 3387 uint32_t num_matches; 3388 ConstString function_name (m_options.m_str.c_str()); 3389 num_matches = target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list); 3390 for (uint32_t idx = 0; idx < num_matches; idx++) 3391 { 3392 SymbolContext sc; 3393 sc_list.GetContextAtIndex(idx, sc); 3394 if (sc.symbol == NULL && sc.function == NULL) 3395 continue; 3396 if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL) 3397 continue; 3398 AddressRange range; 3399 if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range)) 3400 continue; 3401 if (!range.GetBaseAddress().IsValid()) 3402 continue; 3403 ConstString funcname(sc.GetFunctionName()); 3404 if (funcname.IsEmpty()) 3405 continue; 3406 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target); 3407 if (abi) 3408 start_addr = abi->FixCodeAddress(start_addr); 3409 3410 FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc)); 3411 if (func_unwinders_sp.get() == NULL) 3412 continue; 3413 3414 Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target)); 3415 if (first_non_prologue_insn.IsValid()) 3416 { 3417 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); 3418 result.GetOutputStream().Printf ("\n"); 3419 } 3420 3421 UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*thread.get()); 3422 if (non_callsite_unwind_plan.get()) 3423 { 3424 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); 3425 non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3426 result.GetOutputStream().Printf ("\n"); 3427 } 3428 3429 UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(-1); 3430 if (callsite_unwind_plan.get()) 3431 { 3432 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); 3433 callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3434 result.GetOutputStream().Printf ("\n"); 3435 } 3436 3437 UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get()); 3438 if (arch_default_unwind_plan.get()) 3439 { 3440 result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3441 arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3442 result.GetOutputStream().Printf ("\n"); 3443 } 3444 3445 UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get()); 3446 if (fast_unwind_plan.get()) 3447 { 3448 result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3449 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3450 result.GetOutputStream().Printf ("\n"); 3451 } 3452 3453 3454 result.GetOutputStream().Printf ("\n"); 3455 } 3456 } 3457 return result.Succeeded(); 3458 } 3459 3460 CommandOptions m_options; 3461 }; 3462 3463 OptionDefinition 3464 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] = 3465 { 3466 { 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."}, 3467 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3468 }; 3469 3470 //---------------------------------------------------------------------- 3471 // Lookup information in images 3472 //---------------------------------------------------------------------- 3473 class CommandObjectTargetModulesLookup : public CommandObjectParsed 3474 { 3475 public: 3476 3477 enum 3478 { 3479 eLookupTypeInvalid = -1, 3480 eLookupTypeAddress = 0, 3481 eLookupTypeSymbol, 3482 eLookupTypeFileLine, // Line is optional 3483 eLookupTypeFunction, 3484 eLookupTypeFunctionOrSymbol, 3485 eLookupTypeType, 3486 kNumLookupTypes 3487 }; 3488 3489 class CommandOptions : public Options 3490 { 3491 public: 3492 3493 CommandOptions (CommandInterpreter &interpreter) : 3494 Options(interpreter) 3495 { 3496 OptionParsingStarting(); 3497 } 3498 3499 virtual 3500 ~CommandOptions () 3501 { 3502 } 3503 3504 virtual Error 3505 SetOptionValue (uint32_t option_idx, const char *option_arg) 3506 { 3507 Error error; 3508 3509 char short_option = (char) m_getopt_table[option_idx].val; 3510 3511 switch (short_option) 3512 { 3513 case 'a': 3514 m_type = eLookupTypeAddress; 3515 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3516 if (m_addr == LLDB_INVALID_ADDRESS) 3517 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg); 3518 break; 3519 3520 case 'o': 3521 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3522 if (m_offset == LLDB_INVALID_ADDRESS) 3523 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg); 3524 break; 3525 3526 case 's': 3527 m_str = option_arg; 3528 m_type = eLookupTypeSymbol; 3529 break; 3530 3531 case 'f': 3532 m_file.SetFile (option_arg, false); 3533 m_type = eLookupTypeFileLine; 3534 break; 3535 3536 case 'i': 3537 m_include_inlines = false; 3538 break; 3539 3540 case 'l': 3541 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); 3542 if (m_line_number == UINT32_MAX) 3543 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg); 3544 else if (m_line_number == 0) 3545 error.SetErrorString ("zero is an invalid line number"); 3546 m_type = eLookupTypeFileLine; 3547 break; 3548 3549 case 'F': 3550 m_str = option_arg; 3551 m_type = eLookupTypeFunction; 3552 break; 3553 3554 case 'n': 3555 m_str = option_arg; 3556 m_type = eLookupTypeFunctionOrSymbol; 3557 break; 3558 3559 case 't': 3560 m_str = option_arg; 3561 m_type = eLookupTypeType; 3562 break; 3563 3564 case 'v': 3565 m_verbose = 1; 3566 break; 3567 3568 case 'A': 3569 m_print_all = true; 3570 break; 3571 3572 case 'r': 3573 m_use_regex = true; 3574 break; 3575 } 3576 3577 return error; 3578 } 3579 3580 void 3581 OptionParsingStarting () 3582 { 3583 m_type = eLookupTypeInvalid; 3584 m_str.clear(); 3585 m_file.Clear(); 3586 m_addr = LLDB_INVALID_ADDRESS; 3587 m_offset = 0; 3588 m_line_number = 0; 3589 m_use_regex = false; 3590 m_include_inlines = true; 3591 m_verbose = false; 3592 m_print_all = false; 3593 } 3594 3595 const OptionDefinition* 3596 GetDefinitions () 3597 { 3598 return g_option_table; 3599 } 3600 3601 // Options table: Required for subclasses of Options. 3602 3603 static OptionDefinition g_option_table[]; 3604 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3605 std::string m_str; // Holds name lookup 3606 FileSpec m_file; // Files for file lookups 3607 lldb::addr_t m_addr; // Holds the address to lookup 3608 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 3609 uint32_t m_line_number; // Line number for file+line lookups 3610 bool m_use_regex; // Name lookups in m_str are regular expressions. 3611 bool m_include_inlines;// Check for inline entries when looking up by file/line. 3612 bool m_verbose; // Enable verbose lookup info 3613 bool m_print_all; // Print all matches, even in cases where there's a best match. 3614 3615 }; 3616 3617 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 3618 CommandObjectParsed (interpreter, 3619 "target modules lookup", 3620 "Look up information within executable and dependent shared library images.", 3621 NULL), 3622 m_options (interpreter) 3623 { 3624 CommandArgumentEntry arg; 3625 CommandArgumentData file_arg; 3626 3627 // Define the first (and only) variant of this arg. 3628 file_arg.arg_type = eArgTypeFilename; 3629 file_arg.arg_repetition = eArgRepeatStar; 3630 3631 // There is only one variant this argument could be; put it into the argument entry. 3632 arg.push_back (file_arg); 3633 3634 // Push the data for the first argument into the m_arguments vector. 3635 m_arguments.push_back (arg); 3636 } 3637 3638 virtual 3639 ~CommandObjectTargetModulesLookup () 3640 { 3641 } 3642 3643 virtual Options * 3644 GetOptions () 3645 { 3646 return &m_options; 3647 } 3648 3649 bool 3650 LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error) 3651 { 3652 switch (m_options.m_type) 3653 { 3654 case eLookupTypeAddress: 3655 case eLookupTypeFileLine: 3656 case eLookupTypeFunction: 3657 case eLookupTypeFunctionOrSymbol: 3658 case eLookupTypeSymbol: 3659 default: 3660 return false; 3661 case eLookupTypeType: 3662 break; 3663 } 3664 3665 ExecutionContext exe_ctx = interpreter.GetDebugger().GetSelectedExecutionContext(); 3666 3667 StackFrameSP frame = exe_ctx.GetFrameSP(); 3668 3669 if (!frame) 3670 return false; 3671 3672 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule)); 3673 3674 if (!sym_ctx.module_sp) 3675 return false; 3676 3677 switch (m_options.m_type) 3678 { 3679 default: 3680 return false; 3681 case eLookupTypeType: 3682 if (!m_options.m_str.empty()) 3683 { 3684 if (LookupTypeHere (m_interpreter, 3685 result.GetOutputStream(), 3686 sym_ctx, 3687 m_options.m_str.c_str(), 3688 m_options.m_use_regex)) 3689 { 3690 result.SetStatus(eReturnStatusSuccessFinishResult); 3691 return true; 3692 } 3693 } 3694 break; 3695 } 3696 3697 return true; 3698 } 3699 3700 bool 3701 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 3702 { 3703 switch (m_options.m_type) 3704 { 3705 case eLookupTypeAddress: 3706 if (m_options.m_addr != LLDB_INVALID_ADDRESS) 3707 { 3708 if (LookupAddressInModule (m_interpreter, 3709 result.GetOutputStream(), 3710 module, 3711 eSymbolContextEverything, 3712 m_options.m_addr, 3713 m_options.m_offset, 3714 m_options.m_verbose)) 3715 { 3716 result.SetStatus(eReturnStatusSuccessFinishResult); 3717 return true; 3718 } 3719 } 3720 break; 3721 3722 case eLookupTypeSymbol: 3723 if (!m_options.m_str.empty()) 3724 { 3725 if (LookupSymbolInModule (m_interpreter, 3726 result.GetOutputStream(), 3727 module, 3728 m_options.m_str.c_str(), 3729 m_options.m_use_regex, 3730 m_options.m_verbose)) 3731 { 3732 result.SetStatus(eReturnStatusSuccessFinishResult); 3733 return true; 3734 } 3735 } 3736 break; 3737 3738 case eLookupTypeFileLine: 3739 if (m_options.m_file) 3740 { 3741 3742 if (LookupFileAndLineInModule (m_interpreter, 3743 result.GetOutputStream(), 3744 module, 3745 m_options.m_file, 3746 m_options.m_line_number, 3747 m_options.m_include_inlines, 3748 m_options.m_verbose)) 3749 { 3750 result.SetStatus(eReturnStatusSuccessFinishResult); 3751 return true; 3752 } 3753 } 3754 break; 3755 3756 case eLookupTypeFunctionOrSymbol: 3757 case eLookupTypeFunction: 3758 if (!m_options.m_str.empty()) 3759 { 3760 if (LookupFunctionInModule (m_interpreter, 3761 result.GetOutputStream(), 3762 module, 3763 m_options.m_str.c_str(), 3764 m_options.m_use_regex, 3765 m_options.m_include_inlines, 3766 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols 3767 m_options.m_verbose)) 3768 { 3769 result.SetStatus(eReturnStatusSuccessFinishResult); 3770 return true; 3771 } 3772 } 3773 break; 3774 3775 3776 case eLookupTypeType: 3777 if (!m_options.m_str.empty()) 3778 { 3779 if (LookupTypeInModule (m_interpreter, 3780 result.GetOutputStream(), 3781 module, 3782 m_options.m_str.c_str(), 3783 m_options.m_use_regex)) 3784 { 3785 result.SetStatus(eReturnStatusSuccessFinishResult); 3786 return true; 3787 } 3788 } 3789 break; 3790 3791 default: 3792 m_options.GenerateOptionUsage (result.GetErrorStream(), this); 3793 syntax_error = true; 3794 break; 3795 } 3796 3797 result.SetStatus (eReturnStatusFailed); 3798 return false; 3799 } 3800 3801 protected: 3802 virtual bool 3803 DoExecute (Args& command, 3804 CommandReturnObject &result) 3805 { 3806 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3807 if (target == NULL) 3808 { 3809 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3810 result.SetStatus (eReturnStatusFailed); 3811 return false; 3812 } 3813 else 3814 { 3815 bool syntax_error = false; 3816 uint32_t i; 3817 uint32_t num_successful_lookups = 0; 3818 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3819 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3820 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3821 // Dump all sections for all modules images 3822 3823 if (command.GetArgumentCount() == 0) 3824 { 3825 ModuleSP current_module; 3826 3827 // Where it is possible to look in the current symbol context 3828 // first, try that. If this search was successful and --all 3829 // was not passed, don't print anything else. 3830 if (LookupHere (m_interpreter, result, syntax_error)) 3831 { 3832 result.GetOutputStream().EOL(); 3833 num_successful_lookups++; 3834 if (!m_options.m_print_all) 3835 { 3836 result.SetStatus (eReturnStatusSuccessFinishResult); 3837 return result.Succeeded(); 3838 } 3839 } 3840 3841 // Dump all sections for all other modules 3842 3843 ModuleList &target_modules = target->GetImages(); 3844 Mutex::Locker modules_locker(target_modules.GetMutex()); 3845 const uint32_t num_modules = target_modules.GetSize(); 3846 if (num_modules > 0) 3847 { 3848 for (i = 0; i<num_modules && syntax_error == false; ++i) 3849 { 3850 Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i); 3851 3852 if (module_pointer != current_module.get() && 3853 LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error)) 3854 { 3855 result.GetOutputStream().EOL(); 3856 num_successful_lookups++; 3857 } 3858 } 3859 } 3860 else 3861 { 3862 result.AppendError ("the target has no associated executable images"); 3863 result.SetStatus (eReturnStatusFailed); 3864 return false; 3865 } 3866 } 3867 else 3868 { 3869 // Dump specified images (by basename or fullpath) 3870 const char *arg_cstr; 3871 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 3872 { 3873 ModuleList module_list; 3874 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false); 3875 if (num_matches > 0) 3876 { 3877 for (size_t j=0; j<num_matches; ++j) 3878 { 3879 Module *module = module_list.GetModulePointerAtIndex(j); 3880 if (module) 3881 { 3882 if (LookupInModule (m_interpreter, module, result, syntax_error)) 3883 { 3884 result.GetOutputStream().EOL(); 3885 num_successful_lookups++; 3886 } 3887 } 3888 } 3889 } 3890 else 3891 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 3892 } 3893 } 3894 3895 if (num_successful_lookups > 0) 3896 result.SetStatus (eReturnStatusSuccessFinishResult); 3897 else 3898 result.SetStatus (eReturnStatusFailed); 3899 } 3900 return result.Succeeded(); 3901 } 3902 3903 CommandOptions m_options; 3904 }; 3905 3906 OptionDefinition 3907 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 3908 { 3909 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."}, 3910 { 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."}, 3911 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5 3912 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ , 3913 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 3914 { 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."}, 3915 { 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."}, 3916 { 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)."}, 3917 { LLDB_OPT_SET_FROM_TO(3,5), 3918 false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."}, 3919 { 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."}, 3920 { 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."}, 3921 { 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."}, 3922 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 3923 { 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."}, 3924 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3925 }; 3926 3927 3928 #pragma mark CommandObjectMultiwordImageSearchPaths 3929 3930 //------------------------------------------------------------------------- 3931 // CommandObjectMultiwordImageSearchPaths 3932 //------------------------------------------------------------------------- 3933 3934 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 3935 { 3936 public: 3937 3938 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 3939 CommandObjectMultiword (interpreter, 3940 "target modules search-paths", 3941 "A set of commands for operating on debugger target image search paths.", 3942 "target modules search-paths <subcommand> [<subcommand-options>]") 3943 { 3944 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 3945 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 3946 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 3947 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 3948 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 3949 } 3950 3951 ~CommandObjectTargetModulesImageSearchPaths() 3952 { 3953 } 3954 }; 3955 3956 3957 3958 #pragma mark CommandObjectTargetModules 3959 3960 //------------------------------------------------------------------------- 3961 // CommandObjectTargetModules 3962 //------------------------------------------------------------------------- 3963 3964 class CommandObjectTargetModules : public CommandObjectMultiword 3965 { 3966 public: 3967 //------------------------------------------------------------------ 3968 // Constructors and Destructors 3969 //------------------------------------------------------------------ 3970 CommandObjectTargetModules(CommandInterpreter &interpreter) : 3971 CommandObjectMultiword (interpreter, 3972 "target modules", 3973 "A set of commands for accessing information for one or more target modules.", 3974 "target modules <sub-command> ...") 3975 { 3976 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 3977 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 3978 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter))); 3979 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 3980 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 3981 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 3982 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 3983 LoadSubCommand ("show-unwind", CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter))); 3984 3985 } 3986 virtual 3987 ~CommandObjectTargetModules() 3988 { 3989 } 3990 3991 private: 3992 //------------------------------------------------------------------ 3993 // For CommandObjectTargetModules only 3994 //------------------------------------------------------------------ 3995 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 3996 }; 3997 3998 3999 4000 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed 4001 { 4002 public: 4003 CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) : 4004 CommandObjectParsed (interpreter, 4005 "target symbols add", 4006 "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.", 4007 "target symbols add [<symfile>]"), 4008 m_option_group (interpreter), 4009 m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."), 4010 m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true) 4011 4012 { 4013 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4014 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4015 m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2); 4016 m_option_group.Finalize(); 4017 } 4018 4019 virtual 4020 ~CommandObjectTargetSymbolsAdd () 4021 { 4022 } 4023 4024 int 4025 HandleArgumentCompletion (Args &input, 4026 int &cursor_index, 4027 int &cursor_char_position, 4028 OptionElementVector &opt_element_vector, 4029 int match_start_point, 4030 int max_return_elements, 4031 bool &word_complete, 4032 StringList &matches) 4033 { 4034 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 4035 completion_str.erase (cursor_char_position); 4036 4037 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 4038 CommandCompletions::eDiskFileCompletion, 4039 completion_str.c_str(), 4040 match_start_point, 4041 max_return_elements, 4042 NULL, 4043 word_complete, 4044 matches); 4045 return matches.GetSize(); 4046 } 4047 4048 virtual Options * 4049 GetOptions () 4050 { 4051 return &m_option_group; 4052 } 4053 4054 4055 protected: 4056 4057 bool 4058 AddModuleSymbols (Target *target, 4059 const FileSpec &symfile_spec, 4060 bool &flush, 4061 CommandReturnObject &result) 4062 { 4063 ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture())); 4064 const UUID &symfile_uuid = symfile_module_sp->GetUUID(); 4065 StreamString ss_symfile_uuid; 4066 symfile_uuid.Dump(&ss_symfile_uuid); 4067 4068 if (symfile_module_sp) 4069 { 4070 char symfile_path[PATH_MAX]; 4071 symfile_spec.GetPath (symfile_path, sizeof(symfile_path)); 4072 // We now have a module that represents a symbol file 4073 // that can be used for a module that might exist in the 4074 // current target, so we need to find that module in the 4075 // target 4076 4077 ModuleSP old_module_sp (target->GetImages().FindModule (symfile_uuid)); 4078 if (old_module_sp) 4079 { 4080 // The module has not yet created its symbol vendor, we can just 4081 // give the existing target module the symfile path to use for 4082 // when it decides to create it! 4083 old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec()); 4084 4085 // Provide feedback that the symfile has been successfully added. 4086 const FileSpec &module_fs = old_module_sp->GetFileSpec(); 4087 result.AppendMessageWithFormat("symbol file '%s' with UUID %s has been successfully added to the '%s/%s' module\n", 4088 symfile_path, ss_symfile_uuid.GetData(), 4089 module_fs.GetDirectory().AsCString(), module_fs.GetFilename().AsCString()); 4090 4091 // Let clients know something changed in the module 4092 // if it is currently loaded 4093 ModuleList module_list; 4094 module_list.Append (old_module_sp); 4095 target->ModulesDidLoad (module_list); 4096 flush = true; 4097 } 4098 else 4099 { 4100 result.AppendErrorWithFormat ("symbol file '%s' with UUID %s does not match any existing module%s\n", 4101 symfile_path, ss_symfile_uuid.GetData(), 4102 (symfile_spec.GetFileType() != FileSpec::eFileTypeRegular) 4103 ? "\n please specify the full path to the symbol file" 4104 : ""); 4105 return false; 4106 } 4107 } 4108 else 4109 { 4110 result.AppendError ("one or more executable image paths must be specified"); 4111 result.SetStatus (eReturnStatusFailed); 4112 return false; 4113 } 4114 result.SetStatus (eReturnStatusSuccessFinishResult); 4115 return true; 4116 } 4117 4118 virtual bool 4119 DoExecute (Args& args, 4120 CommandReturnObject &result) 4121 { 4122 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 4123 Target *target = exe_ctx.GetTargetPtr(); 4124 result.SetStatus (eReturnStatusFailed); 4125 if (target == NULL) 4126 { 4127 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 4128 } 4129 else 4130 { 4131 bool flush = false; 4132 ModuleSpec sym_spec; 4133 const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet(); 4134 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); 4135 const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet(); 4136 4137 const size_t argc = args.GetArgumentCount(); 4138 if (argc == 0) 4139 { 4140 if (uuid_option_set || file_option_set || frame_option_set) 4141 { 4142 bool success = false; 4143 bool error_set = false; 4144 if (frame_option_set) 4145 { 4146 Process *process = exe_ctx.GetProcessPtr(); 4147 if (process) 4148 { 4149 const StateType process_state = process->GetState(); 4150 if (StateIsStoppedState (process_state, true)) 4151 { 4152 StackFrame *frame = exe_ctx.GetFramePtr(); 4153 if (frame) 4154 { 4155 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp); 4156 if (frame_module_sp) 4157 { 4158 if (frame_module_sp->GetPlatformFileSpec().Exists()) 4159 { 4160 sym_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); 4161 sym_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); 4162 } 4163 sym_spec.GetUUID() = frame_module_sp->GetUUID(); 4164 success = sym_spec.GetUUID().IsValid() || sym_spec.GetFileSpec(); 4165 } 4166 else 4167 { 4168 result.AppendError ("frame has no module"); 4169 error_set = true; 4170 } 4171 } 4172 else 4173 { 4174 result.AppendError ("invalid current frame"); 4175 error_set = true; 4176 } 4177 } 4178 else 4179 { 4180 result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state)); 4181 error_set = true; 4182 } 4183 } 4184 else 4185 { 4186 result.AppendError ("a process must exist in order to use the --frame option"); 4187 error_set = true; 4188 } 4189 } 4190 else 4191 { 4192 if (uuid_option_set) 4193 { 4194 sym_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 4195 success |= sym_spec.GetUUID().IsValid(); 4196 } 4197 else if (file_option_set) 4198 { 4199 sym_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 4200 ModuleSP module_sp (target->GetImages().FindFirstModule(sym_spec)); 4201 if (module_sp) 4202 { 4203 sym_spec.GetFileSpec() = module_sp->GetFileSpec(); 4204 sym_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); 4205 sym_spec.GetUUID() = module_sp->GetUUID(); 4206 sym_spec.GetArchitecture() = module_sp->GetArchitecture(); 4207 } 4208 else 4209 { 4210 sym_spec.GetArchitecture() = target->GetArchitecture(); 4211 } 4212 success |= sym_spec.GetFileSpec().Exists(); 4213 } 4214 } 4215 4216 if (success) 4217 { 4218 if (Symbols::DownloadObjectAndSymbolFile (sym_spec)) 4219 { 4220 if (sym_spec.GetSymbolFileSpec()) 4221 success = AddModuleSymbols (target, sym_spec.GetSymbolFileSpec(), flush, result); 4222 } 4223 } 4224 4225 if (!success && !error_set) 4226 { 4227 StreamString error_strm; 4228 if (uuid_option_set) 4229 { 4230 error_strm.PutCString("unable to find debug symbols for UUID "); 4231 sym_spec.GetUUID().Dump (&error_strm); 4232 } 4233 else if (file_option_set) 4234 { 4235 error_strm.PutCString("unable to find debug symbols for the executable file "); 4236 error_strm << sym_spec.GetFileSpec(); 4237 } 4238 else if (frame_option_set) 4239 { 4240 error_strm.PutCString("unable to find debug symbols for the current frame"); 4241 } 4242 result.AppendError (error_strm.GetData()); 4243 } 4244 } 4245 else 4246 { 4247 result.AppendError ("one or more symbol file paths must be specified, or options must be specified"); 4248 } 4249 } 4250 else 4251 { 4252 if (uuid_option_set) 4253 { 4254 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments"); 4255 } 4256 else if (file_option_set) 4257 { 4258 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments"); 4259 } 4260 else if (frame_option_set) 4261 { 4262 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments"); 4263 } 4264 else 4265 { 4266 PlatformSP platform_sp (target->GetPlatform()); 4267 4268 for (size_t i=0; i<argc; ++i) 4269 { 4270 const char *symfile_path = args.GetArgumentAtIndex(i); 4271 if (symfile_path) 4272 { 4273 FileSpec symfile_spec; 4274 sym_spec.GetSymbolFileSpec().SetFile(symfile_path, true); 4275 if (platform_sp) 4276 platform_sp->ResolveSymbolFile(*target, sym_spec, symfile_spec); 4277 else 4278 symfile_spec.SetFile(symfile_path, true); 4279 4280 ArchSpec arch; 4281 bool symfile_exists = symfile_spec.Exists(); 4282 4283 if (symfile_exists) 4284 { 4285 if (!AddModuleSymbols (target, symfile_spec, flush, result)) 4286 break; 4287 } 4288 else 4289 { 4290 char resolved_symfile_path[PATH_MAX]; 4291 if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path))) 4292 { 4293 if (strcmp (resolved_symfile_path, symfile_path) != 0) 4294 { 4295 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path); 4296 break; 4297 } 4298 } 4299 result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path); 4300 break; 4301 } 4302 } 4303 } 4304 } 4305 } 4306 4307 if (flush) 4308 { 4309 Process *process = exe_ctx.GetProcessPtr(); 4310 if (process) 4311 process->Flush(); 4312 } 4313 } 4314 return result.Succeeded(); 4315 } 4316 4317 OptionGroupOptions m_option_group; 4318 OptionGroupUUID m_uuid_option_group; 4319 OptionGroupFile m_file_option; 4320 OptionGroupBoolean m_current_frame_option; 4321 4322 4323 }; 4324 4325 4326 #pragma mark CommandObjectTargetSymbols 4327 4328 //------------------------------------------------------------------------- 4329 // CommandObjectTargetSymbols 4330 //------------------------------------------------------------------------- 4331 4332 class CommandObjectTargetSymbols : public CommandObjectMultiword 4333 { 4334 public: 4335 //------------------------------------------------------------------ 4336 // Constructors and Destructors 4337 //------------------------------------------------------------------ 4338 CommandObjectTargetSymbols(CommandInterpreter &interpreter) : 4339 CommandObjectMultiword (interpreter, 4340 "target symbols", 4341 "A set of commands for adding and managing debug symbol files.", 4342 "target symbols <sub-command> ...") 4343 { 4344 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter))); 4345 4346 } 4347 virtual 4348 ~CommandObjectTargetSymbols() 4349 { 4350 } 4351 4352 private: 4353 //------------------------------------------------------------------ 4354 // For CommandObjectTargetModules only 4355 //------------------------------------------------------------------ 4356 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols); 4357 }; 4358 4359 4360 #pragma mark CommandObjectTargetStopHookAdd 4361 4362 //------------------------------------------------------------------------- 4363 // CommandObjectTargetStopHookAdd 4364 //------------------------------------------------------------------------- 4365 4366 class CommandObjectTargetStopHookAdd : public CommandObjectParsed 4367 { 4368 public: 4369 4370 class CommandOptions : public Options 4371 { 4372 public: 4373 CommandOptions (CommandInterpreter &interpreter) : 4374 Options(interpreter), 4375 m_line_start(0), 4376 m_line_end (UINT_MAX), 4377 m_func_name_type_mask (eFunctionNameTypeAuto), 4378 m_sym_ctx_specified (false), 4379 m_thread_specified (false), 4380 m_use_one_liner (false), 4381 m_one_liner() 4382 { 4383 } 4384 4385 ~CommandOptions () {} 4386 4387 const OptionDefinition* 4388 GetDefinitions () 4389 { 4390 return g_option_table; 4391 } 4392 4393 virtual Error 4394 SetOptionValue (uint32_t option_idx, const char *option_arg) 4395 { 4396 Error error; 4397 char short_option = (char) m_getopt_table[option_idx].val; 4398 bool success; 4399 4400 switch (short_option) 4401 { 4402 case 'c': 4403 m_class_name = option_arg; 4404 m_sym_ctx_specified = true; 4405 break; 4406 4407 case 'e': 4408 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success); 4409 if (!success) 4410 { 4411 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg); 4412 break; 4413 } 4414 m_sym_ctx_specified = true; 4415 break; 4416 4417 case 'l': 4418 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 4419 if (!success) 4420 { 4421 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg); 4422 break; 4423 } 4424 m_sym_ctx_specified = true; 4425 break; 4426 4427 case 'i': 4428 m_no_inlines = true; 4429 break; 4430 4431 case 'n': 4432 m_function_name = option_arg; 4433 m_func_name_type_mask |= eFunctionNameTypeAuto; 4434 m_sym_ctx_specified = true; 4435 break; 4436 4437 case 'f': 4438 m_file_name = option_arg; 4439 m_sym_ctx_specified = true; 4440 break; 4441 case 's': 4442 m_module_name = option_arg; 4443 m_sym_ctx_specified = true; 4444 break; 4445 case 't' : 4446 { 4447 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 4448 if (m_thread_id == LLDB_INVALID_THREAD_ID) 4449 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 4450 m_thread_specified = true; 4451 } 4452 break; 4453 case 'T': 4454 m_thread_name = option_arg; 4455 m_thread_specified = true; 4456 break; 4457 case 'q': 4458 m_queue_name = option_arg; 4459 m_thread_specified = true; 4460 break; 4461 case 'x': 4462 { 4463 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 4464 if (m_thread_id == UINT32_MAX) 4465 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 4466 m_thread_specified = true; 4467 } 4468 break; 4469 case 'o': 4470 m_use_one_liner = true; 4471 m_one_liner = option_arg; 4472 break; 4473 default: 4474 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option); 4475 break; 4476 } 4477 return error; 4478 } 4479 4480 void 4481 OptionParsingStarting () 4482 { 4483 m_class_name.clear(); 4484 m_function_name.clear(); 4485 m_line_start = 0; 4486 m_line_end = UINT_MAX; 4487 m_file_name.clear(); 4488 m_module_name.clear(); 4489 m_func_name_type_mask = eFunctionNameTypeAuto; 4490 m_thread_id = LLDB_INVALID_THREAD_ID; 4491 m_thread_index = UINT32_MAX; 4492 m_thread_name.clear(); 4493 m_queue_name.clear(); 4494 4495 m_no_inlines = false; 4496 m_sym_ctx_specified = false; 4497 m_thread_specified = false; 4498 4499 m_use_one_liner = false; 4500 m_one_liner.clear(); 4501 } 4502 4503 4504 static OptionDefinition g_option_table[]; 4505 4506 std::string m_class_name; 4507 std::string m_function_name; 4508 uint32_t m_line_start; 4509 uint32_t m_line_end; 4510 std::string m_file_name; 4511 std::string m_module_name; 4512 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 4513 lldb::tid_t m_thread_id; 4514 uint32_t m_thread_index; 4515 std::string m_thread_name; 4516 std::string m_queue_name; 4517 bool m_sym_ctx_specified; 4518 bool m_no_inlines; 4519 bool m_thread_specified; 4520 // Instance variables to hold the values for one_liner options. 4521 bool m_use_one_liner; 4522 std::string m_one_liner; 4523 }; 4524 4525 Options * 4526 GetOptions () 4527 { 4528 return &m_options; 4529 } 4530 4531 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 4532 CommandObjectParsed (interpreter, 4533 "target stop-hook add ", 4534 "Add a hook to be executed when the target stops.", 4535 "target stop-hook add"), 4536 m_options (interpreter) 4537 { 4538 } 4539 4540 ~CommandObjectTargetStopHookAdd () 4541 { 4542 } 4543 4544 static size_t 4545 ReadCommandsCallbackFunction (void *baton, 4546 InputReader &reader, 4547 lldb::InputReaderAction notification, 4548 const char *bytes, 4549 size_t bytes_len) 4550 { 4551 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 4552 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton); 4553 static bool got_interrupted; 4554 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 4555 4556 switch (notification) 4557 { 4558 case eInputReaderActivate: 4559 if (!batch_mode) 4560 { 4561 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end."); 4562 if (reader.GetPrompt()) 4563 out_stream->Printf ("%s", reader.GetPrompt()); 4564 out_stream->Flush(); 4565 } 4566 got_interrupted = false; 4567 break; 4568 4569 case eInputReaderDeactivate: 4570 break; 4571 4572 case eInputReaderReactivate: 4573 if (reader.GetPrompt() && !batch_mode) 4574 { 4575 out_stream->Printf ("%s", reader.GetPrompt()); 4576 out_stream->Flush(); 4577 } 4578 got_interrupted = false; 4579 break; 4580 4581 case eInputReaderAsynchronousOutputWritten: 4582 break; 4583 4584 case eInputReaderGotToken: 4585 if (bytes && bytes_len && baton) 4586 { 4587 StringList *commands = new_stop_hook->GetCommandPointer(); 4588 if (commands) 4589 { 4590 commands->AppendString (bytes, bytes_len); 4591 } 4592 } 4593 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode) 4594 { 4595 out_stream->Printf ("%s", reader.GetPrompt()); 4596 out_stream->Flush(); 4597 } 4598 break; 4599 4600 case eInputReaderInterrupt: 4601 { 4602 // Finish, and cancel the stop hook. 4603 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID()); 4604 if (!batch_mode) 4605 { 4606 out_stream->Printf ("Stop hook cancelled.\n"); 4607 out_stream->Flush(); 4608 } 4609 4610 reader.SetIsDone (true); 4611 } 4612 got_interrupted = true; 4613 break; 4614 4615 case eInputReaderEndOfFile: 4616 reader.SetIsDone (true); 4617 break; 4618 4619 case eInputReaderDone: 4620 if (!got_interrupted && !batch_mode) 4621 { 4622 out_stream->Printf ("Stop hook #%llu added.\n", new_stop_hook->GetID()); 4623 out_stream->Flush(); 4624 } 4625 break; 4626 } 4627 4628 return bytes_len; 4629 } 4630 4631 protected: 4632 bool 4633 DoExecute (Args& command, CommandReturnObject &result) 4634 { 4635 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4636 if (target) 4637 { 4638 Target::StopHookSP new_hook_sp; 4639 target->AddStopHook (new_hook_sp); 4640 4641 // First step, make the specifier. 4642 std::auto_ptr<SymbolContextSpecifier> specifier_ap; 4643 if (m_options.m_sym_ctx_specified) 4644 { 4645 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 4646 4647 if (!m_options.m_module_name.empty()) 4648 { 4649 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 4650 } 4651 4652 if (!m_options.m_class_name.empty()) 4653 { 4654 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 4655 } 4656 4657 if (!m_options.m_file_name.empty()) 4658 { 4659 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 4660 } 4661 4662 if (m_options.m_line_start != 0) 4663 { 4664 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 4665 } 4666 4667 if (m_options.m_line_end != UINT_MAX) 4668 { 4669 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 4670 } 4671 4672 if (!m_options.m_function_name.empty()) 4673 { 4674 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 4675 } 4676 } 4677 4678 if (specifier_ap.get()) 4679 new_hook_sp->SetSpecifier (specifier_ap.release()); 4680 4681 // Next see if any of the thread options have been entered: 4682 4683 if (m_options.m_thread_specified) 4684 { 4685 ThreadSpec *thread_spec = new ThreadSpec(); 4686 4687 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 4688 { 4689 thread_spec->SetTID (m_options.m_thread_id); 4690 } 4691 4692 if (m_options.m_thread_index != UINT32_MAX) 4693 thread_spec->SetIndex (m_options.m_thread_index); 4694 4695 if (!m_options.m_thread_name.empty()) 4696 thread_spec->SetName (m_options.m_thread_name.c_str()); 4697 4698 if (!m_options.m_queue_name.empty()) 4699 thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 4700 4701 new_hook_sp->SetThreadSpecifier (thread_spec); 4702 4703 } 4704 if (m_options.m_use_one_liner) 4705 { 4706 // Use one-liner. 4707 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 4708 result.AppendMessageWithFormat("Stop hook #%llu added.\n", new_hook_sp->GetID()); 4709 } 4710 else 4711 { 4712 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into 4713 // the new stop hook's command string. 4714 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 4715 if (!reader_sp) 4716 { 4717 result.AppendError("out of memory\n"); 4718 result.SetStatus (eReturnStatusFailed); 4719 target->RemoveStopHookByID (new_hook_sp->GetID()); 4720 return false; 4721 } 4722 4723 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction, 4724 new_hook_sp.get(), // baton 4725 eInputReaderGranularityLine, // token size, to pass to callback function 4726 "DONE", // end token 4727 "> ", // prompt 4728 true)); // echo input 4729 if (!err.Success()) 4730 { 4731 result.AppendError (err.AsCString()); 4732 result.SetStatus (eReturnStatusFailed); 4733 target->RemoveStopHookByID (new_hook_sp->GetID()); 4734 return false; 4735 } 4736 m_interpreter.GetDebugger().PushInputReader (reader_sp); 4737 } 4738 result.SetStatus (eReturnStatusSuccessFinishNoResult); 4739 } 4740 else 4741 { 4742 result.AppendError ("invalid target\n"); 4743 result.SetStatus (eReturnStatusFailed); 4744 } 4745 4746 return result.Succeeded(); 4747 } 4748 private: 4749 CommandOptions m_options; 4750 }; 4751 4752 OptionDefinition 4753 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 4754 { 4755 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, 0, eArgTypeOneLiner, 4756 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 4757 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 4758 "Set the module within which the stop-hook is to be run."}, 4759 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex, 4760 "The stop hook is run only for the thread whose index matches this argument."}, 4761 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID, 4762 "The stop hook is run only for the thread whose TID matches this argument."}, 4763 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName, 4764 "The stop hook is run only for the thread whose thread name matches this argument."}, 4765 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName, 4766 "The stop hook is run only for threads in the queue whose name is given by this argument."}, 4767 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 4768 "Specify the source file within which the stop-hook is to be run." }, 4769 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 4770 "Set the start of the line range for which the stop-hook is to be run."}, 4771 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum, 4772 "Set the end of the line range for which the stop-hook is to be run."}, 4773 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, 0, eArgTypeClassName, 4774 "Specify the class within which the stop-hook is to be run." }, 4775 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 4776 "Set the function name within which the stop hook will be run." }, 4777 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 4778 }; 4779 4780 #pragma mark CommandObjectTargetStopHookDelete 4781 4782 //------------------------------------------------------------------------- 4783 // CommandObjectTargetStopHookDelete 4784 //------------------------------------------------------------------------- 4785 4786 class CommandObjectTargetStopHookDelete : public CommandObjectParsed 4787 { 4788 public: 4789 4790 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 4791 CommandObjectParsed (interpreter, 4792 "target stop-hook delete", 4793 "Delete a stop-hook.", 4794 "target stop-hook delete [<idx>]") 4795 { 4796 } 4797 4798 ~CommandObjectTargetStopHookDelete () 4799 { 4800 } 4801 4802 protected: 4803 bool 4804 DoExecute (Args& command, CommandReturnObject &result) 4805 { 4806 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4807 if (target) 4808 { 4809 // FIXME: see if we can use the breakpoint id style parser? 4810 size_t num_args = command.GetArgumentCount(); 4811 if (num_args == 0) 4812 { 4813 if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 4814 { 4815 result.SetStatus (eReturnStatusFailed); 4816 return false; 4817 } 4818 else 4819 { 4820 target->RemoveAllStopHooks(); 4821 } 4822 } 4823 else 4824 { 4825 bool success; 4826 for (size_t i = 0; i < num_args; i++) 4827 { 4828 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 4829 if (!success) 4830 { 4831 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4832 result.SetStatus(eReturnStatusFailed); 4833 return false; 4834 } 4835 success = target->RemoveStopHookByID (user_id); 4836 if (!success) 4837 { 4838 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4839 result.SetStatus(eReturnStatusFailed); 4840 return false; 4841 } 4842 } 4843 } 4844 result.SetStatus (eReturnStatusSuccessFinishNoResult); 4845 } 4846 else 4847 { 4848 result.AppendError ("invalid target\n"); 4849 result.SetStatus (eReturnStatusFailed); 4850 } 4851 4852 return result.Succeeded(); 4853 } 4854 }; 4855 #pragma mark CommandObjectTargetStopHookEnableDisable 4856 4857 //------------------------------------------------------------------------- 4858 // CommandObjectTargetStopHookEnableDisable 4859 //------------------------------------------------------------------------- 4860 4861 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed 4862 { 4863 public: 4864 4865 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 4866 CommandObjectParsed (interpreter, 4867 name, 4868 help, 4869 syntax), 4870 m_enable (enable) 4871 { 4872 } 4873 4874 ~CommandObjectTargetStopHookEnableDisable () 4875 { 4876 } 4877 4878 protected: 4879 bool 4880 DoExecute (Args& command, CommandReturnObject &result) 4881 { 4882 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4883 if (target) 4884 { 4885 // FIXME: see if we can use the breakpoint id style parser? 4886 size_t num_args = command.GetArgumentCount(); 4887 bool success; 4888 4889 if (num_args == 0) 4890 { 4891 target->SetAllStopHooksActiveState (m_enable); 4892 } 4893 else 4894 { 4895 for (size_t i = 0; i < num_args; i++) 4896 { 4897 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 4898 if (!success) 4899 { 4900 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4901 result.SetStatus(eReturnStatusFailed); 4902 return false; 4903 } 4904 success = target->SetStopHookActiveStateByID (user_id, m_enable); 4905 if (!success) 4906 { 4907 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4908 result.SetStatus(eReturnStatusFailed); 4909 return false; 4910 } 4911 } 4912 } 4913 result.SetStatus (eReturnStatusSuccessFinishNoResult); 4914 } 4915 else 4916 { 4917 result.AppendError ("invalid target\n"); 4918 result.SetStatus (eReturnStatusFailed); 4919 } 4920 return result.Succeeded(); 4921 } 4922 private: 4923 bool m_enable; 4924 }; 4925 4926 #pragma mark CommandObjectTargetStopHookList 4927 4928 //------------------------------------------------------------------------- 4929 // CommandObjectTargetStopHookList 4930 //------------------------------------------------------------------------- 4931 4932 class CommandObjectTargetStopHookList : public CommandObjectParsed 4933 { 4934 public: 4935 4936 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 4937 CommandObjectParsed (interpreter, 4938 "target stop-hook list", 4939 "List all stop-hooks.", 4940 "target stop-hook list [<type>]") 4941 { 4942 } 4943 4944 ~CommandObjectTargetStopHookList () 4945 { 4946 } 4947 4948 protected: 4949 bool 4950 DoExecute (Args& command, CommandReturnObject &result) 4951 { 4952 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4953 if (!target) 4954 { 4955 result.AppendError ("invalid target\n"); 4956 result.SetStatus (eReturnStatusFailed); 4957 return result.Succeeded(); 4958 } 4959 4960 size_t num_hooks = target->GetNumStopHooks (); 4961 if (num_hooks == 0) 4962 { 4963 result.GetOutputStream().PutCString ("No stop hooks.\n"); 4964 } 4965 else 4966 { 4967 for (size_t i = 0; i < num_hooks; i++) 4968 { 4969 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 4970 if (i > 0) 4971 result.GetOutputStream().PutCString ("\n"); 4972 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 4973 } 4974 } 4975 result.SetStatus (eReturnStatusSuccessFinishResult); 4976 return result.Succeeded(); 4977 } 4978 }; 4979 4980 #pragma mark CommandObjectMultiwordTargetStopHooks 4981 //------------------------------------------------------------------------- 4982 // CommandObjectMultiwordTargetStopHooks 4983 //------------------------------------------------------------------------- 4984 4985 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 4986 { 4987 public: 4988 4989 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 4990 CommandObjectMultiword (interpreter, 4991 "target stop-hook", 4992 "A set of commands for operating on debugger target stop-hooks.", 4993 "target stop-hook <subcommand> [<subcommand-options>]") 4994 { 4995 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 4996 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 4997 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 4998 false, 4999 "target stop-hook disable [<id>]", 5000 "Disable a stop-hook.", 5001 "target stop-hook disable"))); 5002 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 5003 true, 5004 "target stop-hook enable [<id>]", 5005 "Enable a stop-hook.", 5006 "target stop-hook enable"))); 5007 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 5008 } 5009 5010 ~CommandObjectMultiwordTargetStopHooks() 5011 { 5012 } 5013 }; 5014 5015 5016 5017 #pragma mark CommandObjectMultiwordTarget 5018 5019 //------------------------------------------------------------------------- 5020 // CommandObjectMultiwordTarget 5021 //------------------------------------------------------------------------- 5022 5023 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 5024 CommandObjectMultiword (interpreter, 5025 "target", 5026 "A set of commands for operating on debugger targets.", 5027 "target <subcommand> [<subcommand-options>]") 5028 { 5029 5030 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 5031 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 5032 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 5033 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 5034 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 5035 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 5036 LoadSubCommand ("symbols", CommandObjectSP (new CommandObjectTargetSymbols (interpreter))); 5037 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 5038 } 5039 5040 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 5041 { 5042 } 5043 5044 5045