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