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