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