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