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/Section.h" 22 #include "lldb/Core/State.h" 23 #include "lldb/Core/Timer.h" 24 #include "lldb/Core/ValueObjectVariable.h" 25 #include "lldb/Interpreter/CommandInterpreter.h" 26 #include "lldb/Interpreter/CommandReturnObject.h" 27 #include "lldb/Interpreter/Options.h" 28 #include "lldb/Interpreter/OptionGroupArchitecture.h" 29 #include "lldb/Interpreter/OptionGroupBoolean.h" 30 #include "lldb/Interpreter/OptionGroupFile.h" 31 #include "lldb/Interpreter/OptionGroupVariable.h" 32 #include "lldb/Interpreter/OptionGroupPlatform.h" 33 #include "lldb/Interpreter/OptionGroupUInt64.h" 34 #include "lldb/Interpreter/OptionGroupUUID.h" 35 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" 36 #include "lldb/Symbol/LineTable.h" 37 #include "lldb/Symbol/ObjectFile.h" 38 #include "lldb/Symbol/SymbolFile.h" 39 #include "lldb/Symbol/SymbolVendor.h" 40 #include "lldb/Symbol/VariableList.h" 41 #include "lldb/Target/Process.h" 42 #include "lldb/Target/StackFrame.h" 43 #include "lldb/Target/Thread.h" 44 #include "lldb/Target/ThreadSpec.h" 45 46 using namespace lldb; 47 using namespace lldb_private; 48 49 50 51 static void 52 DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm) 53 { 54 const ArchSpec &target_arch = target->GetArchitecture(); 55 56 Module *exe_module = target->GetExecutableModulePointer(); 57 char exe_path[PATH_MAX]; 58 bool exe_valid = false; 59 if (exe_module) 60 exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path)); 61 62 if (!exe_valid) 63 ::strcpy (exe_path, "<none>"); 64 65 strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path); 66 67 uint32_t properties = 0; 68 if (target_arch.IsValid()) 69 { 70 strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str()); 71 properties++; 72 } 73 PlatformSP platform_sp (target->GetPlatform()); 74 if (platform_sp) 75 strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName()); 76 77 ProcessSP process_sp (target->GetProcessSP()); 78 bool show_process_status = false; 79 if (process_sp) 80 { 81 lldb::pid_t pid = process_sp->GetID(); 82 StateType state = process_sp->GetState(); 83 if (show_stopped_process_status) 84 show_process_status = StateIsStoppedState(state); 85 const char *state_cstr = StateAsCString (state); 86 if (pid != LLDB_INVALID_PROCESS_ID) 87 strm.Printf ("%spid=%i", properties++ > 0 ? ", " : " ( ", pid); 88 strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr); 89 } 90 if (properties > 0) 91 strm.PutCString (" )\n"); 92 else 93 strm.EOL(); 94 if (show_process_status) 95 { 96 const bool only_threads_with_stop_reason = true; 97 const uint32_t start_frame = 0; 98 const uint32_t num_frames = 1; 99 const uint32_t num_frames_with_source = 1; 100 process_sp->GetStatus (strm); 101 process_sp->GetThreadStatus (strm, 102 only_threads_with_stop_reason, 103 start_frame, 104 num_frames, 105 num_frames_with_source); 106 107 } 108 } 109 110 static uint32_t 111 DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm) 112 { 113 const uint32_t num_targets = target_list.GetNumTargets(); 114 if (num_targets) 115 { 116 TargetSP selected_target_sp (target_list.GetSelectedTarget()); 117 strm.PutCString ("Current targets:\n"); 118 for (uint32_t i=0; i<num_targets; ++i) 119 { 120 TargetSP target_sp (target_list.GetTargetAtIndex (i)); 121 if (target_sp) 122 { 123 bool is_selected = target_sp.get() == selected_target_sp.get(); 124 DumpTargetInfo (i, 125 target_sp.get(), 126 is_selected ? "* " : " ", 127 show_stopped_process_status, 128 strm); 129 } 130 } 131 } 132 return num_targets; 133 } 134 #pragma mark CommandObjectTargetCreate 135 136 //------------------------------------------------------------------------- 137 // "target create" 138 //------------------------------------------------------------------------- 139 140 class CommandObjectTargetCreate : public CommandObject 141 { 142 public: 143 CommandObjectTargetCreate(CommandInterpreter &interpreter) : 144 CommandObject (interpreter, 145 "target create", 146 "Create a target using the argument as the main executable.", 147 NULL), 148 m_option_group (interpreter), 149 m_arch_option (), 150 m_platform_options(true) // Do include the "--platform" option in the platform settings by passing true 151 { 152 CommandArgumentEntry arg; 153 CommandArgumentData file_arg; 154 155 // Define the first (and only) variant of this arg. 156 file_arg.arg_type = eArgTypeFilename; 157 file_arg.arg_repetition = eArgRepeatPlain; 158 159 // There is only one variant this argument could be; put it into the argument entry. 160 arg.push_back (file_arg); 161 162 // Push the data for the first argument into the m_arguments vector. 163 m_arguments.push_back (arg); 164 165 m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 166 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 167 m_option_group.Finalize(); 168 } 169 170 ~CommandObjectTargetCreate () 171 { 172 } 173 174 Options * 175 GetOptions () 176 { 177 return &m_option_group; 178 } 179 180 bool 181 Execute (Args& command, CommandReturnObject &result) 182 { 183 const int argc = command.GetArgumentCount(); 184 if (argc == 1) 185 { 186 const char *file_path = command.GetArgumentAtIndex(0); 187 Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path); 188 FileSpec file_spec (file_path, true); 189 190 TargetSP target_sp; 191 Debugger &debugger = m_interpreter.GetDebugger(); 192 const char *arch_cstr = m_arch_option.GetArchitectureName(); 193 const bool get_dependent_files = true; 194 Error error (debugger.GetTargetList().CreateTarget (debugger, 195 file_spec, 196 arch_cstr, 197 get_dependent_files, 198 &m_platform_options, 199 target_sp)); 200 201 if (target_sp) 202 { 203 debugger.GetTargetList().SetSelectedTarget(target_sp.get()); 204 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName()); 205 result.SetStatus (eReturnStatusSuccessFinishNoResult); 206 } 207 else 208 { 209 result.AppendError(error.AsCString()); 210 result.SetStatus (eReturnStatusFailed); 211 } 212 } 213 else 214 { 215 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument.\n", m_cmd_name.c_str()); 216 result.SetStatus (eReturnStatusFailed); 217 } 218 return result.Succeeded(); 219 220 } 221 222 int 223 HandleArgumentCompletion (Args &input, 224 int &cursor_index, 225 int &cursor_char_position, 226 OptionElementVector &opt_element_vector, 227 int match_start_point, 228 int max_return_elements, 229 bool &word_complete, 230 StringList &matches) 231 { 232 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 233 completion_str.erase (cursor_char_position); 234 235 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 236 CommandCompletions::eDiskFileCompletion, 237 completion_str.c_str(), 238 match_start_point, 239 max_return_elements, 240 NULL, 241 word_complete, 242 matches); 243 return matches.GetSize(); 244 } 245 private: 246 OptionGroupOptions m_option_group; 247 OptionGroupArchitecture m_arch_option; 248 OptionGroupPlatform m_platform_options; 249 250 }; 251 252 #pragma mark CommandObjectTargetList 253 254 //---------------------------------------------------------------------- 255 // "target list" 256 //---------------------------------------------------------------------- 257 258 class CommandObjectTargetList : public CommandObject 259 { 260 public: 261 CommandObjectTargetList (CommandInterpreter &interpreter) : 262 CommandObject (interpreter, 263 "target list", 264 "List all current targets in the current debug session.", 265 NULL, 266 0) 267 { 268 } 269 270 virtual 271 ~CommandObjectTargetList () 272 { 273 } 274 275 virtual bool 276 Execute (Args& args, CommandReturnObject &result) 277 { 278 if (args.GetArgumentCount() == 0) 279 { 280 Stream &strm = result.GetOutputStream(); 281 282 bool show_stopped_process_status = false; 283 if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0) 284 { 285 strm.PutCString ("No targets.\n"); 286 } 287 result.SetStatus (eReturnStatusSuccessFinishResult); 288 } 289 else 290 { 291 result.AppendError ("the 'target list' command takes no arguments\n"); 292 result.SetStatus (eReturnStatusFailed); 293 } 294 return result.Succeeded(); 295 } 296 }; 297 298 299 #pragma mark CommandObjectTargetSelect 300 301 //---------------------------------------------------------------------- 302 // "target select" 303 //---------------------------------------------------------------------- 304 305 class CommandObjectTargetSelect : public CommandObject 306 { 307 public: 308 CommandObjectTargetSelect (CommandInterpreter &interpreter) : 309 CommandObject (interpreter, 310 "target select", 311 "Select a target as the current target by target index.", 312 NULL, 313 0) 314 { 315 } 316 317 virtual 318 ~CommandObjectTargetSelect () 319 { 320 } 321 322 virtual bool 323 Execute (Args& args, CommandReturnObject &result) 324 { 325 if (args.GetArgumentCount() == 1) 326 { 327 bool success = false; 328 const char *target_idx_arg = args.GetArgumentAtIndex(0); 329 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success); 330 if (success) 331 { 332 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList(); 333 const uint32_t num_targets = target_list.GetNumTargets(); 334 if (target_idx < num_targets) 335 { 336 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx)); 337 if (target_sp) 338 { 339 Stream &strm = result.GetOutputStream(); 340 target_list.SetSelectedTarget (target_sp.get()); 341 bool show_stopped_process_status = false; 342 DumpTargetList (target_list, show_stopped_process_status, strm); 343 result.SetStatus (eReturnStatusSuccessFinishResult); 344 } 345 else 346 { 347 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx); 348 result.SetStatus (eReturnStatusFailed); 349 } 350 } 351 else 352 { 353 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n", 354 target_idx, 355 num_targets - 1); 356 result.SetStatus (eReturnStatusFailed); 357 } 358 } 359 else 360 { 361 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg); 362 result.SetStatus (eReturnStatusFailed); 363 } 364 } 365 else 366 { 367 result.AppendError ("'target select' takes a single argument: a target index\n"); 368 result.SetStatus (eReturnStatusFailed); 369 } 370 return result.Succeeded(); 371 } 372 }; 373 374 #pragma mark CommandObjectTargetSelect 375 376 //---------------------------------------------------------------------- 377 // "target delete" 378 //---------------------------------------------------------------------- 379 380 class CommandObjectTargetDelete : public CommandObject 381 { 382 public: 383 CommandObjectTargetDelete (CommandInterpreter &interpreter) : 384 CommandObject (interpreter, 385 "target delete", 386 "Delete one or more targets by target index.", 387 NULL, 388 0), 389 m_option_group (interpreter), 390 m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', 0, eArgTypeNone, "Perform extra cleanup to minimize memory consumption after deleting the target.", false) 391 { 392 m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 393 m_option_group.Finalize(); 394 } 395 396 virtual 397 ~CommandObjectTargetDelete () 398 { 399 } 400 401 virtual bool 402 Execute (Args& args, CommandReturnObject &result) 403 { 404 const size_t argc = args.GetArgumentCount(); 405 std::vector<TargetSP> delete_target_list; 406 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList(); 407 bool success = true; 408 TargetSP target_sp; 409 if (argc > 0) 410 { 411 const uint32_t num_targets = target_list.GetNumTargets(); 412 for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx) 413 { 414 const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx); 415 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success); 416 if (success) 417 { 418 if (target_idx < num_targets) 419 { 420 target_sp = target_list.GetTargetAtIndex (target_idx); 421 if (target_sp) 422 { 423 delete_target_list.push_back (target_sp); 424 continue; 425 } 426 } 427 result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n", 428 target_idx, 429 num_targets - 1); 430 result.SetStatus (eReturnStatusFailed); 431 success = false; 432 } 433 else 434 { 435 result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg); 436 result.SetStatus (eReturnStatusFailed); 437 success = false; 438 } 439 } 440 441 } 442 else 443 { 444 target_sp = target_list.GetSelectedTarget(); 445 if (target_sp) 446 { 447 delete_target_list.push_back (target_sp); 448 } 449 else 450 { 451 result.AppendErrorWithFormat("no target is currently selected\n"); 452 result.SetStatus (eReturnStatusFailed); 453 success = false; 454 } 455 } 456 if (success) 457 { 458 const size_t num_targets_to_delete = delete_target_list.size(); 459 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) 460 { 461 target_sp = delete_target_list[idx]; 462 target_list.DeleteTarget(target_sp); 463 target_sp->Destroy(); 464 } 465 // If "--clean" was specified, prune any orphaned shared modules from 466 // the global shared module list 467 if (m_cleanup_option.GetOptionValue ()) 468 { 469 ModuleList::RemoveOrphanSharedModules(); 470 } 471 result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete); 472 result.SetStatus(eReturnStatusSuccessFinishResult); 473 } 474 475 return result.Succeeded(); 476 } 477 478 Options * 479 GetOptions () 480 { 481 return &m_option_group; 482 } 483 484 protected: 485 OptionGroupOptions m_option_group; 486 OptionGroupBoolean m_cleanup_option; 487 }; 488 489 490 #pragma mark CommandObjectTargetVariable 491 492 //---------------------------------------------------------------------- 493 // "target variable" 494 //---------------------------------------------------------------------- 495 496 class CommandObjectTargetVariable : public CommandObject 497 { 498 public: 499 CommandObjectTargetVariable (CommandInterpreter &interpreter) : 500 CommandObject (interpreter, 501 "target variable", 502 "Read global variable(s) prior to running your binary.", 503 NULL, 504 0), 505 m_option_group (interpreter), 506 m_option_variable (false), // Don't include frame options 507 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."), 508 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."), 509 m_varobj_options() 510 { 511 CommandArgumentEntry arg; 512 CommandArgumentData var_name_arg; 513 514 // Define the first (and only) variant of this arg. 515 var_name_arg.arg_type = eArgTypeVarName; 516 var_name_arg.arg_repetition = eArgRepeatPlus; 517 518 // There is only one variant this argument could be; put it into the argument entry. 519 arg.push_back (var_name_arg); 520 521 // Push the data for the first argument into the m_arguments vector. 522 m_arguments.push_back (arg); 523 524 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 525 m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 526 m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 527 m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 528 m_option_group.Finalize(); 529 } 530 531 virtual 532 ~CommandObjectTargetVariable () 533 { 534 } 535 536 void 537 DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name) 538 { 539 ValueObject::DumpValueObjectOptions options; 540 541 options.SetPointerDepth(m_varobj_options.ptr_depth) 542 .SetMaximumDepth(m_varobj_options.max_depth) 543 .SetShowTypes(m_varobj_options.show_types) 544 .SetShowLocation(m_varobj_options.show_location) 545 .SetUseObjectiveC(m_varobj_options.use_objc) 546 .SetUseDynamicType(m_varobj_options.use_dynamic) 547 .SetUseSyntheticValue((lldb::SyntheticValueType)m_varobj_options.use_synth) 548 .SetFlatOutput(m_varobj_options.flat_output) 549 .SetOmitSummaryDepth(m_varobj_options.no_summary_depth) 550 .SetIgnoreCap(m_varobj_options.ignore_cap); 551 552 if (m_option_variable.format != eFormatDefault) 553 valobj_sp->SetFormat (m_option_variable.format); 554 555 switch (var_sp->GetScope()) 556 { 557 case eValueTypeVariableGlobal: 558 if (m_option_variable.show_scope) 559 s.PutCString("GLOBAL: "); 560 break; 561 562 case eValueTypeVariableStatic: 563 if (m_option_variable.show_scope) 564 s.PutCString("STATIC: "); 565 break; 566 567 case eValueTypeVariableArgument: 568 if (m_option_variable.show_scope) 569 s.PutCString(" ARG: "); 570 break; 571 572 case eValueTypeVariableLocal: 573 if (m_option_variable.show_scope) 574 s.PutCString(" LOCAL: "); 575 break; 576 577 default: 578 break; 579 } 580 581 if (m_option_variable.show_decl) 582 { 583 bool show_fullpaths = false; 584 bool show_module = true; 585 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module)) 586 s.PutCString (": "); 587 } 588 589 const Format format = m_option_variable.format; 590 if (format != eFormatDefault) 591 valobj_sp->SetFormat (format); 592 593 ValueObject::DumpValueObject (s, 594 valobj_sp.get(), 595 root_name, 596 options); 597 598 } 599 600 601 static uint32_t GetVariableCallback (void *baton, 602 const char *name, 603 VariableList &variable_list) 604 { 605 Target *target = static_cast<Target *>(baton); 606 if (target) 607 { 608 return target->GetImages().FindGlobalVariables (ConstString(name), 609 true, 610 UINT32_MAX, 611 variable_list); 612 } 613 return 0; 614 } 615 616 617 618 virtual bool 619 Execute (Args& args, CommandReturnObject &result) 620 { 621 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 622 Target *target = exe_ctx.GetTargetPtr(); 623 if (target) 624 { 625 const size_t argc = args.GetArgumentCount(); 626 if (argc > 0) 627 { 628 Stream &s = result.GetOutputStream(); 629 630 for (size_t idx = 0; idx < argc; ++idx) 631 { 632 VariableList variable_list; 633 ValueObjectList valobj_list; 634 635 const char *arg = args.GetArgumentAtIndex(idx); 636 uint32_t matches = 0; 637 bool use_var_name = false; 638 if (m_option_variable.use_regex) 639 { 640 RegularExpression regex(arg); 641 if (!regex.IsValid ()) 642 { 643 result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg); 644 result.SetStatus (eReturnStatusFailed); 645 return false; 646 } 647 use_var_name = true; 648 matches = target->GetImages().FindGlobalVariables (regex, 649 true, 650 UINT32_MAX, 651 variable_list); 652 } 653 else 654 { 655 Error error (Variable::GetValuesForVariableExpressionPath (arg, 656 exe_ctx.GetBestExecutionContextScope(), 657 GetVariableCallback, 658 target, 659 variable_list, 660 valobj_list)); 661 662 // matches = target->GetImages().FindGlobalVariables (ConstString(arg), 663 // true, 664 // UINT32_MAX, 665 // variable_list); 666 matches = variable_list.GetSize(); 667 } 668 669 if (matches == 0) 670 { 671 result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg); 672 result.SetStatus (eReturnStatusFailed); 673 return false; 674 } 675 else 676 { 677 for (uint32_t global_idx=0; global_idx<matches; ++global_idx) 678 { 679 VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx)); 680 if (var_sp) 681 { 682 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx)); 683 if (!valobj_sp) 684 valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp); 685 686 if (valobj_sp) 687 DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg); 688 } 689 } 690 } 691 } 692 } 693 else 694 { 695 result.AppendError ("'target variable' takes one or more global variable names as arguments\n"); 696 result.SetStatus (eReturnStatusFailed); 697 } 698 } 699 else 700 { 701 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 702 result.SetStatus (eReturnStatusFailed); 703 return false; 704 } 705 706 if (m_interpreter.TruncationWarningNecessary()) 707 { 708 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(), 709 m_cmd_name.c_str()); 710 m_interpreter.TruncationWarningGiven(); 711 } 712 713 return result.Succeeded(); 714 } 715 716 Options * 717 GetOptions () 718 { 719 return &m_option_group; 720 } 721 722 protected: 723 OptionGroupOptions m_option_group; 724 OptionGroupVariable m_option_variable; 725 OptionGroupFileList m_option_compile_units; 726 OptionGroupFileList m_option_shared_libraries; 727 OptionGroupValueObjectDisplay m_varobj_options; 728 729 }; 730 731 732 #pragma mark CommandObjectTargetModulesSearchPathsAdd 733 734 class CommandObjectTargetModulesSearchPathsAdd : public CommandObject 735 { 736 public: 737 738 CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) : 739 CommandObject (interpreter, 740 "target modules search-paths add", 741 "Add new image search paths substitution pairs to the current target.", 742 NULL) 743 { 744 CommandArgumentEntry arg; 745 CommandArgumentData old_prefix_arg; 746 CommandArgumentData new_prefix_arg; 747 748 // Define the first variant of this arg pair. 749 old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 750 old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 751 752 // Define the first variant of this arg pair. 753 new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 754 new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 755 756 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 757 // must always occur together, they are treated as two variants of one argument rather than two independent 758 // arguments. Push them both into the first argument position for m_arguments... 759 760 arg.push_back (old_prefix_arg); 761 arg.push_back (new_prefix_arg); 762 763 m_arguments.push_back (arg); 764 } 765 766 ~CommandObjectTargetModulesSearchPathsAdd () 767 { 768 } 769 770 bool 771 Execute (Args& command, 772 CommandReturnObject &result) 773 { 774 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 775 if (target) 776 { 777 uint32_t argc = command.GetArgumentCount(); 778 if (argc & 1) 779 { 780 result.AppendError ("add requires an even number of arguments\n"); 781 result.SetStatus (eReturnStatusFailed); 782 } 783 else 784 { 785 for (uint32_t i=0; i<argc; i+=2) 786 { 787 const char *from = command.GetArgumentAtIndex(i); 788 const char *to = command.GetArgumentAtIndex(i+1); 789 790 if (from[0] && to[0]) 791 { 792 bool last_pair = ((argc - i) == 2); 793 target->GetImageSearchPathList().Append (ConstString(from), 794 ConstString(to), 795 last_pair); // Notify if this is the last pair 796 result.SetStatus (eReturnStatusSuccessFinishNoResult); 797 } 798 else 799 { 800 if (from[0]) 801 result.AppendError ("<path-prefix> can't be empty\n"); 802 else 803 result.AppendError ("<new-path-prefix> can't be empty\n"); 804 result.SetStatus (eReturnStatusFailed); 805 } 806 } 807 } 808 } 809 else 810 { 811 result.AppendError ("invalid target\n"); 812 result.SetStatus (eReturnStatusFailed); 813 } 814 return result.Succeeded(); 815 } 816 }; 817 818 #pragma mark CommandObjectTargetModulesSearchPathsClear 819 820 class CommandObjectTargetModulesSearchPathsClear : public CommandObject 821 { 822 public: 823 824 CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) : 825 CommandObject (interpreter, 826 "target modules search-paths clear", 827 "Clear all current image search path substitution pairs from the current target.", 828 "target modules search-paths clear") 829 { 830 } 831 832 ~CommandObjectTargetModulesSearchPathsClear () 833 { 834 } 835 836 bool 837 Execute (Args& command, 838 CommandReturnObject &result) 839 { 840 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 841 if (target) 842 { 843 bool notify = true; 844 target->GetImageSearchPathList().Clear(notify); 845 result.SetStatus (eReturnStatusSuccessFinishNoResult); 846 } 847 else 848 { 849 result.AppendError ("invalid target\n"); 850 result.SetStatus (eReturnStatusFailed); 851 } 852 return result.Succeeded(); 853 } 854 }; 855 856 #pragma mark CommandObjectTargetModulesSearchPathsInsert 857 858 class CommandObjectTargetModulesSearchPathsInsert : public CommandObject 859 { 860 public: 861 862 CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) : 863 CommandObject (interpreter, 864 "target modules search-paths insert", 865 "Insert a new image search path substitution pair into the current target at the specified index.", 866 NULL) 867 { 868 CommandArgumentEntry arg1; 869 CommandArgumentEntry arg2; 870 CommandArgumentData index_arg; 871 CommandArgumentData old_prefix_arg; 872 CommandArgumentData new_prefix_arg; 873 874 // Define the first and only variant of this arg. 875 index_arg.arg_type = eArgTypeIndex; 876 index_arg.arg_repetition = eArgRepeatPlain; 877 878 // Put the one and only variant into the first arg for m_arguments: 879 arg1.push_back (index_arg); 880 881 // Define the first variant of this arg pair. 882 old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 883 old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 884 885 // Define the first variant of this arg pair. 886 new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 887 new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 888 889 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 890 // must always occur together, they are treated as two variants of one argument rather than two independent 891 // arguments. Push them both into the same argument position for m_arguments... 892 893 arg2.push_back (old_prefix_arg); 894 arg2.push_back (new_prefix_arg); 895 896 // Add arguments to m_arguments. 897 m_arguments.push_back (arg1); 898 m_arguments.push_back (arg2); 899 } 900 901 ~CommandObjectTargetModulesSearchPathsInsert () 902 { 903 } 904 905 bool 906 Execute (Args& command, 907 CommandReturnObject &result) 908 { 909 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 910 if (target) 911 { 912 uint32_t argc = command.GetArgumentCount(); 913 // check for at least 3 arguments and an odd nubmer of parameters 914 if (argc >= 3 && argc & 1) 915 { 916 bool success = false; 917 918 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success); 919 920 if (!success) 921 { 922 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0)); 923 result.SetStatus (eReturnStatusFailed); 924 return result.Succeeded(); 925 } 926 927 // shift off the index 928 command.Shift(); 929 argc = command.GetArgumentCount(); 930 931 for (uint32_t i=0; i<argc; i+=2, ++insert_idx) 932 { 933 const char *from = command.GetArgumentAtIndex(i); 934 const char *to = command.GetArgumentAtIndex(i+1); 935 936 if (from[0] && to[0]) 937 { 938 bool last_pair = ((argc - i) == 2); 939 target->GetImageSearchPathList().Insert (ConstString(from), 940 ConstString(to), 941 insert_idx, 942 last_pair); 943 result.SetStatus (eReturnStatusSuccessFinishNoResult); 944 } 945 else 946 { 947 if (from[0]) 948 result.AppendError ("<path-prefix> can't be empty\n"); 949 else 950 result.AppendError ("<new-path-prefix> can't be empty\n"); 951 result.SetStatus (eReturnStatusFailed); 952 return false; 953 } 954 } 955 } 956 else 957 { 958 result.AppendError ("insert requires at least three arguments\n"); 959 result.SetStatus (eReturnStatusFailed); 960 return result.Succeeded(); 961 } 962 963 } 964 else 965 { 966 result.AppendError ("invalid target\n"); 967 result.SetStatus (eReturnStatusFailed); 968 } 969 return result.Succeeded(); 970 } 971 }; 972 973 974 #pragma mark CommandObjectTargetModulesSearchPathsList 975 976 977 class CommandObjectTargetModulesSearchPathsList : public CommandObject 978 { 979 public: 980 981 CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) : 982 CommandObject (interpreter, 983 "target modules search-paths list", 984 "List all current image search path substitution pairs in the current target.", 985 "target modules search-paths list") 986 { 987 } 988 989 ~CommandObjectTargetModulesSearchPathsList () 990 { 991 } 992 993 bool 994 Execute (Args& command, 995 CommandReturnObject &result) 996 { 997 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 998 if (target) 999 { 1000 if (command.GetArgumentCount() != 0) 1001 { 1002 result.AppendError ("list takes no arguments\n"); 1003 result.SetStatus (eReturnStatusFailed); 1004 return result.Succeeded(); 1005 } 1006 1007 target->GetImageSearchPathList().Dump(&result.GetOutputStream()); 1008 result.SetStatus (eReturnStatusSuccessFinishResult); 1009 } 1010 else 1011 { 1012 result.AppendError ("invalid target\n"); 1013 result.SetStatus (eReturnStatusFailed); 1014 } 1015 return result.Succeeded(); 1016 } 1017 }; 1018 1019 #pragma mark CommandObjectTargetModulesSearchPathsQuery 1020 1021 class CommandObjectTargetModulesSearchPathsQuery : public CommandObject 1022 { 1023 public: 1024 1025 CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) : 1026 CommandObject (interpreter, 1027 "target modules search-paths query", 1028 "Transform a path using the first applicable image search path.", 1029 NULL) 1030 { 1031 CommandArgumentEntry arg; 1032 CommandArgumentData path_arg; 1033 1034 // Define the first (and only) variant of this arg. 1035 path_arg.arg_type = eArgTypePath; 1036 path_arg.arg_repetition = eArgRepeatPlain; 1037 1038 // There is only one variant this argument could be; put it into the argument entry. 1039 arg.push_back (path_arg); 1040 1041 // Push the data for the first argument into the m_arguments vector. 1042 m_arguments.push_back (arg); 1043 } 1044 1045 ~CommandObjectTargetModulesSearchPathsQuery () 1046 { 1047 } 1048 1049 bool 1050 Execute (Args& command, 1051 CommandReturnObject &result) 1052 { 1053 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1054 if (target) 1055 { 1056 if (command.GetArgumentCount() != 1) 1057 { 1058 result.AppendError ("query requires one argument\n"); 1059 result.SetStatus (eReturnStatusFailed); 1060 return result.Succeeded(); 1061 } 1062 1063 ConstString orig(command.GetArgumentAtIndex(0)); 1064 ConstString transformed; 1065 if (target->GetImageSearchPathList().RemapPath(orig, transformed)) 1066 result.GetOutputStream().Printf("%s\n", transformed.GetCString()); 1067 else 1068 result.GetOutputStream().Printf("%s\n", orig.GetCString()); 1069 1070 result.SetStatus (eReturnStatusSuccessFinishResult); 1071 } 1072 else 1073 { 1074 result.AppendError ("invalid target\n"); 1075 result.SetStatus (eReturnStatusFailed); 1076 } 1077 return result.Succeeded(); 1078 } 1079 }; 1080 1081 //---------------------------------------------------------------------- 1082 // Static Helper functions 1083 //---------------------------------------------------------------------- 1084 static void 1085 DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width) 1086 { 1087 if (module) 1088 { 1089 const char *arch_cstr; 1090 if (full_triple) 1091 arch_cstr = module->GetArchitecture().GetTriple().str().c_str(); 1092 else 1093 arch_cstr = module->GetArchitecture().GetArchitectureName(); 1094 if (width) 1095 strm.Printf("%-*s", width, arch_cstr); 1096 else 1097 strm.PutCString(arch_cstr); 1098 } 1099 } 1100 1101 static void 1102 DumpModuleUUID (Stream &strm, Module *module) 1103 { 1104 if (module->GetUUID().IsValid()) 1105 module->GetUUID().Dump (&strm); 1106 else 1107 strm.PutCString(" "); 1108 } 1109 1110 static uint32_t 1111 DumpCompileUnitLineTable 1112 ( 1113 CommandInterpreter &interpreter, 1114 Stream &strm, 1115 Module *module, 1116 const FileSpec &file_spec, 1117 bool load_addresses 1118 ) 1119 { 1120 uint32_t num_matches = 0; 1121 if (module) 1122 { 1123 SymbolContextList sc_list; 1124 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec, 1125 0, 1126 false, 1127 eSymbolContextCompUnit, 1128 sc_list); 1129 1130 for (uint32_t i=0; i<num_matches; ++i) 1131 { 1132 SymbolContext sc; 1133 if (sc_list.GetContextAtIndex(i, sc)) 1134 { 1135 if (i > 0) 1136 strm << "\n\n"; 1137 1138 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `" 1139 << module->GetFileSpec().GetFilename() << "\n"; 1140 LineTable *line_table = sc.comp_unit->GetLineTable(); 1141 if (line_table) 1142 line_table->GetDescription (&strm, 1143 interpreter.GetExecutionContext().GetTargetPtr(), 1144 lldb::eDescriptionLevelBrief); 1145 else 1146 strm << "No line table"; 1147 } 1148 } 1149 } 1150 return num_matches; 1151 } 1152 1153 static void 1154 DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1155 { 1156 if (file_spec_ptr) 1157 { 1158 if (width > 0) 1159 { 1160 char fullpath[PATH_MAX]; 1161 if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath))) 1162 { 1163 strm.Printf("%-*s", width, fullpath); 1164 return; 1165 } 1166 } 1167 else 1168 { 1169 file_spec_ptr->Dump(&strm); 1170 return; 1171 } 1172 } 1173 // Keep the width spacing correct if things go wrong... 1174 if (width > 0) 1175 strm.Printf("%-*s", width, ""); 1176 } 1177 1178 static void 1179 DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1180 { 1181 if (file_spec_ptr) 1182 { 1183 if (width > 0) 1184 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString("")); 1185 else 1186 file_spec_ptr->GetDirectory().Dump(&strm); 1187 return; 1188 } 1189 // Keep the width spacing correct if things go wrong... 1190 if (width > 0) 1191 strm.Printf("%-*s", width, ""); 1192 } 1193 1194 static void 1195 DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1196 { 1197 if (file_spec_ptr) 1198 { 1199 if (width > 0) 1200 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString("")); 1201 else 1202 file_spec_ptr->GetFilename().Dump(&strm); 1203 return; 1204 } 1205 // Keep the width spacing correct if things go wrong... 1206 if (width > 0) 1207 strm.Printf("%-*s", width, ""); 1208 } 1209 1210 1211 static void 1212 DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order) 1213 { 1214 if (module) 1215 { 1216 ObjectFile *objfile = module->GetObjectFile (); 1217 if (objfile) 1218 { 1219 Symtab *symtab = objfile->GetSymtab(); 1220 if (symtab) 1221 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order); 1222 } 1223 } 1224 } 1225 1226 static void 1227 DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module) 1228 { 1229 if (module) 1230 { 1231 ObjectFile *objfile = module->GetObjectFile (); 1232 if (objfile) 1233 { 1234 SectionList *section_list = objfile->GetSectionList(); 1235 if (section_list) 1236 { 1237 strm.PutCString ("Sections for '"); 1238 strm << module->GetFileSpec(); 1239 if (module->GetObjectName()) 1240 strm << '(' << module->GetObjectName() << ')'; 1241 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName()); 1242 strm.IndentMore(); 1243 section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX); 1244 strm.IndentLess(); 1245 } 1246 } 1247 } 1248 } 1249 1250 static bool 1251 DumpModuleSymbolVendor (Stream &strm, Module *module) 1252 { 1253 if (module) 1254 { 1255 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true); 1256 if (symbol_vendor) 1257 { 1258 symbol_vendor->Dump(&strm); 1259 return true; 1260 } 1261 } 1262 return false; 1263 } 1264 1265 static bool 1266 LookupAddressInModule 1267 ( 1268 CommandInterpreter &interpreter, 1269 Stream &strm, 1270 Module *module, 1271 uint32_t resolve_mask, 1272 lldb::addr_t raw_addr, 1273 lldb::addr_t offset, 1274 bool verbose 1275 ) 1276 { 1277 if (module) 1278 { 1279 lldb::addr_t addr = raw_addr - offset; 1280 Address so_addr; 1281 SymbolContext sc; 1282 Target *target = interpreter.GetExecutionContext().GetTargetPtr(); 1283 if (target && !target->GetSectionLoadList().IsEmpty()) 1284 { 1285 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr)) 1286 return false; 1287 else if (so_addr.GetModule() != module) 1288 return false; 1289 } 1290 else 1291 { 1292 if (!module->ResolveFileAddress (addr, so_addr)) 1293 return false; 1294 } 1295 1296 // If an offset was given, print out the address we ended up looking up 1297 if (offset) 1298 strm.Printf("File Address: 0x%llx\n", addr); 1299 1300 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); 1301 strm.IndentMore(); 1302 strm.Indent (" Address: "); 1303 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset); 1304 strm.EOL(); 1305 strm.Indent (" Summary: "); 1306 const uint32_t save_indent = strm.GetIndentLevel (); 1307 strm.SetIndentLevel (save_indent + 11); 1308 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription); 1309 strm.SetIndentLevel (save_indent); 1310 // Print out detailed address information when verbose is enabled 1311 if (verbose) 1312 { 1313 so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext); 1314 } 1315 strm.IndentLess(); 1316 return true; 1317 } 1318 1319 return false; 1320 } 1321 1322 static uint32_t 1323 LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex) 1324 { 1325 if (module) 1326 { 1327 SymbolContext sc; 1328 1329 ObjectFile *objfile = module->GetObjectFile (); 1330 if (objfile) 1331 { 1332 Symtab *symtab = objfile->GetSymtab(); 1333 if (symtab) 1334 { 1335 uint32_t i; 1336 std::vector<uint32_t> match_indexes; 1337 ConstString symbol_name (name); 1338 uint32_t num_matches = 0; 1339 if (name_is_regex) 1340 { 1341 RegularExpression name_regexp(name); 1342 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp, 1343 eSymbolTypeAny, 1344 match_indexes); 1345 } 1346 else 1347 { 1348 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes); 1349 } 1350 1351 1352 if (num_matches > 0) 1353 { 1354 strm.Indent (); 1355 strm.Printf("%u symbols match %s'%s' in ", num_matches, 1356 name_is_regex ? "the regular expression " : "", name); 1357 DumpFullpath (strm, &module->GetFileSpec(), 0); 1358 strm.PutCString(":\n"); 1359 strm.IndentMore (); 1360 Symtab::DumpSymbolHeader (&strm); 1361 for (i=0; i < num_matches; ++i) 1362 { 1363 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); 1364 strm.Indent (); 1365 symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i); 1366 } 1367 strm.IndentLess (); 1368 return num_matches; 1369 } 1370 } 1371 } 1372 } 1373 return 0; 1374 } 1375 1376 1377 static void 1378 DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr, bool verbose) 1379 { 1380 strm.IndentMore (); 1381 uint32_t i; 1382 const uint32_t num_matches = sc_list.GetSize(); 1383 1384 for (i=0; i<num_matches; ++i) 1385 { 1386 SymbolContext sc; 1387 if (sc_list.GetContextAtIndex(i, sc)) 1388 { 1389 strm.Indent(); 1390 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope (); 1391 1392 if (prepend_addr) 1393 { 1394 if (sc.line_entry.range.GetBaseAddress().IsValid()) 1395 { 1396 sc.line_entry.range.GetBaseAddress().Dump (&strm, 1397 exe_scope, 1398 Address::DumpStyleLoadAddress, 1399 Address::DumpStyleModuleWithFileAddress); 1400 strm.PutCString(" in "); 1401 } 1402 } 1403 sc.DumpStopContext(&strm, 1404 exe_scope, 1405 sc.line_entry.range.GetBaseAddress(), 1406 true, 1407 true, 1408 false); 1409 strm.EOL(); 1410 if (verbose) 1411 { 1412 if (sc.line_entry.range.GetBaseAddress().IsValid()) 1413 { 1414 if (sc.line_entry.range.GetBaseAddress().Dump (&strm, 1415 exe_scope, 1416 Address::DumpStyleDetailedSymbolContext)) 1417 strm.PutCString("\n\n"); 1418 } 1419 else if (sc.function->GetAddressRange().GetBaseAddress().IsValid()) 1420 { 1421 if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm, 1422 exe_scope, 1423 Address::DumpStyleDetailedSymbolContext)) 1424 strm.PutCString("\n\n"); 1425 } 1426 } 1427 } 1428 } 1429 strm.IndentLess (); 1430 } 1431 1432 static uint32_t 1433 LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose) 1434 { 1435 if (module && name && name[0]) 1436 { 1437 SymbolContextList sc_list; 1438 const bool include_symbols = false; 1439 const bool append = true; 1440 uint32_t num_matches = 0; 1441 if (name_is_regex) 1442 { 1443 RegularExpression function_name_regex (name); 1444 num_matches = module->FindFunctions (function_name_regex, 1445 include_symbols, 1446 append, 1447 sc_list); 1448 } 1449 else 1450 { 1451 ConstString function_name (name); 1452 num_matches = module->FindFunctions (function_name, 1453 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, 1454 include_symbols, 1455 append, 1456 sc_list); 1457 } 1458 1459 if (num_matches) 1460 { 1461 strm.Indent (); 1462 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1463 DumpFullpath (strm, &module->GetFileSpec(), 0); 1464 strm.PutCString(":\n"); 1465 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); 1466 } 1467 return num_matches; 1468 } 1469 return 0; 1470 } 1471 1472 static uint32_t 1473 LookupTypeInModule (CommandInterpreter &interpreter, 1474 Stream &strm, 1475 Module *module, 1476 const char *name_cstr, 1477 bool name_is_regex) 1478 { 1479 if (module && name_cstr && name_cstr[0]) 1480 { 1481 /*SymbolContextList sc_list; 1482 1483 SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 1484 if (symbol_vendor) 1485 {*/ 1486 TypeList type_list; 1487 uint32_t num_matches = 0; 1488 SymbolContext sc; 1489 // if (name_is_regex) 1490 // { 1491 // RegularExpression name_regex (name_cstr); 1492 // num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list); 1493 // } 1494 // else 1495 // { 1496 ConstString name(name_cstr); 1497 num_matches = module->FindTypes(sc, name, true, UINT32_MAX, type_list); 1498 // } 1499 1500 if (num_matches) 1501 { 1502 strm.Indent (); 1503 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1504 DumpFullpath (strm, &module->GetFileSpec(), 0); 1505 strm.PutCString(":\n"); 1506 const uint32_t num_types = type_list.GetSize(); 1507 for (uint32_t i=0; i<num_types; ++i) 1508 { 1509 TypeSP type_sp (type_list.GetTypeAtIndex(i)); 1510 if (type_sp) 1511 { 1512 // Resolve the clang type so that any forward references 1513 // to types that haven't yet been parsed will get parsed. 1514 type_sp->GetClangFullType (); 1515 type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1516 } 1517 strm.EOL(); 1518 } 1519 } 1520 return num_matches; 1521 //} 1522 } 1523 return 0; 1524 } 1525 1526 static uint32_t 1527 LookupFileAndLineInModule (CommandInterpreter &interpreter, 1528 Stream &strm, 1529 Module *module, 1530 const FileSpec &file_spec, 1531 uint32_t line, 1532 bool check_inlines, 1533 bool verbose) 1534 { 1535 if (module && file_spec) 1536 { 1537 SymbolContextList sc_list; 1538 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, 1539 eSymbolContextEverything, sc_list); 1540 if (num_matches > 0) 1541 { 1542 strm.Indent (); 1543 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1544 strm << file_spec; 1545 if (line > 0) 1546 strm.Printf (":%u", line); 1547 strm << " in "; 1548 DumpFullpath (strm, &module->GetFileSpec(), 0); 1549 strm.PutCString(":\n"); 1550 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); 1551 return num_matches; 1552 } 1553 } 1554 return 0; 1555 1556 } 1557 1558 #pragma mark CommandObjectTargetModulesModuleAutoComplete 1559 1560 //---------------------------------------------------------------------- 1561 // A base command object class that can auto complete with module file 1562 // paths 1563 //---------------------------------------------------------------------- 1564 1565 class CommandObjectTargetModulesModuleAutoComplete : public CommandObject 1566 { 1567 public: 1568 1569 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter, 1570 const char *name, 1571 const char *help, 1572 const char *syntax) : 1573 CommandObject (interpreter, name, help, syntax) 1574 { 1575 CommandArgumentEntry arg; 1576 CommandArgumentData file_arg; 1577 1578 // Define the first (and only) variant of this arg. 1579 file_arg.arg_type = eArgTypeFilename; 1580 file_arg.arg_repetition = eArgRepeatStar; 1581 1582 // There is only one variant this argument could be; put it into the argument entry. 1583 arg.push_back (file_arg); 1584 1585 // Push the data for the first argument into the m_arguments vector. 1586 m_arguments.push_back (arg); 1587 } 1588 1589 virtual 1590 ~CommandObjectTargetModulesModuleAutoComplete () 1591 { 1592 } 1593 1594 virtual int 1595 HandleArgumentCompletion (Args &input, 1596 int &cursor_index, 1597 int &cursor_char_position, 1598 OptionElementVector &opt_element_vector, 1599 int match_start_point, 1600 int max_return_elements, 1601 bool &word_complete, 1602 StringList &matches) 1603 { 1604 // Arguments are the standard module completer. 1605 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1606 completion_str.erase (cursor_char_position); 1607 1608 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1609 CommandCompletions::eModuleCompletion, 1610 completion_str.c_str(), 1611 match_start_point, 1612 max_return_elements, 1613 NULL, 1614 word_complete, 1615 matches); 1616 return matches.GetSize(); 1617 } 1618 }; 1619 1620 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete 1621 1622 //---------------------------------------------------------------------- 1623 // A base command object class that can auto complete with module source 1624 // file paths 1625 //---------------------------------------------------------------------- 1626 1627 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObject 1628 { 1629 public: 1630 1631 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, 1632 const char *name, 1633 const char *help, 1634 const char *syntax) : 1635 CommandObject (interpreter, name, help, syntax) 1636 { 1637 CommandArgumentEntry arg; 1638 CommandArgumentData source_file_arg; 1639 1640 // Define the first (and only) variant of this arg. 1641 source_file_arg.arg_type = eArgTypeSourceFile; 1642 source_file_arg.arg_repetition = eArgRepeatPlus; 1643 1644 // There is only one variant this argument could be; put it into the argument entry. 1645 arg.push_back (source_file_arg); 1646 1647 // Push the data for the first argument into the m_arguments vector. 1648 m_arguments.push_back (arg); 1649 } 1650 1651 virtual 1652 ~CommandObjectTargetModulesSourceFileAutoComplete () 1653 { 1654 } 1655 1656 virtual int 1657 HandleArgumentCompletion (Args &input, 1658 int &cursor_index, 1659 int &cursor_char_position, 1660 OptionElementVector &opt_element_vector, 1661 int match_start_point, 1662 int max_return_elements, 1663 bool &word_complete, 1664 StringList &matches) 1665 { 1666 // Arguments are the standard source file completer. 1667 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1668 completion_str.erase (cursor_char_position); 1669 1670 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1671 CommandCompletions::eSourceFileCompletion, 1672 completion_str.c_str(), 1673 match_start_point, 1674 max_return_elements, 1675 NULL, 1676 word_complete, 1677 matches); 1678 return matches.GetSize(); 1679 } 1680 }; 1681 1682 1683 #pragma mark CommandObjectTargetModulesDumpSymtab 1684 1685 1686 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete 1687 { 1688 public: 1689 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) : 1690 CommandObjectTargetModulesModuleAutoComplete (interpreter, 1691 "target modules dump symtab", 1692 "Dump the symbol table from one or more target modules.", 1693 NULL), 1694 m_options (interpreter) 1695 { 1696 } 1697 1698 virtual 1699 ~CommandObjectTargetModulesDumpSymtab () 1700 { 1701 } 1702 1703 virtual bool 1704 Execute (Args& command, 1705 CommandReturnObject &result) 1706 { 1707 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1708 if (target == NULL) 1709 { 1710 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 1711 result.SetStatus (eReturnStatusFailed); 1712 return false; 1713 } 1714 else 1715 { 1716 uint32_t num_dumped = 0; 1717 1718 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 1719 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 1720 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 1721 1722 if (command.GetArgumentCount() == 0) 1723 { 1724 // Dump all sections for all modules images 1725 const uint32_t num_modules = target->GetImages().GetSize(); 1726 if (num_modules > 0) 1727 { 1728 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules); 1729 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 1730 { 1731 if (num_dumped > 0) 1732 { 1733 result.GetOutputStream().EOL(); 1734 result.GetOutputStream().EOL(); 1735 } 1736 num_dumped++; 1737 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order); 1738 } 1739 } 1740 else 1741 { 1742 result.AppendError ("the target has no associated executable images"); 1743 result.SetStatus (eReturnStatusFailed); 1744 return false; 1745 } 1746 } 1747 else 1748 { 1749 // Dump specified images (by basename or fullpath) 1750 const char *arg_cstr; 1751 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 1752 { 1753 FileSpec image_file(arg_cstr, false); 1754 ModuleList matching_modules; 1755 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); 1756 1757 // Not found in our module list for our target, check the main 1758 // shared module list in case it is a extra file used somewhere 1759 // else 1760 if (num_matching_modules == 0) 1761 num_matching_modules = ModuleList::FindSharedModules (image_file, 1762 target->GetArchitecture(), 1763 NULL, 1764 NULL, 1765 matching_modules); 1766 1767 if (num_matching_modules > 0) 1768 { 1769 for (size_t i=0; i<num_matching_modules; ++i) 1770 { 1771 Module *image_module = matching_modules.GetModulePointerAtIndex(i); 1772 if (image_module) 1773 { 1774 if (num_dumped > 0) 1775 { 1776 result.GetOutputStream().EOL(); 1777 result.GetOutputStream().EOL(); 1778 } 1779 num_dumped++; 1780 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order); 1781 } 1782 } 1783 } 1784 else 1785 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 1786 } 1787 } 1788 1789 if (num_dumped > 0) 1790 result.SetStatus (eReturnStatusSuccessFinishResult); 1791 else 1792 { 1793 result.AppendError ("no matching executable images found"); 1794 result.SetStatus (eReturnStatusFailed); 1795 } 1796 } 1797 return result.Succeeded(); 1798 } 1799 1800 virtual Options * 1801 GetOptions () 1802 { 1803 return &m_options; 1804 } 1805 1806 class CommandOptions : public Options 1807 { 1808 public: 1809 1810 CommandOptions (CommandInterpreter &interpreter) : 1811 Options(interpreter), 1812 m_sort_order (eSortOrderNone) 1813 { 1814 } 1815 1816 virtual 1817 ~CommandOptions () 1818 { 1819 } 1820 1821 virtual Error 1822 SetOptionValue (uint32_t option_idx, const char *option_arg) 1823 { 1824 Error error; 1825 char short_option = (char) m_getopt_table[option_idx].val; 1826 1827 switch (short_option) 1828 { 1829 case 's': 1830 { 1831 bool found_one = false; 1832 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg, 1833 g_option_table[option_idx].enum_values, 1834 eSortOrderNone, 1835 &found_one); 1836 if (!found_one) 1837 error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n", 1838 option_arg, 1839 short_option); 1840 } 1841 break; 1842 1843 default: 1844 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 1845 break; 1846 1847 } 1848 return error; 1849 } 1850 1851 void 1852 OptionParsingStarting () 1853 { 1854 m_sort_order = eSortOrderNone; 1855 } 1856 1857 const OptionDefinition* 1858 GetDefinitions () 1859 { 1860 return g_option_table; 1861 } 1862 1863 // Options table: Required for subclasses of Options. 1864 static OptionDefinition g_option_table[]; 1865 1866 SortOrder m_sort_order; 1867 }; 1868 1869 protected: 1870 1871 CommandOptions m_options; 1872 }; 1873 1874 static OptionEnumValueElement 1875 g_sort_option_enumeration[4] = 1876 { 1877 { eSortOrderNone, "none", "No sorting, use the original symbol table order."}, 1878 { eSortOrderByAddress, "address", "Sort output by symbol address."}, 1879 { eSortOrderByName, "name", "Sort output by symbol name."}, 1880 { 0, NULL, NULL } 1881 }; 1882 1883 1884 OptionDefinition 1885 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] = 1886 { 1887 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."}, 1888 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1889 }; 1890 1891 #pragma mark CommandObjectTargetModulesDumpSections 1892 1893 //---------------------------------------------------------------------- 1894 // Image section dumping command 1895 //---------------------------------------------------------------------- 1896 1897 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete 1898 { 1899 public: 1900 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) : 1901 CommandObjectTargetModulesModuleAutoComplete (interpreter, 1902 "target modules dump sections", 1903 "Dump the sections from one or more target modules.", 1904 //"target modules dump sections [<file1> ...]") 1905 NULL) 1906 { 1907 } 1908 1909 virtual 1910 ~CommandObjectTargetModulesDumpSections () 1911 { 1912 } 1913 1914 virtual bool 1915 Execute (Args& command, 1916 CommandReturnObject &result) 1917 { 1918 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1919 if (target == NULL) 1920 { 1921 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 1922 result.SetStatus (eReturnStatusFailed); 1923 return false; 1924 } 1925 else 1926 { 1927 uint32_t num_dumped = 0; 1928 1929 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 1930 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 1931 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 1932 1933 if (command.GetArgumentCount() == 0) 1934 { 1935 // Dump all sections for all modules images 1936 const uint32_t num_modules = target->GetImages().GetSize(); 1937 if (num_modules > 0) 1938 { 1939 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules); 1940 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 1941 { 1942 num_dumped++; 1943 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)); 1944 } 1945 } 1946 else 1947 { 1948 result.AppendError ("the target has no associated executable images"); 1949 result.SetStatus (eReturnStatusFailed); 1950 return false; 1951 } 1952 } 1953 else 1954 { 1955 // Dump specified images (by basename or fullpath) 1956 const char *arg_cstr; 1957 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 1958 { 1959 FileSpec image_file(arg_cstr, false); 1960 ModuleList matching_modules; 1961 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); 1962 1963 // Not found in our module list for our target, check the main 1964 // shared module list in case it is a extra file used somewhere 1965 // else 1966 if (num_matching_modules == 0) 1967 num_matching_modules = ModuleList::FindSharedModules (image_file, 1968 target->GetArchitecture(), 1969 NULL, 1970 NULL, 1971 matching_modules); 1972 1973 if (num_matching_modules > 0) 1974 { 1975 for (size_t i=0; i<num_matching_modules; ++i) 1976 { 1977 Module * image_module = matching_modules.GetModulePointerAtIndex(i); 1978 if (image_module) 1979 { 1980 num_dumped++; 1981 DumpModuleSections (m_interpreter, result.GetOutputStream(), image_module); 1982 } 1983 } 1984 } 1985 else 1986 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 1987 } 1988 } 1989 1990 if (num_dumped > 0) 1991 result.SetStatus (eReturnStatusSuccessFinishResult); 1992 else 1993 { 1994 result.AppendError ("no matching executable images found"); 1995 result.SetStatus (eReturnStatusFailed); 1996 } 1997 } 1998 return result.Succeeded(); 1999 } 2000 }; 2001 2002 2003 #pragma mark CommandObjectTargetModulesDumpSymfile 2004 2005 //---------------------------------------------------------------------- 2006 // Image debug symbol dumping command 2007 //---------------------------------------------------------------------- 2008 2009 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete 2010 { 2011 public: 2012 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) : 2013 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2014 "target modules dump symfile", 2015 "Dump the debug symbol file for one or more target modules.", 2016 //"target modules dump symfile [<file1> ...]") 2017 NULL) 2018 { 2019 } 2020 2021 virtual 2022 ~CommandObjectTargetModulesDumpSymfile () 2023 { 2024 } 2025 2026 virtual bool 2027 Execute (Args& command, 2028 CommandReturnObject &result) 2029 { 2030 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2031 if (target == NULL) 2032 { 2033 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2034 result.SetStatus (eReturnStatusFailed); 2035 return false; 2036 } 2037 else 2038 { 2039 uint32_t num_dumped = 0; 2040 2041 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2042 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2043 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2044 2045 if (command.GetArgumentCount() == 0) 2046 { 2047 // Dump all sections for all modules images 2048 const uint32_t num_modules = target->GetImages().GetSize(); 2049 if (num_modules > 0) 2050 { 2051 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules); 2052 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2053 { 2054 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx))) 2055 num_dumped++; 2056 } 2057 } 2058 else 2059 { 2060 result.AppendError ("the target has no associated executable images"); 2061 result.SetStatus (eReturnStatusFailed); 2062 return false; 2063 } 2064 } 2065 else 2066 { 2067 // Dump specified images (by basename or fullpath) 2068 const char *arg_cstr; 2069 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2070 { 2071 FileSpec image_file(arg_cstr, false); 2072 ModuleList matching_modules; 2073 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); 2074 2075 // Not found in our module list for our target, check the main 2076 // shared module list in case it is a extra file used somewhere 2077 // else 2078 if (num_matching_modules == 0) 2079 num_matching_modules = ModuleList::FindSharedModules (image_file, 2080 target->GetArchitecture(), 2081 NULL, 2082 NULL, 2083 matching_modules); 2084 2085 if (num_matching_modules > 0) 2086 { 2087 for (size_t i=0; i<num_matching_modules; ++i) 2088 { 2089 Module * image_module = matching_modules.GetModulePointerAtIndex(i); 2090 if (image_module) 2091 { 2092 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module)) 2093 num_dumped++; 2094 } 2095 } 2096 } 2097 else 2098 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2099 } 2100 } 2101 2102 if (num_dumped > 0) 2103 result.SetStatus (eReturnStatusSuccessFinishResult); 2104 else 2105 { 2106 result.AppendError ("no matching executable images found"); 2107 result.SetStatus (eReturnStatusFailed); 2108 } 2109 } 2110 return result.Succeeded(); 2111 } 2112 }; 2113 2114 2115 #pragma mark CommandObjectTargetModulesDumpLineTable 2116 2117 //---------------------------------------------------------------------- 2118 // Image debug line table dumping command 2119 //---------------------------------------------------------------------- 2120 2121 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete 2122 { 2123 public: 2124 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) : 2125 CommandObjectTargetModulesSourceFileAutoComplete (interpreter, 2126 "target modules dump line-table", 2127 "Dump the debug symbol file for one or more target modules.", 2128 NULL) 2129 { 2130 } 2131 2132 virtual 2133 ~CommandObjectTargetModulesDumpLineTable () 2134 { 2135 } 2136 2137 virtual bool 2138 Execute (Args& command, 2139 CommandReturnObject &result) 2140 { 2141 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2142 if (target == NULL) 2143 { 2144 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2145 result.SetStatus (eReturnStatusFailed); 2146 return false; 2147 } 2148 else 2149 { 2150 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 2151 uint32_t total_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 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); 2160 result.SetStatus (eReturnStatusFailed); 2161 } 2162 else 2163 { 2164 // Dump specified images (by basename or fullpath) 2165 const char *arg_cstr; 2166 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2167 { 2168 FileSpec file_spec(arg_cstr, false); 2169 const uint32_t num_modules = target->GetImages().GetSize(); 2170 if (num_modules > 0) 2171 { 2172 uint32_t num_dumped = 0; 2173 for (uint32_t i = 0; i<num_modules; ++i) 2174 { 2175 if (DumpCompileUnitLineTable (m_interpreter, 2176 result.GetOutputStream(), 2177 target->GetImages().GetModulePointerAtIndex(i), 2178 file_spec, 2179 exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive())) 2180 num_dumped++; 2181 } 2182 if (num_dumped == 0) 2183 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); 2184 else 2185 total_num_dumped += num_dumped; 2186 } 2187 } 2188 } 2189 2190 if (total_num_dumped > 0) 2191 result.SetStatus (eReturnStatusSuccessFinishResult); 2192 else 2193 { 2194 result.AppendError ("no source filenames matched any command arguments"); 2195 result.SetStatus (eReturnStatusFailed); 2196 } 2197 } 2198 return result.Succeeded(); 2199 } 2200 }; 2201 2202 2203 #pragma mark CommandObjectTargetModulesDump 2204 2205 //---------------------------------------------------------------------- 2206 // Dump multi-word command for target modules 2207 //---------------------------------------------------------------------- 2208 2209 class CommandObjectTargetModulesDump : public CommandObjectMultiword 2210 { 2211 public: 2212 2213 //------------------------------------------------------------------ 2214 // Constructors and Destructors 2215 //------------------------------------------------------------------ 2216 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) : 2217 CommandObjectMultiword (interpreter, 2218 "target modules dump", 2219 "A set of commands for dumping information about one or more target modules.", 2220 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]") 2221 { 2222 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter))); 2223 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter))); 2224 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter))); 2225 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter))); 2226 } 2227 2228 virtual 2229 ~CommandObjectTargetModulesDump() 2230 { 2231 } 2232 }; 2233 2234 class CommandObjectTargetModulesAdd : public CommandObject 2235 { 2236 public: 2237 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) : 2238 CommandObject (interpreter, 2239 "target modules add", 2240 "Add a new module to the current target's modules.", 2241 "target modules add [<module>]") 2242 { 2243 } 2244 2245 virtual 2246 ~CommandObjectTargetModulesAdd () 2247 { 2248 } 2249 2250 virtual bool 2251 Execute (Args& args, 2252 CommandReturnObject &result) 2253 { 2254 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2255 if (target == NULL) 2256 { 2257 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2258 result.SetStatus (eReturnStatusFailed); 2259 return false; 2260 } 2261 else 2262 { 2263 const size_t argc = args.GetArgumentCount(); 2264 if (argc == 0) 2265 { 2266 result.AppendError ("one or more executable image paths must be specified"); 2267 result.SetStatus (eReturnStatusFailed); 2268 return false; 2269 } 2270 else 2271 { 2272 for (size_t i=0; i<argc; ++i) 2273 { 2274 const char *path = args.GetArgumentAtIndex(i); 2275 if (path) 2276 { 2277 FileSpec file_spec(path, true); 2278 ArchSpec arch; 2279 if (file_spec.Exists()) 2280 { 2281 ModuleSP module_sp (target->GetSharedModule(file_spec, arch)); 2282 if (!module_sp) 2283 { 2284 result.AppendError ("one or more executable image paths must be specified"); 2285 result.SetStatus (eReturnStatusFailed); 2286 return false; 2287 } 2288 result.SetStatus (eReturnStatusSuccessFinishResult); 2289 } 2290 else 2291 { 2292 char resolved_path[PATH_MAX]; 2293 result.SetStatus (eReturnStatusFailed); 2294 if (file_spec.GetPath (resolved_path, sizeof(resolved_path))) 2295 { 2296 if (strcmp (resolved_path, path) != 0) 2297 { 2298 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path); 2299 break; 2300 } 2301 } 2302 result.AppendErrorWithFormat ("invalid module path '%s'\n", path); 2303 break; 2304 } 2305 } 2306 } 2307 } 2308 } 2309 return result.Succeeded(); 2310 } 2311 2312 int 2313 HandleArgumentCompletion (Args &input, 2314 int &cursor_index, 2315 int &cursor_char_position, 2316 OptionElementVector &opt_element_vector, 2317 int match_start_point, 2318 int max_return_elements, 2319 bool &word_complete, 2320 StringList &matches) 2321 { 2322 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2323 completion_str.erase (cursor_char_position); 2324 2325 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2326 CommandCompletions::eDiskFileCompletion, 2327 completion_str.c_str(), 2328 match_start_point, 2329 max_return_elements, 2330 NULL, 2331 word_complete, 2332 matches); 2333 return matches.GetSize(); 2334 } 2335 2336 }; 2337 2338 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete 2339 { 2340 public: 2341 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) : 2342 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2343 "target modules load", 2344 "Set the load addresses for one or more sections in a target module.", 2345 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"), 2346 m_option_group (interpreter), 2347 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."), 2348 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) 2349 { 2350 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2351 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2352 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2353 m_option_group.Finalize(); 2354 } 2355 2356 virtual 2357 ~CommandObjectTargetModulesLoad () 2358 { 2359 } 2360 2361 virtual bool 2362 Execute (Args& args, 2363 CommandReturnObject &result) 2364 { 2365 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2366 if (target == NULL) 2367 { 2368 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2369 result.SetStatus (eReturnStatusFailed); 2370 return false; 2371 } 2372 else 2373 { 2374 const size_t argc = args.GetArgumentCount(); 2375 const FileSpec *file_ptr = NULL; 2376 const UUID *uuid_ptr = NULL; 2377 if (m_file_option.GetOptionValue().OptionWasSet()) 2378 file_ptr = &m_file_option.GetOptionValue().GetCurrentValue(); 2379 2380 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2381 uuid_ptr = &m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2382 2383 if (file_ptr || uuid_ptr) 2384 { 2385 2386 ModuleList matching_modules; 2387 const size_t num_matches = target->GetImages().FindModules (file_ptr, // File spec to match (can be NULL to match by UUID only) 2388 NULL, // Architecture 2389 uuid_ptr, // UUID to match (can be NULL to not match on UUID) 2390 NULL, // Object name 2391 matching_modules); 2392 2393 char path[PATH_MAX]; 2394 if (num_matches == 1) 2395 { 2396 Module *module = matching_modules.GetModulePointerAtIndex(0); 2397 if (module) 2398 { 2399 ObjectFile *objfile = module->GetObjectFile(); 2400 if (objfile) 2401 { 2402 SectionList *section_list = objfile->GetSectionList(); 2403 if (section_list) 2404 { 2405 if (argc == 0) 2406 { 2407 if (m_slide_option.GetOptionValue().OptionWasSet()) 2408 { 2409 Module *module = matching_modules.GetModulePointerAtIndex(0); 2410 if (module) 2411 { 2412 ObjectFile *objfile = module->GetObjectFile(); 2413 if (objfile) 2414 { 2415 SectionList *section_list = objfile->GetSectionList(); 2416 if (section_list) 2417 { 2418 const size_t num_sections = section_list->GetSize(); 2419 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue(); 2420 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) 2421 { 2422 SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx)); 2423 if (section_sp) 2424 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide); 2425 } 2426 } 2427 } 2428 } 2429 } 2430 else 2431 { 2432 result.AppendError ("one or more section name + load address pair must be specified"); 2433 result.SetStatus (eReturnStatusFailed); 2434 return false; 2435 } 2436 } 2437 else 2438 { 2439 if (m_slide_option.GetOptionValue().OptionWasSet()) 2440 { 2441 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n"); 2442 result.SetStatus (eReturnStatusFailed); 2443 return false; 2444 } 2445 2446 for (size_t i=0; i<argc; i += 2) 2447 { 2448 const char *sect_name = args.GetArgumentAtIndex(i); 2449 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1); 2450 if (sect_name && load_addr_cstr) 2451 { 2452 ConstString const_sect_name(sect_name); 2453 bool success = false; 2454 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); 2455 if (success) 2456 { 2457 SectionSP section_sp (section_list->FindSectionByName(const_sect_name)); 2458 if (section_sp) 2459 { 2460 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), load_addr); 2461 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr); 2462 } 2463 else 2464 { 2465 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name); 2466 result.SetStatus (eReturnStatusFailed); 2467 break; 2468 } 2469 } 2470 else 2471 { 2472 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr); 2473 result.SetStatus (eReturnStatusFailed); 2474 break; 2475 } 2476 } 2477 else 2478 { 2479 if (sect_name) 2480 result.AppendError ("section names must be followed by a load address.\n"); 2481 else 2482 result.AppendError ("one or more section name + load address pair must be specified.\n"); 2483 result.SetStatus (eReturnStatusFailed); 2484 break; 2485 } 2486 } 2487 } 2488 } 2489 else 2490 { 2491 module->GetFileSpec().GetPath (path, sizeof(path)); 2492 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path); 2493 result.SetStatus (eReturnStatusFailed); 2494 } 2495 } 2496 else 2497 { 2498 module->GetFileSpec().GetPath (path, sizeof(path)); 2499 result.AppendErrorWithFormat ("no object file for module '%s'\n", path); 2500 result.SetStatus (eReturnStatusFailed); 2501 } 2502 } 2503 else 2504 { 2505 module->GetFileSpec().GetPath (path, sizeof(path)); 2506 result.AppendErrorWithFormat ("invalid module '%s'.\n", path); 2507 result.SetStatus (eReturnStatusFailed); 2508 } 2509 } 2510 else 2511 { 2512 char uuid_cstr[64]; 2513 if (file_ptr) 2514 file_ptr->GetPath (path, sizeof(path)); 2515 else 2516 path[0] = '\0'; 2517 2518 if (uuid_ptr) 2519 uuid_ptr->GetAsCString(uuid_cstr, sizeof(uuid_cstr)); 2520 else 2521 uuid_cstr[0] = '\0'; 2522 if (num_matches > 1) 2523 { 2524 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", 2525 path[0] ? " file=" : "", 2526 path, 2527 uuid_cstr[0] ? " uuid=" : "", 2528 uuid_cstr); 2529 for (size_t i=0; i<num_matches; ++i) 2530 { 2531 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path))) 2532 result.AppendMessageWithFormat("%s\n", path); 2533 } 2534 } 2535 else 2536 { 2537 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n", 2538 path[0] ? " file=" : "", 2539 path, 2540 uuid_cstr[0] ? " uuid=" : "", 2541 uuid_cstr); 2542 } 2543 result.SetStatus (eReturnStatusFailed); 2544 } 2545 } 2546 else 2547 { 2548 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n"); 2549 result.SetStatus (eReturnStatusFailed); 2550 return false; 2551 } 2552 } 2553 return result.Succeeded(); 2554 } 2555 2556 virtual Options * 2557 GetOptions () 2558 { 2559 return &m_option_group; 2560 } 2561 2562 protected: 2563 OptionGroupOptions m_option_group; 2564 OptionGroupUUID m_uuid_option_group; 2565 OptionGroupFile m_file_option; 2566 OptionGroupUInt64 m_slide_option; 2567 }; 2568 2569 //---------------------------------------------------------------------- 2570 // List images with associated information 2571 //---------------------------------------------------------------------- 2572 class CommandObjectTargetModulesList : public CommandObject 2573 { 2574 public: 2575 2576 class CommandOptions : public Options 2577 { 2578 public: 2579 2580 CommandOptions (CommandInterpreter &interpreter) : 2581 Options(interpreter), 2582 m_format_array() 2583 { 2584 } 2585 2586 virtual 2587 ~CommandOptions () 2588 { 2589 } 2590 2591 virtual Error 2592 SetOptionValue (uint32_t option_idx, const char *option_arg) 2593 { 2594 char short_option = (char) m_getopt_table[option_idx].val; 2595 if (short_option == 'g') 2596 { 2597 m_use_global_module_list = true; 2598 } 2599 else 2600 { 2601 uint32_t width = 0; 2602 if (option_arg) 2603 width = strtoul (option_arg, NULL, 0); 2604 m_format_array.push_back(std::make_pair(short_option, width)); 2605 } 2606 Error error; 2607 return error; 2608 } 2609 2610 void 2611 OptionParsingStarting () 2612 { 2613 m_format_array.clear(); 2614 m_use_global_module_list = false; 2615 } 2616 2617 const OptionDefinition* 2618 GetDefinitions () 2619 { 2620 return g_option_table; 2621 } 2622 2623 // Options table: Required for subclasses of Options. 2624 2625 static OptionDefinition g_option_table[]; 2626 2627 // Instance variables to hold the values for command options. 2628 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection; 2629 FormatWidthCollection m_format_array; 2630 bool m_use_global_module_list; 2631 }; 2632 2633 CommandObjectTargetModulesList (CommandInterpreter &interpreter) : 2634 CommandObject (interpreter, 2635 "target modules list", 2636 "List current executable and dependent shared library images.", 2637 "target modules list [<cmd-options>]"), 2638 m_options (interpreter) 2639 { 2640 } 2641 2642 virtual 2643 ~CommandObjectTargetModulesList () 2644 { 2645 } 2646 2647 virtual 2648 Options * 2649 GetOptions () 2650 { 2651 return &m_options; 2652 } 2653 2654 virtual bool 2655 Execute (Args& command, 2656 CommandReturnObject &result) 2657 { 2658 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2659 const bool use_global_module_list = m_options.m_use_global_module_list; 2660 if (target == NULL && use_global_module_list == false) 2661 { 2662 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2663 result.SetStatus (eReturnStatusFailed); 2664 return false; 2665 } 2666 else 2667 { 2668 if (target) 2669 { 2670 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2671 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2672 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2673 } 2674 // Dump all sections for all modules images 2675 uint32_t num_modules = 0; 2676 Mutex::Locker locker; 2677 if (use_global_module_list) 2678 { 2679 locker.Reset (Module::GetAllocationModuleCollectionMutex().GetMutex()); 2680 num_modules = Module::GetNumberAllocatedModules(); 2681 } 2682 else 2683 num_modules = target->GetImages().GetSize(); 2684 2685 if (num_modules > 0) 2686 { 2687 Stream &strm = result.GetOutputStream(); 2688 2689 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2690 { 2691 ModuleSP module_sp; 2692 Module *module; 2693 if (use_global_module_list) 2694 { 2695 module = Module::GetAllocatedModuleAtIndex(image_idx); 2696 module_sp = module; 2697 } 2698 else 2699 { 2700 module_sp = target->GetImages().GetModuleAtIndex(image_idx); 2701 module = module_sp.get(); 2702 } 2703 2704 strm.Printf("[%3u] ", image_idx); 2705 2706 bool dump_object_name = false; 2707 if (m_options.m_format_array.empty()) 2708 { 2709 DumpFullpath(strm, &module->GetFileSpec(), 0); 2710 dump_object_name = true; 2711 } 2712 else 2713 { 2714 const size_t num_entries = m_options.m_format_array.size(); 2715 for (size_t i=0; i<num_entries; ++i) 2716 { 2717 if (i > 0) 2718 strm.PutChar(' '); 2719 char format_char = m_options.m_format_array[i].first; 2720 uint32_t width = m_options.m_format_array[i].second; 2721 switch (format_char) 2722 { 2723 case 'a': 2724 DumpModuleArchitecture (strm, module, false, width); 2725 break; 2726 2727 case 't': 2728 DumpModuleArchitecture (strm, module, true, width); 2729 break; 2730 2731 case 'f': 2732 DumpFullpath (strm, &module->GetFileSpec(), width); 2733 dump_object_name = true; 2734 break; 2735 2736 case 'd': 2737 DumpDirectory (strm, &module->GetFileSpec(), width); 2738 break; 2739 2740 case 'b': 2741 DumpBasename (strm, &module->GetFileSpec(), width); 2742 dump_object_name = true; 2743 break; 2744 2745 case 'r': 2746 { 2747 uint32_t ref_count = 0; 2748 if (module_sp) 2749 { 2750 // Take one away to make sure we don't count our local "module_sp" 2751 ref_count = module_sp.use_count() - 1; 2752 } 2753 if (width) 2754 strm.Printf("{%*u}", width, ref_count); 2755 else 2756 strm.Printf("{%u}", ref_count); 2757 } 2758 break; 2759 2760 case 's': 2761 case 'S': 2762 { 2763 SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 2764 if (symbol_vendor) 2765 { 2766 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 2767 if (symbol_file) 2768 { 2769 if (format_char == 'S') 2770 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 2771 else 2772 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 2773 dump_object_name = true; 2774 break; 2775 } 2776 } 2777 strm.Printf("%.*s", width, "<NONE>"); 2778 } 2779 break; 2780 2781 case 'm': 2782 module->GetModificationTime().Dump(&strm, width); 2783 break; 2784 2785 case 'p': 2786 strm.Printf("%p", module); 2787 break; 2788 2789 case 'u': 2790 DumpModuleUUID(strm, module); 2791 break; 2792 2793 default: 2794 break; 2795 } 2796 2797 } 2798 } 2799 if (dump_object_name) 2800 { 2801 const char *object_name = module->GetObjectName().GetCString(); 2802 if (object_name) 2803 strm.Printf ("(%s)", object_name); 2804 } 2805 strm.EOL(); 2806 } 2807 result.SetStatus (eReturnStatusSuccessFinishResult); 2808 } 2809 else 2810 { 2811 if (use_global_module_list) 2812 result.AppendError ("the global module list is empty"); 2813 else 2814 result.AppendError ("the target has no associated executable images"); 2815 result.SetStatus (eReturnStatusFailed); 2816 return false; 2817 } 2818 } 2819 return result.Succeeded(); 2820 } 2821 protected: 2822 2823 CommandOptions m_options; 2824 }; 2825 2826 OptionDefinition 2827 CommandObjectTargetModulesList::CommandOptions::g_option_table[] = 2828 { 2829 { LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, 2830 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, 2831 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, 2832 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, 2833 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, 2834 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, 2835 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, 2836 { LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."}, 2837 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, 2838 { 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."}, 2839 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."}, 2840 { 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."}, 2841 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2842 }; 2843 2844 2845 2846 //---------------------------------------------------------------------- 2847 // Lookup information in images 2848 //---------------------------------------------------------------------- 2849 class CommandObjectTargetModulesLookup : public CommandObject 2850 { 2851 public: 2852 2853 enum 2854 { 2855 eLookupTypeInvalid = -1, 2856 eLookupTypeAddress = 0, 2857 eLookupTypeSymbol, 2858 eLookupTypeFileLine, // Line is optional 2859 eLookupTypeFunction, 2860 eLookupTypeType, 2861 kNumLookupTypes 2862 }; 2863 2864 class CommandOptions : public Options 2865 { 2866 public: 2867 2868 CommandOptions (CommandInterpreter &interpreter) : 2869 Options(interpreter) 2870 { 2871 OptionParsingStarting(); 2872 } 2873 2874 virtual 2875 ~CommandOptions () 2876 { 2877 } 2878 2879 virtual Error 2880 SetOptionValue (uint32_t option_idx, const char *option_arg) 2881 { 2882 Error error; 2883 2884 char short_option = (char) m_getopt_table[option_idx].val; 2885 2886 switch (short_option) 2887 { 2888 case 'a': 2889 m_type = eLookupTypeAddress; 2890 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 2891 if (m_addr == LLDB_INVALID_ADDRESS) 2892 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg); 2893 break; 2894 2895 case 'o': 2896 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 2897 if (m_offset == LLDB_INVALID_ADDRESS) 2898 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg); 2899 break; 2900 2901 case 's': 2902 m_str = option_arg; 2903 m_type = eLookupTypeSymbol; 2904 break; 2905 2906 case 'f': 2907 m_file.SetFile (option_arg, false); 2908 m_type = eLookupTypeFileLine; 2909 break; 2910 2911 case 'i': 2912 m_check_inlines = false; 2913 break; 2914 2915 case 'l': 2916 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); 2917 if (m_line_number == UINT32_MAX) 2918 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg); 2919 else if (m_line_number == 0) 2920 error.SetErrorString ("Zero is an invalid line number."); 2921 m_type = eLookupTypeFileLine; 2922 break; 2923 2924 case 'n': 2925 m_str = option_arg; 2926 m_type = eLookupTypeFunction; 2927 break; 2928 2929 case 't': 2930 m_str = option_arg; 2931 m_type = eLookupTypeType; 2932 break; 2933 2934 case 'v': 2935 m_verbose = 1; 2936 break; 2937 2938 case 'r': 2939 m_use_regex = true; 2940 break; 2941 } 2942 2943 return error; 2944 } 2945 2946 void 2947 OptionParsingStarting () 2948 { 2949 m_type = eLookupTypeInvalid; 2950 m_str.clear(); 2951 m_file.Clear(); 2952 m_addr = LLDB_INVALID_ADDRESS; 2953 m_offset = 0; 2954 m_line_number = 0; 2955 m_use_regex = false; 2956 m_check_inlines = true; 2957 m_verbose = false; 2958 } 2959 2960 const OptionDefinition* 2961 GetDefinitions () 2962 { 2963 return g_option_table; 2964 } 2965 2966 // Options table: Required for subclasses of Options. 2967 2968 static OptionDefinition g_option_table[]; 2969 int m_type; // Should be a eLookupTypeXXX enum after parsing options 2970 std::string m_str; // Holds name lookup 2971 FileSpec m_file; // Files for file lookups 2972 lldb::addr_t m_addr; // Holds the address to lookup 2973 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 2974 uint32_t m_line_number; // Line number for file+line lookups 2975 bool m_use_regex; // Name lookups in m_str are regular expressions. 2976 bool m_check_inlines;// Check for inline entries when looking up by file/line. 2977 bool m_verbose; // Enable verbose lookup info 2978 2979 }; 2980 2981 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 2982 CommandObject (interpreter, 2983 "target modules lookup", 2984 "Look up information within executable and dependent shared library images.", 2985 NULL), 2986 m_options (interpreter) 2987 { 2988 CommandArgumentEntry arg; 2989 CommandArgumentData file_arg; 2990 2991 // Define the first (and only) variant of this arg. 2992 file_arg.arg_type = eArgTypeFilename; 2993 file_arg.arg_repetition = eArgRepeatStar; 2994 2995 // There is only one variant this argument could be; put it into the argument entry. 2996 arg.push_back (file_arg); 2997 2998 // Push the data for the first argument into the m_arguments vector. 2999 m_arguments.push_back (arg); 3000 } 3001 3002 virtual 3003 ~CommandObjectTargetModulesLookup () 3004 { 3005 } 3006 3007 virtual Options * 3008 GetOptions () 3009 { 3010 return &m_options; 3011 } 3012 3013 3014 bool 3015 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 3016 { 3017 switch (m_options.m_type) 3018 { 3019 case eLookupTypeAddress: 3020 if (m_options.m_addr != LLDB_INVALID_ADDRESS) 3021 { 3022 if (LookupAddressInModule (m_interpreter, 3023 result.GetOutputStream(), 3024 module, 3025 eSymbolContextEverything, 3026 m_options.m_addr, 3027 m_options.m_offset, 3028 m_options.m_verbose)) 3029 { 3030 result.SetStatus(eReturnStatusSuccessFinishResult); 3031 return true; 3032 } 3033 } 3034 break; 3035 3036 case eLookupTypeSymbol: 3037 if (!m_options.m_str.empty()) 3038 { 3039 if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex)) 3040 { 3041 result.SetStatus(eReturnStatusSuccessFinishResult); 3042 return true; 3043 } 3044 } 3045 break; 3046 3047 case eLookupTypeFileLine: 3048 if (m_options.m_file) 3049 { 3050 3051 if (LookupFileAndLineInModule (m_interpreter, 3052 result.GetOutputStream(), 3053 module, 3054 m_options.m_file, 3055 m_options.m_line_number, 3056 m_options.m_check_inlines, 3057 m_options.m_verbose)) 3058 { 3059 result.SetStatus(eReturnStatusSuccessFinishResult); 3060 return true; 3061 } 3062 } 3063 break; 3064 3065 case eLookupTypeFunction: 3066 if (!m_options.m_str.empty()) 3067 { 3068 if (LookupFunctionInModule (m_interpreter, 3069 result.GetOutputStream(), 3070 module, 3071 m_options.m_str.c_str(), 3072 m_options.m_use_regex, 3073 m_options.m_verbose)) 3074 { 3075 result.SetStatus(eReturnStatusSuccessFinishResult); 3076 return true; 3077 } 3078 } 3079 break; 3080 3081 case eLookupTypeType: 3082 if (!m_options.m_str.empty()) 3083 { 3084 if (LookupTypeInModule (m_interpreter, 3085 result.GetOutputStream(), 3086 module, 3087 m_options.m_str.c_str(), 3088 m_options.m_use_regex)) 3089 { 3090 result.SetStatus(eReturnStatusSuccessFinishResult); 3091 return true; 3092 } 3093 } 3094 break; 3095 3096 default: 3097 m_options.GenerateOptionUsage (result.GetErrorStream(), this); 3098 syntax_error = true; 3099 break; 3100 } 3101 3102 result.SetStatus (eReturnStatusFailed); 3103 return false; 3104 } 3105 3106 virtual bool 3107 Execute (Args& command, 3108 CommandReturnObject &result) 3109 { 3110 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3111 if (target == NULL) 3112 { 3113 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3114 result.SetStatus (eReturnStatusFailed); 3115 return false; 3116 } 3117 else 3118 { 3119 bool syntax_error = false; 3120 uint32_t i; 3121 uint32_t num_successful_lookups = 0; 3122 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3123 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3124 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3125 // Dump all sections for all modules images 3126 3127 if (command.GetArgumentCount() == 0) 3128 { 3129 // Dump all sections for all modules images 3130 const uint32_t num_modules = target->GetImages().GetSize(); 3131 if (num_modules > 0) 3132 { 3133 for (i = 0; i<num_modules && syntax_error == false; ++i) 3134 { 3135 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error)) 3136 { 3137 result.GetOutputStream().EOL(); 3138 num_successful_lookups++; 3139 } 3140 } 3141 } 3142 else 3143 { 3144 result.AppendError ("the target has no associated executable images"); 3145 result.SetStatus (eReturnStatusFailed); 3146 return false; 3147 } 3148 } 3149 else 3150 { 3151 // Dump specified images (by basename or fullpath) 3152 const char *arg_cstr; 3153 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 3154 { 3155 FileSpec image_file(arg_cstr, false); 3156 ModuleList matching_modules; 3157 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); 3158 3159 // Not found in our module list for our target, check the main 3160 // shared module list in case it is a extra file used somewhere 3161 // else 3162 if (num_matching_modules == 0) 3163 num_matching_modules = ModuleList::FindSharedModules (image_file, 3164 target->GetArchitecture(), 3165 NULL, 3166 NULL, 3167 matching_modules); 3168 3169 if (num_matching_modules > 0) 3170 { 3171 for (size_t j=0; j<num_matching_modules; ++j) 3172 { 3173 Module * image_module = matching_modules.GetModulePointerAtIndex(j); 3174 if (image_module) 3175 { 3176 if (LookupInModule (m_interpreter, image_module, result, syntax_error)) 3177 { 3178 result.GetOutputStream().EOL(); 3179 num_successful_lookups++; 3180 } 3181 } 3182 } 3183 } 3184 else 3185 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 3186 } 3187 } 3188 3189 if (num_successful_lookups > 0) 3190 result.SetStatus (eReturnStatusSuccessFinishResult); 3191 else 3192 result.SetStatus (eReturnStatusFailed); 3193 } 3194 return result.Succeeded(); 3195 } 3196 protected: 3197 3198 CommandOptions m_options; 3199 }; 3200 3201 OptionDefinition 3202 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 3203 { 3204 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."}, 3205 { 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."}, 3206 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 3207 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_5 */ , 3208 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 3209 { 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."}, 3210 { 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."}, 3211 { 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)."}, 3212 { LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."}, 3213 { LLDB_OPT_SET_4, true, "function", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."}, 3214 { LLDB_OPT_SET_5, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."}, 3215 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 3216 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3217 }; 3218 3219 3220 #pragma mark CommandObjectMultiwordImageSearchPaths 3221 3222 //------------------------------------------------------------------------- 3223 // CommandObjectMultiwordImageSearchPaths 3224 //------------------------------------------------------------------------- 3225 3226 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 3227 { 3228 public: 3229 3230 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 3231 CommandObjectMultiword (interpreter, 3232 "target modules search-paths", 3233 "A set of commands for operating on debugger target image search paths.", 3234 "target modules search-paths <subcommand> [<subcommand-options>]") 3235 { 3236 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 3237 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 3238 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 3239 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 3240 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 3241 } 3242 3243 ~CommandObjectTargetModulesImageSearchPaths() 3244 { 3245 } 3246 }; 3247 3248 3249 3250 #pragma mark CommandObjectTargetModules 3251 3252 //------------------------------------------------------------------------- 3253 // CommandObjectTargetModules 3254 //------------------------------------------------------------------------- 3255 3256 class CommandObjectTargetModules : public CommandObjectMultiword 3257 { 3258 public: 3259 //------------------------------------------------------------------ 3260 // Constructors and Destructors 3261 //------------------------------------------------------------------ 3262 CommandObjectTargetModules(CommandInterpreter &interpreter) : 3263 CommandObjectMultiword (interpreter, 3264 "target modules", 3265 "A set of commands for accessing information for one or more target modules.", 3266 "target modules <sub-command> ...") 3267 { 3268 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 3269 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 3270 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter))); 3271 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 3272 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 3273 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 3274 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 3275 3276 } 3277 virtual 3278 ~CommandObjectTargetModules() 3279 { 3280 } 3281 3282 private: 3283 //------------------------------------------------------------------ 3284 // For CommandObjectTargetModules only 3285 //------------------------------------------------------------------ 3286 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 3287 }; 3288 3289 3290 #pragma mark CommandObjectTargetStopHookAdd 3291 3292 //------------------------------------------------------------------------- 3293 // CommandObjectTargetStopHookAdd 3294 //------------------------------------------------------------------------- 3295 3296 class CommandObjectTargetStopHookAdd : public CommandObject 3297 { 3298 public: 3299 3300 class CommandOptions : public Options 3301 { 3302 public: 3303 CommandOptions (CommandInterpreter &interpreter) : 3304 Options(interpreter), 3305 m_line_start(0), 3306 m_line_end (UINT_MAX), 3307 m_func_name_type_mask (eFunctionNameTypeAuto), 3308 m_sym_ctx_specified (false), 3309 m_thread_specified (false), 3310 m_use_one_liner (false), 3311 m_one_liner() 3312 { 3313 } 3314 3315 ~CommandOptions () {} 3316 3317 const OptionDefinition* 3318 GetDefinitions () 3319 { 3320 return g_option_table; 3321 } 3322 3323 virtual Error 3324 SetOptionValue (uint32_t option_idx, const char *option_arg) 3325 { 3326 Error error; 3327 char short_option = (char) m_getopt_table[option_idx].val; 3328 bool success; 3329 3330 switch (short_option) 3331 { 3332 case 'c': 3333 m_class_name = option_arg; 3334 m_sym_ctx_specified = true; 3335 break; 3336 3337 case 'e': 3338 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success); 3339 if (!success) 3340 { 3341 error.SetErrorStringWithFormat ("Invalid end line number: \"%s\".", option_arg); 3342 break; 3343 } 3344 m_sym_ctx_specified = true; 3345 break; 3346 3347 case 'l': 3348 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 3349 if (!success) 3350 { 3351 error.SetErrorStringWithFormat ("Invalid start line number: \"%s\".", option_arg); 3352 break; 3353 } 3354 m_sym_ctx_specified = true; 3355 break; 3356 3357 case 'n': 3358 m_function_name = option_arg; 3359 m_func_name_type_mask |= eFunctionNameTypeAuto; 3360 m_sym_ctx_specified = true; 3361 break; 3362 3363 case 'f': 3364 m_file_name = option_arg; 3365 m_sym_ctx_specified = true; 3366 break; 3367 case 's': 3368 m_module_name = option_arg; 3369 m_sym_ctx_specified = true; 3370 break; 3371 case 't' : 3372 { 3373 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 3374 if (m_thread_id == LLDB_INVALID_THREAD_ID) 3375 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg); 3376 m_thread_specified = true; 3377 } 3378 break; 3379 case 'T': 3380 m_thread_name = option_arg; 3381 m_thread_specified = true; 3382 break; 3383 case 'q': 3384 m_queue_name = option_arg; 3385 m_thread_specified = true; 3386 break; 3387 case 'x': 3388 { 3389 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 3390 if (m_thread_id == UINT32_MAX) 3391 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg); 3392 m_thread_specified = true; 3393 } 3394 break; 3395 case 'o': 3396 m_use_one_liner = true; 3397 m_one_liner = option_arg; 3398 break; 3399 default: 3400 error.SetErrorStringWithFormat ("Unrecognized option %c.", short_option); 3401 break; 3402 } 3403 return error; 3404 } 3405 3406 void 3407 OptionParsingStarting () 3408 { 3409 m_class_name.clear(); 3410 m_function_name.clear(); 3411 m_line_start = 0; 3412 m_line_end = UINT_MAX; 3413 m_file_name.clear(); 3414 m_module_name.clear(); 3415 m_func_name_type_mask = eFunctionNameTypeAuto; 3416 m_thread_id = LLDB_INVALID_THREAD_ID; 3417 m_thread_index = UINT32_MAX; 3418 m_thread_name.clear(); 3419 m_queue_name.clear(); 3420 3421 m_sym_ctx_specified = false; 3422 m_thread_specified = false; 3423 3424 m_use_one_liner = false; 3425 m_one_liner.clear(); 3426 } 3427 3428 3429 static OptionDefinition g_option_table[]; 3430 3431 std::string m_class_name; 3432 std::string m_function_name; 3433 uint32_t m_line_start; 3434 uint32_t m_line_end; 3435 std::string m_file_name; 3436 std::string m_module_name; 3437 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 3438 lldb::tid_t m_thread_id; 3439 uint32_t m_thread_index; 3440 std::string m_thread_name; 3441 std::string m_queue_name; 3442 bool m_sym_ctx_specified; 3443 bool m_thread_specified; 3444 // Instance variables to hold the values for one_liner options. 3445 bool m_use_one_liner; 3446 std::string m_one_liner; 3447 }; 3448 3449 Options * 3450 GetOptions () 3451 { 3452 return &m_options; 3453 } 3454 3455 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 3456 CommandObject (interpreter, 3457 "target stop-hook add ", 3458 "Add a hook to be executed when the target stops.", 3459 "target stop-hook add"), 3460 m_options (interpreter) 3461 { 3462 } 3463 3464 ~CommandObjectTargetStopHookAdd () 3465 { 3466 } 3467 3468 static size_t 3469 ReadCommandsCallbackFunction (void *baton, 3470 InputReader &reader, 3471 lldb::InputReaderAction notification, 3472 const char *bytes, 3473 size_t bytes_len) 3474 { 3475 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 3476 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton); 3477 static bool got_interrupted; 3478 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 3479 3480 switch (notification) 3481 { 3482 case eInputReaderActivate: 3483 if (!batch_mode) 3484 { 3485 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end."); 3486 if (reader.GetPrompt()) 3487 out_stream->Printf ("%s", reader.GetPrompt()); 3488 out_stream->Flush(); 3489 } 3490 got_interrupted = false; 3491 break; 3492 3493 case eInputReaderDeactivate: 3494 break; 3495 3496 case eInputReaderReactivate: 3497 if (reader.GetPrompt() && !batch_mode) 3498 { 3499 out_stream->Printf ("%s", reader.GetPrompt()); 3500 out_stream->Flush(); 3501 } 3502 got_interrupted = false; 3503 break; 3504 3505 case eInputReaderAsynchronousOutputWritten: 3506 break; 3507 3508 case eInputReaderGotToken: 3509 if (bytes && bytes_len && baton) 3510 { 3511 StringList *commands = new_stop_hook->GetCommandPointer(); 3512 if (commands) 3513 { 3514 commands->AppendString (bytes, bytes_len); 3515 } 3516 } 3517 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode) 3518 { 3519 out_stream->Printf ("%s", reader.GetPrompt()); 3520 out_stream->Flush(); 3521 } 3522 break; 3523 3524 case eInputReaderInterrupt: 3525 { 3526 // Finish, and cancel the stop hook. 3527 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID()); 3528 if (!batch_mode) 3529 { 3530 out_stream->Printf ("Stop hook cancelled.\n"); 3531 out_stream->Flush(); 3532 } 3533 3534 reader.SetIsDone (true); 3535 } 3536 got_interrupted = true; 3537 break; 3538 3539 case eInputReaderEndOfFile: 3540 reader.SetIsDone (true); 3541 break; 3542 3543 case eInputReaderDone: 3544 if (!got_interrupted && !batch_mode) 3545 { 3546 out_stream->Printf ("Stop hook #%d added.\n", new_stop_hook->GetID()); 3547 out_stream->Flush(); 3548 } 3549 break; 3550 } 3551 3552 return bytes_len; 3553 } 3554 3555 bool 3556 Execute (Args& command, 3557 CommandReturnObject &result) 3558 { 3559 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3560 if (target) 3561 { 3562 Target::StopHookSP new_hook_sp; 3563 target->AddStopHook (new_hook_sp); 3564 3565 // First step, make the specifier. 3566 std::auto_ptr<SymbolContextSpecifier> specifier_ap; 3567 if (m_options.m_sym_ctx_specified) 3568 { 3569 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 3570 3571 if (!m_options.m_module_name.empty()) 3572 { 3573 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 3574 } 3575 3576 if (!m_options.m_class_name.empty()) 3577 { 3578 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 3579 } 3580 3581 if (!m_options.m_file_name.empty()) 3582 { 3583 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 3584 } 3585 3586 if (m_options.m_line_start != 0) 3587 { 3588 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 3589 } 3590 3591 if (m_options.m_line_end != UINT_MAX) 3592 { 3593 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 3594 } 3595 3596 if (!m_options.m_function_name.empty()) 3597 { 3598 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 3599 } 3600 } 3601 3602 if (specifier_ap.get()) 3603 new_hook_sp->SetSpecifier (specifier_ap.release()); 3604 3605 // Next see if any of the thread options have been entered: 3606 3607 if (m_options.m_thread_specified) 3608 { 3609 ThreadSpec *thread_spec = new ThreadSpec(); 3610 3611 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 3612 { 3613 thread_spec->SetTID (m_options.m_thread_id); 3614 } 3615 3616 if (m_options.m_thread_index != UINT32_MAX) 3617 thread_spec->SetIndex (m_options.m_thread_index); 3618 3619 if (!m_options.m_thread_name.empty()) 3620 thread_spec->SetName (m_options.m_thread_name.c_str()); 3621 3622 if (!m_options.m_queue_name.empty()) 3623 thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 3624 3625 new_hook_sp->SetThreadSpecifier (thread_spec); 3626 3627 } 3628 if (m_options.m_use_one_liner) 3629 { 3630 // Use one-liner. 3631 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 3632 result.AppendMessageWithFormat("Stop hook #%d added.\n", new_hook_sp->GetID()); 3633 } 3634 else 3635 { 3636 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into 3637 // the new stop hook's command string. 3638 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 3639 if (!reader_sp) 3640 { 3641 result.AppendError("out of memory\n"); 3642 result.SetStatus (eReturnStatusFailed); 3643 target->RemoveStopHookByID (new_hook_sp->GetID()); 3644 return false; 3645 } 3646 3647 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction, 3648 new_hook_sp.get(), // baton 3649 eInputReaderGranularityLine, // token size, to pass to callback function 3650 "DONE", // end token 3651 "> ", // prompt 3652 true)); // echo input 3653 if (!err.Success()) 3654 { 3655 result.AppendError (err.AsCString()); 3656 result.SetStatus (eReturnStatusFailed); 3657 target->RemoveStopHookByID (new_hook_sp->GetID()); 3658 return false; 3659 } 3660 m_interpreter.GetDebugger().PushInputReader (reader_sp); 3661 } 3662 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3663 } 3664 else 3665 { 3666 result.AppendError ("invalid target\n"); 3667 result.SetStatus (eReturnStatusFailed); 3668 } 3669 3670 return result.Succeeded(); 3671 } 3672 private: 3673 CommandOptions m_options; 3674 }; 3675 3676 OptionDefinition 3677 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 3678 { 3679 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner, 3680 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 3681 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 3682 "Set the module within which the stop-hook is to be run."}, 3683 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex, 3684 "The stop hook is run only for the thread whose index matches this argument."}, 3685 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID, 3686 "The stop hook is run only for the thread whose TID matches this argument."}, 3687 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName, 3688 "The stop hook is run only for the thread whose thread name matches this argument."}, 3689 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName, 3690 "The stop hook is run only for threads in the queue whose name is given by this argument."}, 3691 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 3692 "Specify the source file within which the stop-hook is to be run." }, 3693 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 3694 "Set the start of the line range for which the stop-hook is to be run."}, 3695 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum, 3696 "Set the end of the line range for which the stop-hook is to be run."}, 3697 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName, 3698 "Specify the class within which the stop-hook is to be run." }, 3699 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 3700 "Set the function name within which the stop hook will be run." }, 3701 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3702 }; 3703 3704 #pragma mark CommandObjectTargetStopHookDelete 3705 3706 //------------------------------------------------------------------------- 3707 // CommandObjectTargetStopHookDelete 3708 //------------------------------------------------------------------------- 3709 3710 class CommandObjectTargetStopHookDelete : public CommandObject 3711 { 3712 public: 3713 3714 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 3715 CommandObject (interpreter, 3716 "target stop-hook delete [<id>]", 3717 "Delete a stop-hook.", 3718 "target stop-hook delete") 3719 { 3720 } 3721 3722 ~CommandObjectTargetStopHookDelete () 3723 { 3724 } 3725 3726 bool 3727 Execute (Args& command, 3728 CommandReturnObject &result) 3729 { 3730 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3731 if (target) 3732 { 3733 // FIXME: see if we can use the breakpoint id style parser? 3734 size_t num_args = command.GetArgumentCount(); 3735 if (num_args == 0) 3736 { 3737 if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 3738 { 3739 result.SetStatus (eReturnStatusFailed); 3740 return false; 3741 } 3742 else 3743 { 3744 target->RemoveAllStopHooks(); 3745 } 3746 } 3747 else 3748 { 3749 bool success; 3750 for (size_t i = 0; i < num_args; i++) 3751 { 3752 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 3753 if (!success) 3754 { 3755 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3756 result.SetStatus(eReturnStatusFailed); 3757 return false; 3758 } 3759 success = target->RemoveStopHookByID (user_id); 3760 if (!success) 3761 { 3762 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3763 result.SetStatus(eReturnStatusFailed); 3764 return false; 3765 } 3766 } 3767 } 3768 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3769 } 3770 else 3771 { 3772 result.AppendError ("invalid target\n"); 3773 result.SetStatus (eReturnStatusFailed); 3774 } 3775 3776 return result.Succeeded(); 3777 } 3778 }; 3779 #pragma mark CommandObjectTargetStopHookEnableDisable 3780 3781 //------------------------------------------------------------------------- 3782 // CommandObjectTargetStopHookEnableDisable 3783 //------------------------------------------------------------------------- 3784 3785 class CommandObjectTargetStopHookEnableDisable : public CommandObject 3786 { 3787 public: 3788 3789 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 3790 CommandObject (interpreter, 3791 name, 3792 help, 3793 syntax), 3794 m_enable (enable) 3795 { 3796 } 3797 3798 ~CommandObjectTargetStopHookEnableDisable () 3799 { 3800 } 3801 3802 bool 3803 Execute (Args& command, 3804 CommandReturnObject &result) 3805 { 3806 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3807 if (target) 3808 { 3809 // FIXME: see if we can use the breakpoint id style parser? 3810 size_t num_args = command.GetArgumentCount(); 3811 bool success; 3812 3813 if (num_args == 0) 3814 { 3815 target->SetAllStopHooksActiveState (m_enable); 3816 } 3817 else 3818 { 3819 for (size_t i = 0; i < num_args; i++) 3820 { 3821 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 3822 if (!success) 3823 { 3824 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3825 result.SetStatus(eReturnStatusFailed); 3826 return false; 3827 } 3828 success = target->SetStopHookActiveStateByID (user_id, m_enable); 3829 if (!success) 3830 { 3831 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3832 result.SetStatus(eReturnStatusFailed); 3833 return false; 3834 } 3835 } 3836 } 3837 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3838 } 3839 else 3840 { 3841 result.AppendError ("invalid target\n"); 3842 result.SetStatus (eReturnStatusFailed); 3843 } 3844 return result.Succeeded(); 3845 } 3846 private: 3847 bool m_enable; 3848 }; 3849 3850 #pragma mark CommandObjectTargetStopHookList 3851 3852 //------------------------------------------------------------------------- 3853 // CommandObjectTargetStopHookList 3854 //------------------------------------------------------------------------- 3855 3856 class CommandObjectTargetStopHookList : public CommandObject 3857 { 3858 public: 3859 3860 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 3861 CommandObject (interpreter, 3862 "target stop-hook list [<type>]", 3863 "List all stop-hooks.", 3864 "target stop-hook list") 3865 { 3866 } 3867 3868 ~CommandObjectTargetStopHookList () 3869 { 3870 } 3871 3872 bool 3873 Execute (Args& command, 3874 CommandReturnObject &result) 3875 { 3876 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3877 if (target) 3878 { 3879 bool notify = true; 3880 target->GetImageSearchPathList().Clear(notify); 3881 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3882 } 3883 else 3884 { 3885 result.AppendError ("invalid target\n"); 3886 result.SetStatus (eReturnStatusFailed); 3887 return result.Succeeded(); 3888 } 3889 3890 size_t num_hooks = target->GetNumStopHooks (); 3891 if (num_hooks == 0) 3892 { 3893 result.GetOutputStream().PutCString ("No stop hooks.\n"); 3894 } 3895 else 3896 { 3897 for (size_t i = 0; i < num_hooks; i++) 3898 { 3899 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 3900 if (i > 0) 3901 result.GetOutputStream().PutCString ("\n"); 3902 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 3903 } 3904 } 3905 return result.Succeeded(); 3906 } 3907 }; 3908 3909 #pragma mark CommandObjectMultiwordTargetStopHooks 3910 //------------------------------------------------------------------------- 3911 // CommandObjectMultiwordTargetStopHooks 3912 //------------------------------------------------------------------------- 3913 3914 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 3915 { 3916 public: 3917 3918 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 3919 CommandObjectMultiword (interpreter, 3920 "target stop-hook", 3921 "A set of commands for operating on debugger target stop-hooks.", 3922 "target stop-hook <subcommand> [<subcommand-options>]") 3923 { 3924 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 3925 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 3926 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 3927 false, 3928 "target stop-hook disable [<id>]", 3929 "Disable a stop-hook.", 3930 "target stop-hook disable"))); 3931 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 3932 true, 3933 "target stop-hook enable [<id>]", 3934 "Enable a stop-hook.", 3935 "target stop-hook enable"))); 3936 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 3937 } 3938 3939 ~CommandObjectMultiwordTargetStopHooks() 3940 { 3941 } 3942 }; 3943 3944 3945 3946 #pragma mark CommandObjectMultiwordTarget 3947 3948 //------------------------------------------------------------------------- 3949 // CommandObjectMultiwordTarget 3950 //------------------------------------------------------------------------- 3951 3952 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 3953 CommandObjectMultiword (interpreter, 3954 "target", 3955 "A set of commands for operating on debugger targets.", 3956 "target <subcommand> [<subcommand-options>]") 3957 { 3958 3959 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 3960 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 3961 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 3962 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 3963 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 3964 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 3965 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 3966 } 3967 3968 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 3969 { 3970 } 3971 3972 3973