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