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