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