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