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