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