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 //Symtab::DumpSymbolHeader (&strm); 1738 for (i=0; i < num_matches; ++i) 1739 { 1740 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); 1741 DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(), 1742 symbol->GetAddress(), 1743 verbose, 1744 strm); 1745 1746 // strm.Indent (); 1747 // symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i); 1748 } 1749 strm.IndentLess (); 1750 return num_matches; 1751 } 1752 } 1753 } 1754 } 1755 return 0; 1756 } 1757 1758 1759 static void 1760 DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose) 1761 { 1762 strm.IndentMore (); 1763 uint32_t i; 1764 const uint32_t num_matches = sc_list.GetSize(); 1765 1766 for (i=0; i<num_matches; ++i) 1767 { 1768 SymbolContext sc; 1769 if (sc_list.GetContextAtIndex(i, sc)) 1770 { 1771 AddressRange range; 1772 1773 sc.GetAddressRange(eSymbolContextEverything, 1774 0, 1775 true, 1776 range); 1777 1778 DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm); 1779 } 1780 } 1781 strm.IndentLess (); 1782 } 1783 1784 static size_t 1785 LookupFunctionInModule (CommandInterpreter &interpreter, 1786 Stream &strm, 1787 Module *module, 1788 const char *name, 1789 bool name_is_regex, 1790 bool include_inlines, 1791 bool include_symbols, 1792 bool verbose) 1793 { 1794 if (module && name && name[0]) 1795 { 1796 SymbolContextList sc_list; 1797 const bool append = true; 1798 size_t num_matches = 0; 1799 if (name_is_regex) 1800 { 1801 RegularExpression function_name_regex (name); 1802 num_matches = module->FindFunctions (function_name_regex, 1803 include_symbols, 1804 include_inlines, 1805 append, 1806 sc_list); 1807 } 1808 else 1809 { 1810 ConstString function_name (name); 1811 num_matches = module->FindFunctions (function_name, 1812 NULL, 1813 eFunctionNameTypeAuto, 1814 include_symbols, 1815 include_inlines, 1816 append, 1817 sc_list); 1818 } 1819 1820 if (num_matches) 1821 { 1822 strm.Indent (); 1823 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : ""); 1824 DumpFullpath (strm, &module->GetFileSpec(), 0); 1825 strm.PutCString(":\n"); 1826 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose); 1827 } 1828 return num_matches; 1829 } 1830 return 0; 1831 } 1832 1833 static size_t 1834 LookupTypeInModule (CommandInterpreter &interpreter, 1835 Stream &strm, 1836 Module *module, 1837 const char *name_cstr, 1838 bool name_is_regex) 1839 { 1840 if (module && name_cstr && name_cstr[0]) 1841 { 1842 TypeList type_list; 1843 const uint32_t max_num_matches = UINT32_MAX; 1844 size_t num_matches = 0; 1845 bool name_is_fully_qualified = false; 1846 SymbolContext sc; 1847 1848 ConstString name(name_cstr); 1849 num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list); 1850 1851 if (num_matches) 1852 { 1853 strm.Indent (); 1854 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : ""); 1855 DumpFullpath (strm, &module->GetFileSpec(), 0); 1856 strm.PutCString(":\n"); 1857 for (TypeSP type_sp : type_list.Types()) 1858 { 1859 if (type_sp) 1860 { 1861 // Resolve the clang type so that any forward references 1862 // to types that haven't yet been parsed will get parsed. 1863 type_sp->GetClangFullType (); 1864 type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1865 // Print all typedef chains 1866 TypeSP typedef_type_sp (type_sp); 1867 TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType()); 1868 while (typedefed_type_sp) 1869 { 1870 strm.EOL(); 1871 strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString()); 1872 typedefed_type_sp->GetClangFullType (); 1873 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1874 typedef_type_sp = typedefed_type_sp; 1875 typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1876 } 1877 } 1878 strm.EOL(); 1879 } 1880 } 1881 return num_matches; 1882 } 1883 return 0; 1884 } 1885 1886 static size_t 1887 LookupTypeHere (CommandInterpreter &interpreter, 1888 Stream &strm, 1889 const SymbolContext &sym_ctx, 1890 const char *name_cstr, 1891 bool name_is_regex) 1892 { 1893 if (!sym_ctx.module_sp) 1894 return 0; 1895 1896 TypeList type_list; 1897 const uint32_t max_num_matches = UINT32_MAX; 1898 size_t num_matches = 1; 1899 bool name_is_fully_qualified = false; 1900 1901 ConstString name(name_cstr); 1902 num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list); 1903 1904 if (num_matches) 1905 { 1906 strm.Indent (); 1907 strm.PutCString("Best match found in "); 1908 DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0); 1909 strm.PutCString(":\n"); 1910 1911 TypeSP type_sp (type_list.GetTypeAtIndex(0)); 1912 if (type_sp) 1913 { 1914 // Resolve the clang type so that any forward references 1915 // to types that haven't yet been parsed will get parsed. 1916 type_sp->GetClangFullType (); 1917 type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1918 // Print all typedef chains 1919 TypeSP typedef_type_sp (type_sp); 1920 TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType()); 1921 while (typedefed_type_sp) 1922 { 1923 strm.EOL(); 1924 strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString()); 1925 typedefed_type_sp->GetClangFullType (); 1926 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1927 typedef_type_sp = typedefed_type_sp; 1928 typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1929 } 1930 } 1931 strm.EOL(); 1932 } 1933 return num_matches; 1934 } 1935 1936 static uint32_t 1937 LookupFileAndLineInModule (CommandInterpreter &interpreter, 1938 Stream &strm, 1939 Module *module, 1940 const FileSpec &file_spec, 1941 uint32_t line, 1942 bool check_inlines, 1943 bool verbose) 1944 { 1945 if (module && file_spec) 1946 { 1947 SymbolContextList sc_list; 1948 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, 1949 eSymbolContextEverything, sc_list); 1950 if (num_matches > 0) 1951 { 1952 strm.Indent (); 1953 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1954 strm << file_spec; 1955 if (line > 0) 1956 strm.Printf (":%u", line); 1957 strm << " in "; 1958 DumpFullpath (strm, &module->GetFileSpec(), 0); 1959 strm.PutCString(":\n"); 1960 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose); 1961 return num_matches; 1962 } 1963 } 1964 return 0; 1965 } 1966 1967 1968 static size_t 1969 FindModulesByName (Target *target, 1970 const char *module_name, 1971 ModuleList &module_list, 1972 bool check_global_list) 1973 { 1974 // Dump specified images (by basename or fullpath) 1975 FileSpec module_file_spec(module_name, false); 1976 ModuleSpec module_spec (module_file_spec); 1977 1978 const size_t initial_size = module_list.GetSize (); 1979 1980 if (check_global_list) 1981 { 1982 // Check the global list 1983 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 1984 const size_t num_modules = Module::GetNumberAllocatedModules(); 1985 ModuleSP module_sp; 1986 for (size_t image_idx = 0; image_idx<num_modules; ++image_idx) 1987 { 1988 Module *module = Module::GetAllocatedModuleAtIndex(image_idx); 1989 1990 if (module) 1991 { 1992 if (module->MatchesModuleSpec (module_spec)) 1993 { 1994 module_sp = module->shared_from_this(); 1995 module_list.AppendIfNeeded(module_sp); 1996 } 1997 } 1998 } 1999 } 2000 else 2001 { 2002 if (target) 2003 { 2004 const size_t num_matches = target->GetImages().FindModules (module_spec, module_list); 2005 2006 // Not found in our module list for our target, check the main 2007 // shared module list in case it is a extra file used somewhere 2008 // else 2009 if (num_matches == 0) 2010 { 2011 module_spec.GetArchitecture() = target->GetArchitecture(); 2012 ModuleList::FindSharedModules (module_spec, module_list); 2013 } 2014 } 2015 else 2016 { 2017 ModuleList::FindSharedModules (module_spec,module_list); 2018 } 2019 } 2020 2021 return module_list.GetSize () - initial_size; 2022 } 2023 2024 #pragma mark CommandObjectTargetModulesModuleAutoComplete 2025 2026 //---------------------------------------------------------------------- 2027 // A base command object class that can auto complete with module file 2028 // paths 2029 //---------------------------------------------------------------------- 2030 2031 class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed 2032 { 2033 public: 2034 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter, 2035 const char *name, 2036 const char *help, 2037 const char *syntax) : 2038 CommandObjectParsed (interpreter, name, help, syntax) 2039 { 2040 CommandArgumentEntry arg; 2041 CommandArgumentData file_arg; 2042 2043 // Define the first (and only) variant of this arg. 2044 file_arg.arg_type = eArgTypeFilename; 2045 file_arg.arg_repetition = eArgRepeatStar; 2046 2047 // There is only one variant this argument could be; put it into the argument entry. 2048 arg.push_back (file_arg); 2049 2050 // Push the data for the first argument into the m_arguments vector. 2051 m_arguments.push_back (arg); 2052 } 2053 2054 virtual 2055 ~CommandObjectTargetModulesModuleAutoComplete () 2056 { 2057 } 2058 2059 virtual int 2060 HandleArgumentCompletion (Args &input, 2061 int &cursor_index, 2062 int &cursor_char_position, 2063 OptionElementVector &opt_element_vector, 2064 int match_start_point, 2065 int max_return_elements, 2066 bool &word_complete, 2067 StringList &matches) 2068 { 2069 // Arguments are the standard module completer. 2070 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2071 completion_str.erase (cursor_char_position); 2072 2073 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2074 CommandCompletions::eModuleCompletion, 2075 completion_str.c_str(), 2076 match_start_point, 2077 max_return_elements, 2078 NULL, 2079 word_complete, 2080 matches); 2081 return matches.GetSize(); 2082 } 2083 }; 2084 2085 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete 2086 2087 //---------------------------------------------------------------------- 2088 // A base command object class that can auto complete with module source 2089 // file paths 2090 //---------------------------------------------------------------------- 2091 2092 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed 2093 { 2094 public: 2095 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, 2096 const char *name, 2097 const char *help, 2098 const char *syntax, 2099 uint32_t flags) : 2100 CommandObjectParsed (interpreter, name, help, syntax, flags) 2101 { 2102 CommandArgumentEntry arg; 2103 CommandArgumentData source_file_arg; 2104 2105 // Define the first (and only) variant of this arg. 2106 source_file_arg.arg_type = eArgTypeSourceFile; 2107 source_file_arg.arg_repetition = eArgRepeatPlus; 2108 2109 // There is only one variant this argument could be; put it into the argument entry. 2110 arg.push_back (source_file_arg); 2111 2112 // Push the data for the first argument into the m_arguments vector. 2113 m_arguments.push_back (arg); 2114 } 2115 2116 virtual 2117 ~CommandObjectTargetModulesSourceFileAutoComplete () 2118 { 2119 } 2120 2121 virtual int 2122 HandleArgumentCompletion (Args &input, 2123 int &cursor_index, 2124 int &cursor_char_position, 2125 OptionElementVector &opt_element_vector, 2126 int match_start_point, 2127 int max_return_elements, 2128 bool &word_complete, 2129 StringList &matches) 2130 { 2131 // Arguments are the standard source file completer. 2132 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2133 completion_str.erase (cursor_char_position); 2134 2135 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2136 CommandCompletions::eSourceFileCompletion, 2137 completion_str.c_str(), 2138 match_start_point, 2139 max_return_elements, 2140 NULL, 2141 word_complete, 2142 matches); 2143 return matches.GetSize(); 2144 } 2145 }; 2146 2147 2148 #pragma mark CommandObjectTargetModulesDumpSymtab 2149 2150 2151 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete 2152 { 2153 public: 2154 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) : 2155 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2156 "target modules dump symtab", 2157 "Dump the symbol table from one or more target modules.", 2158 NULL), 2159 m_options (interpreter) 2160 { 2161 } 2162 2163 virtual 2164 ~CommandObjectTargetModulesDumpSymtab () 2165 { 2166 } 2167 2168 virtual Options * 2169 GetOptions () 2170 { 2171 return &m_options; 2172 } 2173 2174 class CommandOptions : public Options 2175 { 2176 public: 2177 CommandOptions (CommandInterpreter &interpreter) : 2178 Options(interpreter), 2179 m_sort_order (eSortOrderNone) 2180 { 2181 } 2182 2183 virtual 2184 ~CommandOptions () 2185 { 2186 } 2187 2188 virtual Error 2189 SetOptionValue (uint32_t option_idx, const char *option_arg) 2190 { 2191 Error error; 2192 const int short_option = m_getopt_table[option_idx].val; 2193 2194 switch (short_option) 2195 { 2196 case 's': 2197 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg, 2198 g_option_table[option_idx].enum_values, 2199 eSortOrderNone, 2200 error); 2201 break; 2202 2203 default: 2204 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 2205 break; 2206 2207 } 2208 return error; 2209 } 2210 2211 void 2212 OptionParsingStarting () 2213 { 2214 m_sort_order = eSortOrderNone; 2215 } 2216 2217 const OptionDefinition* 2218 GetDefinitions () 2219 { 2220 return g_option_table; 2221 } 2222 2223 // Options table: Required for subclasses of Options. 2224 static OptionDefinition g_option_table[]; 2225 2226 SortOrder m_sort_order; 2227 }; 2228 2229 protected: 2230 virtual bool 2231 DoExecute (Args& command, 2232 CommandReturnObject &result) 2233 { 2234 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2235 if (target == NULL) 2236 { 2237 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2238 result.SetStatus (eReturnStatusFailed); 2239 return false; 2240 } 2241 else 2242 { 2243 uint32_t num_dumped = 0; 2244 2245 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2246 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2247 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2248 2249 if (command.GetArgumentCount() == 0) 2250 { 2251 // Dump all sections for all modules images 2252 Mutex::Locker modules_locker(target->GetImages().GetMutex()); 2253 const size_t num_modules = target->GetImages().GetSize(); 2254 if (num_modules > 0) 2255 { 2256 result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64 " modules.\n", (uint64_t)num_modules); 2257 for (size_t image_idx = 0; image_idx<num_modules; ++image_idx) 2258 { 2259 if (num_dumped > 0) 2260 { 2261 result.GetOutputStream().EOL(); 2262 result.GetOutputStream().EOL(); 2263 } 2264 num_dumped++; 2265 DumpModuleSymtab (m_interpreter, 2266 result.GetOutputStream(), 2267 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx), 2268 m_options.m_sort_order); 2269 } 2270 } 2271 else 2272 { 2273 result.AppendError ("the target has no associated executable images"); 2274 result.SetStatus (eReturnStatusFailed); 2275 return false; 2276 } 2277 } 2278 else 2279 { 2280 // Dump specified images (by basename or fullpath) 2281 const char *arg_cstr; 2282 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2283 { 2284 ModuleList module_list; 2285 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2286 if (num_matches > 0) 2287 { 2288 for (size_t i=0; i<num_matches; ++i) 2289 { 2290 Module *module = module_list.GetModulePointerAtIndex(i); 2291 if (module) 2292 { 2293 if (num_dumped > 0) 2294 { 2295 result.GetOutputStream().EOL(); 2296 result.GetOutputStream().EOL(); 2297 } 2298 num_dumped++; 2299 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order); 2300 } 2301 } 2302 } 2303 else 2304 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2305 } 2306 } 2307 2308 if (num_dumped > 0) 2309 result.SetStatus (eReturnStatusSuccessFinishResult); 2310 else 2311 { 2312 result.AppendError ("no matching executable images found"); 2313 result.SetStatus (eReturnStatusFailed); 2314 } 2315 } 2316 return result.Succeeded(); 2317 } 2318 2319 CommandOptions m_options; 2320 }; 2321 2322 static OptionEnumValueElement 2323 g_sort_option_enumeration[4] = 2324 { 2325 { eSortOrderNone, "none", "No sorting, use the original symbol table order."}, 2326 { eSortOrderByAddress, "address", "Sort output by symbol address."}, 2327 { eSortOrderByName, "name", "Sort output by symbol name."}, 2328 { 0, NULL, NULL } 2329 }; 2330 2331 2332 OptionDefinition 2333 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] = 2334 { 2335 { 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."}, 2336 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2337 }; 2338 2339 #pragma mark CommandObjectTargetModulesDumpSections 2340 2341 //---------------------------------------------------------------------- 2342 // Image section dumping command 2343 //---------------------------------------------------------------------- 2344 2345 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete 2346 { 2347 public: 2348 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) : 2349 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2350 "target modules dump sections", 2351 "Dump the sections from one or more target modules.", 2352 //"target modules dump sections [<file1> ...]") 2353 NULL) 2354 { 2355 } 2356 2357 virtual 2358 ~CommandObjectTargetModulesDumpSections () 2359 { 2360 } 2361 2362 protected: 2363 virtual bool 2364 DoExecute (Args& command, 2365 CommandReturnObject &result) 2366 { 2367 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2368 if (target == NULL) 2369 { 2370 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2371 result.SetStatus (eReturnStatusFailed); 2372 return false; 2373 } 2374 else 2375 { 2376 uint32_t num_dumped = 0; 2377 2378 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2379 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2380 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2381 2382 if (command.GetArgumentCount() == 0) 2383 { 2384 // Dump all sections for all modules images 2385 const size_t num_modules = target->GetImages().GetSize(); 2386 if (num_modules > 0) 2387 { 2388 result.GetOutputStream().Printf("Dumping sections for %" PRIu64 " modules.\n", (uint64_t)num_modules); 2389 for (size_t image_idx = 0; image_idx<num_modules; ++image_idx) 2390 { 2391 num_dumped++; 2392 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)); 2393 } 2394 } 2395 else 2396 { 2397 result.AppendError ("the target has no associated executable images"); 2398 result.SetStatus (eReturnStatusFailed); 2399 return false; 2400 } 2401 } 2402 else 2403 { 2404 // Dump specified images (by basename or fullpath) 2405 const char *arg_cstr; 2406 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2407 { 2408 ModuleList module_list; 2409 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2410 if (num_matches > 0) 2411 { 2412 for (size_t i=0; i<num_matches; ++i) 2413 { 2414 Module *module = module_list.GetModulePointerAtIndex(i); 2415 if (module) 2416 { 2417 num_dumped++; 2418 DumpModuleSections (m_interpreter, result.GetOutputStream(), module); 2419 } 2420 } 2421 } 2422 else 2423 { 2424 // Check the global list 2425 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 2426 2427 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2428 } 2429 } 2430 } 2431 2432 if (num_dumped > 0) 2433 result.SetStatus (eReturnStatusSuccessFinishResult); 2434 else 2435 { 2436 result.AppendError ("no matching executable images found"); 2437 result.SetStatus (eReturnStatusFailed); 2438 } 2439 } 2440 return result.Succeeded(); 2441 } 2442 }; 2443 2444 2445 #pragma mark CommandObjectTargetModulesDumpSymfile 2446 2447 //---------------------------------------------------------------------- 2448 // Image debug symbol dumping command 2449 //---------------------------------------------------------------------- 2450 2451 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete 2452 { 2453 public: 2454 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) : 2455 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2456 "target modules dump symfile", 2457 "Dump the debug symbol file for one or more target modules.", 2458 //"target modules dump symfile [<file1> ...]") 2459 NULL) 2460 { 2461 } 2462 2463 virtual 2464 ~CommandObjectTargetModulesDumpSymfile () 2465 { 2466 } 2467 2468 protected: 2469 virtual bool 2470 DoExecute (Args& command, 2471 CommandReturnObject &result) 2472 { 2473 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2474 if (target == NULL) 2475 { 2476 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2477 result.SetStatus (eReturnStatusFailed); 2478 return false; 2479 } 2480 else 2481 { 2482 uint32_t num_dumped = 0; 2483 2484 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2485 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2486 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2487 2488 if (command.GetArgumentCount() == 0) 2489 { 2490 // Dump all sections for all modules images 2491 const ModuleList &target_modules = target->GetImages(); 2492 Mutex::Locker modules_locker (target_modules.GetMutex()); 2493 const size_t num_modules = target_modules.GetSize(); 2494 if (num_modules > 0) 2495 { 2496 result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64 " modules.\n", (uint64_t)num_modules); 2497 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2498 { 2499 if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx))) 2500 num_dumped++; 2501 } 2502 } 2503 else 2504 { 2505 result.AppendError ("the target has no associated executable images"); 2506 result.SetStatus (eReturnStatusFailed); 2507 return false; 2508 } 2509 } 2510 else 2511 { 2512 // Dump specified images (by basename or fullpath) 2513 const char *arg_cstr; 2514 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2515 { 2516 ModuleList module_list; 2517 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2518 if (num_matches > 0) 2519 { 2520 for (size_t i=0; i<num_matches; ++i) 2521 { 2522 Module *module = module_list.GetModulePointerAtIndex(i); 2523 if (module) 2524 { 2525 if (DumpModuleSymbolVendor (result.GetOutputStream(), module)) 2526 num_dumped++; 2527 } 2528 } 2529 } 2530 else 2531 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2532 } 2533 } 2534 2535 if (num_dumped > 0) 2536 result.SetStatus (eReturnStatusSuccessFinishResult); 2537 else 2538 { 2539 result.AppendError ("no matching executable images found"); 2540 result.SetStatus (eReturnStatusFailed); 2541 } 2542 } 2543 return result.Succeeded(); 2544 } 2545 }; 2546 2547 2548 #pragma mark CommandObjectTargetModulesDumpLineTable 2549 2550 //---------------------------------------------------------------------- 2551 // Image debug line table dumping command 2552 //---------------------------------------------------------------------- 2553 2554 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete 2555 { 2556 public: 2557 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) : 2558 CommandObjectTargetModulesSourceFileAutoComplete (interpreter, 2559 "target modules dump line-table", 2560 "Dump the line table for one or more compilation units.", 2561 NULL, 2562 eCommandRequiresTarget) 2563 { 2564 } 2565 2566 virtual 2567 ~CommandObjectTargetModulesDumpLineTable () 2568 { 2569 } 2570 2571 protected: 2572 virtual bool 2573 DoExecute (Args& command, 2574 CommandReturnObject &result) 2575 { 2576 Target *target = m_exe_ctx.GetTargetPtr(); 2577 uint32_t total_num_dumped = 0; 2578 2579 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2580 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2581 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2582 2583 if (command.GetArgumentCount() == 0) 2584 { 2585 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); 2586 result.SetStatus (eReturnStatusFailed); 2587 } 2588 else 2589 { 2590 // Dump specified images (by basename or fullpath) 2591 const char *arg_cstr; 2592 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2593 { 2594 FileSpec file_spec(arg_cstr, false); 2595 2596 const ModuleList &target_modules = target->GetImages(); 2597 Mutex::Locker modules_locker(target_modules.GetMutex()); 2598 const size_t num_modules = target_modules.GetSize(); 2599 if (num_modules > 0) 2600 { 2601 uint32_t num_dumped = 0; 2602 for (uint32_t i = 0; i<num_modules; ++i) 2603 { 2604 if (DumpCompileUnitLineTable (m_interpreter, 2605 result.GetOutputStream(), 2606 target_modules.GetModulePointerAtIndexUnlocked(i), 2607 file_spec, 2608 m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive())) 2609 num_dumped++; 2610 } 2611 if (num_dumped == 0) 2612 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); 2613 else 2614 total_num_dumped += num_dumped; 2615 } 2616 } 2617 } 2618 2619 if (total_num_dumped > 0) 2620 result.SetStatus (eReturnStatusSuccessFinishResult); 2621 else 2622 { 2623 result.AppendError ("no source filenames matched any command arguments"); 2624 result.SetStatus (eReturnStatusFailed); 2625 } 2626 return result.Succeeded(); 2627 } 2628 }; 2629 2630 2631 #pragma mark CommandObjectTargetModulesDump 2632 2633 //---------------------------------------------------------------------- 2634 // Dump multi-word command for target modules 2635 //---------------------------------------------------------------------- 2636 2637 class CommandObjectTargetModulesDump : public CommandObjectMultiword 2638 { 2639 public: 2640 //------------------------------------------------------------------ 2641 // Constructors and Destructors 2642 //------------------------------------------------------------------ 2643 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) : 2644 CommandObjectMultiword (interpreter, 2645 "target modules dump", 2646 "A set of commands for dumping information about one or more target modules.", 2647 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]") 2648 { 2649 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter))); 2650 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter))); 2651 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter))); 2652 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter))); 2653 } 2654 2655 virtual 2656 ~CommandObjectTargetModulesDump() 2657 { 2658 } 2659 }; 2660 2661 class CommandObjectTargetModulesAdd : public CommandObjectParsed 2662 { 2663 public: 2664 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) : 2665 CommandObjectParsed (interpreter, 2666 "target modules add", 2667 "Add a new module to the current target's modules.", 2668 "target modules add [<module>]"), 2669 m_option_group (interpreter), 2670 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.") 2671 { 2672 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2673 m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2674 m_option_group.Finalize(); 2675 } 2676 2677 virtual 2678 ~CommandObjectTargetModulesAdd () 2679 { 2680 } 2681 2682 virtual Options * 2683 GetOptions () 2684 { 2685 return &m_option_group; 2686 } 2687 2688 virtual int 2689 HandleArgumentCompletion (Args &input, 2690 int &cursor_index, 2691 int &cursor_char_position, 2692 OptionElementVector &opt_element_vector, 2693 int match_start_point, 2694 int max_return_elements, 2695 bool &word_complete, 2696 StringList &matches) 2697 { 2698 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2699 completion_str.erase (cursor_char_position); 2700 2701 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2702 CommandCompletions::eDiskFileCompletion, 2703 completion_str.c_str(), 2704 match_start_point, 2705 max_return_elements, 2706 NULL, 2707 word_complete, 2708 matches); 2709 return matches.GetSize(); 2710 } 2711 2712 protected: 2713 OptionGroupOptions m_option_group; 2714 OptionGroupUUID m_uuid_option_group; 2715 OptionGroupFile m_symbol_file; 2716 2717 virtual bool 2718 DoExecute (Args& args, 2719 CommandReturnObject &result) 2720 { 2721 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2722 if (target == NULL) 2723 { 2724 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2725 result.SetStatus (eReturnStatusFailed); 2726 return false; 2727 } 2728 else 2729 { 2730 bool flush = false; 2731 2732 const size_t argc = args.GetArgumentCount(); 2733 if (argc == 0) 2734 { 2735 if (m_uuid_option_group.GetOptionValue ().OptionWasSet()) 2736 { 2737 // We are given a UUID only, go locate the file 2738 ModuleSpec module_spec; 2739 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue(); 2740 if (m_symbol_file.GetOptionValue().OptionWasSet()) 2741 module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue(); 2742 if (Symbols::DownloadObjectAndSymbolFile (module_spec)) 2743 { 2744 ModuleSP module_sp (target->GetSharedModule (module_spec)); 2745 if (module_sp) 2746 { 2747 result.SetStatus (eReturnStatusSuccessFinishResult); 2748 return true; 2749 } 2750 else 2751 { 2752 StreamString strm; 2753 module_spec.GetUUID().Dump (&strm); 2754 if (module_spec.GetFileSpec()) 2755 { 2756 if (module_spec.GetSymbolFileSpec()) 2757 { 2758 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s and symbol file %s", 2759 strm.GetString().c_str(), 2760 module_spec.GetFileSpec().GetPath().c_str(), 2761 module_spec.GetSymbolFileSpec().GetPath().c_str()); 2762 } 2763 else 2764 { 2765 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s", 2766 strm.GetString().c_str(), 2767 module_spec.GetFileSpec().GetPath().c_str()); 2768 } 2769 } 2770 else 2771 { 2772 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s", 2773 strm.GetString().c_str()); 2774 } 2775 result.SetStatus (eReturnStatusFailed); 2776 return false; 2777 } 2778 } 2779 else 2780 { 2781 StreamString strm; 2782 module_spec.GetUUID().Dump (&strm); 2783 result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str()); 2784 result.SetStatus (eReturnStatusFailed); 2785 return false; 2786 } 2787 } 2788 else 2789 { 2790 result.AppendError ("one or more executable image paths must be specified"); 2791 result.SetStatus (eReturnStatusFailed); 2792 return false; 2793 } 2794 } 2795 else 2796 { 2797 for (size_t i=0; i<argc; ++i) 2798 { 2799 const char *path = args.GetArgumentAtIndex(i); 2800 if (path) 2801 { 2802 FileSpec file_spec(path, true); 2803 if (file_spec.Exists()) 2804 { 2805 ModuleSpec module_spec (file_spec); 2806 if (m_uuid_option_group.GetOptionValue ().OptionWasSet()) 2807 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue(); 2808 if (m_symbol_file.GetOptionValue().OptionWasSet()) 2809 module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue(); 2810 if (!module_spec.GetArchitecture().IsValid()) 2811 module_spec.GetArchitecture() = target->GetArchitecture(); 2812 Error error; 2813 ModuleSP module_sp (target->GetSharedModule (module_spec, &error)); 2814 if (!module_sp) 2815 { 2816 const char *error_cstr = error.AsCString(); 2817 if (error_cstr) 2818 result.AppendError (error_cstr); 2819 else 2820 result.AppendErrorWithFormat ("unsupported module: %s", path); 2821 result.SetStatus (eReturnStatusFailed); 2822 return false; 2823 } 2824 else 2825 { 2826 flush = true; 2827 } 2828 result.SetStatus (eReturnStatusSuccessFinishResult); 2829 } 2830 else 2831 { 2832 char resolved_path[PATH_MAX]; 2833 result.SetStatus (eReturnStatusFailed); 2834 if (file_spec.GetPath (resolved_path, sizeof(resolved_path))) 2835 { 2836 if (strcmp (resolved_path, path) != 0) 2837 { 2838 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path); 2839 break; 2840 } 2841 } 2842 result.AppendErrorWithFormat ("invalid module path '%s'\n", path); 2843 break; 2844 } 2845 } 2846 } 2847 } 2848 2849 if (flush) 2850 { 2851 ProcessSP process = target->GetProcessSP(); 2852 if (process) 2853 process->Flush(); 2854 } 2855 } 2856 2857 return result.Succeeded(); 2858 } 2859 2860 }; 2861 2862 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete 2863 { 2864 public: 2865 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) : 2866 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2867 "target modules load", 2868 "Set the load addresses for one or more sections in a target module.", 2869 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"), 2870 m_option_group (interpreter), 2871 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""), 2872 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) 2873 { 2874 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2875 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2876 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2877 m_option_group.Finalize(); 2878 } 2879 2880 virtual 2881 ~CommandObjectTargetModulesLoad () 2882 { 2883 } 2884 2885 virtual Options * 2886 GetOptions () 2887 { 2888 return &m_option_group; 2889 } 2890 2891 protected: 2892 virtual bool 2893 DoExecute (Args& args, 2894 CommandReturnObject &result) 2895 { 2896 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2897 if (target == NULL) 2898 { 2899 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2900 result.SetStatus (eReturnStatusFailed); 2901 return false; 2902 } 2903 else 2904 { 2905 const size_t argc = args.GetArgumentCount(); 2906 ModuleSpec module_spec; 2907 bool search_using_module_spec = false; 2908 if (m_file_option.GetOptionValue().OptionWasSet()) 2909 { 2910 search_using_module_spec = true; 2911 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue(); 2912 const bool use_global_module_list = true; 2913 ModuleList module_list; 2914 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list); 2915 if (num_matches == 1) 2916 { 2917 module_spec.GetFileSpec() = module_list.GetModuleAtIndex(0)->GetFileSpec(); 2918 } 2919 else if (num_matches > 1 ) 2920 { 2921 search_using_module_spec = false; 2922 result.AppendErrorWithFormat ("more than 1 module matched by name '%s'\n", arg_cstr); 2923 result.SetStatus (eReturnStatusFailed); 2924 } 2925 else 2926 { 2927 search_using_module_spec = false; 2928 result.AppendErrorWithFormat ("no object file for module '%s'\n", arg_cstr); 2929 result.SetStatus (eReturnStatusFailed); 2930 } 2931 } 2932 2933 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2934 { 2935 search_using_module_spec = true; 2936 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2937 } 2938 2939 if (search_using_module_spec) 2940 { 2941 ModuleList matching_modules; 2942 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules); 2943 2944 char path[PATH_MAX]; 2945 if (num_matches == 1) 2946 { 2947 Module *module = matching_modules.GetModulePointerAtIndex(0); 2948 if (module) 2949 { 2950 ObjectFile *objfile = module->GetObjectFile(); 2951 if (objfile) 2952 { 2953 SectionList *section_list = module->GetSectionList(); 2954 if (section_list) 2955 { 2956 bool changed = false; 2957 if (argc == 0) 2958 { 2959 if (m_slide_option.GetOptionValue().OptionWasSet()) 2960 { 2961 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue(); 2962 const bool slide_is_offset = true; 2963 module->SetLoadAddress (*target, slide, slide_is_offset, changed); 2964 } 2965 else 2966 { 2967 result.AppendError ("one or more section name + load address pair must be specified"); 2968 result.SetStatus (eReturnStatusFailed); 2969 return false; 2970 } 2971 } 2972 else 2973 { 2974 if (m_slide_option.GetOptionValue().OptionWasSet()) 2975 { 2976 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n"); 2977 result.SetStatus (eReturnStatusFailed); 2978 return false; 2979 } 2980 2981 for (size_t i=0; i<argc; i += 2) 2982 { 2983 const char *sect_name = args.GetArgumentAtIndex(i); 2984 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1); 2985 if (sect_name && load_addr_cstr) 2986 { 2987 ConstString const_sect_name(sect_name); 2988 bool success = false; 2989 addr_t load_addr = StringConvert::ToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); 2990 if (success) 2991 { 2992 SectionSP section_sp (section_list->FindSectionByName(const_sect_name)); 2993 if (section_sp) 2994 { 2995 if (section_sp->IsThreadSpecific()) 2996 { 2997 result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name); 2998 result.SetStatus (eReturnStatusFailed); 2999 break; 3000 } 3001 else 3002 { 3003 if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr)) 3004 changed = true; 3005 result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr); 3006 } 3007 } 3008 else 3009 { 3010 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name); 3011 result.SetStatus (eReturnStatusFailed); 3012 break; 3013 } 3014 } 3015 else 3016 { 3017 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr); 3018 result.SetStatus (eReturnStatusFailed); 3019 break; 3020 } 3021 } 3022 else 3023 { 3024 if (sect_name) 3025 result.AppendError ("section names must be followed by a load address.\n"); 3026 else 3027 result.AppendError ("one or more section name + load address pair must be specified.\n"); 3028 result.SetStatus (eReturnStatusFailed); 3029 break; 3030 } 3031 } 3032 } 3033 3034 if (changed) 3035 { 3036 target->ModulesDidLoad (matching_modules); 3037 Process *process = m_exe_ctx.GetProcessPtr(); 3038 if (process) 3039 process->Flush(); 3040 } 3041 } 3042 else 3043 { 3044 module->GetFileSpec().GetPath (path, sizeof(path)); 3045 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path); 3046 result.SetStatus (eReturnStatusFailed); 3047 } 3048 } 3049 else 3050 { 3051 module->GetFileSpec().GetPath (path, sizeof(path)); 3052 result.AppendErrorWithFormat ("no object file for module '%s'\n", path); 3053 result.SetStatus (eReturnStatusFailed); 3054 } 3055 } 3056 else 3057 { 3058 FileSpec *module_spec_file = module_spec.GetFileSpecPtr(); 3059 if (module_spec_file) 3060 { 3061 module_spec_file->GetPath (path, sizeof(path)); 3062 result.AppendErrorWithFormat ("invalid module '%s'.\n", path); 3063 } 3064 else 3065 result.AppendError ("no module spec"); 3066 result.SetStatus (eReturnStatusFailed); 3067 } 3068 } 3069 else 3070 { 3071 std::string uuid_str; 3072 3073 if (module_spec.GetFileSpec()) 3074 module_spec.GetFileSpec().GetPath (path, sizeof(path)); 3075 else 3076 path[0] = '\0'; 3077 3078 if (module_spec.GetUUIDPtr()) 3079 uuid_str = module_spec.GetUUID().GetAsString(); 3080 if (num_matches > 1) 3081 { 3082 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", 3083 path[0] ? " file=" : "", 3084 path, 3085 !uuid_str.empty() ? " uuid=" : "", 3086 uuid_str.c_str()); 3087 for (size_t i=0; i<num_matches; ++i) 3088 { 3089 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path))) 3090 result.AppendMessageWithFormat("%s\n", path); 3091 } 3092 } 3093 else 3094 { 3095 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n", 3096 path[0] ? " file=" : "", 3097 path, 3098 !uuid_str.empty() ? " uuid=" : "", 3099 uuid_str.c_str()); 3100 } 3101 result.SetStatus (eReturnStatusFailed); 3102 } 3103 } 3104 else 3105 { 3106 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n"); 3107 result.SetStatus (eReturnStatusFailed); 3108 return false; 3109 } 3110 } 3111 return result.Succeeded(); 3112 } 3113 3114 OptionGroupOptions m_option_group; 3115 OptionGroupUUID m_uuid_option_group; 3116 OptionGroupString m_file_option; 3117 OptionGroupUInt64 m_slide_option; 3118 }; 3119 3120 //---------------------------------------------------------------------- 3121 // List images with associated information 3122 //---------------------------------------------------------------------- 3123 class CommandObjectTargetModulesList : public CommandObjectParsed 3124 { 3125 public: 3126 class CommandOptions : public Options 3127 { 3128 public: 3129 CommandOptions (CommandInterpreter &interpreter) : 3130 Options(interpreter), 3131 m_format_array(), 3132 m_use_global_module_list (false), 3133 m_module_addr (LLDB_INVALID_ADDRESS) 3134 { 3135 } 3136 3137 virtual 3138 ~CommandOptions () 3139 { 3140 } 3141 3142 virtual Error 3143 SetOptionValue (uint32_t option_idx, const char *option_arg) 3144 { 3145 Error error; 3146 3147 const int short_option = m_getopt_table[option_idx].val; 3148 if (short_option == 'g') 3149 { 3150 m_use_global_module_list = true; 3151 } 3152 else if (short_option == 'a') 3153 { 3154 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3155 m_module_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3156 } 3157 else 3158 { 3159 unsigned long width = 0; 3160 if (option_arg) 3161 width = strtoul (option_arg, NULL, 0); 3162 m_format_array.push_back(std::make_pair(short_option, width)); 3163 } 3164 return error; 3165 } 3166 3167 void 3168 OptionParsingStarting () 3169 { 3170 m_format_array.clear(); 3171 m_use_global_module_list = false; 3172 m_module_addr = LLDB_INVALID_ADDRESS; 3173 } 3174 3175 const OptionDefinition* 3176 GetDefinitions () 3177 { 3178 return g_option_table; 3179 } 3180 3181 // Options table: Required for subclasses of Options. 3182 3183 static OptionDefinition g_option_table[]; 3184 3185 // Instance variables to hold the values for command options. 3186 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection; 3187 FormatWidthCollection m_format_array; 3188 bool m_use_global_module_list; 3189 lldb::addr_t m_module_addr; 3190 }; 3191 3192 CommandObjectTargetModulesList (CommandInterpreter &interpreter) : 3193 CommandObjectParsed (interpreter, 3194 "target modules list", 3195 "List current executable and dependent shared library images.", 3196 "target modules list [<cmd-options>]"), 3197 m_options (interpreter) 3198 { 3199 } 3200 3201 virtual 3202 ~CommandObjectTargetModulesList () 3203 { 3204 } 3205 3206 virtual 3207 Options * 3208 GetOptions () 3209 { 3210 return &m_options; 3211 } 3212 3213 protected: 3214 virtual bool 3215 DoExecute (Args& command, 3216 CommandReturnObject &result) 3217 { 3218 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3219 const bool use_global_module_list = m_options.m_use_global_module_list; 3220 // Define a local module list here to ensure it lives longer than any "locker" 3221 // object which might lock its contents below (through the "module_list_ptr" 3222 // variable). 3223 ModuleList module_list; 3224 if (target == NULL && use_global_module_list == false) 3225 { 3226 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3227 result.SetStatus (eReturnStatusFailed); 3228 return false; 3229 } 3230 else 3231 { 3232 if (target) 3233 { 3234 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3235 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3236 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3237 } 3238 // Dump all sections for all modules images 3239 Stream &strm = result.GetOutputStream(); 3240 3241 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) 3242 { 3243 if (target) 3244 { 3245 Address module_address; 3246 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) 3247 { 3248 ModuleSP module_sp (module_address.GetModule()); 3249 if (module_sp) 3250 { 3251 PrintModule (target, module_sp.get(), 0, strm); 3252 result.SetStatus (eReturnStatusSuccessFinishResult); 3253 } 3254 else 3255 { 3256 result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr); 3257 result.SetStatus (eReturnStatusFailed); 3258 } 3259 } 3260 else 3261 { 3262 result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr); 3263 result.SetStatus (eReturnStatusFailed); 3264 } 3265 } 3266 else 3267 { 3268 result.AppendError ("Can only look up modules by address with a valid target."); 3269 result.SetStatus (eReturnStatusFailed); 3270 } 3271 return result.Succeeded(); 3272 } 3273 3274 size_t num_modules = 0; 3275 Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL. 3276 // Otherwise it will lock the AllocationModuleCollectionMutex when accessing 3277 // the global module list directly. 3278 const ModuleList *module_list_ptr = NULL; 3279 const size_t argc = command.GetArgumentCount(); 3280 if (argc == 0) 3281 { 3282 if (use_global_module_list) 3283 { 3284 locker.Lock (Module::GetAllocationModuleCollectionMutex()); 3285 num_modules = Module::GetNumberAllocatedModules(); 3286 } 3287 else 3288 { 3289 module_list_ptr = &target->GetImages(); 3290 } 3291 } 3292 else 3293 { 3294 for (size_t i=0; i<argc; ++i) 3295 { 3296 // Dump specified images (by basename or fullpath) 3297 const char *arg_cstr = command.GetArgumentAtIndex(i); 3298 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list); 3299 if (num_matches == 0) 3300 { 3301 if (argc == 1) 3302 { 3303 result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr); 3304 result.SetStatus (eReturnStatusFailed); 3305 return false; 3306 } 3307 } 3308 } 3309 3310 module_list_ptr = &module_list; 3311 } 3312 3313 if (module_list_ptr != NULL) 3314 { 3315 locker.Lock(module_list_ptr->GetMutex()); 3316 num_modules = module_list_ptr->GetSize(); 3317 } 3318 3319 if (num_modules > 0) 3320 { 3321 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 3322 { 3323 ModuleSP module_sp; 3324 Module *module; 3325 if (module_list_ptr) 3326 { 3327 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx); 3328 module = module_sp.get(); 3329 } 3330 else 3331 { 3332 module = Module::GetAllocatedModuleAtIndex(image_idx); 3333 module_sp = module->shared_from_this(); 3334 } 3335 3336 const size_t indent = strm.Printf("[%3u] ", image_idx); 3337 PrintModule (target, module, indent, strm); 3338 3339 } 3340 result.SetStatus (eReturnStatusSuccessFinishResult); 3341 } 3342 else 3343 { 3344 if (argc) 3345 { 3346 if (use_global_module_list) 3347 result.AppendError ("the global module list has no matching modules"); 3348 else 3349 result.AppendError ("the target has no matching modules"); 3350 } 3351 else 3352 { 3353 if (use_global_module_list) 3354 result.AppendError ("the global module list is empty"); 3355 else 3356 result.AppendError ("the target has no associated executable images"); 3357 } 3358 result.SetStatus (eReturnStatusFailed); 3359 return false; 3360 } 3361 } 3362 return result.Succeeded(); 3363 } 3364 3365 void 3366 PrintModule (Target *target, Module *module, int indent, Stream &strm) 3367 { 3368 3369 if (module == NULL) 3370 { 3371 strm.PutCString("Null module"); 3372 return; 3373 } 3374 3375 bool dump_object_name = false; 3376 if (m_options.m_format_array.empty()) 3377 { 3378 m_options.m_format_array.push_back(std::make_pair('u', 0)); 3379 m_options.m_format_array.push_back(std::make_pair('h', 0)); 3380 m_options.m_format_array.push_back(std::make_pair('f', 0)); 3381 m_options.m_format_array.push_back(std::make_pair('S', 0)); 3382 } 3383 const size_t num_entries = m_options.m_format_array.size(); 3384 bool print_space = false; 3385 for (size_t i=0; i<num_entries; ++i) 3386 { 3387 if (print_space) 3388 strm.PutChar(' '); 3389 print_space = true; 3390 const char format_char = m_options.m_format_array[i].first; 3391 uint32_t width = m_options.m_format_array[i].second; 3392 switch (format_char) 3393 { 3394 case 'A': 3395 DumpModuleArchitecture (strm, module, false, width); 3396 break; 3397 3398 case 't': 3399 DumpModuleArchitecture (strm, module, true, width); 3400 break; 3401 3402 case 'f': 3403 DumpFullpath (strm, &module->GetFileSpec(), width); 3404 dump_object_name = true; 3405 break; 3406 3407 case 'd': 3408 DumpDirectory (strm, &module->GetFileSpec(), width); 3409 break; 3410 3411 case 'b': 3412 DumpBasename (strm, &module->GetFileSpec(), width); 3413 dump_object_name = true; 3414 break; 3415 3416 case 'h': 3417 case 'o': 3418 // Image header address 3419 { 3420 uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16; 3421 3422 ObjectFile *objfile = module->GetObjectFile (); 3423 if (objfile) 3424 { 3425 Address header_addr(objfile->GetHeaderAddress()); 3426 if (header_addr.IsValid()) 3427 { 3428 if (target && !target->GetSectionLoadList().IsEmpty()) 3429 { 3430 lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target); 3431 if (header_load_addr == LLDB_INVALID_ADDRESS) 3432 { 3433 header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress); 3434 } 3435 else 3436 { 3437 if (format_char == 'o') 3438 { 3439 // Show the offset of slide for the image 3440 strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress()); 3441 } 3442 else 3443 { 3444 // Show the load address of the image 3445 strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr); 3446 } 3447 } 3448 break; 3449 } 3450 // The address was valid, but the image isn't loaded, output the address in an appropriate format 3451 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress); 3452 break; 3453 } 3454 } 3455 strm.Printf ("%*s", addr_nibble_width + 2, ""); 3456 } 3457 break; 3458 case 'r': 3459 { 3460 size_t ref_count = 0; 3461 ModuleSP module_sp (module->shared_from_this()); 3462 if (module_sp) 3463 { 3464 // Take one away to make sure we don't count our local "module_sp" 3465 ref_count = module_sp.use_count() - 1; 3466 } 3467 if (width) 3468 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count); 3469 else 3470 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count); 3471 } 3472 break; 3473 3474 case 's': 3475 case 'S': 3476 { 3477 const SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 3478 if (symbol_vendor) 3479 { 3480 const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec(); 3481 if (format_char == 'S') 3482 { 3483 // Dump symbol file only if different from module file 3484 if (!symfile_spec || symfile_spec == module->GetFileSpec()) 3485 { 3486 print_space = false; 3487 break; 3488 } 3489 // Add a newline and indent past the index 3490 strm.Printf ("\n%*s", indent, ""); 3491 } 3492 DumpFullpath (strm, &symfile_spec, width); 3493 dump_object_name = true; 3494 break; 3495 } 3496 strm.Printf("%.*s", width, "<NONE>"); 3497 } 3498 break; 3499 3500 case 'm': 3501 module->GetModificationTime().Dump(&strm, width); 3502 break; 3503 3504 case 'p': 3505 strm.Printf("%p", static_cast<void*>(module)); 3506 break; 3507 3508 case 'u': 3509 DumpModuleUUID(strm, module); 3510 break; 3511 3512 default: 3513 break; 3514 } 3515 3516 } 3517 if (dump_object_name) 3518 { 3519 const char *object_name = module->GetObjectName().GetCString(); 3520 if (object_name) 3521 strm.Printf ("(%s)", object_name); 3522 } 3523 strm.EOL(); 3524 } 3525 3526 CommandOptions m_options; 3527 }; 3528 3529 OptionDefinition 3530 CommandObjectTargetModulesList::CommandOptions::g_option_table[] = 3531 { 3532 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."}, 3533 { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, 3534 { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, 3535 { 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."}, 3536 { 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)."}, 3537 { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, 3538 { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, 3539 { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, 3540 { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, 3541 { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, 3542 { 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."}, 3543 { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, 3544 { 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."}, 3545 { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeNone, "Display the module pointer."}, 3546 { 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."}, 3547 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3548 }; 3549 3550 #pragma mark CommandObjectTargetModulesShowUnwind 3551 3552 //---------------------------------------------------------------------- 3553 // Lookup unwind information in images 3554 //---------------------------------------------------------------------- 3555 3556 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed 3557 { 3558 public: 3559 3560 enum 3561 { 3562 eLookupTypeInvalid = -1, 3563 eLookupTypeAddress = 0, 3564 eLookupTypeSymbol, 3565 eLookupTypeFunction, 3566 eLookupTypeFunctionOrSymbol, 3567 kNumLookupTypes 3568 }; 3569 3570 class CommandOptions : public Options 3571 { 3572 public: 3573 3574 CommandOptions (CommandInterpreter &interpreter) : 3575 Options(interpreter), 3576 m_type(eLookupTypeInvalid), 3577 m_str(), 3578 m_addr(LLDB_INVALID_ADDRESS) 3579 { 3580 } 3581 3582 virtual 3583 ~CommandOptions () 3584 { 3585 } 3586 3587 virtual Error 3588 SetOptionValue (uint32_t option_idx, const char *option_arg) 3589 { 3590 Error error; 3591 3592 const int short_option = m_getopt_table[option_idx].val; 3593 3594 switch (short_option) 3595 { 3596 case 'a': 3597 { 3598 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3599 m_str = option_arg; 3600 m_type = eLookupTypeAddress; 3601 m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3602 if (m_addr == LLDB_INVALID_ADDRESS) 3603 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg); 3604 break; 3605 } 3606 3607 case 'n': 3608 { 3609 m_str = option_arg; 3610 m_type = eLookupTypeFunctionOrSymbol; 3611 break; 3612 } 3613 3614 default: 3615 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option); 3616 break; 3617 } 3618 3619 return error; 3620 } 3621 3622 void 3623 OptionParsingStarting () 3624 { 3625 m_type = eLookupTypeInvalid; 3626 m_str.clear(); 3627 m_addr = LLDB_INVALID_ADDRESS; 3628 } 3629 3630 const OptionDefinition* 3631 GetDefinitions () 3632 { 3633 return g_option_table; 3634 } 3635 3636 // Options table: Required for subclasses of Options. 3637 3638 static OptionDefinition g_option_table[]; 3639 3640 // Instance variables to hold the values for command options. 3641 3642 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3643 std::string m_str; // Holds name lookup 3644 lldb::addr_t m_addr; // Holds the address to lookup 3645 }; 3646 3647 CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) : 3648 CommandObjectParsed (interpreter, 3649 "target modules show-unwind", 3650 "Show synthesized unwind instructions for a function.", 3651 NULL, 3652 eCommandRequiresTarget | 3653 eCommandRequiresProcess | 3654 eCommandProcessMustBeLaunched | 3655 eCommandProcessMustBePaused ), 3656 m_options (interpreter) 3657 { 3658 } 3659 3660 virtual 3661 ~CommandObjectTargetModulesShowUnwind () 3662 { 3663 } 3664 3665 virtual 3666 Options * 3667 GetOptions () 3668 { 3669 return &m_options; 3670 } 3671 3672 protected: 3673 bool 3674 DoExecute (Args& command, 3675 CommandReturnObject &result) 3676 { 3677 Target *target = m_exe_ctx.GetTargetPtr(); 3678 Process *process = m_exe_ctx.GetProcessPtr(); 3679 ABI *abi = NULL; 3680 if (process) 3681 abi = process->GetABI().get(); 3682 3683 if (process == NULL) 3684 { 3685 result.AppendError ("You must have a process running to use this command."); 3686 result.SetStatus (eReturnStatusFailed); 3687 return false; 3688 } 3689 3690 ThreadList threads(process->GetThreadList()); 3691 if (threads.GetSize() == 0) 3692 { 3693 result.AppendError ("The process must be paused to use this command."); 3694 result.SetStatus (eReturnStatusFailed); 3695 return false; 3696 } 3697 3698 ThreadSP thread(threads.GetThreadAtIndex(0)); 3699 if (thread.get() == NULL) 3700 { 3701 result.AppendError ("The process must be paused to use this command."); 3702 result.SetStatus (eReturnStatusFailed); 3703 return false; 3704 } 3705 3706 SymbolContextList sc_list; 3707 3708 if (m_options.m_type == eLookupTypeFunctionOrSymbol) 3709 { 3710 ConstString function_name (m_options.m_str.c_str()); 3711 target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list); 3712 } 3713 else if (m_options.m_type == eLookupTypeAddress && target) 3714 { 3715 Address addr; 3716 if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr)) 3717 { 3718 SymbolContext sc; 3719 ModuleSP module_sp (addr.GetModule()); 3720 module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc); 3721 if (sc.function || sc.symbol) 3722 { 3723 sc_list.Append(sc); 3724 } 3725 } 3726 } 3727 else 3728 { 3729 result.AppendError ("address-expression or function name option must be specified."); 3730 result.SetStatus (eReturnStatusFailed); 3731 return false; 3732 } 3733 3734 size_t num_matches = sc_list.GetSize(); 3735 if (num_matches == 0) 3736 { 3737 result.AppendErrorWithFormat ("no unwind data found that matches '%s'.", m_options.m_str.c_str()); 3738 result.SetStatus (eReturnStatusFailed); 3739 return false; 3740 } 3741 3742 for (uint32_t idx = 0; idx < num_matches; idx++) 3743 { 3744 SymbolContext sc; 3745 sc_list.GetContextAtIndex(idx, sc); 3746 if (sc.symbol == NULL && sc.function == NULL) 3747 continue; 3748 if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL) 3749 continue; 3750 AddressRange range; 3751 if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range)) 3752 continue; 3753 if (!range.GetBaseAddress().IsValid()) 3754 continue; 3755 ConstString funcname(sc.GetFunctionName()); 3756 if (funcname.IsEmpty()) 3757 continue; 3758 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target); 3759 if (abi) 3760 start_addr = abi->FixCodeAddress(start_addr); 3761 3762 FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc)); 3763 if (func_unwinders_sp.get() == NULL) 3764 continue; 3765 3766 result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3767 3768 UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1); 3769 if (non_callsite_unwind_plan.get()) 3770 { 3771 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString()); 3772 } 3773 UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1); 3774 if (callsite_unwind_plan.get()) 3775 { 3776 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString()); 3777 } 3778 UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get()); 3779 if (fast_unwind_plan.get()) 3780 { 3781 result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString()); 3782 } 3783 3784 result.GetOutputStream().Printf("\n"); 3785 3786 UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread.get(), 0); 3787 if (assembly_sp) 3788 { 3789 result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n"); 3790 assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3791 result.GetOutputStream().Printf("\n"); 3792 } 3793 3794 3795 UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0); 3796 if (ehframe_sp) 3797 { 3798 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n"); 3799 ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3800 result.GetOutputStream().Printf("\n"); 3801 } 3802 3803 UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread.get(), 0); 3804 if (ehframe_augmented_sp) 3805 { 3806 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n"); 3807 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3808 result.GetOutputStream().Printf("\n"); 3809 } 3810 3811 UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0); 3812 if (compact_unwind_sp) 3813 { 3814 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n"); 3815 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3816 result.GetOutputStream().Printf("\n"); 3817 } 3818 3819 if (fast_unwind_plan) 3820 { 3821 result.GetOutputStream().Printf("Fast UnwindPlan:\n"); 3822 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3823 result.GetOutputStream().Printf("\n"); 3824 } 3825 3826 ABISP abi_sp = process->GetABI(); 3827 if (abi_sp) 3828 { 3829 UnwindPlan arch_default(lldb::eRegisterKindGeneric); 3830 if (abi_sp->CreateDefaultUnwindPlan (arch_default)) 3831 { 3832 result.GetOutputStream().Printf("Arch default UnwindPlan:\n"); 3833 arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3834 result.GetOutputStream().Printf("\n"); 3835 } 3836 3837 UnwindPlan arch_entry(lldb::eRegisterKindGeneric); 3838 if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry)) 3839 { 3840 result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n"); 3841 arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3842 result.GetOutputStream().Printf("\n"); 3843 } 3844 } 3845 3846 result.GetOutputStream().Printf ("\n"); 3847 } 3848 return result.Succeeded(); 3849 } 3850 3851 CommandOptions m_options; 3852 }; 3853 3854 OptionDefinition 3855 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] = 3856 { 3857 { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."}, 3858 { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"}, 3859 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3860 }; 3861 3862 //---------------------------------------------------------------------- 3863 // Lookup information in images 3864 //---------------------------------------------------------------------- 3865 class CommandObjectTargetModulesLookup : public CommandObjectParsed 3866 { 3867 public: 3868 enum 3869 { 3870 eLookupTypeInvalid = -1, 3871 eLookupTypeAddress = 0, 3872 eLookupTypeSymbol, 3873 eLookupTypeFileLine, // Line is optional 3874 eLookupTypeFunction, 3875 eLookupTypeFunctionOrSymbol, 3876 eLookupTypeType, 3877 kNumLookupTypes 3878 }; 3879 3880 class CommandOptions : public Options 3881 { 3882 public: 3883 CommandOptions (CommandInterpreter &interpreter) : 3884 Options(interpreter) 3885 { 3886 OptionParsingStarting(); 3887 } 3888 3889 virtual 3890 ~CommandOptions () 3891 { 3892 } 3893 3894 virtual Error 3895 SetOptionValue (uint32_t option_idx, const char *option_arg) 3896 { 3897 Error error; 3898 3899 const int short_option = m_getopt_table[option_idx].val; 3900 3901 switch (short_option) 3902 { 3903 case 'a': 3904 { 3905 m_type = eLookupTypeAddress; 3906 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3907 m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3908 } 3909 break; 3910 3911 case 'o': 3912 m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3913 if (m_offset == LLDB_INVALID_ADDRESS) 3914 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg); 3915 break; 3916 3917 case 's': 3918 m_str = option_arg; 3919 m_type = eLookupTypeSymbol; 3920 break; 3921 3922 case 'f': 3923 m_file.SetFile (option_arg, false); 3924 m_type = eLookupTypeFileLine; 3925 break; 3926 3927 case 'i': 3928 m_include_inlines = false; 3929 break; 3930 3931 case 'l': 3932 m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX); 3933 if (m_line_number == UINT32_MAX) 3934 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg); 3935 else if (m_line_number == 0) 3936 error.SetErrorString ("zero is an invalid line number"); 3937 m_type = eLookupTypeFileLine; 3938 break; 3939 3940 case 'F': 3941 m_str = option_arg; 3942 m_type = eLookupTypeFunction; 3943 break; 3944 3945 case 'n': 3946 m_str = option_arg; 3947 m_type = eLookupTypeFunctionOrSymbol; 3948 break; 3949 3950 case 't': 3951 m_str = option_arg; 3952 m_type = eLookupTypeType; 3953 break; 3954 3955 case 'v': 3956 m_verbose = 1; 3957 break; 3958 3959 case 'A': 3960 m_print_all = true; 3961 break; 3962 3963 case 'r': 3964 m_use_regex = true; 3965 break; 3966 } 3967 3968 return error; 3969 } 3970 3971 void 3972 OptionParsingStarting () 3973 { 3974 m_type = eLookupTypeInvalid; 3975 m_str.clear(); 3976 m_file.Clear(); 3977 m_addr = LLDB_INVALID_ADDRESS; 3978 m_offset = 0; 3979 m_line_number = 0; 3980 m_use_regex = false; 3981 m_include_inlines = true; 3982 m_verbose = false; 3983 m_print_all = false; 3984 } 3985 3986 const OptionDefinition* 3987 GetDefinitions () 3988 { 3989 return g_option_table; 3990 } 3991 3992 // Options table: Required for subclasses of Options. 3993 3994 static OptionDefinition g_option_table[]; 3995 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3996 std::string m_str; // Holds name lookup 3997 FileSpec m_file; // Files for file lookups 3998 lldb::addr_t m_addr; // Holds the address to lookup 3999 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 4000 uint32_t m_line_number; // Line number for file+line lookups 4001 bool m_use_regex; // Name lookups in m_str are regular expressions. 4002 bool m_include_inlines;// Check for inline entries when looking up by file/line. 4003 bool m_verbose; // Enable verbose lookup info 4004 bool m_print_all; // Print all matches, even in cases where there's a best match. 4005 }; 4006 4007 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 4008 CommandObjectParsed (interpreter, 4009 "target modules lookup", 4010 "Look up information within executable and dependent shared library images.", 4011 NULL, 4012 eCommandRequiresTarget), 4013 m_options (interpreter) 4014 { 4015 CommandArgumentEntry arg; 4016 CommandArgumentData file_arg; 4017 4018 // Define the first (and only) variant of this arg. 4019 file_arg.arg_type = eArgTypeFilename; 4020 file_arg.arg_repetition = eArgRepeatStar; 4021 4022 // There is only one variant this argument could be; put it into the argument entry. 4023 arg.push_back (file_arg); 4024 4025 // Push the data for the first argument into the m_arguments vector. 4026 m_arguments.push_back (arg); 4027 } 4028 4029 virtual 4030 ~CommandObjectTargetModulesLookup () 4031 { 4032 } 4033 4034 virtual Options * 4035 GetOptions () 4036 { 4037 return &m_options; 4038 } 4039 4040 bool 4041 LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error) 4042 { 4043 switch (m_options.m_type) 4044 { 4045 case eLookupTypeAddress: 4046 case eLookupTypeFileLine: 4047 case eLookupTypeFunction: 4048 case eLookupTypeFunctionOrSymbol: 4049 case eLookupTypeSymbol: 4050 default: 4051 return false; 4052 case eLookupTypeType: 4053 break; 4054 } 4055 4056 StackFrameSP frame = m_exe_ctx.GetFrameSP(); 4057 4058 if (!frame) 4059 return false; 4060 4061 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule)); 4062 4063 if (!sym_ctx.module_sp) 4064 return false; 4065 4066 switch (m_options.m_type) 4067 { 4068 default: 4069 return false; 4070 case eLookupTypeType: 4071 if (!m_options.m_str.empty()) 4072 { 4073 if (LookupTypeHere (m_interpreter, 4074 result.GetOutputStream(), 4075 sym_ctx, 4076 m_options.m_str.c_str(), 4077 m_options.m_use_regex)) 4078 { 4079 result.SetStatus(eReturnStatusSuccessFinishResult); 4080 return true; 4081 } 4082 } 4083 break; 4084 } 4085 4086 return true; 4087 } 4088 4089 bool 4090 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 4091 { 4092 switch (m_options.m_type) 4093 { 4094 case eLookupTypeAddress: 4095 if (m_options.m_addr != LLDB_INVALID_ADDRESS) 4096 { 4097 if (LookupAddressInModule (m_interpreter, 4098 result.GetOutputStream(), 4099 module, 4100 eSymbolContextEverything | (m_options.m_verbose ? eSymbolContextVariable : 0), 4101 m_options.m_addr, 4102 m_options.m_offset, 4103 m_options.m_verbose)) 4104 { 4105 result.SetStatus(eReturnStatusSuccessFinishResult); 4106 return true; 4107 } 4108 } 4109 break; 4110 4111 case eLookupTypeSymbol: 4112 if (!m_options.m_str.empty()) 4113 { 4114 if (LookupSymbolInModule (m_interpreter, 4115 result.GetOutputStream(), 4116 module, 4117 m_options.m_str.c_str(), 4118 m_options.m_use_regex, 4119 m_options.m_verbose)) 4120 { 4121 result.SetStatus(eReturnStatusSuccessFinishResult); 4122 return true; 4123 } 4124 } 4125 break; 4126 4127 case eLookupTypeFileLine: 4128 if (m_options.m_file) 4129 { 4130 if (LookupFileAndLineInModule (m_interpreter, 4131 result.GetOutputStream(), 4132 module, 4133 m_options.m_file, 4134 m_options.m_line_number, 4135 m_options.m_include_inlines, 4136 m_options.m_verbose)) 4137 { 4138 result.SetStatus(eReturnStatusSuccessFinishResult); 4139 return true; 4140 } 4141 } 4142 break; 4143 4144 case eLookupTypeFunctionOrSymbol: 4145 case eLookupTypeFunction: 4146 if (!m_options.m_str.empty()) 4147 { 4148 if (LookupFunctionInModule (m_interpreter, 4149 result.GetOutputStream(), 4150 module, 4151 m_options.m_str.c_str(), 4152 m_options.m_use_regex, 4153 m_options.m_include_inlines, 4154 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols 4155 m_options.m_verbose)) 4156 { 4157 result.SetStatus(eReturnStatusSuccessFinishResult); 4158 return true; 4159 } 4160 } 4161 break; 4162 4163 case eLookupTypeType: 4164 if (!m_options.m_str.empty()) 4165 { 4166 if (LookupTypeInModule (m_interpreter, 4167 result.GetOutputStream(), 4168 module, 4169 m_options.m_str.c_str(), 4170 m_options.m_use_regex)) 4171 { 4172 result.SetStatus(eReturnStatusSuccessFinishResult); 4173 return true; 4174 } 4175 } 4176 break; 4177 4178 default: 4179 m_options.GenerateOptionUsage (result.GetErrorStream(), this); 4180 syntax_error = true; 4181 break; 4182 } 4183 4184 result.SetStatus (eReturnStatusFailed); 4185 return false; 4186 } 4187 4188 protected: 4189 virtual bool 4190 DoExecute (Args& command, 4191 CommandReturnObject &result) 4192 { 4193 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4194 if (target == NULL) 4195 { 4196 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 4197 result.SetStatus (eReturnStatusFailed); 4198 return false; 4199 } 4200 else 4201 { 4202 bool syntax_error = false; 4203 uint32_t i; 4204 uint32_t num_successful_lookups = 0; 4205 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 4206 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 4207 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 4208 // Dump all sections for all modules images 4209 4210 if (command.GetArgumentCount() == 0) 4211 { 4212 ModuleSP current_module; 4213 4214 // Where it is possible to look in the current symbol context 4215 // first, try that. If this search was successful and --all 4216 // was not passed, don't print anything else. 4217 if (LookupHere (m_interpreter, result, syntax_error)) 4218 { 4219 result.GetOutputStream().EOL(); 4220 num_successful_lookups++; 4221 if (!m_options.m_print_all) 4222 { 4223 result.SetStatus (eReturnStatusSuccessFinishResult); 4224 return result.Succeeded(); 4225 } 4226 } 4227 4228 // Dump all sections for all other modules 4229 4230 const ModuleList &target_modules = target->GetImages(); 4231 Mutex::Locker modules_locker(target_modules.GetMutex()); 4232 const size_t num_modules = target_modules.GetSize(); 4233 if (num_modules > 0) 4234 { 4235 for (i = 0; i<num_modules && syntax_error == false; ++i) 4236 { 4237 Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i); 4238 4239 if (module_pointer != current_module.get() && 4240 LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error)) 4241 { 4242 result.GetOutputStream().EOL(); 4243 num_successful_lookups++; 4244 } 4245 } 4246 } 4247 else 4248 { 4249 result.AppendError ("the target has no associated executable images"); 4250 result.SetStatus (eReturnStatusFailed); 4251 return false; 4252 } 4253 } 4254 else 4255 { 4256 // Dump specified images (by basename or fullpath) 4257 const char *arg_cstr; 4258 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 4259 { 4260 ModuleList module_list; 4261 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false); 4262 if (num_matches > 0) 4263 { 4264 for (size_t j=0; j<num_matches; ++j) 4265 { 4266 Module *module = module_list.GetModulePointerAtIndex(j); 4267 if (module) 4268 { 4269 if (LookupInModule (m_interpreter, module, result, syntax_error)) 4270 { 4271 result.GetOutputStream().EOL(); 4272 num_successful_lookups++; 4273 } 4274 } 4275 } 4276 } 4277 else 4278 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 4279 } 4280 } 4281 4282 if (num_successful_lookups > 0) 4283 result.SetStatus (eReturnStatusSuccessFinishResult); 4284 else 4285 result.SetStatus (eReturnStatusFailed); 4286 } 4287 return result.Succeeded(); 4288 } 4289 4290 CommandOptions m_options; 4291 }; 4292 4293 OptionDefinition 4294 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 4295 { 4296 { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."}, 4297 { 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."}, 4298 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5 4299 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ , 4300 false, "regex", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 4301 { 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."}, 4302 { 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."}, 4303 { 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)."}, 4304 { LLDB_OPT_SET_FROM_TO(3,5), 4305 false, "no-inlines", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."}, 4306 { 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."}, 4307 { 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."}, 4308 { 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."}, 4309 { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 4310 { 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."}, 4311 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 4312 }; 4313 4314 4315 #pragma mark CommandObjectMultiwordImageSearchPaths 4316 4317 //------------------------------------------------------------------------- 4318 // CommandObjectMultiwordImageSearchPaths 4319 //------------------------------------------------------------------------- 4320 4321 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 4322 { 4323 public: 4324 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 4325 CommandObjectMultiword (interpreter, 4326 "target modules search-paths", 4327 "A set of commands for operating on debugger target image search paths.", 4328 "target modules search-paths <subcommand> [<subcommand-options>]") 4329 { 4330 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 4331 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 4332 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 4333 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 4334 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 4335 } 4336 4337 ~CommandObjectTargetModulesImageSearchPaths() 4338 { 4339 } 4340 }; 4341 4342 4343 4344 #pragma mark CommandObjectTargetModules 4345 4346 //------------------------------------------------------------------------- 4347 // CommandObjectTargetModules 4348 //------------------------------------------------------------------------- 4349 4350 class CommandObjectTargetModules : public CommandObjectMultiword 4351 { 4352 public: 4353 //------------------------------------------------------------------ 4354 // Constructors and Destructors 4355 //------------------------------------------------------------------ 4356 CommandObjectTargetModules(CommandInterpreter &interpreter) : 4357 CommandObjectMultiword (interpreter, 4358 "target modules", 4359 "A set of commands for accessing information for one or more target modules.", 4360 "target modules <sub-command> ...") 4361 { 4362 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 4363 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 4364 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 4365 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 4366 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 4367 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 4368 LoadSubCommand ("show-unwind", CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter))); 4369 4370 } 4371 virtual 4372 ~CommandObjectTargetModules() 4373 { 4374 } 4375 4376 private: 4377 //------------------------------------------------------------------ 4378 // For CommandObjectTargetModules only 4379 //------------------------------------------------------------------ 4380 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 4381 }; 4382 4383 4384 4385 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed 4386 { 4387 public: 4388 CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) : 4389 CommandObjectParsed (interpreter, 4390 "target symbols add", 4391 "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.", 4392 "target symbols add [<symfile>]", eCommandRequiresTarget), 4393 m_option_group (interpreter), 4394 m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."), 4395 m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true) 4396 4397 { 4398 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4399 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4400 m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2); 4401 m_option_group.Finalize(); 4402 } 4403 4404 virtual 4405 ~CommandObjectTargetSymbolsAdd () 4406 { 4407 } 4408 4409 virtual int 4410 HandleArgumentCompletion (Args &input, 4411 int &cursor_index, 4412 int &cursor_char_position, 4413 OptionElementVector &opt_element_vector, 4414 int match_start_point, 4415 int max_return_elements, 4416 bool &word_complete, 4417 StringList &matches) 4418 { 4419 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 4420 completion_str.erase (cursor_char_position); 4421 4422 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 4423 CommandCompletions::eDiskFileCompletion, 4424 completion_str.c_str(), 4425 match_start_point, 4426 max_return_elements, 4427 NULL, 4428 word_complete, 4429 matches); 4430 return matches.GetSize(); 4431 } 4432 4433 virtual Options * 4434 GetOptions () 4435 { 4436 return &m_option_group; 4437 } 4438 4439 protected: 4440 bool 4441 AddModuleSymbols (Target *target, 4442 ModuleSpec &module_spec, 4443 bool &flush, 4444 CommandReturnObject &result) 4445 { 4446 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec(); 4447 if (symbol_fspec) 4448 { 4449 char symfile_path[PATH_MAX]; 4450 symbol_fspec.GetPath (symfile_path, sizeof(symfile_path)); 4451 4452 if (!module_spec.GetUUID().IsValid()) 4453 { 4454 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec()) 4455 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename(); 4456 } 4457 // We now have a module that represents a symbol file 4458 // that can be used for a module that might exist in the 4459 // current target, so we need to find that module in the 4460 // target 4461 ModuleList matching_module_list; 4462 4463 size_t num_matches = 0; 4464 // First extract all module specs from the symbol file 4465 lldb_private::ModuleSpecList symfile_module_specs; 4466 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs)) 4467 { 4468 // Now extract the module spec that matches the target architecture 4469 ModuleSpec target_arch_module_spec; 4470 ModuleSpec symfile_module_spec; 4471 target_arch_module_spec.GetArchitecture() = target->GetArchitecture(); 4472 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec)) 4473 { 4474 // See if it has a UUID? 4475 if (symfile_module_spec.GetUUID().IsValid()) 4476 { 4477 // It has a UUID, look for this UUID in the target modules 4478 ModuleSpec symfile_uuid_module_spec; 4479 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4480 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); 4481 } 4482 } 4483 4484 if (num_matches == 0) 4485 { 4486 // No matches yet, iterate through the module specs to find a UUID value that 4487 // we can match up to an image in our target 4488 const size_t num_symfile_module_specs = symfile_module_specs.GetSize(); 4489 for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i) 4490 { 4491 if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec)) 4492 { 4493 if (symfile_module_spec.GetUUID().IsValid()) 4494 { 4495 // It has a UUID, look for this UUID in the target modules 4496 ModuleSpec symfile_uuid_module_spec; 4497 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4498 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); 4499 } 4500 } 4501 } 4502 } 4503 } 4504 4505 // Just try to match up the file by basename if we have no matches at this point 4506 if (num_matches == 0) 4507 num_matches = target->GetImages().FindModules (module_spec, matching_module_list); 4508 4509 while (num_matches == 0) 4510 { 4511 ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension()); 4512 // Empty string returned, lets bail 4513 if (!filename_no_extension) 4514 break; 4515 4516 // Check if there was no extension to strip and the basename is the same 4517 if (filename_no_extension == module_spec.GetFileSpec().GetFilename()) 4518 break; 4519 4520 // Replace basename with one less extension 4521 module_spec.GetFileSpec().GetFilename() = filename_no_extension; 4522 4523 num_matches = target->GetImages().FindModules (module_spec, matching_module_list); 4524 } 4525 4526 if (num_matches > 1) 4527 { 4528 result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path); 4529 } 4530 else if (num_matches == 1) 4531 { 4532 ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0)); 4533 4534 // The module has not yet created its symbol vendor, we can just 4535 // give the existing target module the symfile path to use for 4536 // when it decides to create it! 4537 module_sp->SetSymbolFileFileSpec (symbol_fspec); 4538 4539 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream()); 4540 if (symbol_vendor) 4541 { 4542 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 4543 4544 if (symbol_file) 4545 { 4546 ObjectFile *object_file = symbol_file->GetObjectFile(); 4547 4548 if (object_file && object_file->GetFileSpec() == symbol_fspec) 4549 { 4550 // Provide feedback that the symfile has been successfully added. 4551 const FileSpec &module_fs = module_sp->GetFileSpec(); 4552 result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n", 4553 symfile_path, 4554 module_fs.GetPath().c_str()); 4555 4556 // Let clients know something changed in the module 4557 // if it is currently loaded 4558 ModuleList module_list; 4559 module_list.Append (module_sp); 4560 target->SymbolsDidLoad (module_list); 4561 4562 // Make sure we load any scripting resources that may be embedded 4563 // in the debug info files in case the platform supports that. 4564 Error error; 4565 StreamString feedback_stream; 4566 module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream); 4567 if (error.Fail() && error.AsCString()) 4568 result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s", 4569 module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(), 4570 error.AsCString()); 4571 else if (feedback_stream.GetSize()) 4572 result.AppendWarningWithFormat("%s",feedback_stream.GetData()); 4573 4574 flush = true; 4575 result.SetStatus (eReturnStatusSuccessFinishResult); 4576 return true; 4577 } 4578 } 4579 } 4580 // Clear the symbol file spec if anything went wrong 4581 module_sp->SetSymbolFileFileSpec (FileSpec()); 4582 } 4583 4584 if (module_spec.GetUUID().IsValid()) 4585 { 4586 StreamString ss_symfile_uuid; 4587 module_spec.GetUUID().Dump(&ss_symfile_uuid); 4588 result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n", 4589 symfile_path, 4590 ss_symfile_uuid.GetData(), 4591 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) 4592 ? "\n please specify the full path to the symbol file" 4593 : ""); 4594 } 4595 else 4596 { 4597 result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n", 4598 symfile_path, 4599 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) 4600 ? "\n please specify the full path to the symbol file" 4601 : ""); 4602 } 4603 } 4604 else 4605 { 4606 result.AppendError ("one or more executable image paths must be specified"); 4607 } 4608 result.SetStatus (eReturnStatusFailed); 4609 return false; 4610 } 4611 4612 virtual bool 4613 DoExecute (Args& args, 4614 CommandReturnObject &result) 4615 { 4616 Target *target = m_exe_ctx.GetTargetPtr(); 4617 result.SetStatus (eReturnStatusFailed); 4618 bool flush = false; 4619 ModuleSpec module_spec; 4620 const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet(); 4621 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); 4622 const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet(); 4623 4624 const size_t argc = args.GetArgumentCount(); 4625 if (argc == 0) 4626 { 4627 if (uuid_option_set || file_option_set || frame_option_set) 4628 { 4629 bool success = false; 4630 bool error_set = false; 4631 if (frame_option_set) 4632 { 4633 Process *process = m_exe_ctx.GetProcessPtr(); 4634 if (process) 4635 { 4636 const StateType process_state = process->GetState(); 4637 if (StateIsStoppedState (process_state, true)) 4638 { 4639 StackFrame *frame = m_exe_ctx.GetFramePtr(); 4640 if (frame) 4641 { 4642 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp); 4643 if (frame_module_sp) 4644 { 4645 if (frame_module_sp->GetPlatformFileSpec().Exists()) 4646 { 4647 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); 4648 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); 4649 } 4650 module_spec.GetUUID() = frame_module_sp->GetUUID(); 4651 success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec(); 4652 } 4653 else 4654 { 4655 result.AppendError ("frame has no module"); 4656 error_set = true; 4657 } 4658 } 4659 else 4660 { 4661 result.AppendError ("invalid current frame"); 4662 error_set = true; 4663 } 4664 } 4665 else 4666 { 4667 result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state)); 4668 error_set = true; 4669 } 4670 } 4671 else 4672 { 4673 result.AppendError ("a process must exist in order to use the --frame option"); 4674 error_set = true; 4675 } 4676 } 4677 else 4678 { 4679 if (uuid_option_set) 4680 { 4681 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 4682 success |= module_spec.GetUUID().IsValid(); 4683 } 4684 else if (file_option_set) 4685 { 4686 module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 4687 ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); 4688 if (module_sp) 4689 { 4690 module_spec.GetFileSpec() = module_sp->GetFileSpec(); 4691 module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); 4692 module_spec.GetUUID() = module_sp->GetUUID(); 4693 module_spec.GetArchitecture() = module_sp->GetArchitecture(); 4694 } 4695 else 4696 { 4697 module_spec.GetArchitecture() = target->GetArchitecture(); 4698 } 4699 success |= module_spec.GetFileSpec().Exists(); 4700 } 4701 } 4702 4703 if (success) 4704 { 4705 if (Symbols::DownloadObjectAndSymbolFile (module_spec)) 4706 { 4707 if (module_spec.GetSymbolFileSpec()) 4708 success = AddModuleSymbols (target, module_spec, flush, result); 4709 } 4710 } 4711 4712 if (!success && !error_set) 4713 { 4714 StreamString error_strm; 4715 if (uuid_option_set) 4716 { 4717 error_strm.PutCString("unable to find debug symbols for UUID "); 4718 module_spec.GetUUID().Dump (&error_strm); 4719 } 4720 else if (file_option_set) 4721 { 4722 error_strm.PutCString("unable to find debug symbols for the executable file "); 4723 error_strm << module_spec.GetFileSpec(); 4724 } 4725 else if (frame_option_set) 4726 { 4727 error_strm.PutCString("unable to find debug symbols for the current frame"); 4728 } 4729 result.AppendError (error_strm.GetData()); 4730 } 4731 } 4732 else 4733 { 4734 result.AppendError ("one or more symbol file paths must be specified, or options must be specified"); 4735 } 4736 } 4737 else 4738 { 4739 if (uuid_option_set) 4740 { 4741 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments"); 4742 } 4743 else if (file_option_set) 4744 { 4745 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments"); 4746 } 4747 else if (frame_option_set) 4748 { 4749 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments"); 4750 } 4751 else 4752 { 4753 PlatformSP platform_sp (target->GetPlatform()); 4754 4755 for (size_t i=0; i<argc; ++i) 4756 { 4757 const char *symfile_path = args.GetArgumentAtIndex(i); 4758 if (symfile_path) 4759 { 4760 module_spec.GetSymbolFileSpec().SetFile(symfile_path, true); 4761 if (platform_sp) 4762 { 4763 FileSpec symfile_spec; 4764 if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success()) 4765 module_spec.GetSymbolFileSpec() = symfile_spec; 4766 } 4767 4768 ArchSpec arch; 4769 bool symfile_exists = module_spec.GetSymbolFileSpec().Exists(); 4770 4771 if (symfile_exists) 4772 { 4773 if (!AddModuleSymbols (target, module_spec, flush, result)) 4774 break; 4775 } 4776 else 4777 { 4778 char resolved_symfile_path[PATH_MAX]; 4779 if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path))) 4780 { 4781 if (strcmp (resolved_symfile_path, symfile_path) != 0) 4782 { 4783 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path); 4784 break; 4785 } 4786 } 4787 result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path); 4788 break; 4789 } 4790 } 4791 } 4792 } 4793 } 4794 4795 if (flush) 4796 { 4797 Process *process = m_exe_ctx.GetProcessPtr(); 4798 if (process) 4799 process->Flush(); 4800 } 4801 return result.Succeeded(); 4802 } 4803 4804 OptionGroupOptions m_option_group; 4805 OptionGroupUUID m_uuid_option_group; 4806 OptionGroupFile m_file_option; 4807 OptionGroupBoolean m_current_frame_option; 4808 }; 4809 4810 4811 #pragma mark CommandObjectTargetSymbols 4812 4813 //------------------------------------------------------------------------- 4814 // CommandObjectTargetSymbols 4815 //------------------------------------------------------------------------- 4816 4817 class CommandObjectTargetSymbols : public CommandObjectMultiword 4818 { 4819 public: 4820 //------------------------------------------------------------------ 4821 // Constructors and Destructors 4822 //------------------------------------------------------------------ 4823 CommandObjectTargetSymbols(CommandInterpreter &interpreter) : 4824 CommandObjectMultiword (interpreter, 4825 "target symbols", 4826 "A set of commands for adding and managing debug symbol files.", 4827 "target symbols <sub-command> ...") 4828 { 4829 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter))); 4830 4831 } 4832 virtual 4833 ~CommandObjectTargetSymbols() 4834 { 4835 } 4836 4837 private: 4838 //------------------------------------------------------------------ 4839 // For CommandObjectTargetModules only 4840 //------------------------------------------------------------------ 4841 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols); 4842 }; 4843 4844 4845 #pragma mark CommandObjectTargetStopHookAdd 4846 4847 //------------------------------------------------------------------------- 4848 // CommandObjectTargetStopHookAdd 4849 //------------------------------------------------------------------------- 4850 4851 class CommandObjectTargetStopHookAdd : 4852 public CommandObjectParsed, 4853 public IOHandlerDelegateMultiline 4854 { 4855 public: 4856 4857 class CommandOptions : public Options 4858 { 4859 public: 4860 CommandOptions (CommandInterpreter &interpreter) : 4861 Options(interpreter), 4862 m_line_start(0), 4863 m_line_end (UINT_MAX), 4864 m_func_name_type_mask (eFunctionNameTypeAuto), 4865 m_sym_ctx_specified (false), 4866 m_thread_specified (false), 4867 m_use_one_liner (false), 4868 m_one_liner() 4869 { 4870 } 4871 4872 ~CommandOptions () {} 4873 4874 const OptionDefinition* 4875 GetDefinitions () 4876 { 4877 return g_option_table; 4878 } 4879 4880 virtual Error 4881 SetOptionValue (uint32_t option_idx, const char *option_arg) 4882 { 4883 Error error; 4884 const int short_option = m_getopt_table[option_idx].val; 4885 bool success; 4886 4887 switch (short_option) 4888 { 4889 case 'c': 4890 m_class_name = option_arg; 4891 m_sym_ctx_specified = true; 4892 break; 4893 4894 case 'e': 4895 m_line_end = StringConvert::ToUInt32 (option_arg, UINT_MAX, 0, &success); 4896 if (!success) 4897 { 4898 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg); 4899 break; 4900 } 4901 m_sym_ctx_specified = true; 4902 break; 4903 4904 case 'l': 4905 m_line_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success); 4906 if (!success) 4907 { 4908 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg); 4909 break; 4910 } 4911 m_sym_ctx_specified = true; 4912 break; 4913 4914 case 'i': 4915 m_no_inlines = true; 4916 break; 4917 4918 case 'n': 4919 m_function_name = option_arg; 4920 m_func_name_type_mask |= eFunctionNameTypeAuto; 4921 m_sym_ctx_specified = true; 4922 break; 4923 4924 case 'f': 4925 m_file_name = option_arg; 4926 m_sym_ctx_specified = true; 4927 break; 4928 case 's': 4929 m_module_name = option_arg; 4930 m_sym_ctx_specified = true; 4931 break; 4932 case 't' : 4933 { 4934 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 4935 if (m_thread_id == LLDB_INVALID_THREAD_ID) 4936 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 4937 m_thread_specified = true; 4938 } 4939 break; 4940 case 'T': 4941 m_thread_name = option_arg; 4942 m_thread_specified = true; 4943 break; 4944 case 'q': 4945 m_queue_name = option_arg; 4946 m_thread_specified = true; 4947 break; 4948 case 'x': 4949 { 4950 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 4951 if (m_thread_id == UINT32_MAX) 4952 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 4953 m_thread_specified = true; 4954 } 4955 break; 4956 case 'o': 4957 m_use_one_liner = true; 4958 m_one_liner = option_arg; 4959 break; 4960 default: 4961 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option); 4962 break; 4963 } 4964 return error; 4965 } 4966 4967 void 4968 OptionParsingStarting () 4969 { 4970 m_class_name.clear(); 4971 m_function_name.clear(); 4972 m_line_start = 0; 4973 m_line_end = UINT_MAX; 4974 m_file_name.clear(); 4975 m_module_name.clear(); 4976 m_func_name_type_mask = eFunctionNameTypeAuto; 4977 m_thread_id = LLDB_INVALID_THREAD_ID; 4978 m_thread_index = UINT32_MAX; 4979 m_thread_name.clear(); 4980 m_queue_name.clear(); 4981 4982 m_no_inlines = false; 4983 m_sym_ctx_specified = false; 4984 m_thread_specified = false; 4985 4986 m_use_one_liner = false; 4987 m_one_liner.clear(); 4988 } 4989 4990 4991 static OptionDefinition g_option_table[]; 4992 4993 std::string m_class_name; 4994 std::string m_function_name; 4995 uint32_t m_line_start; 4996 uint32_t m_line_end; 4997 std::string m_file_name; 4998 std::string m_module_name; 4999 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 5000 lldb::tid_t m_thread_id; 5001 uint32_t m_thread_index; 5002 std::string m_thread_name; 5003 std::string m_queue_name; 5004 bool m_sym_ctx_specified; 5005 bool m_no_inlines; 5006 bool m_thread_specified; 5007 // Instance variables to hold the values for one_liner options. 5008 bool m_use_one_liner; 5009 std::string m_one_liner; 5010 }; 5011 5012 Options * 5013 GetOptions () 5014 { 5015 return &m_options; 5016 } 5017 5018 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 5019 CommandObjectParsed (interpreter, 5020 "target stop-hook add", 5021 "Add a hook to be executed when the target stops.", 5022 "target stop-hook add"), 5023 IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand), 5024 m_options (interpreter) 5025 { 5026 } 5027 5028 ~CommandObjectTargetStopHookAdd () 5029 { 5030 } 5031 5032 protected: 5033 virtual void 5034 IOHandlerActivated (IOHandler &io_handler) 5035 { 5036 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 5037 if (output_sp) 5038 { 5039 output_sp->PutCString("Enter your stop hook command(s). Type 'DONE' to end.\n"); 5040 output_sp->Flush(); 5041 } 5042 } 5043 5044 virtual void 5045 IOHandlerInputComplete (IOHandler &io_handler, std::string &line) 5046 { 5047 if (m_stop_hook_sp) 5048 { 5049 if (line.empty()) 5050 { 5051 StreamFileSP error_sp(io_handler.GetErrorStreamFile()); 5052 if (error_sp) 5053 { 5054 error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID()); 5055 error_sp->Flush(); 5056 } 5057 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5058 if (target) 5059 target->RemoveStopHookByID(m_stop_hook_sp->GetID()); 5060 } 5061 else 5062 { 5063 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line); 5064 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 5065 if (output_sp) 5066 { 5067 output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID()); 5068 output_sp->Flush(); 5069 } 5070 } 5071 m_stop_hook_sp.reset(); 5072 } 5073 io_handler.SetIsDone(true); 5074 } 5075 5076 bool 5077 DoExecute (Args& command, CommandReturnObject &result) 5078 { 5079 m_stop_hook_sp.reset(); 5080 5081 Target *target = GetSelectedOrDummyTarget(); 5082 if (target) 5083 { 5084 Target::StopHookSP new_hook_sp = target->CreateStopHook(); 5085 5086 // First step, make the specifier. 5087 std::unique_ptr<SymbolContextSpecifier> specifier_ap; 5088 if (m_options.m_sym_ctx_specified) 5089 { 5090 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 5091 5092 if (!m_options.m_module_name.empty()) 5093 { 5094 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 5095 } 5096 5097 if (!m_options.m_class_name.empty()) 5098 { 5099 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 5100 } 5101 5102 if (!m_options.m_file_name.empty()) 5103 { 5104 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 5105 } 5106 5107 if (m_options.m_line_start != 0) 5108 { 5109 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 5110 } 5111 5112 if (m_options.m_line_end != UINT_MAX) 5113 { 5114 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 5115 } 5116 5117 if (!m_options.m_function_name.empty()) 5118 { 5119 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 5120 } 5121 } 5122 5123 if (specifier_ap.get()) 5124 new_hook_sp->SetSpecifier (specifier_ap.release()); 5125 5126 // Next see if any of the thread options have been entered: 5127 5128 if (m_options.m_thread_specified) 5129 { 5130 ThreadSpec *thread_spec = new ThreadSpec(); 5131 5132 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 5133 { 5134 thread_spec->SetTID (m_options.m_thread_id); 5135 } 5136 5137 if (m_options.m_thread_index != UINT32_MAX) 5138 thread_spec->SetIndex (m_options.m_thread_index); 5139 5140 if (!m_options.m_thread_name.empty()) 5141 thread_spec->SetName (m_options.m_thread_name.c_str()); 5142 5143 if (!m_options.m_queue_name.empty()) 5144 thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 5145 5146 new_hook_sp->SetThreadSpecifier (thread_spec); 5147 5148 } 5149 if (m_options.m_use_one_liner) 5150 { 5151 // Use one-liner. 5152 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 5153 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID()); 5154 } 5155 else 5156 { 5157 m_stop_hook_sp = new_hook_sp; 5158 m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt 5159 *this, // IOHandlerDelegate 5160 true, // Run IOHandler in async mode 5161 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 5162 5163 } 5164 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5165 } 5166 else 5167 { 5168 result.AppendError ("invalid target\n"); 5169 result.SetStatus (eReturnStatusFailed); 5170 } 5171 5172 return result.Succeeded(); 5173 } 5174 private: 5175 CommandOptions m_options; 5176 Target::StopHookSP m_stop_hook_sp; 5177 }; 5178 5179 OptionDefinition 5180 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 5181 { 5182 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner, 5183 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 5184 { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 5185 "Set the module within which the stop-hook is to be run."}, 5186 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, 5187 "The stop hook is run only for the thread whose index matches this argument."}, 5188 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, 5189 "The stop hook is run only for the thread whose TID matches this argument."}, 5190 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, 5191 "The stop hook is run only for the thread whose thread name matches this argument."}, 5192 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, 5193 "The stop hook is run only for threads in the queue whose name is given by this argument."}, 5194 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 5195 "Specify the source file within which the stop-hook is to be run." }, 5196 { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 5197 "Set the start of the line range for which the stop-hook is to be run."}, 5198 { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 5199 "Set the end of the line range for which the stop-hook is to be run."}, 5200 { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeClassName, 5201 "Specify the class within which the stop-hook is to be run." }, 5202 { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 5203 "Set the function name within which the stop hook will be run." }, 5204 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 5205 }; 5206 5207 #pragma mark CommandObjectTargetStopHookDelete 5208 5209 //------------------------------------------------------------------------- 5210 // CommandObjectTargetStopHookDelete 5211 //------------------------------------------------------------------------- 5212 5213 class CommandObjectTargetStopHookDelete : public CommandObjectParsed 5214 { 5215 public: 5216 5217 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 5218 CommandObjectParsed (interpreter, 5219 "target stop-hook delete", 5220 "Delete a stop-hook.", 5221 "target stop-hook delete [<idx>]") 5222 { 5223 } 5224 5225 ~CommandObjectTargetStopHookDelete () 5226 { 5227 } 5228 5229 protected: 5230 bool 5231 DoExecute (Args& command, CommandReturnObject &result) 5232 { 5233 Target *target = GetSelectedOrDummyTarget(); 5234 if (target) 5235 { 5236 // FIXME: see if we can use the breakpoint id style parser? 5237 size_t num_args = command.GetArgumentCount(); 5238 if (num_args == 0) 5239 { 5240 if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 5241 { 5242 result.SetStatus (eReturnStatusFailed); 5243 return false; 5244 } 5245 else 5246 { 5247 target->RemoveAllStopHooks(); 5248 } 5249 } 5250 else 5251 { 5252 bool success; 5253 for (size_t i = 0; i < num_args; i++) 5254 { 5255 lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 5256 if (!success) 5257 { 5258 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5259 result.SetStatus(eReturnStatusFailed); 5260 return false; 5261 } 5262 success = target->RemoveStopHookByID (user_id); 5263 if (!success) 5264 { 5265 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5266 result.SetStatus(eReturnStatusFailed); 5267 return false; 5268 } 5269 } 5270 } 5271 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5272 } 5273 else 5274 { 5275 result.AppendError ("invalid target\n"); 5276 result.SetStatus (eReturnStatusFailed); 5277 } 5278 5279 return result.Succeeded(); 5280 } 5281 }; 5282 #pragma mark CommandObjectTargetStopHookEnableDisable 5283 5284 //------------------------------------------------------------------------- 5285 // CommandObjectTargetStopHookEnableDisable 5286 //------------------------------------------------------------------------- 5287 5288 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed 5289 { 5290 public: 5291 5292 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 5293 CommandObjectParsed (interpreter, 5294 name, 5295 help, 5296 syntax), 5297 m_enable (enable) 5298 { 5299 } 5300 5301 ~CommandObjectTargetStopHookEnableDisable () 5302 { 5303 } 5304 5305 protected: 5306 bool 5307 DoExecute (Args& command, CommandReturnObject &result) 5308 { 5309 Target *target = GetSelectedOrDummyTarget(); 5310 if (target) 5311 { 5312 // FIXME: see if we can use the breakpoint id style parser? 5313 size_t num_args = command.GetArgumentCount(); 5314 bool success; 5315 5316 if (num_args == 0) 5317 { 5318 target->SetAllStopHooksActiveState (m_enable); 5319 } 5320 else 5321 { 5322 for (size_t i = 0; i < num_args; i++) 5323 { 5324 lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 5325 if (!success) 5326 { 5327 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5328 result.SetStatus(eReturnStatusFailed); 5329 return false; 5330 } 5331 success = target->SetStopHookActiveStateByID (user_id, m_enable); 5332 if (!success) 5333 { 5334 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5335 result.SetStatus(eReturnStatusFailed); 5336 return false; 5337 } 5338 } 5339 } 5340 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5341 } 5342 else 5343 { 5344 result.AppendError ("invalid target\n"); 5345 result.SetStatus (eReturnStatusFailed); 5346 } 5347 return result.Succeeded(); 5348 } 5349 private: 5350 bool m_enable; 5351 }; 5352 5353 #pragma mark CommandObjectTargetStopHookList 5354 5355 //------------------------------------------------------------------------- 5356 // CommandObjectTargetStopHookList 5357 //------------------------------------------------------------------------- 5358 5359 class CommandObjectTargetStopHookList : public CommandObjectParsed 5360 { 5361 public: 5362 5363 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 5364 CommandObjectParsed (interpreter, 5365 "target stop-hook list", 5366 "List all stop-hooks.", 5367 "target stop-hook list [<type>]") 5368 { 5369 } 5370 5371 ~CommandObjectTargetStopHookList () 5372 { 5373 } 5374 5375 protected: 5376 bool 5377 DoExecute (Args& command, CommandReturnObject &result) 5378 { 5379 Target *target = GetSelectedOrDummyTarget(); 5380 if (!target) 5381 { 5382 result.AppendError ("invalid target\n"); 5383 result.SetStatus (eReturnStatusFailed); 5384 return result.Succeeded(); 5385 } 5386 5387 size_t num_hooks = target->GetNumStopHooks (); 5388 if (num_hooks == 0) 5389 { 5390 result.GetOutputStream().PutCString ("No stop hooks.\n"); 5391 } 5392 else 5393 { 5394 for (size_t i = 0; i < num_hooks; i++) 5395 { 5396 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 5397 if (i > 0) 5398 result.GetOutputStream().PutCString ("\n"); 5399 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 5400 } 5401 } 5402 result.SetStatus (eReturnStatusSuccessFinishResult); 5403 return result.Succeeded(); 5404 } 5405 }; 5406 5407 #pragma mark CommandObjectMultiwordTargetStopHooks 5408 //------------------------------------------------------------------------- 5409 // CommandObjectMultiwordTargetStopHooks 5410 //------------------------------------------------------------------------- 5411 5412 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 5413 { 5414 public: 5415 5416 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 5417 CommandObjectMultiword (interpreter, 5418 "target stop-hook", 5419 "A set of commands for operating on debugger target stop-hooks.", 5420 "target stop-hook <subcommand> [<subcommand-options>]") 5421 { 5422 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 5423 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 5424 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 5425 false, 5426 "target stop-hook disable [<id>]", 5427 "Disable a stop-hook.", 5428 "target stop-hook disable"))); 5429 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 5430 true, 5431 "target stop-hook enable [<id>]", 5432 "Enable a stop-hook.", 5433 "target stop-hook enable"))); 5434 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 5435 } 5436 5437 ~CommandObjectMultiwordTargetStopHooks() 5438 { 5439 } 5440 }; 5441 5442 5443 5444 #pragma mark CommandObjectMultiwordTarget 5445 5446 //------------------------------------------------------------------------- 5447 // CommandObjectMultiwordTarget 5448 //------------------------------------------------------------------------- 5449 5450 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 5451 CommandObjectMultiword (interpreter, 5452 "target", 5453 "A set of commands for operating on debugger targets.", 5454 "target <subcommand> [<subcommand-options>]") 5455 { 5456 5457 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 5458 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 5459 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 5460 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 5461 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 5462 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 5463 LoadSubCommand ("symbols", CommandObjectSP (new CommandObjectTargetSymbols (interpreter))); 5464 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 5465 } 5466 5467 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 5468 { 5469 } 5470 5471 5472