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