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