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::eOpenOptionRead); 276 277 if (!file) { 278 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", 279 core_file.GetPath(), 280 llvm::toString(file.takeError())); 281 return false; 282 } 283 } 284 285 if (argc == 1 || core_file || remote_file) { 286 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue()); 287 if (symfile) { 288 auto file = FileSystem::Instance().Open( 289 symfile, lldb_private::File::eOpenOptionRead); 290 291 if (!file) { 292 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", 293 symfile.GetPath(), 294 llvm::toString(file.takeError())); 295 return false; 296 } 297 } 298 299 const char *file_path = command.GetArgumentAtIndex(0); 300 LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path); 301 FileSpec file_spec; 302 303 if (file_path) { 304 file_spec.SetFile(file_path, FileSpec::Style::native); 305 FileSystem::Instance().Resolve(file_spec); 306 } 307 308 bool must_set_platform_path = false; 309 310 Debugger &debugger = GetDebugger(); 311 312 TargetSP target_sp; 313 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName(); 314 Status error(debugger.GetTargetList().CreateTarget( 315 debugger, file_path, arch_cstr, 316 m_add_dependents.m_load_dependent_files, &m_platform_options, 317 target_sp)); 318 319 if (!target_sp) { 320 result.AppendError(error.AsCString()); 321 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 bool include_inlines, bool include_symbols, 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, include_symbols, 1581 include_inlines, sc_list); 1582 } else { 1583 ConstString function_name(name); 1584 module->FindFunctions(function_name, CompilerDeclContext(), 1585 eFunctionNameTypeAuto, include_symbols, 1586 include_inlines, sc_list); 1587 } 1588 num_matches = sc_list.GetSize(); 1589 if (num_matches) { 1590 strm.Indent(); 1591 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, 1592 num_matches > 1 ? "es" : ""); 1593 DumpFullpath(strm, &module->GetFileSpec(), 0); 1594 strm.PutCString(":\n"); 1595 DumpSymbolContextList( 1596 interpreter.GetExecutionContext().GetBestExecutionContextScope(), 1597 strm, sc_list, verbose); 1598 } 1599 return num_matches; 1600 } 1601 return 0; 1602 } 1603 1604 static size_t LookupTypeInModule(Target *target, 1605 CommandInterpreter &interpreter, Stream &strm, 1606 Module *module, const char *name_cstr, 1607 bool name_is_regex) { 1608 TypeList type_list; 1609 if (module && name_cstr && name_cstr[0]) { 1610 const uint32_t max_num_matches = UINT32_MAX; 1611 size_t num_matches = 0; 1612 bool name_is_fully_qualified = false; 1613 1614 ConstString name(name_cstr); 1615 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files; 1616 module->FindTypes(name, name_is_fully_qualified, max_num_matches, 1617 searched_symbol_files, type_list); 1618 1619 if (type_list.Empty()) 1620 return 0; 1621 1622 strm.Indent(); 1623 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, 1624 num_matches > 1 ? "es" : ""); 1625 DumpFullpath(strm, &module->GetFileSpec(), 0); 1626 strm.PutCString(":\n"); 1627 for (TypeSP type_sp : type_list.Types()) { 1628 if (!type_sp) 1629 continue; 1630 // Resolve the clang type so that any forward references to types 1631 // that haven't yet been parsed will get parsed. 1632 type_sp->GetFullCompilerType(); 1633 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target); 1634 // Print all typedef chains 1635 TypeSP typedef_type_sp(type_sp); 1636 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType()); 1637 while (typedefed_type_sp) { 1638 strm.EOL(); 1639 strm.Printf(" typedef '%s': ", 1640 typedef_type_sp->GetName().GetCString()); 1641 typedefed_type_sp->GetFullCompilerType(); 1642 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true, 1643 target); 1644 typedef_type_sp = typedefed_type_sp; 1645 typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1646 } 1647 } 1648 strm.EOL(); 1649 } 1650 return type_list.GetSize(); 1651 } 1652 1653 static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter, 1654 Stream &strm, Module &module, 1655 const char *name_cstr, bool name_is_regex) { 1656 TypeList type_list; 1657 const uint32_t max_num_matches = UINT32_MAX; 1658 bool name_is_fully_qualified = false; 1659 1660 ConstString name(name_cstr); 1661 llvm::DenseSet<SymbolFile *> searched_symbol_files; 1662 module.FindTypes(name, name_is_fully_qualified, max_num_matches, 1663 searched_symbol_files, type_list); 1664 1665 if (type_list.Empty()) 1666 return 0; 1667 1668 strm.Indent(); 1669 strm.PutCString("Best match found in "); 1670 DumpFullpath(strm, &module.GetFileSpec(), 0); 1671 strm.PutCString(":\n"); 1672 1673 TypeSP type_sp(type_list.GetTypeAtIndex(0)); 1674 if (type_sp) { 1675 // Resolve the clang type so that any forward references to types that 1676 // haven't yet been parsed will get parsed. 1677 type_sp->GetFullCompilerType(); 1678 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target); 1679 // Print all typedef chains. 1680 TypeSP typedef_type_sp(type_sp); 1681 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType()); 1682 while (typedefed_type_sp) { 1683 strm.EOL(); 1684 strm.Printf(" typedef '%s': ", 1685 typedef_type_sp->GetName().GetCString()); 1686 typedefed_type_sp->GetFullCompilerType(); 1687 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true, 1688 target); 1689 typedef_type_sp = typedefed_type_sp; 1690 typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1691 } 1692 } 1693 strm.EOL(); 1694 return type_list.GetSize(); 1695 } 1696 1697 static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter, 1698 Stream &strm, Module *module, 1699 const FileSpec &file_spec, 1700 uint32_t line, bool check_inlines, 1701 bool verbose) { 1702 if (module && file_spec) { 1703 SymbolContextList sc_list; 1704 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec( 1705 file_spec, line, check_inlines, eSymbolContextEverything, sc_list); 1706 if (num_matches > 0) { 1707 strm.Indent(); 1708 strm.Printf("%u match%s found in ", num_matches, 1709 num_matches > 1 ? "es" : ""); 1710 strm << file_spec; 1711 if (line > 0) 1712 strm.Printf(":%u", line); 1713 strm << " in "; 1714 DumpFullpath(strm, &module->GetFileSpec(), 0); 1715 strm.PutCString(":\n"); 1716 DumpSymbolContextList( 1717 interpreter.GetExecutionContext().GetBestExecutionContextScope(), 1718 strm, sc_list, verbose); 1719 return num_matches; 1720 } 1721 } 1722 return 0; 1723 } 1724 1725 static size_t FindModulesByName(Target *target, const char *module_name, 1726 ModuleList &module_list, 1727 bool check_global_list) { 1728 FileSpec module_file_spec(module_name); 1729 ModuleSpec module_spec(module_file_spec); 1730 1731 const size_t initial_size = module_list.GetSize(); 1732 1733 if (check_global_list) { 1734 // Check the global list 1735 std::lock_guard<std::recursive_mutex> guard( 1736 Module::GetAllocationModuleCollectionMutex()); 1737 const size_t num_modules = Module::GetNumberAllocatedModules(); 1738 ModuleSP module_sp; 1739 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { 1740 Module *module = Module::GetAllocatedModuleAtIndex(image_idx); 1741 1742 if (module) { 1743 if (module->MatchesModuleSpec(module_spec)) { 1744 module_sp = module->shared_from_this(); 1745 module_list.AppendIfNeeded(module_sp); 1746 } 1747 } 1748 } 1749 } else { 1750 if (target) { 1751 target->GetImages().FindModules(module_spec, module_list); 1752 const size_t num_matches = module_list.GetSize(); 1753 1754 // Not found in our module list for our target, check the main shared 1755 // module list in case it is a extra file used somewhere else 1756 if (num_matches == 0) { 1757 module_spec.GetArchitecture() = target->GetArchitecture(); 1758 ModuleList::FindSharedModules(module_spec, module_list); 1759 } 1760 } else { 1761 ModuleList::FindSharedModules(module_spec, module_list); 1762 } 1763 } 1764 1765 return module_list.GetSize() - initial_size; 1766 } 1767 1768 #pragma mark CommandObjectTargetModulesModuleAutoComplete 1769 1770 // A base command object class that can auto complete with module file 1771 // paths 1772 1773 class CommandObjectTargetModulesModuleAutoComplete 1774 : public CommandObjectParsed { 1775 public: 1776 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter, 1777 const char *name, 1778 const char *help, 1779 const char *syntax, 1780 uint32_t flags = 0) 1781 : CommandObjectParsed(interpreter, name, help, syntax, flags) { 1782 CommandArgumentEntry arg; 1783 CommandArgumentData file_arg; 1784 1785 // Define the first (and only) variant of this arg. 1786 file_arg.arg_type = eArgTypeFilename; 1787 file_arg.arg_repetition = eArgRepeatStar; 1788 1789 // There is only one variant this argument could be; put it into the 1790 // argument entry. 1791 arg.push_back(file_arg); 1792 1793 // Push the data for the first argument into the m_arguments vector. 1794 m_arguments.push_back(arg); 1795 } 1796 1797 ~CommandObjectTargetModulesModuleAutoComplete() override = default; 1798 1799 void 1800 HandleArgumentCompletion(CompletionRequest &request, 1801 OptionElementVector &opt_element_vector) override { 1802 CommandCompletions::InvokeCommonCompletionCallbacks( 1803 GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request, 1804 nullptr); 1805 } 1806 }; 1807 1808 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete 1809 1810 // A base command object class that can auto complete with module source 1811 // file paths 1812 1813 class CommandObjectTargetModulesSourceFileAutoComplete 1814 : public CommandObjectParsed { 1815 public: 1816 CommandObjectTargetModulesSourceFileAutoComplete( 1817 CommandInterpreter &interpreter, const char *name, const char *help, 1818 const char *syntax, uint32_t flags) 1819 : CommandObjectParsed(interpreter, name, help, syntax, flags) { 1820 CommandArgumentEntry arg; 1821 CommandArgumentData source_file_arg; 1822 1823 // Define the first (and only) variant of this arg. 1824 source_file_arg.arg_type = eArgTypeSourceFile; 1825 source_file_arg.arg_repetition = eArgRepeatPlus; 1826 1827 // There is only one variant this argument could be; put it into the 1828 // argument entry. 1829 arg.push_back(source_file_arg); 1830 1831 // Push the data for the first argument into the m_arguments vector. 1832 m_arguments.push_back(arg); 1833 } 1834 1835 ~CommandObjectTargetModulesSourceFileAutoComplete() override = default; 1836 1837 void 1838 HandleArgumentCompletion(CompletionRequest &request, 1839 OptionElementVector &opt_element_vector) override { 1840 CommandCompletions::InvokeCommonCompletionCallbacks( 1841 GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion, 1842 request, nullptr); 1843 } 1844 }; 1845 1846 #pragma mark CommandObjectTargetModulesDumpObjfile 1847 1848 class CommandObjectTargetModulesDumpObjfile 1849 : public CommandObjectTargetModulesModuleAutoComplete { 1850 public: 1851 CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter) 1852 : CommandObjectTargetModulesModuleAutoComplete( 1853 interpreter, "target modules dump objfile", 1854 "Dump the object file headers from one or more target modules.", 1855 nullptr, eCommandRequiresTarget) {} 1856 1857 ~CommandObjectTargetModulesDumpObjfile() override = default; 1858 1859 protected: 1860 bool DoExecute(Args &command, CommandReturnObject &result) override { 1861 Target *target = &GetSelectedTarget(); 1862 1863 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 1864 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 1865 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 1866 1867 size_t num_dumped = 0; 1868 if (command.GetArgumentCount() == 0) { 1869 // Dump all headers for all modules images 1870 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(), 1871 target->GetImages()); 1872 if (num_dumped == 0) { 1873 result.AppendError("the target has no associated executable images"); 1874 } 1875 } else { 1876 // Find the modules that match the basename or full path. 1877 ModuleList module_list; 1878 const char *arg_cstr; 1879 for (int arg_idx = 0; 1880 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; 1881 ++arg_idx) { 1882 size_t num_matched = 1883 FindModulesByName(target, arg_cstr, module_list, true); 1884 if (num_matched == 0) { 1885 result.AppendWarningWithFormat( 1886 "Unable to find an image that matches '%s'.\n", arg_cstr); 1887 } 1888 } 1889 // Dump all the modules we found. 1890 num_dumped = 1891 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list); 1892 } 1893 1894 if (num_dumped > 0) { 1895 result.SetStatus(eReturnStatusSuccessFinishResult); 1896 } else { 1897 result.AppendError("no matching executable images found"); 1898 } 1899 return result.Succeeded(); 1900 } 1901 }; 1902 1903 #pragma mark CommandObjectTargetModulesDumpSymtab 1904 1905 static constexpr OptionEnumValueElement g_sort_option_enumeration[] = { 1906 { 1907 eSortOrderNone, 1908 "none", 1909 "No sorting, use the original symbol table order.", 1910 }, 1911 { 1912 eSortOrderByAddress, 1913 "address", 1914 "Sort output by symbol address.", 1915 }, 1916 { 1917 eSortOrderByName, 1918 "name", 1919 "Sort output by symbol name.", 1920 }, 1921 }; 1922 1923 #define LLDB_OPTIONS_target_modules_dump_symtab 1924 #include "CommandOptions.inc" 1925 1926 class CommandObjectTargetModulesDumpSymtab 1927 : public CommandObjectTargetModulesModuleAutoComplete { 1928 public: 1929 CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter) 1930 : CommandObjectTargetModulesModuleAutoComplete( 1931 interpreter, "target modules dump symtab", 1932 "Dump the symbol table from one or more target modules.", nullptr, 1933 eCommandRequiresTarget), 1934 m_options() {} 1935 1936 ~CommandObjectTargetModulesDumpSymtab() override = default; 1937 1938 Options *GetOptions() override { return &m_options; } 1939 1940 class CommandOptions : public Options { 1941 public: 1942 CommandOptions() : Options() {} 1943 1944 ~CommandOptions() override = default; 1945 1946 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1947 ExecutionContext *execution_context) override { 1948 Status error; 1949 const int short_option = m_getopt_table[option_idx].val; 1950 1951 switch (short_option) { 1952 case 'm': 1953 m_prefer_mangled.SetCurrentValue(true); 1954 m_prefer_mangled.SetOptionWasSet(); 1955 break; 1956 1957 case 's': 1958 m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum( 1959 option_arg, GetDefinitions()[option_idx].enum_values, 1960 eSortOrderNone, error); 1961 break; 1962 1963 default: 1964 llvm_unreachable("Unimplemented option"); 1965 } 1966 return error; 1967 } 1968 1969 void OptionParsingStarting(ExecutionContext *execution_context) override { 1970 m_sort_order = eSortOrderNone; 1971 m_prefer_mangled.Clear(); 1972 } 1973 1974 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1975 return llvm::makeArrayRef(g_target_modules_dump_symtab_options); 1976 } 1977 1978 SortOrder m_sort_order = eSortOrderNone; 1979 OptionValueBoolean m_prefer_mangled = {false, false}; 1980 }; 1981 1982 protected: 1983 bool DoExecute(Args &command, CommandReturnObject &result) override { 1984 Target *target = &GetSelectedTarget(); 1985 uint32_t num_dumped = 0; 1986 Mangled::NamePreference name_preference = 1987 (m_options.m_prefer_mangled ? Mangled::ePreferMangled 1988 : Mangled::ePreferDemangled); 1989 1990 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 1991 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 1992 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 1993 1994 if (command.GetArgumentCount() == 0) { 1995 // Dump all sections for all modules images 1996 const ModuleList &module_list = target->GetImages(); 1997 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex()); 1998 const size_t num_modules = module_list.GetSize(); 1999 if (num_modules > 0) { 2000 result.GetOutputStream().Format( 2001 "Dumping symbol table for {0} modules.\n", num_modules); 2002 for (ModuleSP module_sp : module_list.ModulesNoLocking()) { 2003 if (num_dumped > 0) { 2004 result.GetOutputStream().EOL(); 2005 result.GetOutputStream().EOL(); 2006 } 2007 if (m_interpreter.WasInterrupted()) 2008 break; 2009 num_dumped++; 2010 DumpModuleSymtab(m_interpreter, result.GetOutputStream(), 2011 module_sp.get(), m_options.m_sort_order, 2012 name_preference); 2013 } 2014 } else { 2015 result.AppendError("the target has no associated executable images"); 2016 return false; 2017 } 2018 } else { 2019 // Dump specified images (by basename or fullpath) 2020 const char *arg_cstr; 2021 for (int arg_idx = 0; 2022 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; 2023 ++arg_idx) { 2024 ModuleList module_list; 2025 const size_t num_matches = 2026 FindModulesByName(target, arg_cstr, module_list, true); 2027 if (num_matches > 0) { 2028 for (ModuleSP module_sp : module_list.Modules()) { 2029 if (module_sp) { 2030 if (num_dumped > 0) { 2031 result.GetOutputStream().EOL(); 2032 result.GetOutputStream().EOL(); 2033 } 2034 if (m_interpreter.WasInterrupted()) 2035 break; 2036 num_dumped++; 2037 DumpModuleSymtab(m_interpreter, result.GetOutputStream(), 2038 module_sp.get(), m_options.m_sort_order, 2039 name_preference); 2040 } 2041 } 2042 } else 2043 result.AppendWarningWithFormat( 2044 "Unable to find an image that matches '%s'.\n", arg_cstr); 2045 } 2046 } 2047 2048 if (num_dumped > 0) 2049 result.SetStatus(eReturnStatusSuccessFinishResult); 2050 else { 2051 result.AppendError("no matching executable images found"); 2052 } 2053 return result.Succeeded(); 2054 } 2055 2056 CommandOptions m_options; 2057 }; 2058 2059 #pragma mark CommandObjectTargetModulesDumpSections 2060 2061 // Image section dumping command 2062 2063 class CommandObjectTargetModulesDumpSections 2064 : public CommandObjectTargetModulesModuleAutoComplete { 2065 public: 2066 CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter) 2067 : CommandObjectTargetModulesModuleAutoComplete( 2068 interpreter, "target modules dump sections", 2069 "Dump the sections from one or more target modules.", 2070 //"target modules dump sections [<file1> ...]") 2071 nullptr, eCommandRequiresTarget) {} 2072 2073 ~CommandObjectTargetModulesDumpSections() override = default; 2074 2075 protected: 2076 bool DoExecute(Args &command, CommandReturnObject &result) override { 2077 Target *target = &GetSelectedTarget(); 2078 uint32_t num_dumped = 0; 2079 2080 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2081 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2082 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2083 2084 if (command.GetArgumentCount() == 0) { 2085 // Dump all sections for all modules images 2086 const size_t num_modules = target->GetImages().GetSize(); 2087 if (num_modules == 0) { 2088 result.AppendError("the target has no associated executable images"); 2089 return false; 2090 } 2091 2092 result.GetOutputStream().Format("Dumping sections for {0} modules.\n", 2093 num_modules); 2094 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { 2095 if (m_interpreter.WasInterrupted()) 2096 break; 2097 num_dumped++; 2098 DumpModuleSections( 2099 m_interpreter, result.GetOutputStream(), 2100 target->GetImages().GetModulePointerAtIndex(image_idx)); 2101 } 2102 } else { 2103 // Dump specified images (by basename or fullpath) 2104 const char *arg_cstr; 2105 for (int arg_idx = 0; 2106 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; 2107 ++arg_idx) { 2108 ModuleList module_list; 2109 const size_t num_matches = 2110 FindModulesByName(target, arg_cstr, module_list, true); 2111 if (num_matches > 0) { 2112 for (size_t i = 0; i < num_matches; ++i) { 2113 if (m_interpreter.WasInterrupted()) 2114 break; 2115 Module *module = module_list.GetModulePointerAtIndex(i); 2116 if (module) { 2117 num_dumped++; 2118 DumpModuleSections(m_interpreter, result.GetOutputStream(), 2119 module); 2120 } 2121 } 2122 } else { 2123 // Check the global list 2124 std::lock_guard<std::recursive_mutex> guard( 2125 Module::GetAllocationModuleCollectionMutex()); 2126 2127 result.AppendWarningWithFormat( 2128 "Unable to find an image that matches '%s'.\n", arg_cstr); 2129 } 2130 } 2131 } 2132 2133 if (num_dumped > 0) 2134 result.SetStatus(eReturnStatusSuccessFinishResult); 2135 else { 2136 result.AppendError("no matching executable images found"); 2137 } 2138 return result.Succeeded(); 2139 } 2140 }; 2141 2142 #pragma mark CommandObjectTargetModulesDumpClangAST 2143 2144 // Clang AST dumping command 2145 2146 class CommandObjectTargetModulesDumpClangAST 2147 : public CommandObjectTargetModulesModuleAutoComplete { 2148 public: 2149 CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter) 2150 : CommandObjectTargetModulesModuleAutoComplete( 2151 interpreter, "target modules dump ast", 2152 "Dump the clang ast for a given module's symbol file.", 2153 //"target modules dump ast [<file1> ...]") 2154 nullptr, eCommandRequiresTarget) {} 2155 2156 ~CommandObjectTargetModulesDumpClangAST() override = default; 2157 2158 protected: 2159 bool DoExecute(Args &command, CommandReturnObject &result) override { 2160 Target *target = &GetSelectedTarget(); 2161 2162 const ModuleList &module_list = target->GetImages(); 2163 const size_t num_modules = module_list.GetSize(); 2164 if (num_modules == 0) { 2165 result.AppendError("the target has no associated executable images"); 2166 return false; 2167 } 2168 2169 if (command.GetArgumentCount() == 0) { 2170 // Dump all ASTs for all modules images 2171 result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n", 2172 num_modules); 2173 for (ModuleSP module_sp : module_list.ModulesNoLocking()) { 2174 if (m_interpreter.WasInterrupted()) 2175 break; 2176 if (SymbolFile *sf = module_sp->GetSymbolFile()) 2177 sf->DumpClangAST(result.GetOutputStream()); 2178 } 2179 result.SetStatus(eReturnStatusSuccessFinishResult); 2180 return true; 2181 } 2182 2183 // Dump specified ASTs (by basename or fullpath) 2184 for (const Args::ArgEntry &arg : command.entries()) { 2185 ModuleList module_list; 2186 const size_t num_matches = 2187 FindModulesByName(target, arg.c_str(), module_list, true); 2188 if (num_matches == 0) { 2189 // Check the global list 2190 std::lock_guard<std::recursive_mutex> guard( 2191 Module::GetAllocationModuleCollectionMutex()); 2192 2193 result.AppendWarningWithFormat( 2194 "Unable to find an image that matches '%s'.\n", arg.c_str()); 2195 continue; 2196 } 2197 2198 for (size_t i = 0; i < num_matches; ++i) { 2199 if (m_interpreter.WasInterrupted()) 2200 break; 2201 Module *m = module_list.GetModulePointerAtIndex(i); 2202 if (SymbolFile *sf = m->GetSymbolFile()) 2203 sf->DumpClangAST(result.GetOutputStream()); 2204 } 2205 } 2206 result.SetStatus(eReturnStatusSuccessFinishResult); 2207 return true; 2208 } 2209 }; 2210 2211 #pragma mark CommandObjectTargetModulesDumpSymfile 2212 2213 // Image debug symbol dumping command 2214 2215 class CommandObjectTargetModulesDumpSymfile 2216 : public CommandObjectTargetModulesModuleAutoComplete { 2217 public: 2218 CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter) 2219 : CommandObjectTargetModulesModuleAutoComplete( 2220 interpreter, "target modules dump symfile", 2221 "Dump the debug symbol file for one or more target modules.", 2222 //"target modules dump symfile [<file1> ...]") 2223 nullptr, eCommandRequiresTarget) {} 2224 2225 ~CommandObjectTargetModulesDumpSymfile() override = default; 2226 2227 protected: 2228 bool DoExecute(Args &command, CommandReturnObject &result) override { 2229 Target *target = &GetSelectedTarget(); 2230 uint32_t num_dumped = 0; 2231 2232 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2233 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2234 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2235 2236 if (command.GetArgumentCount() == 0) { 2237 // Dump all sections for all modules images 2238 const ModuleList &target_modules = target->GetImages(); 2239 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); 2240 const size_t num_modules = target_modules.GetSize(); 2241 if (num_modules == 0) { 2242 result.AppendError("the target has no associated executable images"); 2243 return false; 2244 } 2245 result.GetOutputStream().Format( 2246 "Dumping debug symbols for {0} modules.\n", num_modules); 2247 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) { 2248 if (m_interpreter.WasInterrupted()) 2249 break; 2250 if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get())) 2251 num_dumped++; 2252 } 2253 } else { 2254 // Dump specified images (by basename or fullpath) 2255 const char *arg_cstr; 2256 for (int arg_idx = 0; 2257 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; 2258 ++arg_idx) { 2259 ModuleList module_list; 2260 const size_t num_matches = 2261 FindModulesByName(target, arg_cstr, module_list, true); 2262 if (num_matches > 0) { 2263 for (size_t i = 0; i < num_matches; ++i) { 2264 if (m_interpreter.WasInterrupted()) 2265 break; 2266 Module *module = module_list.GetModulePointerAtIndex(i); 2267 if (module) { 2268 if (DumpModuleSymbolFile(result.GetOutputStream(), module)) 2269 num_dumped++; 2270 } 2271 } 2272 } else 2273 result.AppendWarningWithFormat( 2274 "Unable to find an image that matches '%s'.\n", arg_cstr); 2275 } 2276 } 2277 2278 if (num_dumped > 0) 2279 result.SetStatus(eReturnStatusSuccessFinishResult); 2280 else { 2281 result.AppendError("no matching executable images found"); 2282 } 2283 return result.Succeeded(); 2284 } 2285 }; 2286 2287 #pragma mark CommandObjectTargetModulesDumpLineTable 2288 #define LLDB_OPTIONS_target_modules_dump 2289 #include "CommandOptions.inc" 2290 2291 // Image debug line table dumping command 2292 2293 class CommandObjectTargetModulesDumpLineTable 2294 : public CommandObjectTargetModulesSourceFileAutoComplete { 2295 public: 2296 CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter) 2297 : CommandObjectTargetModulesSourceFileAutoComplete( 2298 interpreter, "target modules dump line-table", 2299 "Dump the line table for one or more compilation units.", nullptr, 2300 eCommandRequiresTarget) {} 2301 2302 ~CommandObjectTargetModulesDumpLineTable() override = default; 2303 2304 Options *GetOptions() override { return &m_options; } 2305 2306 protected: 2307 bool DoExecute(Args &command, CommandReturnObject &result) override { 2308 Target *target = m_exe_ctx.GetTargetPtr(); 2309 uint32_t total_num_dumped = 0; 2310 2311 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2312 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2313 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2314 2315 if (command.GetArgumentCount() == 0) { 2316 result.AppendError("file option must be specified."); 2317 return result.Succeeded(); 2318 } else { 2319 // Dump specified images (by basename or fullpath) 2320 const char *arg_cstr; 2321 for (int arg_idx = 0; 2322 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; 2323 ++arg_idx) { 2324 FileSpec file_spec(arg_cstr); 2325 2326 const ModuleList &target_modules = target->GetImages(); 2327 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); 2328 if (target_modules.GetSize() > 0) { 2329 uint32_t num_dumped = 0; 2330 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) { 2331 if (m_interpreter.WasInterrupted()) 2332 break; 2333 if (DumpCompileUnitLineTable( 2334 m_interpreter, result.GetOutputStream(), module_sp.get(), 2335 file_spec, 2336 m_options.m_verbose ? eDescriptionLevelFull 2337 : eDescriptionLevelBrief)) 2338 num_dumped++; 2339 } 2340 if (num_dumped == 0) 2341 result.AppendWarningWithFormat( 2342 "No source filenames matched '%s'.\n", arg_cstr); 2343 else 2344 total_num_dumped += num_dumped; 2345 } 2346 } 2347 } 2348 2349 if (total_num_dumped > 0) 2350 result.SetStatus(eReturnStatusSuccessFinishResult); 2351 else { 2352 result.AppendError("no source filenames matched any command arguments"); 2353 } 2354 return result.Succeeded(); 2355 } 2356 2357 class CommandOptions : public Options { 2358 public: 2359 CommandOptions() : Options() { OptionParsingStarting(nullptr); } 2360 2361 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2362 ExecutionContext *execution_context) override { 2363 assert(option_idx == 0 && "We only have one option."); 2364 m_verbose = true; 2365 2366 return Status(); 2367 } 2368 2369 void OptionParsingStarting(ExecutionContext *execution_context) override { 2370 m_verbose = false; 2371 } 2372 2373 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 2374 return llvm::makeArrayRef(g_target_modules_dump_options); 2375 } 2376 2377 bool m_verbose; 2378 }; 2379 2380 CommandOptions m_options; 2381 }; 2382 2383 #pragma mark CommandObjectTargetModulesDump 2384 2385 // Dump multi-word command for target modules 2386 2387 class CommandObjectTargetModulesDump : public CommandObjectMultiword { 2388 public: 2389 // Constructors and Destructors 2390 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) 2391 : CommandObjectMultiword( 2392 interpreter, "target modules dump", 2393 "Commands for dumping information about one or " 2394 "more target modules.", 2395 "target modules dump " 2396 "[headers|symtab|sections|ast|symfile|line-table] " 2397 "[<file1> <file2> ...]") { 2398 LoadSubCommand("objfile", 2399 CommandObjectSP( 2400 new CommandObjectTargetModulesDumpObjfile(interpreter))); 2401 LoadSubCommand( 2402 "symtab", 2403 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter))); 2404 LoadSubCommand("sections", 2405 CommandObjectSP(new CommandObjectTargetModulesDumpSections( 2406 interpreter))); 2407 LoadSubCommand("symfile", 2408 CommandObjectSP( 2409 new CommandObjectTargetModulesDumpSymfile(interpreter))); 2410 LoadSubCommand( 2411 "ast", CommandObjectSP( 2412 new CommandObjectTargetModulesDumpClangAST(interpreter))); 2413 LoadSubCommand("line-table", 2414 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable( 2415 interpreter))); 2416 } 2417 2418 ~CommandObjectTargetModulesDump() override = default; 2419 }; 2420 2421 class CommandObjectTargetModulesAdd : public CommandObjectParsed { 2422 public: 2423 CommandObjectTargetModulesAdd(CommandInterpreter &interpreter) 2424 : CommandObjectParsed(interpreter, "target modules add", 2425 "Add a new module to the current target's modules.", 2426 "target modules add [<module>]", 2427 eCommandRequiresTarget), 2428 m_option_group(), m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 2429 0, eArgTypeFilename, 2430 "Fullpath to a stand alone debug " 2431 "symbols file for when debug symbols " 2432 "are not in the executable.") { 2433 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, 2434 LLDB_OPT_SET_1); 2435 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2436 m_option_group.Finalize(); 2437 } 2438 2439 ~CommandObjectTargetModulesAdd() override = default; 2440 2441 Options *GetOptions() override { return &m_option_group; } 2442 2443 void 2444 HandleArgumentCompletion(CompletionRequest &request, 2445 OptionElementVector &opt_element_vector) override { 2446 CommandCompletions::InvokeCommonCompletionCallbacks( 2447 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, 2448 request, nullptr); 2449 } 2450 2451 protected: 2452 OptionGroupOptions m_option_group; 2453 OptionGroupUUID m_uuid_option_group; 2454 OptionGroupFile m_symbol_file; 2455 2456 bool DoExecute(Args &args, CommandReturnObject &result) override { 2457 Target *target = &GetSelectedTarget(); 2458 bool flush = false; 2459 2460 const size_t argc = args.GetArgumentCount(); 2461 if (argc == 0) { 2462 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) { 2463 // We are given a UUID only, go locate the file 2464 ModuleSpec module_spec; 2465 module_spec.GetUUID() = 2466 m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2467 if (m_symbol_file.GetOptionValue().OptionWasSet()) 2468 module_spec.GetSymbolFileSpec() = 2469 m_symbol_file.GetOptionValue().GetCurrentValue(); 2470 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) { 2471 ModuleSP module_sp( 2472 target->GetOrCreateModule(module_spec, true /* notify */)); 2473 if (module_sp) { 2474 result.SetStatus(eReturnStatusSuccessFinishResult); 2475 return true; 2476 } else { 2477 StreamString strm; 2478 module_spec.GetUUID().Dump(&strm); 2479 if (module_spec.GetFileSpec()) { 2480 if (module_spec.GetSymbolFileSpec()) { 2481 result.AppendErrorWithFormat( 2482 "Unable to create the executable or symbol file with " 2483 "UUID %s with path %s and symbol file %s", 2484 strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(), 2485 module_spec.GetSymbolFileSpec().GetPath().c_str()); 2486 } else { 2487 result.AppendErrorWithFormat( 2488 "Unable to create the executable or symbol file with " 2489 "UUID %s with path %s", 2490 strm.GetData(), 2491 module_spec.GetFileSpec().GetPath().c_str()); 2492 } 2493 } else { 2494 result.AppendErrorWithFormat("Unable to create the executable " 2495 "or symbol file with UUID %s", 2496 strm.GetData()); 2497 } 2498 return false; 2499 } 2500 } else { 2501 StreamString strm; 2502 module_spec.GetUUID().Dump(&strm); 2503 result.AppendErrorWithFormat( 2504 "Unable to locate the executable or symbol file with UUID %s", 2505 strm.GetData()); 2506 return false; 2507 } 2508 } else { 2509 result.AppendError( 2510 "one or more executable image paths must be specified"); 2511 return false; 2512 } 2513 } else { 2514 for (auto &entry : args.entries()) { 2515 if (entry.ref().empty()) 2516 continue; 2517 2518 FileSpec file_spec(entry.ref()); 2519 if (FileSystem::Instance().Exists(file_spec)) { 2520 ModuleSpec module_spec(file_spec); 2521 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2522 module_spec.GetUUID() = 2523 m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2524 if (m_symbol_file.GetOptionValue().OptionWasSet()) 2525 module_spec.GetSymbolFileSpec() = 2526 m_symbol_file.GetOptionValue().GetCurrentValue(); 2527 if (!module_spec.GetArchitecture().IsValid()) 2528 module_spec.GetArchitecture() = target->GetArchitecture(); 2529 Status error; 2530 ModuleSP module_sp(target->GetOrCreateModule( 2531 module_spec, true /* notify */, &error)); 2532 if (!module_sp) { 2533 const char *error_cstr = error.AsCString(); 2534 if (error_cstr) 2535 result.AppendError(error_cstr); 2536 else 2537 result.AppendErrorWithFormat("unsupported module: %s", 2538 entry.c_str()); 2539 return false; 2540 } else { 2541 flush = true; 2542 } 2543 result.SetStatus(eReturnStatusSuccessFinishResult); 2544 } else { 2545 std::string resolved_path = file_spec.GetPath(); 2546 if (resolved_path != entry.ref()) { 2547 result.AppendErrorWithFormat( 2548 "invalid module path '%s' with resolved path '%s'\n", 2549 entry.ref().str().c_str(), resolved_path.c_str()); 2550 break; 2551 } 2552 result.AppendErrorWithFormat("invalid module path '%s'\n", 2553 entry.c_str()); 2554 break; 2555 } 2556 } 2557 } 2558 2559 if (flush) { 2560 ProcessSP process = target->GetProcessSP(); 2561 if (process) 2562 process->Flush(); 2563 } 2564 2565 return result.Succeeded(); 2566 } 2567 }; 2568 2569 class CommandObjectTargetModulesLoad 2570 : public CommandObjectTargetModulesModuleAutoComplete { 2571 public: 2572 CommandObjectTargetModulesLoad(CommandInterpreter &interpreter) 2573 : CommandObjectTargetModulesModuleAutoComplete( 2574 interpreter, "target modules load", 2575 "Set the load addresses for one or more sections in a target " 2576 "module.", 2577 "target modules load [--file <module> --uuid <uuid>] <sect-name> " 2578 "<address> [<sect-name> <address> ....]", 2579 eCommandRequiresTarget), 2580 m_option_group(), 2581 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, 2582 "Fullpath or basename for module to load.", ""), 2583 m_load_option(LLDB_OPT_SET_1, false, "load", 'l', 2584 "Write file contents to the memory.", false, true), 2585 m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p', 2586 "Set PC to the entry point." 2587 " Only applicable with '--load' option.", 2588 false, true), 2589 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset, 2590 "Set the load address for all sections to be the " 2591 "virtual address in the file plus the offset.", 2592 0) { 2593 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, 2594 LLDB_OPT_SET_1); 2595 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2596 m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2597 m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2598 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2599 m_option_group.Finalize(); 2600 } 2601 2602 ~CommandObjectTargetModulesLoad() override = default; 2603 2604 Options *GetOptions() override { return &m_option_group; } 2605 2606 protected: 2607 bool DoExecute(Args &args, CommandReturnObject &result) override { 2608 Target *target = &GetSelectedTarget(); 2609 const bool load = m_load_option.GetOptionValue().GetCurrentValue(); 2610 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue(); 2611 2612 const size_t argc = args.GetArgumentCount(); 2613 ModuleSpec module_spec; 2614 bool search_using_module_spec = false; 2615 2616 // Allow "load" option to work without --file or --uuid option. 2617 if (load) { 2618 if (!m_file_option.GetOptionValue().OptionWasSet() && 2619 !m_uuid_option_group.GetOptionValue().OptionWasSet()) { 2620 ModuleList &module_list = target->GetImages(); 2621 if (module_list.GetSize() == 1) { 2622 search_using_module_spec = true; 2623 module_spec.GetFileSpec() = 2624 module_list.GetModuleAtIndex(0)->GetFileSpec(); 2625 } 2626 } 2627 } 2628 2629 if (m_file_option.GetOptionValue().OptionWasSet()) { 2630 search_using_module_spec = true; 2631 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue(); 2632 const bool use_global_module_list = true; 2633 ModuleList module_list; 2634 const size_t num_matches = FindModulesByName( 2635 target, arg_cstr, module_list, use_global_module_list); 2636 if (num_matches == 1) { 2637 module_spec.GetFileSpec() = 2638 module_list.GetModuleAtIndex(0)->GetFileSpec(); 2639 } else if (num_matches > 1) { 2640 search_using_module_spec = false; 2641 result.AppendErrorWithFormat( 2642 "more than 1 module matched by name '%s'\n", arg_cstr); 2643 } else { 2644 search_using_module_spec = false; 2645 result.AppendErrorWithFormat("no object file for module '%s'\n", 2646 arg_cstr); 2647 } 2648 } 2649 2650 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) { 2651 search_using_module_spec = true; 2652 module_spec.GetUUID() = 2653 m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2654 } 2655 2656 if (search_using_module_spec) { 2657 ModuleList matching_modules; 2658 target->GetImages().FindModules(module_spec, matching_modules); 2659 const size_t num_matches = matching_modules.GetSize(); 2660 2661 char path[PATH_MAX]; 2662 if (num_matches == 1) { 2663 Module *module = matching_modules.GetModulePointerAtIndex(0); 2664 if (module) { 2665 ObjectFile *objfile = module->GetObjectFile(); 2666 if (objfile) { 2667 SectionList *section_list = module->GetSectionList(); 2668 if (section_list) { 2669 bool changed = false; 2670 if (argc == 0) { 2671 if (m_slide_option.GetOptionValue().OptionWasSet()) { 2672 const addr_t slide = 2673 m_slide_option.GetOptionValue().GetCurrentValue(); 2674 const bool slide_is_offset = true; 2675 module->SetLoadAddress(*target, slide, slide_is_offset, 2676 changed); 2677 } else { 2678 result.AppendError("one or more section name + load " 2679 "address pair must be specified"); 2680 return false; 2681 } 2682 } else { 2683 if (m_slide_option.GetOptionValue().OptionWasSet()) { 2684 result.AppendError("The \"--slide <offset>\" option can't " 2685 "be used in conjunction with setting " 2686 "section load addresses.\n"); 2687 return false; 2688 } 2689 2690 for (size_t i = 0; i < argc; i += 2) { 2691 const char *sect_name = args.GetArgumentAtIndex(i); 2692 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1); 2693 if (sect_name && load_addr_cstr) { 2694 ConstString const_sect_name(sect_name); 2695 addr_t load_addr; 2696 if (llvm::to_integer(load_addr_cstr, load_addr)) { 2697 SectionSP section_sp( 2698 section_list->FindSectionByName(const_sect_name)); 2699 if (section_sp) { 2700 if (section_sp->IsThreadSpecific()) { 2701 result.AppendErrorWithFormat( 2702 "thread specific sections are not yet " 2703 "supported (section '%s')\n", 2704 sect_name); 2705 break; 2706 } else { 2707 if (target->GetSectionLoadList() 2708 .SetSectionLoadAddress(section_sp, load_addr)) 2709 changed = true; 2710 result.AppendMessageWithFormat( 2711 "section '%s' loaded at 0x%" PRIx64 "\n", 2712 sect_name, load_addr); 2713 } 2714 } else { 2715 result.AppendErrorWithFormat("no section found that " 2716 "matches the section " 2717 "name '%s'\n", 2718 sect_name); 2719 break; 2720 } 2721 } else { 2722 result.AppendErrorWithFormat( 2723 "invalid load address string '%s'\n", load_addr_cstr); 2724 break; 2725 } 2726 } else { 2727 if (sect_name) 2728 result.AppendError("section names must be followed by " 2729 "a load address.\n"); 2730 else 2731 result.AppendError("one or more section name + load " 2732 "address pair must be specified.\n"); 2733 break; 2734 } 2735 } 2736 } 2737 2738 if (changed) { 2739 target->ModulesDidLoad(matching_modules); 2740 Process *process = m_exe_ctx.GetProcessPtr(); 2741 if (process) 2742 process->Flush(); 2743 } 2744 if (load) { 2745 ProcessSP process = target->CalculateProcess(); 2746 Address file_entry = objfile->GetEntryPointAddress(); 2747 if (!process) { 2748 result.AppendError("No process"); 2749 return false; 2750 } 2751 if (set_pc && !file_entry.IsValid()) { 2752 result.AppendError("No entry address in object file"); 2753 return false; 2754 } 2755 std::vector<ObjectFile::LoadableData> loadables( 2756 objfile->GetLoadableData(*target)); 2757 if (loadables.size() == 0) { 2758 result.AppendError("No loadable sections"); 2759 return false; 2760 } 2761 Status error = process->WriteObjectFile(std::move(loadables)); 2762 if (error.Fail()) { 2763 result.AppendError(error.AsCString()); 2764 return false; 2765 } 2766 if (set_pc) { 2767 ThreadList &thread_list = process->GetThreadList(); 2768 RegisterContextSP reg_context( 2769 thread_list.GetSelectedThread()->GetRegisterContext()); 2770 addr_t file_entry_addr = file_entry.GetLoadAddress(target); 2771 if (!reg_context->SetPC(file_entry_addr)) { 2772 result.AppendErrorWithFormat("failed to set PC value to " 2773 "0x%" PRIx64 "\n", 2774 file_entry_addr); 2775 } 2776 } 2777 } 2778 } else { 2779 module->GetFileSpec().GetPath(path, sizeof(path)); 2780 result.AppendErrorWithFormat("no sections in object file '%s'\n", 2781 path); 2782 } 2783 } else { 2784 module->GetFileSpec().GetPath(path, sizeof(path)); 2785 result.AppendErrorWithFormat("no object file for module '%s'\n", 2786 path); 2787 } 2788 } else { 2789 FileSpec *module_spec_file = module_spec.GetFileSpecPtr(); 2790 if (module_spec_file) { 2791 module_spec_file->GetPath(path, sizeof(path)); 2792 result.AppendErrorWithFormat("invalid module '%s'.\n", path); 2793 } else 2794 result.AppendError("no module spec"); 2795 } 2796 } else { 2797 std::string uuid_str; 2798 2799 if (module_spec.GetFileSpec()) 2800 module_spec.GetFileSpec().GetPath(path, sizeof(path)); 2801 else 2802 path[0] = '\0'; 2803 2804 if (module_spec.GetUUIDPtr()) 2805 uuid_str = module_spec.GetUUID().GetAsString(); 2806 if (num_matches > 1) { 2807 result.AppendErrorWithFormat( 2808 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "", 2809 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str()); 2810 for (size_t i = 0; i < num_matches; ++i) { 2811 if (matching_modules.GetModulePointerAtIndex(i) 2812 ->GetFileSpec() 2813 .GetPath(path, sizeof(path))) 2814 result.AppendMessageWithFormat("%s\n", path); 2815 } 2816 } else { 2817 result.AppendErrorWithFormat( 2818 "no modules were found that match%s%s%s%s.\n", 2819 path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "", 2820 uuid_str.c_str()); 2821 } 2822 } 2823 } else { 2824 result.AppendError("either the \"--file <module>\" or the \"--uuid " 2825 "<uuid>\" option must be specified.\n"); 2826 return false; 2827 } 2828 return result.Succeeded(); 2829 } 2830 2831 OptionGroupOptions m_option_group; 2832 OptionGroupUUID m_uuid_option_group; 2833 OptionGroupString m_file_option; 2834 OptionGroupBoolean m_load_option; 2835 OptionGroupBoolean m_pc_option; 2836 OptionGroupUInt64 m_slide_option; 2837 }; 2838 2839 // List images with associated information 2840 #define LLDB_OPTIONS_target_modules_list 2841 #include "CommandOptions.inc" 2842 2843 class CommandObjectTargetModulesList : public CommandObjectParsed { 2844 public: 2845 class CommandOptions : public Options { 2846 public: 2847 CommandOptions() : Options(), m_format_array() {} 2848 2849 ~CommandOptions() override = default; 2850 2851 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2852 ExecutionContext *execution_context) override { 2853 Status error; 2854 2855 const int short_option = m_getopt_table[option_idx].val; 2856 if (short_option == 'g') { 2857 m_use_global_module_list = true; 2858 } else if (short_option == 'a') { 2859 m_module_addr = OptionArgParser::ToAddress( 2860 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error); 2861 } else { 2862 unsigned long width = 0; 2863 option_arg.getAsInteger(0, width); 2864 m_format_array.push_back(std::make_pair(short_option, width)); 2865 } 2866 return error; 2867 } 2868 2869 void OptionParsingStarting(ExecutionContext *execution_context) override { 2870 m_format_array.clear(); 2871 m_use_global_module_list = false; 2872 m_module_addr = LLDB_INVALID_ADDRESS; 2873 } 2874 2875 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 2876 return llvm::makeArrayRef(g_target_modules_list_options); 2877 } 2878 2879 // Instance variables to hold the values for command options. 2880 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection; 2881 FormatWidthCollection m_format_array; 2882 bool m_use_global_module_list = false; 2883 lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS; 2884 }; 2885 2886 CommandObjectTargetModulesList(CommandInterpreter &interpreter) 2887 : CommandObjectParsed( 2888 interpreter, "target modules list", 2889 "List current executable and dependent shared library images.", 2890 "target modules list [<cmd-options>]"), 2891 m_options() {} 2892 2893 ~CommandObjectTargetModulesList() override = default; 2894 2895 Options *GetOptions() override { return &m_options; } 2896 2897 protected: 2898 bool DoExecute(Args &command, CommandReturnObject &result) override { 2899 Target *target = GetDebugger().GetSelectedTarget().get(); 2900 const bool use_global_module_list = m_options.m_use_global_module_list; 2901 // Define a local module list here to ensure it lives longer than any 2902 // "locker" object which might lock its contents below (through the 2903 // "module_list_ptr" variable). 2904 ModuleList module_list; 2905 if (target == nullptr && !use_global_module_list) { 2906 result.AppendError("invalid target, create a debug target using the " 2907 "'target create' command"); 2908 return false; 2909 } else { 2910 if (target) { 2911 uint32_t addr_byte_size = 2912 target->GetArchitecture().GetAddressByteSize(); 2913 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2914 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2915 } 2916 // Dump all sections for all modules images 2917 Stream &strm = result.GetOutputStream(); 2918 2919 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) { 2920 if (target) { 2921 Address module_address; 2922 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) { 2923 ModuleSP module_sp(module_address.GetModule()); 2924 if (module_sp) { 2925 PrintModule(target, module_sp.get(), 0, strm); 2926 result.SetStatus(eReturnStatusSuccessFinishResult); 2927 } else { 2928 result.AppendErrorWithFormat( 2929 "Couldn't find module matching address: 0x%" PRIx64 ".", 2930 m_options.m_module_addr); 2931 } 2932 } else { 2933 result.AppendErrorWithFormat( 2934 "Couldn't find module containing address: 0x%" PRIx64 ".", 2935 m_options.m_module_addr); 2936 } 2937 } else { 2938 result.AppendError( 2939 "Can only look up modules by address with a valid target."); 2940 } 2941 return result.Succeeded(); 2942 } 2943 2944 size_t num_modules = 0; 2945 2946 // This locker will be locked on the mutex in module_list_ptr if it is 2947 // non-nullptr. Otherwise it will lock the 2948 // AllocationModuleCollectionMutex when accessing the global module list 2949 // directly. 2950 std::unique_lock<std::recursive_mutex> guard( 2951 Module::GetAllocationModuleCollectionMutex(), std::defer_lock); 2952 2953 const ModuleList *module_list_ptr = nullptr; 2954 const size_t argc = command.GetArgumentCount(); 2955 if (argc == 0) { 2956 if (use_global_module_list) { 2957 guard.lock(); 2958 num_modules = Module::GetNumberAllocatedModules(); 2959 } else { 2960 module_list_ptr = &target->GetImages(); 2961 } 2962 } else { 2963 for (const Args::ArgEntry &arg : command) { 2964 // Dump specified images (by basename or fullpath) 2965 const size_t num_matches = FindModulesByName( 2966 target, arg.c_str(), module_list, use_global_module_list); 2967 if (num_matches == 0) { 2968 if (argc == 1) { 2969 result.AppendErrorWithFormat("no modules found that match '%s'", 2970 arg.c_str()); 2971 return false; 2972 } 2973 } 2974 } 2975 2976 module_list_ptr = &module_list; 2977 } 2978 2979 std::unique_lock<std::recursive_mutex> lock; 2980 if (module_list_ptr != nullptr) { 2981 lock = 2982 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex()); 2983 2984 num_modules = module_list_ptr->GetSize(); 2985 } 2986 2987 if (num_modules > 0) { 2988 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) { 2989 ModuleSP module_sp; 2990 Module *module; 2991 if (module_list_ptr) { 2992 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx); 2993 module = module_sp.get(); 2994 } else { 2995 module = Module::GetAllocatedModuleAtIndex(image_idx); 2996 module_sp = module->shared_from_this(); 2997 } 2998 2999 const size_t indent = strm.Printf("[%3u] ", image_idx); 3000 PrintModule(target, module, indent, strm); 3001 } 3002 result.SetStatus(eReturnStatusSuccessFinishResult); 3003 } else { 3004 if (argc) { 3005 if (use_global_module_list) 3006 result.AppendError( 3007 "the global module list has no matching modules"); 3008 else 3009 result.AppendError("the target has no matching modules"); 3010 } else { 3011 if (use_global_module_list) 3012 result.AppendError("the global module list is empty"); 3013 else 3014 result.AppendError( 3015 "the target has no associated executable images"); 3016 } 3017 return false; 3018 } 3019 } 3020 return result.Succeeded(); 3021 } 3022 3023 void PrintModule(Target *target, Module *module, int indent, Stream &strm) { 3024 if (module == nullptr) { 3025 strm.PutCString("Null module"); 3026 return; 3027 } 3028 3029 bool dump_object_name = false; 3030 if (m_options.m_format_array.empty()) { 3031 m_options.m_format_array.push_back(std::make_pair('u', 0)); 3032 m_options.m_format_array.push_back(std::make_pair('h', 0)); 3033 m_options.m_format_array.push_back(std::make_pair('f', 0)); 3034 m_options.m_format_array.push_back(std::make_pair('S', 0)); 3035 } 3036 const size_t num_entries = m_options.m_format_array.size(); 3037 bool print_space = false; 3038 for (size_t i = 0; i < num_entries; ++i) { 3039 if (print_space) 3040 strm.PutChar(' '); 3041 print_space = true; 3042 const char format_char = m_options.m_format_array[i].first; 3043 uint32_t width = m_options.m_format_array[i].second; 3044 switch (format_char) { 3045 case 'A': 3046 DumpModuleArchitecture(strm, module, false, width); 3047 break; 3048 3049 case 't': 3050 DumpModuleArchitecture(strm, module, true, width); 3051 break; 3052 3053 case 'f': 3054 DumpFullpath(strm, &module->GetFileSpec(), width); 3055 dump_object_name = true; 3056 break; 3057 3058 case 'd': 3059 DumpDirectory(strm, &module->GetFileSpec(), width); 3060 break; 3061 3062 case 'b': 3063 DumpBasename(strm, &module->GetFileSpec(), width); 3064 dump_object_name = true; 3065 break; 3066 3067 case 'h': 3068 case 'o': 3069 // Image header address 3070 { 3071 uint32_t addr_nibble_width = 3072 target ? (target->GetArchitecture().GetAddressByteSize() * 2) 3073 : 16; 3074 3075 ObjectFile *objfile = module->GetObjectFile(); 3076 if (objfile) { 3077 Address base_addr(objfile->GetBaseAddress()); 3078 if (base_addr.IsValid()) { 3079 if (target && !target->GetSectionLoadList().IsEmpty()) { 3080 lldb::addr_t load_addr = base_addr.GetLoadAddress(target); 3081 if (load_addr == LLDB_INVALID_ADDRESS) { 3082 base_addr.Dump(&strm, target, 3083 Address::DumpStyleModuleWithFileAddress, 3084 Address::DumpStyleFileAddress); 3085 } else { 3086 if (format_char == 'o') { 3087 // Show the offset of slide for the image 3088 strm.Printf("0x%*.*" PRIx64, addr_nibble_width, 3089 addr_nibble_width, 3090 load_addr - base_addr.GetFileAddress()); 3091 } else { 3092 // Show the load address of the image 3093 strm.Printf("0x%*.*" PRIx64, addr_nibble_width, 3094 addr_nibble_width, load_addr); 3095 } 3096 } 3097 break; 3098 } 3099 // The address was valid, but the image isn't loaded, output the 3100 // address in an appropriate format 3101 base_addr.Dump(&strm, target, Address::DumpStyleFileAddress); 3102 break; 3103 } 3104 } 3105 strm.Printf("%*s", addr_nibble_width + 2, ""); 3106 } 3107 break; 3108 3109 case 'r': { 3110 size_t ref_count = 0; 3111 ModuleSP module_sp(module->shared_from_this()); 3112 if (module_sp) { 3113 // Take one away to make sure we don't count our local "module_sp" 3114 ref_count = module_sp.use_count() - 1; 3115 } 3116 if (width) 3117 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count); 3118 else 3119 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count); 3120 } break; 3121 3122 case 's': 3123 case 'S': { 3124 if (const SymbolFile *symbol_file = module->GetSymbolFile()) { 3125 const FileSpec symfile_spec = 3126 symbol_file->GetObjectFile()->GetFileSpec(); 3127 if (format_char == 'S') { 3128 // Dump symbol file only if different from module file 3129 if (!symfile_spec || symfile_spec == module->GetFileSpec()) { 3130 print_space = false; 3131 break; 3132 } 3133 // Add a newline and indent past the index 3134 strm.Printf("\n%*s", indent, ""); 3135 } 3136 DumpFullpath(strm, &symfile_spec, width); 3137 dump_object_name = true; 3138 break; 3139 } 3140 strm.Printf("%.*s", width, "<NONE>"); 3141 } break; 3142 3143 case 'm': 3144 strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(), 3145 llvm::AlignStyle::Left, width)); 3146 break; 3147 3148 case 'p': 3149 strm.Printf("%p", static_cast<void *>(module)); 3150 break; 3151 3152 case 'u': 3153 DumpModuleUUID(strm, module); 3154 break; 3155 3156 default: 3157 break; 3158 } 3159 } 3160 if (dump_object_name) { 3161 const char *object_name = module->GetObjectName().GetCString(); 3162 if (object_name) 3163 strm.Printf("(%s)", object_name); 3164 } 3165 strm.EOL(); 3166 } 3167 3168 CommandOptions m_options; 3169 }; 3170 3171 #pragma mark CommandObjectTargetModulesShowUnwind 3172 3173 // Lookup unwind information in images 3174 #define LLDB_OPTIONS_target_modules_show_unwind 3175 #include "CommandOptions.inc" 3176 3177 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed { 3178 public: 3179 enum { 3180 eLookupTypeInvalid = -1, 3181 eLookupTypeAddress = 0, 3182 eLookupTypeSymbol, 3183 eLookupTypeFunction, 3184 eLookupTypeFunctionOrSymbol, 3185 kNumLookupTypes 3186 }; 3187 3188 class CommandOptions : public Options { 3189 public: 3190 CommandOptions() : Options(), m_str() {} 3191 3192 ~CommandOptions() override = default; 3193 3194 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 3195 ExecutionContext *execution_context) override { 3196 Status error; 3197 3198 const int short_option = m_getopt_table[option_idx].val; 3199 3200 switch (short_option) { 3201 case 'a': { 3202 m_str = std::string(option_arg); 3203 m_type = eLookupTypeAddress; 3204 m_addr = OptionArgParser::ToAddress(execution_context, option_arg, 3205 LLDB_INVALID_ADDRESS, &error); 3206 if (m_addr == LLDB_INVALID_ADDRESS) 3207 error.SetErrorStringWithFormat("invalid address string '%s'", 3208 option_arg.str().c_str()); 3209 break; 3210 } 3211 3212 case 'n': 3213 m_str = std::string(option_arg); 3214 m_type = eLookupTypeFunctionOrSymbol; 3215 break; 3216 3217 default: 3218 llvm_unreachable("Unimplemented option"); 3219 } 3220 3221 return error; 3222 } 3223 3224 void OptionParsingStarting(ExecutionContext *execution_context) override { 3225 m_type = eLookupTypeInvalid; 3226 m_str.clear(); 3227 m_addr = LLDB_INVALID_ADDRESS; 3228 } 3229 3230 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 3231 return llvm::makeArrayRef(g_target_modules_show_unwind_options); 3232 } 3233 3234 // Instance variables to hold the values for command options. 3235 3236 int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after 3237 // parsing options 3238 std::string m_str; // Holds name lookup 3239 lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup 3240 }; 3241 3242 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter) 3243 : CommandObjectParsed( 3244 interpreter, "target modules show-unwind", 3245 "Show synthesized unwind instructions for a function.", nullptr, 3246 eCommandRequiresTarget | eCommandRequiresProcess | 3247 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), 3248 m_options() {} 3249 3250 ~CommandObjectTargetModulesShowUnwind() override = default; 3251 3252 Options *GetOptions() override { return &m_options; } 3253 3254 protected: 3255 bool DoExecute(Args &command, CommandReturnObject &result) override { 3256 Target *target = m_exe_ctx.GetTargetPtr(); 3257 Process *process = m_exe_ctx.GetProcessPtr(); 3258 ABI *abi = nullptr; 3259 if (process) 3260 abi = process->GetABI().get(); 3261 3262 if (process == nullptr) { 3263 result.AppendError( 3264 "You must have a process running to use this command."); 3265 return false; 3266 } 3267 3268 ThreadList threads(process->GetThreadList()); 3269 if (threads.GetSize() == 0) { 3270 result.AppendError("The process must be paused to use this command."); 3271 return false; 3272 } 3273 3274 ThreadSP thread(threads.GetThreadAtIndex(0)); 3275 if (!thread) { 3276 result.AppendError("The process must be paused to use this command."); 3277 return false; 3278 } 3279 3280 SymbolContextList sc_list; 3281 3282 if (m_options.m_type == eLookupTypeFunctionOrSymbol) { 3283 ConstString function_name(m_options.m_str.c_str()); 3284 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto, 3285 true, false, sc_list); 3286 } else if (m_options.m_type == eLookupTypeAddress && target) { 3287 Address addr; 3288 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr, 3289 addr)) { 3290 SymbolContext sc; 3291 ModuleSP module_sp(addr.GetModule()); 3292 module_sp->ResolveSymbolContextForAddress(addr, 3293 eSymbolContextEverything, sc); 3294 if (sc.function || sc.symbol) { 3295 sc_list.Append(sc); 3296 } 3297 } 3298 } else { 3299 result.AppendError( 3300 "address-expression or function name option must be specified."); 3301 return false; 3302 } 3303 3304 size_t num_matches = sc_list.GetSize(); 3305 if (num_matches == 0) { 3306 result.AppendErrorWithFormat("no unwind data found that matches '%s'.", 3307 m_options.m_str.c_str()); 3308 return false; 3309 } 3310 3311 for (uint32_t idx = 0; idx < num_matches; idx++) { 3312 SymbolContext sc; 3313 sc_list.GetContextAtIndex(idx, sc); 3314 if (sc.symbol == nullptr && sc.function == nullptr) 3315 continue; 3316 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr) 3317 continue; 3318 AddressRange range; 3319 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, 3320 false, range)) 3321 continue; 3322 if (!range.GetBaseAddress().IsValid()) 3323 continue; 3324 ConstString funcname(sc.GetFunctionName()); 3325 if (funcname.IsEmpty()) 3326 continue; 3327 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target); 3328 if (abi) 3329 start_addr = abi->FixCodeAddress(start_addr); 3330 3331 FuncUnwindersSP func_unwinders_sp( 3332 sc.module_sp->GetUnwindTable() 3333 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc)); 3334 if (!func_unwinders_sp) 3335 continue; 3336 3337 result.GetOutputStream().Printf( 3338 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n", 3339 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), 3340 funcname.AsCString(), start_addr); 3341 3342 Args args; 3343 target->GetUserSpecifiedTrapHandlerNames(args); 3344 size_t count = args.GetArgumentCount(); 3345 for (size_t i = 0; i < count; i++) { 3346 const char *trap_func_name = args.GetArgumentAtIndex(i); 3347 if (strcmp(funcname.GetCString(), trap_func_name) == 0) 3348 result.GetOutputStream().Printf( 3349 "This function is " 3350 "treated as a trap handler function via user setting.\n"); 3351 } 3352 PlatformSP platform_sp(target->GetPlatform()); 3353 if (platform_sp) { 3354 const std::vector<ConstString> trap_handler_names( 3355 platform_sp->GetTrapHandlerSymbolNames()); 3356 for (ConstString trap_name : trap_handler_names) { 3357 if (trap_name == funcname) { 3358 result.GetOutputStream().Printf( 3359 "This function's " 3360 "name is listed by the platform as a trap handler.\n"); 3361 } 3362 } 3363 } 3364 3365 result.GetOutputStream().Printf("\n"); 3366 3367 UnwindPlanSP non_callsite_unwind_plan = 3368 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread); 3369 if (non_callsite_unwind_plan) { 3370 result.GetOutputStream().Printf( 3371 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", 3372 non_callsite_unwind_plan->GetSourceName().AsCString()); 3373 } 3374 UnwindPlanSP callsite_unwind_plan = 3375 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread); 3376 if (callsite_unwind_plan) { 3377 result.GetOutputStream().Printf( 3378 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", 3379 callsite_unwind_plan->GetSourceName().AsCString()); 3380 } 3381 UnwindPlanSP fast_unwind_plan = 3382 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread); 3383 if (fast_unwind_plan) { 3384 result.GetOutputStream().Printf( 3385 "Fast UnwindPlan is '%s'\n", 3386 fast_unwind_plan->GetSourceName().AsCString()); 3387 } 3388 3389 result.GetOutputStream().Printf("\n"); 3390 3391 UnwindPlanSP assembly_sp = 3392 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread); 3393 if (assembly_sp) { 3394 result.GetOutputStream().Printf( 3395 "Assembly language inspection UnwindPlan:\n"); 3396 assembly_sp->Dump(result.GetOutputStream(), thread.get(), 3397 LLDB_INVALID_ADDRESS); 3398 result.GetOutputStream().Printf("\n"); 3399 } 3400 3401 UnwindPlanSP of_unwind_sp = 3402 func_unwinders_sp->GetObjectFileUnwindPlan(*target); 3403 if (of_unwind_sp) { 3404 result.GetOutputStream().Printf("object file UnwindPlan:\n"); 3405 of_unwind_sp->Dump(result.GetOutputStream(), thread.get(), 3406 LLDB_INVALID_ADDRESS); 3407 result.GetOutputStream().Printf("\n"); 3408 } 3409 3410 UnwindPlanSP of_unwind_augmented_sp = 3411 func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread); 3412 if (of_unwind_augmented_sp) { 3413 result.GetOutputStream().Printf("object file augmented UnwindPlan:\n"); 3414 of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(), 3415 LLDB_INVALID_ADDRESS); 3416 result.GetOutputStream().Printf("\n"); 3417 } 3418 3419 UnwindPlanSP ehframe_sp = 3420 func_unwinders_sp->GetEHFrameUnwindPlan(*target); 3421 if (ehframe_sp) { 3422 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n"); 3423 ehframe_sp->Dump(result.GetOutputStream(), thread.get(), 3424 LLDB_INVALID_ADDRESS); 3425 result.GetOutputStream().Printf("\n"); 3426 } 3427 3428 UnwindPlanSP ehframe_augmented_sp = 3429 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread); 3430 if (ehframe_augmented_sp) { 3431 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n"); 3432 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), 3433 LLDB_INVALID_ADDRESS); 3434 result.GetOutputStream().Printf("\n"); 3435 } 3436 3437 if (UnwindPlanSP plan_sp = 3438 func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) { 3439 result.GetOutputStream().Printf("debug_frame UnwindPlan:\n"); 3440 plan_sp->Dump(result.GetOutputStream(), thread.get(), 3441 LLDB_INVALID_ADDRESS); 3442 result.GetOutputStream().Printf("\n"); 3443 } 3444 3445 if (UnwindPlanSP plan_sp = 3446 func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target, 3447 *thread)) { 3448 result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n"); 3449 plan_sp->Dump(result.GetOutputStream(), thread.get(), 3450 LLDB_INVALID_ADDRESS); 3451 result.GetOutputStream().Printf("\n"); 3452 } 3453 3454 UnwindPlanSP arm_unwind_sp = 3455 func_unwinders_sp->GetArmUnwindUnwindPlan(*target); 3456 if (arm_unwind_sp) { 3457 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n"); 3458 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(), 3459 LLDB_INVALID_ADDRESS); 3460 result.GetOutputStream().Printf("\n"); 3461 } 3462 3463 if (UnwindPlanSP symfile_plan_sp = 3464 func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) { 3465 result.GetOutputStream().Printf("Symbol file UnwindPlan:\n"); 3466 symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(), 3467 LLDB_INVALID_ADDRESS); 3468 result.GetOutputStream().Printf("\n"); 3469 } 3470 3471 UnwindPlanSP compact_unwind_sp = 3472 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target); 3473 if (compact_unwind_sp) { 3474 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n"); 3475 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), 3476 LLDB_INVALID_ADDRESS); 3477 result.GetOutputStream().Printf("\n"); 3478 } 3479 3480 if (fast_unwind_plan) { 3481 result.GetOutputStream().Printf("Fast UnwindPlan:\n"); 3482 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), 3483 LLDB_INVALID_ADDRESS); 3484 result.GetOutputStream().Printf("\n"); 3485 } 3486 3487 ABISP abi_sp = process->GetABI(); 3488 if (abi_sp) { 3489 UnwindPlan arch_default(lldb::eRegisterKindGeneric); 3490 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) { 3491 result.GetOutputStream().Printf("Arch default UnwindPlan:\n"); 3492 arch_default.Dump(result.GetOutputStream(), thread.get(), 3493 LLDB_INVALID_ADDRESS); 3494 result.GetOutputStream().Printf("\n"); 3495 } 3496 3497 UnwindPlan arch_entry(lldb::eRegisterKindGeneric); 3498 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) { 3499 result.GetOutputStream().Printf( 3500 "Arch default at entry point UnwindPlan:\n"); 3501 arch_entry.Dump(result.GetOutputStream(), thread.get(), 3502 LLDB_INVALID_ADDRESS); 3503 result.GetOutputStream().Printf("\n"); 3504 } 3505 } 3506 3507 result.GetOutputStream().Printf("\n"); 3508 } 3509 return result.Succeeded(); 3510 } 3511 3512 CommandOptions m_options; 3513 }; 3514 3515 // Lookup information in images 3516 #define LLDB_OPTIONS_target_modules_lookup 3517 #include "CommandOptions.inc" 3518 3519 class CommandObjectTargetModulesLookup : public CommandObjectParsed { 3520 public: 3521 enum { 3522 eLookupTypeInvalid = -1, 3523 eLookupTypeAddress = 0, 3524 eLookupTypeSymbol, 3525 eLookupTypeFileLine, // Line is optional 3526 eLookupTypeFunction, 3527 eLookupTypeFunctionOrSymbol, 3528 eLookupTypeType, 3529 kNumLookupTypes 3530 }; 3531 3532 class CommandOptions : public Options { 3533 public: 3534 CommandOptions() : Options() { OptionParsingStarting(nullptr); } 3535 3536 ~CommandOptions() override = default; 3537 3538 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 3539 ExecutionContext *execution_context) override { 3540 Status error; 3541 3542 const int short_option = m_getopt_table[option_idx].val; 3543 3544 switch (short_option) { 3545 case 'a': { 3546 m_type = eLookupTypeAddress; 3547 m_addr = OptionArgParser::ToAddress(execution_context, option_arg, 3548 LLDB_INVALID_ADDRESS, &error); 3549 } break; 3550 3551 case 'o': 3552 if (option_arg.getAsInteger(0, m_offset)) 3553 error.SetErrorStringWithFormat("invalid offset string '%s'", 3554 option_arg.str().c_str()); 3555 break; 3556 3557 case 's': 3558 m_str = std::string(option_arg); 3559 m_type = eLookupTypeSymbol; 3560 break; 3561 3562 case 'f': 3563 m_file.SetFile(option_arg, FileSpec::Style::native); 3564 m_type = eLookupTypeFileLine; 3565 break; 3566 3567 case 'i': 3568 m_include_inlines = false; 3569 break; 3570 3571 case 'l': 3572 if (option_arg.getAsInteger(0, m_line_number)) 3573 error.SetErrorStringWithFormat("invalid line number string '%s'", 3574 option_arg.str().c_str()); 3575 else if (m_line_number == 0) 3576 error.SetErrorString("zero is an invalid line number"); 3577 m_type = eLookupTypeFileLine; 3578 break; 3579 3580 case 'F': 3581 m_str = std::string(option_arg); 3582 m_type = eLookupTypeFunction; 3583 break; 3584 3585 case 'n': 3586 m_str = std::string(option_arg); 3587 m_type = eLookupTypeFunctionOrSymbol; 3588 break; 3589 3590 case 't': 3591 m_str = std::string(option_arg); 3592 m_type = eLookupTypeType; 3593 break; 3594 3595 case 'v': 3596 m_verbose = true; 3597 break; 3598 3599 case 'A': 3600 m_print_all = true; 3601 break; 3602 3603 case 'r': 3604 m_use_regex = true; 3605 break; 3606 default: 3607 llvm_unreachable("Unimplemented option"); 3608 } 3609 3610 return error; 3611 } 3612 3613 void OptionParsingStarting(ExecutionContext *execution_context) override { 3614 m_type = eLookupTypeInvalid; 3615 m_str.clear(); 3616 m_file.Clear(); 3617 m_addr = LLDB_INVALID_ADDRESS; 3618 m_offset = 0; 3619 m_line_number = 0; 3620 m_use_regex = false; 3621 m_include_inlines = true; 3622 m_verbose = false; 3623 m_print_all = false; 3624 } 3625 3626 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 3627 return llvm::makeArrayRef(g_target_modules_lookup_options); 3628 } 3629 3630 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3631 std::string m_str; // Holds name lookup 3632 FileSpec m_file; // Files for file lookups 3633 lldb::addr_t m_addr; // Holds the address to lookup 3634 lldb::addr_t 3635 m_offset; // Subtract this offset from m_addr before doing lookups. 3636 uint32_t m_line_number; // Line number for file+line lookups 3637 bool m_use_regex; // Name lookups in m_str are regular expressions. 3638 bool m_include_inlines; // Check for inline entries when looking up by 3639 // file/line. 3640 bool m_verbose; // Enable verbose lookup info 3641 bool m_print_all; // Print all matches, even in cases where there's a best 3642 // match. 3643 }; 3644 3645 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter) 3646 : CommandObjectParsed(interpreter, "target modules lookup", 3647 "Look up information within executable and " 3648 "dependent shared library images.", 3649 nullptr, eCommandRequiresTarget), 3650 m_options() { 3651 CommandArgumentEntry arg; 3652 CommandArgumentData file_arg; 3653 3654 // Define the first (and only) variant of this arg. 3655 file_arg.arg_type = eArgTypeFilename; 3656 file_arg.arg_repetition = eArgRepeatStar; 3657 3658 // There is only one variant this argument could be; put it into the 3659 // argument entry. 3660 arg.push_back(file_arg); 3661 3662 // Push the data for the first argument into the m_arguments vector. 3663 m_arguments.push_back(arg); 3664 } 3665 3666 ~CommandObjectTargetModulesLookup() override = default; 3667 3668 Options *GetOptions() override { return &m_options; } 3669 3670 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result, 3671 bool &syntax_error) { 3672 switch (m_options.m_type) { 3673 case eLookupTypeAddress: 3674 case eLookupTypeFileLine: 3675 case eLookupTypeFunction: 3676 case eLookupTypeFunctionOrSymbol: 3677 case eLookupTypeSymbol: 3678 default: 3679 return false; 3680 case eLookupTypeType: 3681 break; 3682 } 3683 3684 StackFrameSP frame = m_exe_ctx.GetFrameSP(); 3685 3686 if (!frame) 3687 return false; 3688 3689 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule)); 3690 3691 if (!sym_ctx.module_sp) 3692 return false; 3693 3694 switch (m_options.m_type) { 3695 default: 3696 return false; 3697 case eLookupTypeType: 3698 if (!m_options.m_str.empty()) { 3699 if (LookupTypeHere(&GetSelectedTarget(), m_interpreter, 3700 result.GetOutputStream(), *sym_ctx.module_sp, 3701 m_options.m_str.c_str(), m_options.m_use_regex)) { 3702 result.SetStatus(eReturnStatusSuccessFinishResult); 3703 return true; 3704 } 3705 } 3706 break; 3707 } 3708 3709 return false; 3710 } 3711 3712 bool LookupInModule(CommandInterpreter &interpreter, Module *module, 3713 CommandReturnObject &result, bool &syntax_error) { 3714 switch (m_options.m_type) { 3715 case eLookupTypeAddress: 3716 if (m_options.m_addr != LLDB_INVALID_ADDRESS) { 3717 if (LookupAddressInModule( 3718 m_interpreter, result.GetOutputStream(), module, 3719 eSymbolContextEverything | 3720 (m_options.m_verbose 3721 ? static_cast<int>(eSymbolContextVariable) 3722 : 0), 3723 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) { 3724 result.SetStatus(eReturnStatusSuccessFinishResult); 3725 return true; 3726 } 3727 } 3728 break; 3729 3730 case eLookupTypeSymbol: 3731 if (!m_options.m_str.empty()) { 3732 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(), 3733 module, m_options.m_str.c_str(), 3734 m_options.m_use_regex, m_options.m_verbose)) { 3735 result.SetStatus(eReturnStatusSuccessFinishResult); 3736 return true; 3737 } 3738 } 3739 break; 3740 3741 case eLookupTypeFileLine: 3742 if (m_options.m_file) { 3743 if (LookupFileAndLineInModule( 3744 m_interpreter, result.GetOutputStream(), module, 3745 m_options.m_file, m_options.m_line_number, 3746 m_options.m_include_inlines, m_options.m_verbose)) { 3747 result.SetStatus(eReturnStatusSuccessFinishResult); 3748 return true; 3749 } 3750 } 3751 break; 3752 3753 case eLookupTypeFunctionOrSymbol: 3754 case eLookupTypeFunction: 3755 if (!m_options.m_str.empty()) { 3756 if (LookupFunctionInModule( 3757 m_interpreter, result.GetOutputStream(), module, 3758 m_options.m_str.c_str(), m_options.m_use_regex, 3759 m_options.m_include_inlines, 3760 m_options.m_type == 3761 eLookupTypeFunctionOrSymbol, // include symbols 3762 m_options.m_verbose)) { 3763 result.SetStatus(eReturnStatusSuccessFinishResult); 3764 return true; 3765 } 3766 } 3767 break; 3768 3769 case eLookupTypeType: 3770 if (!m_options.m_str.empty()) { 3771 if (LookupTypeInModule( 3772 &GetSelectedTarget(), m_interpreter, result.GetOutputStream(), 3773 module, m_options.m_str.c_str(), m_options.m_use_regex)) { 3774 result.SetStatus(eReturnStatusSuccessFinishResult); 3775 return true; 3776 } 3777 } 3778 break; 3779 3780 default: 3781 m_options.GenerateOptionUsage( 3782 result.GetErrorStream(), this, 3783 GetCommandInterpreter().GetDebugger().GetTerminalWidth()); 3784 syntax_error = true; 3785 break; 3786 } 3787 3788 result.SetStatus(eReturnStatusFailed); 3789 return false; 3790 } 3791 3792 protected: 3793 bool DoExecute(Args &command, CommandReturnObject &result) override { 3794 Target *target = &GetSelectedTarget(); 3795 bool syntax_error = false; 3796 uint32_t i; 3797 uint32_t num_successful_lookups = 0; 3798 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3799 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3800 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3801 // Dump all sections for all modules images 3802 3803 if (command.GetArgumentCount() == 0) { 3804 ModuleSP current_module; 3805 3806 // Where it is possible to look in the current symbol context first, 3807 // try that. If this search was successful and --all was not passed, 3808 // don't print anything else. 3809 if (LookupHere(m_interpreter, result, syntax_error)) { 3810 result.GetOutputStream().EOL(); 3811 num_successful_lookups++; 3812 if (!m_options.m_print_all) { 3813 result.SetStatus(eReturnStatusSuccessFinishResult); 3814 return result.Succeeded(); 3815 } 3816 } 3817 3818 // Dump all sections for all other modules 3819 3820 const ModuleList &target_modules = target->GetImages(); 3821 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); 3822 if (target_modules.GetSize() == 0) { 3823 result.AppendError("the target has no associated executable images"); 3824 return false; 3825 } 3826 3827 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) { 3828 if (module_sp != current_module && 3829 LookupInModule(m_interpreter, module_sp.get(), result, 3830 syntax_error)) { 3831 result.GetOutputStream().EOL(); 3832 num_successful_lookups++; 3833 } 3834 } 3835 } else { 3836 // Dump specified images (by basename or fullpath) 3837 const char *arg_cstr; 3838 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr && 3839 !syntax_error; 3840 ++i) { 3841 ModuleList module_list; 3842 const size_t num_matches = 3843 FindModulesByName(target, arg_cstr, module_list, false); 3844 if (num_matches > 0) { 3845 for (size_t j = 0; j < num_matches; ++j) { 3846 Module *module = module_list.GetModulePointerAtIndex(j); 3847 if (module) { 3848 if (LookupInModule(m_interpreter, module, result, syntax_error)) { 3849 result.GetOutputStream().EOL(); 3850 num_successful_lookups++; 3851 } 3852 } 3853 } 3854 } else 3855 result.AppendWarningWithFormat( 3856 "Unable to find an image that matches '%s'.\n", arg_cstr); 3857 } 3858 } 3859 3860 if (num_successful_lookups > 0) 3861 result.SetStatus(eReturnStatusSuccessFinishResult); 3862 else 3863 result.SetStatus(eReturnStatusFailed); 3864 return result.Succeeded(); 3865 } 3866 3867 CommandOptions m_options; 3868 }; 3869 3870 #pragma mark CommandObjectMultiwordImageSearchPaths 3871 3872 // CommandObjectMultiwordImageSearchPaths 3873 3874 class CommandObjectTargetModulesImageSearchPaths 3875 : public CommandObjectMultiword { 3876 public: 3877 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter) 3878 : CommandObjectMultiword( 3879 interpreter, "target modules search-paths", 3880 "Commands for managing module search paths for a target.", 3881 "target modules search-paths <subcommand> [<subcommand-options>]") { 3882 LoadSubCommand( 3883 "add", CommandObjectSP( 3884 new CommandObjectTargetModulesSearchPathsAdd(interpreter))); 3885 LoadSubCommand( 3886 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear( 3887 interpreter))); 3888 LoadSubCommand( 3889 "insert", 3890 CommandObjectSP( 3891 new CommandObjectTargetModulesSearchPathsInsert(interpreter))); 3892 LoadSubCommand( 3893 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList( 3894 interpreter))); 3895 LoadSubCommand( 3896 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery( 3897 interpreter))); 3898 } 3899 3900 ~CommandObjectTargetModulesImageSearchPaths() override = default; 3901 }; 3902 3903 #pragma mark CommandObjectTargetModules 3904 3905 // CommandObjectTargetModules 3906 3907 class CommandObjectTargetModules : public CommandObjectMultiword { 3908 public: 3909 // Constructors and Destructors 3910 CommandObjectTargetModules(CommandInterpreter &interpreter) 3911 : CommandObjectMultiword(interpreter, "target modules", 3912 "Commands for accessing information for one or " 3913 "more target modules.", 3914 "target modules <sub-command> ...") { 3915 LoadSubCommand( 3916 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter))); 3917 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad( 3918 interpreter))); 3919 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump( 3920 interpreter))); 3921 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList( 3922 interpreter))); 3923 LoadSubCommand( 3924 "lookup", 3925 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter))); 3926 LoadSubCommand( 3927 "search-paths", 3928 CommandObjectSP( 3929 new CommandObjectTargetModulesImageSearchPaths(interpreter))); 3930 LoadSubCommand( 3931 "show-unwind", 3932 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter))); 3933 } 3934 3935 ~CommandObjectTargetModules() override = default; 3936 3937 private: 3938 // For CommandObjectTargetModules only 3939 CommandObjectTargetModules(const CommandObjectTargetModules &) = delete; 3940 const CommandObjectTargetModules & 3941 operator=(const CommandObjectTargetModules &) = delete; 3942 }; 3943 3944 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed { 3945 public: 3946 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter) 3947 : CommandObjectParsed( 3948 interpreter, "target symbols add", 3949 "Add a debug symbol file to one of the target's current modules by " 3950 "specifying a path to a debug symbols file or by using the options " 3951 "to specify a module.", 3952 "target symbols add <cmd-options> [<symfile>]", 3953 eCommandRequiresTarget), 3954 m_option_group(), 3955 m_file_option( 3956 LLDB_OPT_SET_1, false, "shlib", 's', 3957 CommandCompletions::eModuleCompletion, eArgTypeShlibName, 3958 "Locate the debug symbols for the shared library specified by " 3959 "name."), 3960 m_current_frame_option( 3961 LLDB_OPT_SET_2, false, "frame", 'F', 3962 "Locate the debug symbols for the currently selected frame.", 3963 false, true) 3964 3965 { 3966 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, 3967 LLDB_OPT_SET_1); 3968 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 3969 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2, 3970 LLDB_OPT_SET_2); 3971 m_option_group.Finalize(); 3972 } 3973 3974 ~CommandObjectTargetSymbolsAdd() override = default; 3975 3976 void 3977 HandleArgumentCompletion(CompletionRequest &request, 3978 OptionElementVector &opt_element_vector) override { 3979 CommandCompletions::InvokeCommonCompletionCallbacks( 3980 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, 3981 request, nullptr); 3982 } 3983 3984 Options *GetOptions() override { return &m_option_group; } 3985 3986 protected: 3987 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush, 3988 CommandReturnObject &result) { 3989 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec(); 3990 if (!symbol_fspec) { 3991 result.AppendError( 3992 "one or more executable image paths must be specified"); 3993 return false; 3994 } 3995 3996 char symfile_path[PATH_MAX]; 3997 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path)); 3998 3999 if (!module_spec.GetUUID().IsValid()) { 4000 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec()) 4001 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename(); 4002 } 4003 4004 // Now module_spec represents a symbol file for a module that might exist 4005 // in the current target. Let's find possible matches. 4006 ModuleList matching_modules; 4007 4008 // First extract all module specs from the symbol file 4009 lldb_private::ModuleSpecList symfile_module_specs; 4010 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 4011 0, 0, symfile_module_specs)) { 4012 // Now extract the module spec that matches the target architecture 4013 ModuleSpec target_arch_module_spec; 4014 ModuleSpec symfile_module_spec; 4015 target_arch_module_spec.GetArchitecture() = target->GetArchitecture(); 4016 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, 4017 symfile_module_spec)) { 4018 if (symfile_module_spec.GetUUID().IsValid()) { 4019 // It has a UUID, look for this UUID in the target modules 4020 ModuleSpec symfile_uuid_module_spec; 4021 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4022 target->GetImages().FindModules(symfile_uuid_module_spec, 4023 matching_modules); 4024 } 4025 } 4026 4027 if (matching_modules.IsEmpty()) { 4028 // No matches yet. Iterate through the module specs to find a UUID 4029 // value that we can match up to an image in our target. 4030 const size_t num_symfile_module_specs = symfile_module_specs.GetSize(); 4031 for (size_t i = 0; 4032 i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) { 4033 if (symfile_module_specs.GetModuleSpecAtIndex( 4034 i, symfile_module_spec)) { 4035 if (symfile_module_spec.GetUUID().IsValid()) { 4036 // It has a UUID. Look for this UUID in the target modules. 4037 ModuleSpec symfile_uuid_module_spec; 4038 symfile_uuid_module_spec.GetUUID() = 4039 symfile_module_spec.GetUUID(); 4040 target->GetImages().FindModules(symfile_uuid_module_spec, 4041 matching_modules); 4042 } 4043 } 4044 } 4045 } 4046 } 4047 4048 // Just try to match up the file by basename if we have no matches at 4049 // this point. For example, module foo might have symbols in foo.debug. 4050 if (matching_modules.IsEmpty()) 4051 target->GetImages().FindModules(module_spec, matching_modules); 4052 4053 while (matching_modules.IsEmpty()) { 4054 ConstString filename_no_extension( 4055 module_spec.GetFileSpec().GetFileNameStrippingExtension()); 4056 // Empty string returned, let's bail 4057 if (!filename_no_extension) 4058 break; 4059 4060 // Check if there was no extension to strip and the basename is the same 4061 if (filename_no_extension == module_spec.GetFileSpec().GetFilename()) 4062 break; 4063 4064 // Replace basename with one fewer extension 4065 module_spec.GetFileSpec().GetFilename() = filename_no_extension; 4066 target->GetImages().FindModules(module_spec, matching_modules); 4067 } 4068 4069 if (matching_modules.GetSize() > 1) { 4070 result.AppendErrorWithFormat("multiple modules match symbol file '%s', " 4071 "use the --uuid option to resolve the " 4072 "ambiguity.\n", 4073 symfile_path); 4074 return false; 4075 } 4076 4077 if (matching_modules.GetSize() == 1) { 4078 ModuleSP module_sp(matching_modules.GetModuleAtIndex(0)); 4079 4080 // The module has not yet created its symbol vendor, we can just give 4081 // the existing target module the symfile path to use for when it 4082 // decides to create it! 4083 module_sp->SetSymbolFileFileSpec(symbol_fspec); 4084 4085 SymbolFile *symbol_file = 4086 module_sp->GetSymbolFile(true, &result.GetErrorStream()); 4087 if (symbol_file) { 4088 ObjectFile *object_file = symbol_file->GetObjectFile(); 4089 if (object_file && object_file->GetFileSpec() == symbol_fspec) { 4090 // Provide feedback that the symfile has been successfully added. 4091 const FileSpec &module_fs = module_sp->GetFileSpec(); 4092 result.AppendMessageWithFormat( 4093 "symbol file '%s' has been added to '%s'\n", symfile_path, 4094 module_fs.GetPath().c_str()); 4095 4096 // Let clients know something changed in the module if it is 4097 // currently loaded 4098 ModuleList module_list; 4099 module_list.Append(module_sp); 4100 target->SymbolsDidLoad(module_list); 4101 4102 // Make sure we load any scripting resources that may be embedded 4103 // in the debug info files in case the platform supports that. 4104 Status error; 4105 StreamString feedback_stream; 4106 module_sp->LoadScriptingResourceInTarget(target, error, 4107 &feedback_stream); 4108 if (error.Fail() && error.AsCString()) 4109 result.AppendWarningWithFormat( 4110 "unable to load scripting data for module %s - error " 4111 "reported was %s", 4112 module_sp->GetFileSpec() 4113 .GetFileNameStrippingExtension() 4114 .GetCString(), 4115 error.AsCString()); 4116 else if (feedback_stream.GetSize()) 4117 result.AppendWarning(feedback_stream.GetData()); 4118 4119 flush = true; 4120 result.SetStatus(eReturnStatusSuccessFinishResult); 4121 return true; 4122 } 4123 } 4124 // Clear the symbol file spec if anything went wrong 4125 module_sp->SetSymbolFileFileSpec(FileSpec()); 4126 } 4127 4128 StreamString ss_symfile_uuid; 4129 if (module_spec.GetUUID().IsValid()) { 4130 ss_symfile_uuid << " ("; 4131 module_spec.GetUUID().Dump(&ss_symfile_uuid); 4132 ss_symfile_uuid << ')'; 4133 } 4134 result.AppendErrorWithFormat( 4135 "symbol file '%s'%s does not match any existing module%s\n", 4136 symfile_path, ss_symfile_uuid.GetData(), 4137 !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath()) 4138 ? "\n please specify the full path to the symbol file" 4139 : ""); 4140 return false; 4141 } 4142 4143 bool DoExecute(Args &args, CommandReturnObject &result) override { 4144 Target *target = m_exe_ctx.GetTargetPtr(); 4145 result.SetStatus(eReturnStatusFailed); 4146 bool flush = false; 4147 ModuleSpec module_spec; 4148 const bool uuid_option_set = 4149 m_uuid_option_group.GetOptionValue().OptionWasSet(); 4150 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); 4151 const bool frame_option_set = 4152 m_current_frame_option.GetOptionValue().OptionWasSet(); 4153 const size_t argc = args.GetArgumentCount(); 4154 4155 if (argc == 0) { 4156 if (uuid_option_set || file_option_set || frame_option_set) { 4157 bool success = false; 4158 bool error_set = false; 4159 if (frame_option_set) { 4160 Process *process = m_exe_ctx.GetProcessPtr(); 4161 if (process) { 4162 const StateType process_state = process->GetState(); 4163 if (StateIsStoppedState(process_state, true)) { 4164 StackFrame *frame = m_exe_ctx.GetFramePtr(); 4165 if (frame) { 4166 ModuleSP frame_module_sp( 4167 frame->GetSymbolContext(eSymbolContextModule).module_sp); 4168 if (frame_module_sp) { 4169 if (FileSystem::Instance().Exists( 4170 frame_module_sp->GetPlatformFileSpec())) { 4171 module_spec.GetArchitecture() = 4172 frame_module_sp->GetArchitecture(); 4173 module_spec.GetFileSpec() = 4174 frame_module_sp->GetPlatformFileSpec(); 4175 } 4176 module_spec.GetUUID() = frame_module_sp->GetUUID(); 4177 success = module_spec.GetUUID().IsValid() || 4178 module_spec.GetFileSpec(); 4179 } else { 4180 result.AppendError("frame has no module"); 4181 error_set = true; 4182 } 4183 } else { 4184 result.AppendError("invalid current frame"); 4185 error_set = true; 4186 } 4187 } else { 4188 result.AppendErrorWithFormat("process is not stopped: %s", 4189 StateAsCString(process_state)); 4190 error_set = true; 4191 } 4192 } else { 4193 result.AppendError( 4194 "a process must exist in order to use the --frame option"); 4195 error_set = true; 4196 } 4197 } else { 4198 if (uuid_option_set) { 4199 module_spec.GetUUID() = 4200 m_uuid_option_group.GetOptionValue().GetCurrentValue(); 4201 success |= module_spec.GetUUID().IsValid(); 4202 } else if (file_option_set) { 4203 module_spec.GetFileSpec() = 4204 m_file_option.GetOptionValue().GetCurrentValue(); 4205 ModuleSP module_sp( 4206 target->GetImages().FindFirstModule(module_spec)); 4207 if (module_sp) { 4208 module_spec.GetFileSpec() = module_sp->GetFileSpec(); 4209 module_spec.GetPlatformFileSpec() = 4210 module_sp->GetPlatformFileSpec(); 4211 module_spec.GetUUID() = module_sp->GetUUID(); 4212 module_spec.GetArchitecture() = module_sp->GetArchitecture(); 4213 } else { 4214 module_spec.GetArchitecture() = target->GetArchitecture(); 4215 } 4216 success |= module_spec.GetUUID().IsValid() || 4217 FileSystem::Instance().Exists(module_spec.GetFileSpec()); 4218 } 4219 } 4220 4221 if (success) { 4222 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) { 4223 if (module_spec.GetSymbolFileSpec()) 4224 success = AddModuleSymbols(target, module_spec, flush, result); 4225 } 4226 } 4227 4228 if (!success && !error_set) { 4229 StreamString error_strm; 4230 if (uuid_option_set) { 4231 error_strm.PutCString("unable to find debug symbols for UUID "); 4232 module_spec.GetUUID().Dump(&error_strm); 4233 } else if (file_option_set) { 4234 error_strm.PutCString( 4235 "unable to find debug symbols for the executable file "); 4236 error_strm << module_spec.GetFileSpec(); 4237 } else if (frame_option_set) { 4238 error_strm.PutCString( 4239 "unable to find debug symbols for the current frame"); 4240 } 4241 result.AppendError(error_strm.GetString()); 4242 } 4243 } else { 4244 result.AppendError("one or more symbol file paths must be specified, " 4245 "or options must be specified"); 4246 } 4247 } else { 4248 if (uuid_option_set) { 4249 result.AppendError("specify either one or more paths to symbol files " 4250 "or use the --uuid option without arguments"); 4251 } else if (frame_option_set) { 4252 result.AppendError("specify either one or more paths to symbol files " 4253 "or use the --frame option without arguments"); 4254 } else if (file_option_set && argc > 1) { 4255 result.AppendError("specify at most one symbol file path when " 4256 "--shlib option is set"); 4257 } else { 4258 PlatformSP platform_sp(target->GetPlatform()); 4259 4260 for (auto &entry : args.entries()) { 4261 if (!entry.ref().empty()) { 4262 auto &symbol_file_spec = module_spec.GetSymbolFileSpec(); 4263 symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native); 4264 FileSystem::Instance().Resolve(symbol_file_spec); 4265 if (file_option_set) { 4266 module_spec.GetFileSpec() = 4267 m_file_option.GetOptionValue().GetCurrentValue(); 4268 } 4269 if (platform_sp) { 4270 FileSpec symfile_spec; 4271 if (platform_sp 4272 ->ResolveSymbolFile(*target, module_spec, symfile_spec) 4273 .Success()) 4274 module_spec.GetSymbolFileSpec() = symfile_spec; 4275 } 4276 4277 bool symfile_exists = 4278 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec()); 4279 4280 if (symfile_exists) { 4281 if (!AddModuleSymbols(target, module_spec, flush, result)) 4282 break; 4283 } else { 4284 std::string resolved_symfile_path = 4285 module_spec.GetSymbolFileSpec().GetPath(); 4286 if (resolved_symfile_path != entry.ref()) { 4287 result.AppendErrorWithFormat( 4288 "invalid module path '%s' with resolved path '%s'\n", 4289 entry.c_str(), resolved_symfile_path.c_str()); 4290 break; 4291 } 4292 result.AppendErrorWithFormat("invalid module path '%s'\n", 4293 entry.c_str()); 4294 break; 4295 } 4296 } 4297 } 4298 } 4299 } 4300 4301 if (flush) { 4302 Process *process = m_exe_ctx.GetProcessPtr(); 4303 if (process) 4304 process->Flush(); 4305 } 4306 return result.Succeeded(); 4307 } 4308 4309 OptionGroupOptions m_option_group; 4310 OptionGroupUUID m_uuid_option_group; 4311 OptionGroupFile m_file_option; 4312 OptionGroupBoolean m_current_frame_option; 4313 }; 4314 4315 #pragma mark CommandObjectTargetSymbols 4316 4317 // CommandObjectTargetSymbols 4318 4319 class CommandObjectTargetSymbols : public CommandObjectMultiword { 4320 public: 4321 // Constructors and Destructors 4322 CommandObjectTargetSymbols(CommandInterpreter &interpreter) 4323 : CommandObjectMultiword( 4324 interpreter, "target symbols", 4325 "Commands for adding and managing debug symbol files.", 4326 "target symbols <sub-command> ...") { 4327 LoadSubCommand( 4328 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter))); 4329 } 4330 4331 ~CommandObjectTargetSymbols() override = default; 4332 4333 private: 4334 // For CommandObjectTargetModules only 4335 CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete; 4336 const CommandObjectTargetSymbols & 4337 operator=(const CommandObjectTargetSymbols &) = delete; 4338 }; 4339 4340 #pragma mark CommandObjectTargetStopHookAdd 4341 4342 // CommandObjectTargetStopHookAdd 4343 #define LLDB_OPTIONS_target_stop_hook_add 4344 #include "CommandOptions.inc" 4345 4346 class CommandObjectTargetStopHookAdd : public CommandObjectParsed, 4347 public IOHandlerDelegateMultiline { 4348 public: 4349 class CommandOptions : public OptionGroup { 4350 public: 4351 CommandOptions() : OptionGroup(), m_line_end(UINT_MAX), m_one_liner() {} 4352 4353 ~CommandOptions() override = default; 4354 4355 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 4356 return llvm::makeArrayRef(g_target_stop_hook_add_options); 4357 } 4358 4359 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 4360 ExecutionContext *execution_context) override { 4361 Status error; 4362 const int short_option = 4363 g_target_stop_hook_add_options[option_idx].short_option; 4364 4365 switch (short_option) { 4366 case 'c': 4367 m_class_name = std::string(option_arg); 4368 m_sym_ctx_specified = true; 4369 break; 4370 4371 case 'e': 4372 if (option_arg.getAsInteger(0, m_line_end)) { 4373 error.SetErrorStringWithFormat("invalid end line number: \"%s\"", 4374 option_arg.str().c_str()); 4375 break; 4376 } 4377 m_sym_ctx_specified = true; 4378 break; 4379 4380 case 'G': { 4381 bool value, success; 4382 value = OptionArgParser::ToBoolean(option_arg, false, &success); 4383 if (success) { 4384 m_auto_continue = value; 4385 } else 4386 error.SetErrorStringWithFormat( 4387 "invalid boolean value '%s' passed for -G option", 4388 option_arg.str().c_str()); 4389 } break; 4390 case 'l': 4391 if (option_arg.getAsInteger(0, m_line_start)) { 4392 error.SetErrorStringWithFormat("invalid start line number: \"%s\"", 4393 option_arg.str().c_str()); 4394 break; 4395 } 4396 m_sym_ctx_specified = true; 4397 break; 4398 4399 case 'i': 4400 m_no_inlines = true; 4401 break; 4402 4403 case 'n': 4404 m_function_name = std::string(option_arg); 4405 m_func_name_type_mask |= eFunctionNameTypeAuto; 4406 m_sym_ctx_specified = true; 4407 break; 4408 4409 case 'f': 4410 m_file_name = std::string(option_arg); 4411 m_sym_ctx_specified = true; 4412 break; 4413 4414 case 's': 4415 m_module_name = std::string(option_arg); 4416 m_sym_ctx_specified = true; 4417 break; 4418 4419 case 't': 4420 if (option_arg.getAsInteger(0, m_thread_id)) 4421 error.SetErrorStringWithFormat("invalid thread id string '%s'", 4422 option_arg.str().c_str()); 4423 m_thread_specified = true; 4424 break; 4425 4426 case 'T': 4427 m_thread_name = std::string(option_arg); 4428 m_thread_specified = true; 4429 break; 4430 4431 case 'q': 4432 m_queue_name = std::string(option_arg); 4433 m_thread_specified = true; 4434 break; 4435 4436 case 'x': 4437 if (option_arg.getAsInteger(0, m_thread_index)) 4438 error.SetErrorStringWithFormat("invalid thread index string '%s'", 4439 option_arg.str().c_str()); 4440 m_thread_specified = true; 4441 break; 4442 4443 case 'o': 4444 m_use_one_liner = true; 4445 m_one_liner.push_back(std::string(option_arg)); 4446 break; 4447 4448 default: 4449 llvm_unreachable("Unimplemented option"); 4450 } 4451 return error; 4452 } 4453 4454 void OptionParsingStarting(ExecutionContext *execution_context) override { 4455 m_class_name.clear(); 4456 m_function_name.clear(); 4457 m_line_start = 0; 4458 m_line_end = UINT_MAX; 4459 m_file_name.clear(); 4460 m_module_name.clear(); 4461 m_func_name_type_mask = eFunctionNameTypeAuto; 4462 m_thread_id = LLDB_INVALID_THREAD_ID; 4463 m_thread_index = UINT32_MAX; 4464 m_thread_name.clear(); 4465 m_queue_name.clear(); 4466 4467 m_no_inlines = false; 4468 m_sym_ctx_specified = false; 4469 m_thread_specified = false; 4470 4471 m_use_one_liner = false; 4472 m_one_liner.clear(); 4473 m_auto_continue = false; 4474 } 4475 4476 std::string m_class_name; 4477 std::string m_function_name; 4478 uint32_t m_line_start = 0; 4479 uint32_t m_line_end; 4480 std::string m_file_name; 4481 std::string m_module_name; 4482 uint32_t m_func_name_type_mask = 4483 eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType. 4484 lldb::tid_t m_thread_id; 4485 uint32_t m_thread_index; 4486 std::string m_thread_name; 4487 std::string m_queue_name; 4488 bool m_sym_ctx_specified = false; 4489 bool m_no_inlines; 4490 bool m_thread_specified = false; 4491 // Instance variables to hold the values for one_liner options. 4492 bool m_use_one_liner = false; 4493 std::vector<std::string> m_one_liner; 4494 4495 bool m_auto_continue; 4496 }; 4497 4498 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter) 4499 : CommandObjectParsed(interpreter, "target stop-hook add", 4500 "Add a hook to be executed when the target stops." 4501 "The hook can either be a list of commands or an " 4502 "appropriately defined Python class. You can also " 4503 "add filters so the hook only runs a certain stop " 4504 "points.", 4505 "target stop-hook add"), 4506 IOHandlerDelegateMultiline("DONE", 4507 IOHandlerDelegate::Completion::LLDBCommand), 4508 m_options(), m_python_class_options("scripted stop-hook", true, 'P') { 4509 SetHelpLong( 4510 R"( 4511 Command Based stop-hooks: 4512 ------------------------- 4513 Stop hooks can run a list of lldb commands by providing one or more 4514 --one-line-command options. The commands will get run in the order they are 4515 added. Or you can provide no commands, in which case you will enter a 4516 command editor where you can enter the commands to be run. 4517 4518 Python Based Stop Hooks: 4519 ------------------------ 4520 Stop hooks can be implemented with a suitably defined Python class, whose name 4521 is passed in the --python-class option. 4522 4523 When the stop hook is added, the class is initialized by calling: 4524 4525 def __init__(self, target, extra_args, internal_dict): 4526 4527 target: The target that the stop hook is being added to. 4528 extra_args: An SBStructuredData Dictionary filled with the -key -value 4529 option pairs passed to the command. 4530 dict: An implementation detail provided by lldb. 4531 4532 Then when the stop-hook triggers, lldb will run the 'handle_stop' method. 4533 The method has the signature: 4534 4535 def handle_stop(self, exe_ctx, stream): 4536 4537 exe_ctx: An SBExecutionContext for the thread that has stopped. 4538 stream: An SBStream, anything written to this stream will be printed in the 4539 the stop message when the process stops. 4540 4541 Return Value: The method returns "should_stop". If should_stop is false 4542 from all the stop hook executions on threads that stopped 4543 with a reason, then the process will continue. Note that this 4544 will happen only after all the stop hooks are run. 4545 4546 Filter Options: 4547 --------------- 4548 Stop hooks can be set to always run, or to only run when the stopped thread 4549 matches the filter options passed on the command line. The available filter 4550 options include a shared library or a thread or queue specification, 4551 a line range in a source file, a function name or a class name. 4552 )"); 4553 m_all_options.Append(&m_python_class_options, 4554 LLDB_OPT_SET_1 | LLDB_OPT_SET_2, 4555 LLDB_OPT_SET_FROM_TO(4, 6)); 4556 m_all_options.Append(&m_options); 4557 m_all_options.Finalize(); 4558 } 4559 4560 ~CommandObjectTargetStopHookAdd() override = default; 4561 4562 Options *GetOptions() override { return &m_all_options; } 4563 4564 protected: 4565 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { 4566 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); 4567 if (output_sp && interactive) { 4568 output_sp->PutCString( 4569 "Enter your stop hook command(s). Type 'DONE' to end.\n"); 4570 output_sp->Flush(); 4571 } 4572 } 4573 4574 void IOHandlerInputComplete(IOHandler &io_handler, 4575 std::string &line) override { 4576 if (m_stop_hook_sp) { 4577 if (line.empty()) { 4578 StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); 4579 if (error_sp) { 4580 error_sp->Printf("error: stop hook #%" PRIu64 4581 " aborted, no commands.\n", 4582 m_stop_hook_sp->GetID()); 4583 error_sp->Flush(); 4584 } 4585 Target *target = GetDebugger().GetSelectedTarget().get(); 4586 if (target) { 4587 target->UndoCreateStopHook(m_stop_hook_sp->GetID()); 4588 } 4589 } else { 4590 // The IOHandler editor is only for command lines stop hooks: 4591 Target::StopHookCommandLine *hook_ptr = 4592 static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get()); 4593 4594 hook_ptr->SetActionFromString(line); 4595 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); 4596 if (output_sp) { 4597 output_sp->Printf("Stop hook #%" PRIu64 " added.\n", 4598 m_stop_hook_sp->GetID()); 4599 output_sp->Flush(); 4600 } 4601 } 4602 m_stop_hook_sp.reset(); 4603 } 4604 io_handler.SetIsDone(true); 4605 } 4606 4607 bool DoExecute(Args &command, CommandReturnObject &result) override { 4608 m_stop_hook_sp.reset(); 4609 4610 Target &target = GetSelectedOrDummyTarget(); 4611 Target::StopHookSP new_hook_sp = 4612 target.CreateStopHook(m_python_class_options.GetName().empty() ? 4613 Target::StopHook::StopHookKind::CommandBased 4614 : Target::StopHook::StopHookKind::ScriptBased); 4615 4616 // First step, make the specifier. 4617 std::unique_ptr<SymbolContextSpecifier> specifier_up; 4618 if (m_options.m_sym_ctx_specified) { 4619 specifier_up = std::make_unique<SymbolContextSpecifier>( 4620 GetDebugger().GetSelectedTarget()); 4621 4622 if (!m_options.m_module_name.empty()) { 4623 specifier_up->AddSpecification( 4624 m_options.m_module_name.c_str(), 4625 SymbolContextSpecifier::eModuleSpecified); 4626 } 4627 4628 if (!m_options.m_class_name.empty()) { 4629 specifier_up->AddSpecification( 4630 m_options.m_class_name.c_str(), 4631 SymbolContextSpecifier::eClassOrNamespaceSpecified); 4632 } 4633 4634 if (!m_options.m_file_name.empty()) { 4635 specifier_up->AddSpecification(m_options.m_file_name.c_str(), 4636 SymbolContextSpecifier::eFileSpecified); 4637 } 4638 4639 if (m_options.m_line_start != 0) { 4640 specifier_up->AddLineSpecification( 4641 m_options.m_line_start, 4642 SymbolContextSpecifier::eLineStartSpecified); 4643 } 4644 4645 if (m_options.m_line_end != UINT_MAX) { 4646 specifier_up->AddLineSpecification( 4647 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 4648 } 4649 4650 if (!m_options.m_function_name.empty()) { 4651 specifier_up->AddSpecification( 4652 m_options.m_function_name.c_str(), 4653 SymbolContextSpecifier::eFunctionSpecified); 4654 } 4655 } 4656 4657 if (specifier_up) 4658 new_hook_sp->SetSpecifier(specifier_up.release()); 4659 4660 // Next see if any of the thread options have been entered: 4661 4662 if (m_options.m_thread_specified) { 4663 ThreadSpec *thread_spec = new ThreadSpec(); 4664 4665 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) { 4666 thread_spec->SetTID(m_options.m_thread_id); 4667 } 4668 4669 if (m_options.m_thread_index != UINT32_MAX) 4670 thread_spec->SetIndex(m_options.m_thread_index); 4671 4672 if (!m_options.m_thread_name.empty()) 4673 thread_spec->SetName(m_options.m_thread_name.c_str()); 4674 4675 if (!m_options.m_queue_name.empty()) 4676 thread_spec->SetQueueName(m_options.m_queue_name.c_str()); 4677 4678 new_hook_sp->SetThreadSpecifier(thread_spec); 4679 } 4680 4681 new_hook_sp->SetAutoContinue(m_options.m_auto_continue); 4682 if (m_options.m_use_one_liner) { 4683 // This is a command line stop hook: 4684 Target::StopHookCommandLine *hook_ptr = 4685 static_cast<Target::StopHookCommandLine *>(new_hook_sp.get()); 4686 hook_ptr->SetActionFromStrings(m_options.m_one_liner); 4687 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", 4688 new_hook_sp->GetID()); 4689 } else if (!m_python_class_options.GetName().empty()) { 4690 // This is a scripted stop hook: 4691 Target::StopHookScripted *hook_ptr = 4692 static_cast<Target::StopHookScripted *>(new_hook_sp.get()); 4693 Status error = hook_ptr->SetScriptCallback( 4694 m_python_class_options.GetName(), 4695 m_python_class_options.GetStructuredData()); 4696 if (error.Success()) 4697 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", 4698 new_hook_sp->GetID()); 4699 else { 4700 // FIXME: Set the stop hook ID counter back. 4701 result.AppendErrorWithFormat("Couldn't add stop hook: %s", 4702 error.AsCString()); 4703 target.UndoCreateStopHook(new_hook_sp->GetID()); 4704 return false; 4705 } 4706 } else { 4707 m_stop_hook_sp = new_hook_sp; 4708 m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt 4709 *this); // IOHandlerDelegate 4710 } 4711 result.SetStatus(eReturnStatusSuccessFinishNoResult); 4712 4713 return result.Succeeded(); 4714 } 4715 4716 private: 4717 CommandOptions m_options; 4718 OptionGroupPythonClassWithDict m_python_class_options; 4719 OptionGroupOptions m_all_options; 4720 4721 Target::StopHookSP m_stop_hook_sp; 4722 }; 4723 4724 #pragma mark CommandObjectTargetStopHookDelete 4725 4726 // CommandObjectTargetStopHookDelete 4727 4728 class CommandObjectTargetStopHookDelete : public CommandObjectParsed { 4729 public: 4730 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter) 4731 : CommandObjectParsed(interpreter, "target stop-hook delete", 4732 "Delete a stop-hook.", 4733 "target stop-hook delete [<idx>]") {} 4734 4735 ~CommandObjectTargetStopHookDelete() override = default; 4736 4737 void 4738 HandleArgumentCompletion(CompletionRequest &request, 4739 OptionElementVector &opt_element_vector) override { 4740 CommandCompletions::InvokeCommonCompletionCallbacks( 4741 GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion, 4742 request, nullptr); 4743 } 4744 4745 protected: 4746 bool DoExecute(Args &command, CommandReturnObject &result) override { 4747 Target &target = GetSelectedOrDummyTarget(); 4748 // FIXME: see if we can use the breakpoint id style parser? 4749 size_t num_args = command.GetArgumentCount(); 4750 if (num_args == 0) { 4751 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) { 4752 result.SetStatus(eReturnStatusFailed); 4753 return false; 4754 } else { 4755 target.RemoveAllStopHooks(); 4756 } 4757 } else { 4758 for (size_t i = 0; i < num_args; i++) { 4759 lldb::user_id_t user_id; 4760 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { 4761 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", 4762 command.GetArgumentAtIndex(i)); 4763 return false; 4764 } 4765 if (!target.RemoveStopHookByID(user_id)) { 4766 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", 4767 command.GetArgumentAtIndex(i)); 4768 return false; 4769 } 4770 } 4771 } 4772 result.SetStatus(eReturnStatusSuccessFinishNoResult); 4773 return result.Succeeded(); 4774 } 4775 }; 4776 4777 #pragma mark CommandObjectTargetStopHookEnableDisable 4778 4779 // CommandObjectTargetStopHookEnableDisable 4780 4781 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed { 4782 public: 4783 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter, 4784 bool enable, const char *name, 4785 const char *help, const char *syntax) 4786 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) { 4787 } 4788 4789 ~CommandObjectTargetStopHookEnableDisable() override = default; 4790 4791 void 4792 HandleArgumentCompletion(CompletionRequest &request, 4793 OptionElementVector &opt_element_vector) override { 4794 if (request.GetCursorIndex()) 4795 return; 4796 CommandCompletions::InvokeCommonCompletionCallbacks( 4797 GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion, 4798 request, nullptr); 4799 } 4800 4801 protected: 4802 bool DoExecute(Args &command, CommandReturnObject &result) override { 4803 Target &target = GetSelectedOrDummyTarget(); 4804 // FIXME: see if we can use the breakpoint id style parser? 4805 size_t num_args = command.GetArgumentCount(); 4806 bool success; 4807 4808 if (num_args == 0) { 4809 target.SetAllStopHooksActiveState(m_enable); 4810 } else { 4811 for (size_t i = 0; i < num_args; i++) { 4812 lldb::user_id_t user_id; 4813 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { 4814 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", 4815 command.GetArgumentAtIndex(i)); 4816 return false; 4817 } 4818 success = target.SetStopHookActiveStateByID(user_id, m_enable); 4819 if (!success) { 4820 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", 4821 command.GetArgumentAtIndex(i)); 4822 return false; 4823 } 4824 } 4825 } 4826 result.SetStatus(eReturnStatusSuccessFinishNoResult); 4827 return result.Succeeded(); 4828 } 4829 4830 private: 4831 bool m_enable; 4832 }; 4833 4834 #pragma mark CommandObjectTargetStopHookList 4835 4836 // CommandObjectTargetStopHookList 4837 4838 class CommandObjectTargetStopHookList : public CommandObjectParsed { 4839 public: 4840 CommandObjectTargetStopHookList(CommandInterpreter &interpreter) 4841 : CommandObjectParsed(interpreter, "target stop-hook list", 4842 "List all stop-hooks.", 4843 "target stop-hook list [<type>]") {} 4844 4845 ~CommandObjectTargetStopHookList() override = default; 4846 4847 protected: 4848 bool DoExecute(Args &command, CommandReturnObject &result) override { 4849 Target &target = GetSelectedOrDummyTarget(); 4850 4851 size_t num_hooks = target.GetNumStopHooks(); 4852 if (num_hooks == 0) { 4853 result.GetOutputStream().PutCString("No stop hooks.\n"); 4854 } else { 4855 for (size_t i = 0; i < num_hooks; i++) { 4856 Target::StopHookSP this_hook = target.GetStopHookAtIndex(i); 4857 if (i > 0) 4858 result.GetOutputStream().PutCString("\n"); 4859 this_hook->GetDescription(&(result.GetOutputStream()), 4860 eDescriptionLevelFull); 4861 } 4862 } 4863 result.SetStatus(eReturnStatusSuccessFinishResult); 4864 return result.Succeeded(); 4865 } 4866 }; 4867 4868 #pragma mark CommandObjectMultiwordTargetStopHooks 4869 4870 // CommandObjectMultiwordTargetStopHooks 4871 4872 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword { 4873 public: 4874 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter) 4875 : CommandObjectMultiword( 4876 interpreter, "target stop-hook", 4877 "Commands for operating on debugger target stop-hooks.", 4878 "target stop-hook <subcommand> [<subcommand-options>]") { 4879 LoadSubCommand("add", CommandObjectSP( 4880 new CommandObjectTargetStopHookAdd(interpreter))); 4881 LoadSubCommand( 4882 "delete", 4883 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter))); 4884 LoadSubCommand("disable", 4885 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable( 4886 interpreter, false, "target stop-hook disable [<id>]", 4887 "Disable a stop-hook.", "target stop-hook disable"))); 4888 LoadSubCommand("enable", 4889 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable( 4890 interpreter, true, "target stop-hook enable [<id>]", 4891 "Enable a stop-hook.", "target stop-hook enable"))); 4892 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList( 4893 interpreter))); 4894 } 4895 4896 ~CommandObjectMultiwordTargetStopHooks() override = default; 4897 }; 4898 4899 #pragma mark CommandObjectMultiwordTarget 4900 4901 // CommandObjectMultiwordTarget 4902 4903 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget( 4904 CommandInterpreter &interpreter) 4905 : CommandObjectMultiword(interpreter, "target", 4906 "Commands for operating on debugger targets.", 4907 "target <subcommand> [<subcommand-options>]") { 4908 LoadSubCommand("create", 4909 CommandObjectSP(new CommandObjectTargetCreate(interpreter))); 4910 LoadSubCommand("delete", 4911 CommandObjectSP(new CommandObjectTargetDelete(interpreter))); 4912 LoadSubCommand("list", 4913 CommandObjectSP(new CommandObjectTargetList(interpreter))); 4914 LoadSubCommand("select", 4915 CommandObjectSP(new CommandObjectTargetSelect(interpreter))); 4916 LoadSubCommand("show-launch-environment", 4917 CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment( 4918 interpreter))); 4919 LoadSubCommand( 4920 "stop-hook", 4921 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter))); 4922 LoadSubCommand("modules", 4923 CommandObjectSP(new CommandObjectTargetModules(interpreter))); 4924 LoadSubCommand("symbols", 4925 CommandObjectSP(new CommandObjectTargetSymbols(interpreter))); 4926 LoadSubCommand("variable", 4927 CommandObjectSP(new CommandObjectTargetVariable(interpreter))); 4928 } 4929 4930 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default; 4931