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