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