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