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