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