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