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