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