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