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