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