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 if (check_global_list) 1747 { 1748 // Check the global list 1749 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 1750 const uint32_t num_modules = Module::GetNumberAllocatedModules(); 1751 ModuleSP module_sp; 1752 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 1753 { 1754 Module *module = Module::GetAllocatedModuleAtIndex(image_idx); 1755 1756 if (module) 1757 { 1758 if (module->MatchesModuleSpec (module_spec)) 1759 { 1760 module_sp = module->shared_from_this(); 1761 module_list.AppendIfNeeded(module_sp); 1762 } 1763 } 1764 } 1765 } 1766 else 1767 { 1768 if (target) 1769 { 1770 const size_t num_matches = target->GetImages().FindModules (module_spec, module_list); 1771 1772 // Not found in our module list for our target, check the main 1773 // shared module list in case it is a extra file used somewhere 1774 // else 1775 if (num_matches == 0) 1776 { 1777 module_spec.GetArchitecture() = target->GetArchitecture(); 1778 ModuleList::FindSharedModules (module_spec, module_list); 1779 } 1780 } 1781 else 1782 { 1783 ModuleList::FindSharedModules (module_spec,module_list); 1784 } 1785 } 1786 1787 return module_list.GetSize () - initial_size; 1788 } 1789 1790 #pragma mark CommandObjectTargetModulesModuleAutoComplete 1791 1792 //---------------------------------------------------------------------- 1793 // A base command object class that can auto complete with module file 1794 // paths 1795 //---------------------------------------------------------------------- 1796 1797 class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed 1798 { 1799 public: 1800 1801 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter, 1802 const char *name, 1803 const char *help, 1804 const char *syntax) : 1805 CommandObjectParsed (interpreter, name, help, syntax) 1806 { 1807 CommandArgumentEntry arg; 1808 CommandArgumentData file_arg; 1809 1810 // Define the first (and only) variant of this arg. 1811 file_arg.arg_type = eArgTypeFilename; 1812 file_arg.arg_repetition = eArgRepeatStar; 1813 1814 // There is only one variant this argument could be; put it into the argument entry. 1815 arg.push_back (file_arg); 1816 1817 // Push the data for the first argument into the m_arguments vector. 1818 m_arguments.push_back (arg); 1819 } 1820 1821 virtual 1822 ~CommandObjectTargetModulesModuleAutoComplete () 1823 { 1824 } 1825 1826 virtual int 1827 HandleArgumentCompletion (Args &input, 1828 int &cursor_index, 1829 int &cursor_char_position, 1830 OptionElementVector &opt_element_vector, 1831 int match_start_point, 1832 int max_return_elements, 1833 bool &word_complete, 1834 StringList &matches) 1835 { 1836 // Arguments are the standard module completer. 1837 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1838 completion_str.erase (cursor_char_position); 1839 1840 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1841 CommandCompletions::eModuleCompletion, 1842 completion_str.c_str(), 1843 match_start_point, 1844 max_return_elements, 1845 NULL, 1846 word_complete, 1847 matches); 1848 return matches.GetSize(); 1849 } 1850 }; 1851 1852 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete 1853 1854 //---------------------------------------------------------------------- 1855 // A base command object class that can auto complete with module source 1856 // file paths 1857 //---------------------------------------------------------------------- 1858 1859 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed 1860 { 1861 public: 1862 1863 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, 1864 const char *name, 1865 const char *help, 1866 const char *syntax) : 1867 CommandObjectParsed (interpreter, name, help, syntax) 1868 { 1869 CommandArgumentEntry arg; 1870 CommandArgumentData source_file_arg; 1871 1872 // Define the first (and only) variant of this arg. 1873 source_file_arg.arg_type = eArgTypeSourceFile; 1874 source_file_arg.arg_repetition = eArgRepeatPlus; 1875 1876 // There is only one variant this argument could be; put it into the argument entry. 1877 arg.push_back (source_file_arg); 1878 1879 // Push the data for the first argument into the m_arguments vector. 1880 m_arguments.push_back (arg); 1881 } 1882 1883 virtual 1884 ~CommandObjectTargetModulesSourceFileAutoComplete () 1885 { 1886 } 1887 1888 virtual int 1889 HandleArgumentCompletion (Args &input, 1890 int &cursor_index, 1891 int &cursor_char_position, 1892 OptionElementVector &opt_element_vector, 1893 int match_start_point, 1894 int max_return_elements, 1895 bool &word_complete, 1896 StringList &matches) 1897 { 1898 // Arguments are the standard source file completer. 1899 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1900 completion_str.erase (cursor_char_position); 1901 1902 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1903 CommandCompletions::eSourceFileCompletion, 1904 completion_str.c_str(), 1905 match_start_point, 1906 max_return_elements, 1907 NULL, 1908 word_complete, 1909 matches); 1910 return matches.GetSize(); 1911 } 1912 }; 1913 1914 1915 #pragma mark CommandObjectTargetModulesDumpSymtab 1916 1917 1918 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete 1919 { 1920 public: 1921 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) : 1922 CommandObjectTargetModulesModuleAutoComplete (interpreter, 1923 "target modules dump symtab", 1924 "Dump the symbol table from one or more target modules.", 1925 NULL), 1926 m_options (interpreter) 1927 { 1928 } 1929 1930 virtual 1931 ~CommandObjectTargetModulesDumpSymtab () 1932 { 1933 } 1934 1935 virtual Options * 1936 GetOptions () 1937 { 1938 return &m_options; 1939 } 1940 1941 class CommandOptions : public Options 1942 { 1943 public: 1944 1945 CommandOptions (CommandInterpreter &interpreter) : 1946 Options(interpreter), 1947 m_sort_order (eSortOrderNone) 1948 { 1949 } 1950 1951 virtual 1952 ~CommandOptions () 1953 { 1954 } 1955 1956 virtual Error 1957 SetOptionValue (uint32_t option_idx, const char *option_arg) 1958 { 1959 Error error; 1960 char short_option = (char) m_getopt_table[option_idx].val; 1961 1962 switch (short_option) 1963 { 1964 case 's': 1965 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg, 1966 g_option_table[option_idx].enum_values, 1967 eSortOrderNone, 1968 error); 1969 break; 1970 1971 default: 1972 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1973 break; 1974 1975 } 1976 return error; 1977 } 1978 1979 void 1980 OptionParsingStarting () 1981 { 1982 m_sort_order = eSortOrderNone; 1983 } 1984 1985 const OptionDefinition* 1986 GetDefinitions () 1987 { 1988 return g_option_table; 1989 } 1990 1991 // Options table: Required for subclasses of Options. 1992 static OptionDefinition g_option_table[]; 1993 1994 SortOrder m_sort_order; 1995 }; 1996 1997 protected: 1998 virtual bool 1999 DoExecute (Args& command, 2000 CommandReturnObject &result) 2001 { 2002 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2003 if (target == NULL) 2004 { 2005 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2006 result.SetStatus (eReturnStatusFailed); 2007 return false; 2008 } 2009 else 2010 { 2011 uint32_t num_dumped = 0; 2012 2013 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2014 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2015 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2016 2017 if (command.GetArgumentCount() == 0) 2018 { 2019 // Dump all sections for all modules images 2020 Mutex::Locker modules_locker(target->GetImages().GetMutex()); 2021 const uint32_t num_modules = target->GetImages().GetSize(); 2022 if (num_modules > 0) 2023 { 2024 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules); 2025 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2026 { 2027 if (num_dumped > 0) 2028 { 2029 result.GetOutputStream().EOL(); 2030 result.GetOutputStream().EOL(); 2031 } 2032 num_dumped++; 2033 DumpModuleSymtab (m_interpreter, 2034 result.GetOutputStream(), 2035 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx), 2036 m_options.m_sort_order); 2037 } 2038 } 2039 else 2040 { 2041 result.AppendError ("the target has no associated executable images"); 2042 result.SetStatus (eReturnStatusFailed); 2043 return false; 2044 } 2045 } 2046 else 2047 { 2048 // Dump specified images (by basename or fullpath) 2049 const char *arg_cstr; 2050 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2051 { 2052 ModuleList module_list; 2053 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2054 if (num_matches > 0) 2055 { 2056 for (size_t i=0; i<num_matches; ++i) 2057 { 2058 Module *module = module_list.GetModulePointerAtIndex(i); 2059 if (module) 2060 { 2061 if (num_dumped > 0) 2062 { 2063 result.GetOutputStream().EOL(); 2064 result.GetOutputStream().EOL(); 2065 } 2066 num_dumped++; 2067 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order); 2068 } 2069 } 2070 } 2071 else 2072 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2073 } 2074 } 2075 2076 if (num_dumped > 0) 2077 result.SetStatus (eReturnStatusSuccessFinishResult); 2078 else 2079 { 2080 result.AppendError ("no matching executable images found"); 2081 result.SetStatus (eReturnStatusFailed); 2082 } 2083 } 2084 return result.Succeeded(); 2085 } 2086 2087 2088 CommandOptions m_options; 2089 }; 2090 2091 static OptionEnumValueElement 2092 g_sort_option_enumeration[4] = 2093 { 2094 { eSortOrderNone, "none", "No sorting, use the original symbol table order."}, 2095 { eSortOrderByAddress, "address", "Sort output by symbol address."}, 2096 { eSortOrderByName, "name", "Sort output by symbol name."}, 2097 { 0, NULL, NULL } 2098 }; 2099 2100 2101 OptionDefinition 2102 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] = 2103 { 2104 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."}, 2105 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2106 }; 2107 2108 #pragma mark CommandObjectTargetModulesDumpSections 2109 2110 //---------------------------------------------------------------------- 2111 // Image section dumping command 2112 //---------------------------------------------------------------------- 2113 2114 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete 2115 { 2116 public: 2117 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) : 2118 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2119 "target modules dump sections", 2120 "Dump the sections from one or more target modules.", 2121 //"target modules dump sections [<file1> ...]") 2122 NULL) 2123 { 2124 } 2125 2126 virtual 2127 ~CommandObjectTargetModulesDumpSections () 2128 { 2129 } 2130 2131 protected: 2132 virtual bool 2133 DoExecute (Args& command, 2134 CommandReturnObject &result) 2135 { 2136 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2137 if (target == NULL) 2138 { 2139 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2140 result.SetStatus (eReturnStatusFailed); 2141 return false; 2142 } 2143 else 2144 { 2145 uint32_t num_dumped = 0; 2146 2147 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2148 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2149 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2150 2151 if (command.GetArgumentCount() == 0) 2152 { 2153 // Dump all sections for all modules images 2154 const uint32_t num_modules = target->GetImages().GetSize(); 2155 if (num_modules > 0) 2156 { 2157 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules); 2158 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2159 { 2160 num_dumped++; 2161 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)); 2162 } 2163 } 2164 else 2165 { 2166 result.AppendError ("the target has no associated executable images"); 2167 result.SetStatus (eReturnStatusFailed); 2168 return false; 2169 } 2170 } 2171 else 2172 { 2173 // Dump specified images (by basename or fullpath) 2174 const char *arg_cstr; 2175 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2176 { 2177 ModuleList module_list; 2178 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2179 if (num_matches > 0) 2180 { 2181 for (size_t i=0; i<num_matches; ++i) 2182 { 2183 Module *module = module_list.GetModulePointerAtIndex(i); 2184 if (module) 2185 { 2186 num_dumped++; 2187 DumpModuleSections (m_interpreter, result.GetOutputStream(), module); 2188 } 2189 } 2190 } 2191 else 2192 { 2193 // Check the global list 2194 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 2195 2196 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2197 } 2198 } 2199 } 2200 2201 if (num_dumped > 0) 2202 result.SetStatus (eReturnStatusSuccessFinishResult); 2203 else 2204 { 2205 result.AppendError ("no matching executable images found"); 2206 result.SetStatus (eReturnStatusFailed); 2207 } 2208 } 2209 return result.Succeeded(); 2210 } 2211 }; 2212 2213 2214 #pragma mark CommandObjectTargetModulesDumpSymfile 2215 2216 //---------------------------------------------------------------------- 2217 // Image debug symbol dumping command 2218 //---------------------------------------------------------------------- 2219 2220 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete 2221 { 2222 public: 2223 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) : 2224 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2225 "target modules dump symfile", 2226 "Dump the debug symbol file for one or more target modules.", 2227 //"target modules dump symfile [<file1> ...]") 2228 NULL) 2229 { 2230 } 2231 2232 virtual 2233 ~CommandObjectTargetModulesDumpSymfile () 2234 { 2235 } 2236 2237 protected: 2238 virtual bool 2239 DoExecute (Args& command, 2240 CommandReturnObject &result) 2241 { 2242 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2243 if (target == NULL) 2244 { 2245 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2246 result.SetStatus (eReturnStatusFailed); 2247 return false; 2248 } 2249 else 2250 { 2251 uint32_t num_dumped = 0; 2252 2253 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2254 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2255 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2256 2257 if (command.GetArgumentCount() == 0) 2258 { 2259 // Dump all sections for all modules images 2260 ModuleList &target_modules = target->GetImages(); 2261 Mutex::Locker modules_locker (target_modules.GetMutex()); 2262 const uint32_t num_modules = target_modules.GetSize(); 2263 if (num_modules > 0) 2264 { 2265 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules); 2266 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2267 { 2268 if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx))) 2269 num_dumped++; 2270 } 2271 } 2272 else 2273 { 2274 result.AppendError ("the target has no associated executable images"); 2275 result.SetStatus (eReturnStatusFailed); 2276 return false; 2277 } 2278 } 2279 else 2280 { 2281 // Dump specified images (by basename or fullpath) 2282 const char *arg_cstr; 2283 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2284 { 2285 ModuleList module_list; 2286 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2287 if (num_matches > 0) 2288 { 2289 for (size_t i=0; i<num_matches; ++i) 2290 { 2291 Module *module = module_list.GetModulePointerAtIndex(i); 2292 if (module) 2293 { 2294 if (DumpModuleSymbolVendor (result.GetOutputStream(), module)) 2295 num_dumped++; 2296 } 2297 } 2298 } 2299 else 2300 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2301 } 2302 } 2303 2304 if (num_dumped > 0) 2305 result.SetStatus (eReturnStatusSuccessFinishResult); 2306 else 2307 { 2308 result.AppendError ("no matching executable images found"); 2309 result.SetStatus (eReturnStatusFailed); 2310 } 2311 } 2312 return result.Succeeded(); 2313 } 2314 }; 2315 2316 2317 #pragma mark CommandObjectTargetModulesDumpLineTable 2318 2319 //---------------------------------------------------------------------- 2320 // Image debug line table dumping command 2321 //---------------------------------------------------------------------- 2322 2323 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete 2324 { 2325 public: 2326 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) : 2327 CommandObjectTargetModulesSourceFileAutoComplete (interpreter, 2328 "target modules dump line-table", 2329 "Dump the debug symbol file for one or more target modules.", 2330 NULL) 2331 { 2332 } 2333 2334 virtual 2335 ~CommandObjectTargetModulesDumpLineTable () 2336 { 2337 } 2338 2339 protected: 2340 virtual bool 2341 DoExecute (Args& command, 2342 CommandReturnObject &result) 2343 { 2344 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2345 if (target == NULL) 2346 { 2347 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2348 result.SetStatus (eReturnStatusFailed); 2349 return false; 2350 } 2351 else 2352 { 2353 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 2354 uint32_t total_num_dumped = 0; 2355 2356 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2357 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2358 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2359 2360 if (command.GetArgumentCount() == 0) 2361 { 2362 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); 2363 result.SetStatus (eReturnStatusFailed); 2364 } 2365 else 2366 { 2367 // Dump specified images (by basename or fullpath) 2368 const char *arg_cstr; 2369 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2370 { 2371 FileSpec file_spec(arg_cstr, false); 2372 2373 ModuleList &target_modules = target->GetImages(); 2374 Mutex::Locker modules_locker(target_modules.GetMutex()); 2375 const uint32_t num_modules = target_modules.GetSize(); 2376 if (num_modules > 0) 2377 { 2378 uint32_t num_dumped = 0; 2379 for (uint32_t i = 0; i<num_modules; ++i) 2380 { 2381 if (DumpCompileUnitLineTable (m_interpreter, 2382 result.GetOutputStream(), 2383 target_modules.GetModulePointerAtIndexUnlocked(i), 2384 file_spec, 2385 exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive())) 2386 num_dumped++; 2387 } 2388 if (num_dumped == 0) 2389 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); 2390 else 2391 total_num_dumped += num_dumped; 2392 } 2393 } 2394 } 2395 2396 if (total_num_dumped > 0) 2397 result.SetStatus (eReturnStatusSuccessFinishResult); 2398 else 2399 { 2400 result.AppendError ("no source filenames matched any command arguments"); 2401 result.SetStatus (eReturnStatusFailed); 2402 } 2403 } 2404 return result.Succeeded(); 2405 } 2406 }; 2407 2408 2409 #pragma mark CommandObjectTargetModulesDump 2410 2411 //---------------------------------------------------------------------- 2412 // Dump multi-word command for target modules 2413 //---------------------------------------------------------------------- 2414 2415 class CommandObjectTargetModulesDump : public CommandObjectMultiword 2416 { 2417 public: 2418 2419 //------------------------------------------------------------------ 2420 // Constructors and Destructors 2421 //------------------------------------------------------------------ 2422 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) : 2423 CommandObjectMultiword (interpreter, 2424 "target modules dump", 2425 "A set of commands for dumping information about one or more target modules.", 2426 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]") 2427 { 2428 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter))); 2429 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter))); 2430 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter))); 2431 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter))); 2432 } 2433 2434 virtual 2435 ~CommandObjectTargetModulesDump() 2436 { 2437 } 2438 }; 2439 2440 class CommandObjectTargetModulesAdd : public CommandObjectParsed 2441 { 2442 public: 2443 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) : 2444 CommandObjectParsed (interpreter, 2445 "target modules add", 2446 "Add a new module to the current target's modules.", 2447 "target modules add [<module>]") 2448 { 2449 } 2450 2451 virtual 2452 ~CommandObjectTargetModulesAdd () 2453 { 2454 } 2455 2456 int 2457 HandleArgumentCompletion (Args &input, 2458 int &cursor_index, 2459 int &cursor_char_position, 2460 OptionElementVector &opt_element_vector, 2461 int match_start_point, 2462 int max_return_elements, 2463 bool &word_complete, 2464 StringList &matches) 2465 { 2466 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2467 completion_str.erase (cursor_char_position); 2468 2469 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2470 CommandCompletions::eDiskFileCompletion, 2471 completion_str.c_str(), 2472 match_start_point, 2473 max_return_elements, 2474 NULL, 2475 word_complete, 2476 matches); 2477 return matches.GetSize(); 2478 } 2479 2480 protected: 2481 virtual bool 2482 DoExecute (Args& args, 2483 CommandReturnObject &result) 2484 { 2485 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2486 if (target == NULL) 2487 { 2488 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2489 result.SetStatus (eReturnStatusFailed); 2490 return false; 2491 } 2492 else 2493 { 2494 const size_t argc = args.GetArgumentCount(); 2495 if (argc == 0) 2496 { 2497 result.AppendError ("one or more executable image paths must be specified"); 2498 result.SetStatus (eReturnStatusFailed); 2499 return false; 2500 } 2501 else 2502 { 2503 for (size_t i=0; i<argc; ++i) 2504 { 2505 const char *path = args.GetArgumentAtIndex(i); 2506 if (path) 2507 { 2508 FileSpec file_spec(path, true); 2509 if (file_spec.Exists()) 2510 { 2511 ModuleSpec module_spec (file_spec); 2512 ModuleSP module_sp (target->GetSharedModule (module_spec)); 2513 if (!module_sp) 2514 { 2515 result.AppendError ("one or more executable image paths must be specified"); 2516 result.SetStatus (eReturnStatusFailed); 2517 return false; 2518 } 2519 result.SetStatus (eReturnStatusSuccessFinishResult); 2520 } 2521 else 2522 { 2523 char resolved_path[PATH_MAX]; 2524 result.SetStatus (eReturnStatusFailed); 2525 if (file_spec.GetPath (resolved_path, sizeof(resolved_path))) 2526 { 2527 if (strcmp (resolved_path, path) != 0) 2528 { 2529 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path); 2530 break; 2531 } 2532 } 2533 result.AppendErrorWithFormat ("invalid module path '%s'\n", path); 2534 break; 2535 } 2536 } 2537 } 2538 } 2539 } 2540 return result.Succeeded(); 2541 } 2542 2543 }; 2544 2545 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete 2546 { 2547 public: 2548 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) : 2549 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2550 "target modules load", 2551 "Set the load addresses for one or more sections in a target module.", 2552 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"), 2553 m_option_group (interpreter), 2554 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."), 2555 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) 2556 { 2557 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2558 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2559 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2560 m_option_group.Finalize(); 2561 } 2562 2563 virtual 2564 ~CommandObjectTargetModulesLoad () 2565 { 2566 } 2567 2568 virtual Options * 2569 GetOptions () 2570 { 2571 return &m_option_group; 2572 } 2573 2574 protected: 2575 virtual bool 2576 DoExecute (Args& args, 2577 CommandReturnObject &result) 2578 { 2579 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2580 if (target == NULL) 2581 { 2582 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2583 result.SetStatus (eReturnStatusFailed); 2584 return false; 2585 } 2586 else 2587 { 2588 const size_t argc = args.GetArgumentCount(); 2589 ModuleSpec module_spec; 2590 bool search_using_module_spec = false; 2591 if (m_file_option.GetOptionValue().OptionWasSet()) 2592 { 2593 search_using_module_spec = true; 2594 module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 2595 } 2596 2597 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2598 { 2599 search_using_module_spec = true; 2600 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2601 } 2602 2603 if (search_using_module_spec) 2604 { 2605 2606 ModuleList matching_modules; 2607 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules); 2608 2609 char path[PATH_MAX]; 2610 if (num_matches == 1) 2611 { 2612 Module *module = matching_modules.GetModulePointerAtIndex(0); 2613 if (module) 2614 { 2615 ObjectFile *objfile = module->GetObjectFile(); 2616 if (objfile) 2617 { 2618 SectionList *section_list = objfile->GetSectionList(); 2619 if (section_list) 2620 { 2621 bool changed = false; 2622 if (argc == 0) 2623 { 2624 if (m_slide_option.GetOptionValue().OptionWasSet()) 2625 { 2626 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue(); 2627 module->SetLoadAddress (*target, slide, changed); 2628 } 2629 else 2630 { 2631 result.AppendError ("one or more section name + load address pair must be specified"); 2632 result.SetStatus (eReturnStatusFailed); 2633 return false; 2634 } 2635 } 2636 else 2637 { 2638 if (m_slide_option.GetOptionValue().OptionWasSet()) 2639 { 2640 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n"); 2641 result.SetStatus (eReturnStatusFailed); 2642 return false; 2643 } 2644 2645 for (size_t i=0; i<argc; i += 2) 2646 { 2647 const char *sect_name = args.GetArgumentAtIndex(i); 2648 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1); 2649 if (sect_name && load_addr_cstr) 2650 { 2651 ConstString const_sect_name(sect_name); 2652 bool success = false; 2653 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); 2654 if (success) 2655 { 2656 SectionSP section_sp (section_list->FindSectionByName(const_sect_name)); 2657 if (section_sp) 2658 { 2659 if (section_sp->IsThreadSpecific()) 2660 { 2661 result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name); 2662 result.SetStatus (eReturnStatusFailed); 2663 break; 2664 } 2665 else 2666 { 2667 if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr)) 2668 changed = true; 2669 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr); 2670 } 2671 } 2672 else 2673 { 2674 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name); 2675 result.SetStatus (eReturnStatusFailed); 2676 break; 2677 } 2678 } 2679 else 2680 { 2681 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr); 2682 result.SetStatus (eReturnStatusFailed); 2683 break; 2684 } 2685 } 2686 else 2687 { 2688 if (sect_name) 2689 result.AppendError ("section names must be followed by a load address.\n"); 2690 else 2691 result.AppendError ("one or more section name + load address pair must be specified.\n"); 2692 result.SetStatus (eReturnStatusFailed); 2693 break; 2694 } 2695 } 2696 } 2697 2698 if (changed) 2699 target->ModulesDidLoad (matching_modules); 2700 } 2701 else 2702 { 2703 module->GetFileSpec().GetPath (path, sizeof(path)); 2704 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path); 2705 result.SetStatus (eReturnStatusFailed); 2706 } 2707 } 2708 else 2709 { 2710 module->GetFileSpec().GetPath (path, sizeof(path)); 2711 result.AppendErrorWithFormat ("no object file for module '%s'\n", path); 2712 result.SetStatus (eReturnStatusFailed); 2713 } 2714 } 2715 else 2716 { 2717 module->GetFileSpec().GetPath (path, sizeof(path)); 2718 result.AppendErrorWithFormat ("invalid module '%s'.\n", path); 2719 result.SetStatus (eReturnStatusFailed); 2720 } 2721 } 2722 else 2723 { 2724 char uuid_cstr[64]; 2725 2726 if (module_spec.GetFileSpec()) 2727 module_spec.GetFileSpec().GetPath (path, sizeof(path)); 2728 else 2729 path[0] = '\0'; 2730 2731 if (module_spec.GetUUIDPtr()) 2732 module_spec.GetUUID().GetAsCString(uuid_cstr, sizeof(uuid_cstr)); 2733 else 2734 uuid_cstr[0] = '\0'; 2735 if (num_matches > 1) 2736 { 2737 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", 2738 path[0] ? " file=" : "", 2739 path, 2740 uuid_cstr[0] ? " uuid=" : "", 2741 uuid_cstr); 2742 for (size_t i=0; i<num_matches; ++i) 2743 { 2744 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path))) 2745 result.AppendMessageWithFormat("%s\n", path); 2746 } 2747 } 2748 else 2749 { 2750 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n", 2751 path[0] ? " file=" : "", 2752 path, 2753 uuid_cstr[0] ? " uuid=" : "", 2754 uuid_cstr); 2755 } 2756 result.SetStatus (eReturnStatusFailed); 2757 } 2758 } 2759 else 2760 { 2761 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n"); 2762 result.SetStatus (eReturnStatusFailed); 2763 return false; 2764 } 2765 } 2766 return result.Succeeded(); 2767 } 2768 2769 OptionGroupOptions m_option_group; 2770 OptionGroupUUID m_uuid_option_group; 2771 OptionGroupFile m_file_option; 2772 OptionGroupUInt64 m_slide_option; 2773 }; 2774 2775 //---------------------------------------------------------------------- 2776 // List images with associated information 2777 //---------------------------------------------------------------------- 2778 class CommandObjectTargetModulesList : public CommandObjectParsed 2779 { 2780 public: 2781 2782 class CommandOptions : public Options 2783 { 2784 public: 2785 2786 CommandOptions (CommandInterpreter &interpreter) : 2787 Options(interpreter), 2788 m_format_array(), 2789 m_use_global_module_list (false), 2790 m_module_addr (LLDB_INVALID_ADDRESS) 2791 { 2792 } 2793 2794 virtual 2795 ~CommandOptions () 2796 { 2797 } 2798 2799 virtual Error 2800 SetOptionValue (uint32_t option_idx, const char *option_arg) 2801 { 2802 char short_option = (char) m_getopt_table[option_idx].val; 2803 if (short_option == 'g') 2804 { 2805 m_use_global_module_list = true; 2806 } 2807 else if (short_option == 'a') 2808 { 2809 bool success; 2810 m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success); 2811 if (!success) 2812 { 2813 Error error; 2814 error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg); 2815 } 2816 } 2817 else 2818 { 2819 uint32_t width = 0; 2820 if (option_arg) 2821 width = strtoul (option_arg, NULL, 0); 2822 m_format_array.push_back(std::make_pair(short_option, width)); 2823 } 2824 Error error; 2825 return error; 2826 } 2827 2828 void 2829 OptionParsingStarting () 2830 { 2831 m_format_array.clear(); 2832 m_use_global_module_list = false; 2833 m_module_addr = LLDB_INVALID_ADDRESS; 2834 } 2835 2836 const OptionDefinition* 2837 GetDefinitions () 2838 { 2839 return g_option_table; 2840 } 2841 2842 // Options table: Required for subclasses of Options. 2843 2844 static OptionDefinition g_option_table[]; 2845 2846 // Instance variables to hold the values for command options. 2847 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection; 2848 FormatWidthCollection m_format_array; 2849 bool m_use_global_module_list; 2850 lldb::addr_t m_module_addr; 2851 }; 2852 2853 CommandObjectTargetModulesList (CommandInterpreter &interpreter) : 2854 CommandObjectParsed (interpreter, 2855 "target modules list", 2856 "List current executable and dependent shared library images.", 2857 "target modules list [<cmd-options>]"), 2858 m_options (interpreter) 2859 { 2860 } 2861 2862 virtual 2863 ~CommandObjectTargetModulesList () 2864 { 2865 } 2866 2867 virtual 2868 Options * 2869 GetOptions () 2870 { 2871 return &m_options; 2872 } 2873 2874 protected: 2875 virtual bool 2876 DoExecute (Args& command, 2877 CommandReturnObject &result) 2878 { 2879 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2880 const bool use_global_module_list = m_options.m_use_global_module_list; 2881 // Define a local module list here to ensure it lives longer than any "locker" 2882 // object which might lock its contents below (through the "module_list_ptr" 2883 // variable). 2884 ModuleList module_list; 2885 if (target == NULL && use_global_module_list == false) 2886 { 2887 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2888 result.SetStatus (eReturnStatusFailed); 2889 return false; 2890 } 2891 else 2892 { 2893 if (target) 2894 { 2895 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2896 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2897 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2898 } 2899 // Dump all sections for all modules images 2900 Stream &strm = result.GetOutputStream(); 2901 2902 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) 2903 { 2904 if (target) 2905 { 2906 Address module_address; 2907 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) 2908 { 2909 ModuleSP module_sp (module_address.GetModule()); 2910 if (module_sp) 2911 { 2912 PrintModule (target, module_sp.get(), UINT32_MAX, 0, strm); 2913 result.SetStatus (eReturnStatusSuccessFinishResult); 2914 } 2915 else 2916 { 2917 result.AppendError ("Couldn't find module matching address: 0x%llx.", m_options.m_module_addr); 2918 result.SetStatus (eReturnStatusFailed); 2919 } 2920 } 2921 else 2922 { 2923 result.AppendError ("Couldn't find module containing address: 0x%llx.", m_options.m_module_addr); 2924 result.SetStatus (eReturnStatusFailed); 2925 } 2926 } 2927 else 2928 { 2929 result.AppendError ("Can only look up modules by address with a valid target."); 2930 result.SetStatus (eReturnStatusFailed); 2931 } 2932 return result.Succeeded(); 2933 } 2934 2935 uint32_t num_modules = 0; 2936 Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL. 2937 // Otherwise it will lock the AllocationModuleCollectionMutex when accessing 2938 // the global module list directly. 2939 ModuleList *module_list_ptr = NULL; 2940 const size_t argc = command.GetArgumentCount(); 2941 if (argc == 0) 2942 { 2943 if (use_global_module_list) 2944 { 2945 locker.Lock (Module::GetAllocationModuleCollectionMutex()); 2946 num_modules = Module::GetNumberAllocatedModules(); 2947 } 2948 else 2949 { 2950 module_list_ptr = &target->GetImages(); 2951 } 2952 } 2953 else 2954 { 2955 for (size_t i=0; i<argc; ++i) 2956 { 2957 // Dump specified images (by basename or fullpath) 2958 const char *arg_cstr = command.GetArgumentAtIndex(i); 2959 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list); 2960 if (num_matches == 0) 2961 { 2962 if (argc == 1) 2963 { 2964 result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr); 2965 result.SetStatus (eReturnStatusFailed); 2966 return false; 2967 } 2968 } 2969 } 2970 2971 module_list_ptr = &module_list; 2972 } 2973 2974 if (module_list_ptr != NULL) 2975 { 2976 locker.Lock(module_list_ptr->GetMutex()); 2977 num_modules = module_list_ptr->GetSize(); 2978 } 2979 2980 if (num_modules > 0) 2981 { 2982 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2983 { 2984 ModuleSP module_sp; 2985 Module *module; 2986 if (module_list_ptr) 2987 { 2988 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx); 2989 module = module_sp.get(); 2990 } 2991 else 2992 { 2993 module = Module::GetAllocatedModuleAtIndex(image_idx); 2994 module_sp = module->shared_from_this(); 2995 } 2996 2997 int indent = strm.Printf("[%3u] ", image_idx); 2998 PrintModule (target, module, image_idx, indent, strm); 2999 3000 } 3001 result.SetStatus (eReturnStatusSuccessFinishResult); 3002 } 3003 else 3004 { 3005 if (argc) 3006 { 3007 if (use_global_module_list) 3008 result.AppendError ("the global module list has no matching modules"); 3009 else 3010 result.AppendError ("the target has no matching modules"); 3011 } 3012 else 3013 { 3014 if (use_global_module_list) 3015 result.AppendError ("the global module list is empty"); 3016 else 3017 result.AppendError ("the target has no associated executable images"); 3018 } 3019 result.SetStatus (eReturnStatusFailed); 3020 return false; 3021 } 3022 } 3023 return result.Succeeded(); 3024 } 3025 3026 void 3027 PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm) 3028 { 3029 3030 bool dump_object_name = false; 3031 if (m_options.m_format_array.empty()) 3032 { 3033 m_options.m_format_array.push_back(std::make_pair('u', 0)); 3034 m_options.m_format_array.push_back(std::make_pair('h', 0)); 3035 m_options.m_format_array.push_back(std::make_pair('f', 0)); 3036 m_options.m_format_array.push_back(std::make_pair('S', 0)); 3037 } 3038 const size_t num_entries = m_options.m_format_array.size(); 3039 bool print_space = false; 3040 for (size_t i=0; i<num_entries; ++i) 3041 { 3042 if (print_space) 3043 strm.PutChar(' '); 3044 print_space = true; 3045 const char format_char = m_options.m_format_array[i].first; 3046 uint32_t width = m_options.m_format_array[i].second; 3047 switch (format_char) 3048 { 3049 case 'A': 3050 DumpModuleArchitecture (strm, module, false, width); 3051 break; 3052 3053 case 't': 3054 DumpModuleArchitecture (strm, module, true, width); 3055 break; 3056 3057 case 'f': 3058 DumpFullpath (strm, &module->GetFileSpec(), width); 3059 dump_object_name = true; 3060 break; 3061 3062 case 'd': 3063 DumpDirectory (strm, &module->GetFileSpec(), width); 3064 break; 3065 3066 case 'b': 3067 DumpBasename (strm, &module->GetFileSpec(), width); 3068 dump_object_name = true; 3069 break; 3070 3071 case 'h': 3072 case 'o': 3073 // Image header address 3074 { 3075 uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16; 3076 3077 ObjectFile *objfile = module->GetObjectFile (); 3078 if (objfile) 3079 { 3080 Address header_addr(objfile->GetHeaderAddress()); 3081 if (header_addr.IsValid()) 3082 { 3083 if (target && !target->GetSectionLoadList().IsEmpty()) 3084 { 3085 lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target); 3086 if (header_load_addr == LLDB_INVALID_ADDRESS) 3087 { 3088 header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress); 3089 } 3090 else 3091 { 3092 if (format_char == 'o') 3093 { 3094 // Show the offset of slide for the image 3095 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress()); 3096 } 3097 else 3098 { 3099 // Show the load address of the image 3100 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr); 3101 } 3102 } 3103 break; 3104 } 3105 // The address was valid, but the image isn't loaded, output the address in an appropriate format 3106 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress); 3107 break; 3108 } 3109 } 3110 strm.Printf ("%*s", addr_nibble_width + 2, ""); 3111 } 3112 break; 3113 case 'r': 3114 { 3115 uint32_t ref_count = 0; 3116 ModuleSP module_sp (module->shared_from_this()); 3117 if (module_sp) 3118 { 3119 // Take one away to make sure we don't count our local "module_sp" 3120 ref_count = module_sp.use_count() - 1; 3121 } 3122 if (width) 3123 strm.Printf("{%*u}", width, ref_count); 3124 else 3125 strm.Printf("{%u}", ref_count); 3126 } 3127 break; 3128 3129 case 's': 3130 case 'S': 3131 { 3132 SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 3133 if (symbol_vendor) 3134 { 3135 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 3136 if (symbol_file) 3137 { 3138 if (format_char == 'S') 3139 { 3140 FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec(); 3141 // Dump symbol file only if different from module file 3142 if (!symfile_spec || symfile_spec == module->GetFileSpec()) 3143 { 3144 print_space = false; 3145 break; 3146 } 3147 // Add a newline and indent past the index 3148 strm.Printf ("\n%*s", indent, ""); 3149 } 3150 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 3151 dump_object_name = true; 3152 break; 3153 } 3154 } 3155 strm.Printf("%.*s", width, "<NONE>"); 3156 } 3157 break; 3158 3159 case 'm': 3160 module->GetModificationTime().Dump(&strm, width); 3161 break; 3162 3163 case 'p': 3164 strm.Printf("%p", module); 3165 break; 3166 3167 case 'u': 3168 DumpModuleUUID(strm, module); 3169 break; 3170 3171 default: 3172 break; 3173 } 3174 3175 } 3176 if (dump_object_name) 3177 { 3178 const char *object_name = module->GetObjectName().GetCString(); 3179 if (object_name) 3180 strm.Printf ("(%s)", object_name); 3181 } 3182 strm.EOL(); 3183 } 3184 3185 CommandOptions m_options; 3186 }; 3187 3188 OptionDefinition 3189 CommandObjectTargetModulesList::CommandOptions::g_option_table[] = 3190 { 3191 { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."}, 3192 { LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, 3193 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, 3194 { 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."}, 3195 { 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)."}, 3196 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, 3197 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, 3198 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, 3199 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, 3200 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, 3201 { 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."}, 3202 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, 3203 { 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."}, 3204 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."}, 3205 { 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."}, 3206 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3207 }; 3208 3209 3210 3211 //---------------------------------------------------------------------- 3212 // Lookup information in images 3213 //---------------------------------------------------------------------- 3214 class CommandObjectTargetModulesLookup : public CommandObjectParsed 3215 { 3216 public: 3217 3218 enum 3219 { 3220 eLookupTypeInvalid = -1, 3221 eLookupTypeAddress = 0, 3222 eLookupTypeSymbol, 3223 eLookupTypeFileLine, // Line is optional 3224 eLookupTypeFunction, 3225 eLookupTypeFunctionOrSymbol, 3226 eLookupTypeType, 3227 kNumLookupTypes 3228 }; 3229 3230 class CommandOptions : public Options 3231 { 3232 public: 3233 3234 CommandOptions (CommandInterpreter &interpreter) : 3235 Options(interpreter) 3236 { 3237 OptionParsingStarting(); 3238 } 3239 3240 virtual 3241 ~CommandOptions () 3242 { 3243 } 3244 3245 virtual Error 3246 SetOptionValue (uint32_t option_idx, const char *option_arg) 3247 { 3248 Error error; 3249 3250 char short_option = (char) m_getopt_table[option_idx].val; 3251 3252 switch (short_option) 3253 { 3254 case 'a': 3255 m_type = eLookupTypeAddress; 3256 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3257 if (m_addr == LLDB_INVALID_ADDRESS) 3258 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg); 3259 break; 3260 3261 case 'o': 3262 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3263 if (m_offset == LLDB_INVALID_ADDRESS) 3264 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg); 3265 break; 3266 3267 case 's': 3268 m_str = option_arg; 3269 m_type = eLookupTypeSymbol; 3270 break; 3271 3272 case 'f': 3273 m_file.SetFile (option_arg, false); 3274 m_type = eLookupTypeFileLine; 3275 break; 3276 3277 case 'i': 3278 m_include_inlines = false; 3279 break; 3280 3281 case 'l': 3282 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); 3283 if (m_line_number == UINT32_MAX) 3284 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg); 3285 else if (m_line_number == 0) 3286 error.SetErrorString ("zero is an invalid line number"); 3287 m_type = eLookupTypeFileLine; 3288 break; 3289 3290 case 'F': 3291 m_str = option_arg; 3292 m_type = eLookupTypeFunction; 3293 break; 3294 3295 case 'n': 3296 m_str = option_arg; 3297 m_type = eLookupTypeFunctionOrSymbol; 3298 break; 3299 3300 case 't': 3301 m_str = option_arg; 3302 m_type = eLookupTypeType; 3303 break; 3304 3305 case 'v': 3306 m_verbose = 1; 3307 break; 3308 3309 case 'A': 3310 m_print_all = true; 3311 break; 3312 3313 case 'r': 3314 m_use_regex = true; 3315 break; 3316 } 3317 3318 return error; 3319 } 3320 3321 void 3322 OptionParsingStarting () 3323 { 3324 m_type = eLookupTypeInvalid; 3325 m_str.clear(); 3326 m_file.Clear(); 3327 m_addr = LLDB_INVALID_ADDRESS; 3328 m_offset = 0; 3329 m_line_number = 0; 3330 m_use_regex = false; 3331 m_include_inlines = true; 3332 m_verbose = false; 3333 m_print_all = false; 3334 } 3335 3336 const OptionDefinition* 3337 GetDefinitions () 3338 { 3339 return g_option_table; 3340 } 3341 3342 // Options table: Required for subclasses of Options. 3343 3344 static OptionDefinition g_option_table[]; 3345 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3346 std::string m_str; // Holds name lookup 3347 FileSpec m_file; // Files for file lookups 3348 lldb::addr_t m_addr; // Holds the address to lookup 3349 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 3350 uint32_t m_line_number; // Line number for file+line lookups 3351 bool m_use_regex; // Name lookups in m_str are regular expressions. 3352 bool m_include_inlines;// Check for inline entries when looking up by file/line. 3353 bool m_verbose; // Enable verbose lookup info 3354 bool m_print_all; // Print all matches, even in cases where there's a best match. 3355 3356 }; 3357 3358 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 3359 CommandObjectParsed (interpreter, 3360 "target modules lookup", 3361 "Look up information within executable and dependent shared library images.", 3362 NULL), 3363 m_options (interpreter) 3364 { 3365 CommandArgumentEntry arg; 3366 CommandArgumentData file_arg; 3367 3368 // Define the first (and only) variant of this arg. 3369 file_arg.arg_type = eArgTypeFilename; 3370 file_arg.arg_repetition = eArgRepeatStar; 3371 3372 // There is only one variant this argument could be; put it into the argument entry. 3373 arg.push_back (file_arg); 3374 3375 // Push the data for the first argument into the m_arguments vector. 3376 m_arguments.push_back (arg); 3377 } 3378 3379 virtual 3380 ~CommandObjectTargetModulesLookup () 3381 { 3382 } 3383 3384 virtual Options * 3385 GetOptions () 3386 { 3387 return &m_options; 3388 } 3389 3390 bool 3391 LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error) 3392 { 3393 switch (m_options.m_type) 3394 { 3395 case eLookupTypeAddress: 3396 case eLookupTypeFileLine: 3397 case eLookupTypeFunction: 3398 case eLookupTypeFunctionOrSymbol: 3399 case eLookupTypeSymbol: 3400 default: 3401 return false; 3402 case eLookupTypeType: 3403 break; 3404 } 3405 3406 ExecutionContext exe_ctx = interpreter.GetDebugger().GetSelectedExecutionContext(); 3407 3408 StackFrameSP frame = exe_ctx.GetFrameSP(); 3409 3410 if (!frame) 3411 return false; 3412 3413 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule)); 3414 3415 if (!sym_ctx.module_sp) 3416 return false; 3417 3418 switch (m_options.m_type) 3419 { 3420 default: 3421 return false; 3422 case eLookupTypeType: 3423 if (!m_options.m_str.empty()) 3424 { 3425 if (LookupTypeHere (m_interpreter, 3426 result.GetOutputStream(), 3427 sym_ctx, 3428 m_options.m_str.c_str(), 3429 m_options.m_use_regex)) 3430 { 3431 result.SetStatus(eReturnStatusSuccessFinishResult); 3432 return true; 3433 } 3434 } 3435 break; 3436 } 3437 3438 return true; 3439 } 3440 3441 bool 3442 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 3443 { 3444 switch (m_options.m_type) 3445 { 3446 case eLookupTypeAddress: 3447 if (m_options.m_addr != LLDB_INVALID_ADDRESS) 3448 { 3449 if (LookupAddressInModule (m_interpreter, 3450 result.GetOutputStream(), 3451 module, 3452 eSymbolContextEverything, 3453 m_options.m_addr, 3454 m_options.m_offset, 3455 m_options.m_verbose)) 3456 { 3457 result.SetStatus(eReturnStatusSuccessFinishResult); 3458 return true; 3459 } 3460 } 3461 break; 3462 3463 case eLookupTypeSymbol: 3464 if (!m_options.m_str.empty()) 3465 { 3466 if (LookupSymbolInModule (m_interpreter, 3467 result.GetOutputStream(), 3468 module, 3469 m_options.m_str.c_str(), 3470 m_options.m_use_regex, 3471 m_options.m_verbose)) 3472 { 3473 result.SetStatus(eReturnStatusSuccessFinishResult); 3474 return true; 3475 } 3476 } 3477 break; 3478 3479 case eLookupTypeFileLine: 3480 if (m_options.m_file) 3481 { 3482 3483 if (LookupFileAndLineInModule (m_interpreter, 3484 result.GetOutputStream(), 3485 module, 3486 m_options.m_file, 3487 m_options.m_line_number, 3488 m_options.m_include_inlines, 3489 m_options.m_verbose)) 3490 { 3491 result.SetStatus(eReturnStatusSuccessFinishResult); 3492 return true; 3493 } 3494 } 3495 break; 3496 3497 case eLookupTypeFunctionOrSymbol: 3498 case eLookupTypeFunction: 3499 if (!m_options.m_str.empty()) 3500 { 3501 if (LookupFunctionInModule (m_interpreter, 3502 result.GetOutputStream(), 3503 module, 3504 m_options.m_str.c_str(), 3505 m_options.m_use_regex, 3506 m_options.m_include_inlines, 3507 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols 3508 m_options.m_verbose)) 3509 { 3510 result.SetStatus(eReturnStatusSuccessFinishResult); 3511 return true; 3512 } 3513 } 3514 break; 3515 3516 3517 case eLookupTypeType: 3518 if (!m_options.m_str.empty()) 3519 { 3520 if (LookupTypeInModule (m_interpreter, 3521 result.GetOutputStream(), 3522 module, 3523 m_options.m_str.c_str(), 3524 m_options.m_use_regex)) 3525 { 3526 result.SetStatus(eReturnStatusSuccessFinishResult); 3527 return true; 3528 } 3529 } 3530 break; 3531 3532 default: 3533 m_options.GenerateOptionUsage (result.GetErrorStream(), this); 3534 syntax_error = true; 3535 break; 3536 } 3537 3538 result.SetStatus (eReturnStatusFailed); 3539 return false; 3540 } 3541 3542 protected: 3543 virtual bool 3544 DoExecute (Args& command, 3545 CommandReturnObject &result) 3546 { 3547 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3548 if (target == NULL) 3549 { 3550 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3551 result.SetStatus (eReturnStatusFailed); 3552 return false; 3553 } 3554 else 3555 { 3556 bool syntax_error = false; 3557 uint32_t i; 3558 uint32_t num_successful_lookups = 0; 3559 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3560 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3561 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3562 // Dump all sections for all modules images 3563 3564 if (command.GetArgumentCount() == 0) 3565 { 3566 ModuleSP current_module; 3567 3568 // Where it is possible to look in the current symbol context 3569 // first, try that. If this search was successful and --all 3570 // was not passed, don't print anything else. 3571 if (LookupHere (m_interpreter, result, syntax_error)) 3572 { 3573 result.GetOutputStream().EOL(); 3574 num_successful_lookups++; 3575 if (!m_options.m_print_all) 3576 { 3577 result.SetStatus (eReturnStatusSuccessFinishResult); 3578 return result.Succeeded(); 3579 } 3580 } 3581 3582 // Dump all sections for all other modules 3583 3584 ModuleList &target_modules = target->GetImages(); 3585 Mutex::Locker modules_locker(target_modules.GetMutex()); 3586 const uint32_t num_modules = target_modules.GetSize(); 3587 if (num_modules > 0) 3588 { 3589 for (i = 0; i<num_modules && syntax_error == false; ++i) 3590 { 3591 Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i); 3592 3593 if (module_pointer != current_module.get() && 3594 LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error)) 3595 { 3596 result.GetOutputStream().EOL(); 3597 num_successful_lookups++; 3598 } 3599 } 3600 } 3601 else 3602 { 3603 result.AppendError ("the target has no associated executable images"); 3604 result.SetStatus (eReturnStatusFailed); 3605 return false; 3606 } 3607 } 3608 else 3609 { 3610 // Dump specified images (by basename or fullpath) 3611 const char *arg_cstr; 3612 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 3613 { 3614 ModuleList module_list; 3615 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false); 3616 if (num_matches > 0) 3617 { 3618 for (size_t i=0; i<num_matches; ++i) 3619 { 3620 Module *module = module_list.GetModulePointerAtIndex(i); 3621 if (module) 3622 { 3623 if (LookupInModule (m_interpreter, module, result, syntax_error)) 3624 { 3625 result.GetOutputStream().EOL(); 3626 num_successful_lookups++; 3627 } 3628 } 3629 } 3630 } 3631 else 3632 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 3633 } 3634 } 3635 3636 if (num_successful_lookups > 0) 3637 result.SetStatus (eReturnStatusSuccessFinishResult); 3638 else 3639 result.SetStatus (eReturnStatusFailed); 3640 } 3641 return result.Succeeded(); 3642 } 3643 3644 CommandOptions m_options; 3645 }; 3646 3647 OptionDefinition 3648 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 3649 { 3650 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."}, 3651 { 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."}, 3652 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5 3653 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ , 3654 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 3655 { 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."}, 3656 { 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."}, 3657 { 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)."}, 3658 { LLDB_OPT_SET_FROM_TO(3,5), 3659 false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."}, 3660 { 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."}, 3661 { 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."}, 3662 { 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."}, 3663 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 3664 { 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."}, 3665 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3666 }; 3667 3668 3669 #pragma mark CommandObjectMultiwordImageSearchPaths 3670 3671 //------------------------------------------------------------------------- 3672 // CommandObjectMultiwordImageSearchPaths 3673 //------------------------------------------------------------------------- 3674 3675 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 3676 { 3677 public: 3678 3679 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 3680 CommandObjectMultiword (interpreter, 3681 "target modules search-paths", 3682 "A set of commands for operating on debugger target image search paths.", 3683 "target modules search-paths <subcommand> [<subcommand-options>]") 3684 { 3685 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 3686 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 3687 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 3688 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 3689 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 3690 } 3691 3692 ~CommandObjectTargetModulesImageSearchPaths() 3693 { 3694 } 3695 }; 3696 3697 3698 3699 #pragma mark CommandObjectTargetModules 3700 3701 //------------------------------------------------------------------------- 3702 // CommandObjectTargetModules 3703 //------------------------------------------------------------------------- 3704 3705 class CommandObjectTargetModules : public CommandObjectMultiword 3706 { 3707 public: 3708 //------------------------------------------------------------------ 3709 // Constructors and Destructors 3710 //------------------------------------------------------------------ 3711 CommandObjectTargetModules(CommandInterpreter &interpreter) : 3712 CommandObjectMultiword (interpreter, 3713 "target modules", 3714 "A set of commands for accessing information for one or more target modules.", 3715 "target modules <sub-command> ...") 3716 { 3717 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 3718 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 3719 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter))); 3720 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 3721 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 3722 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 3723 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 3724 3725 } 3726 virtual 3727 ~CommandObjectTargetModules() 3728 { 3729 } 3730 3731 private: 3732 //------------------------------------------------------------------ 3733 // For CommandObjectTargetModules only 3734 //------------------------------------------------------------------ 3735 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 3736 }; 3737 3738 3739 3740 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed 3741 { 3742 public: 3743 CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) : 3744 CommandObjectParsed (interpreter, 3745 "target symbols add", 3746 "Add a debug symbol file to one of the target's current modules.", 3747 "target symbols add [<symfile>]") 3748 { 3749 } 3750 3751 virtual 3752 ~CommandObjectTargetSymbolsAdd () 3753 { 3754 } 3755 3756 int 3757 HandleArgumentCompletion (Args &input, 3758 int &cursor_index, 3759 int &cursor_char_position, 3760 OptionElementVector &opt_element_vector, 3761 int match_start_point, 3762 int max_return_elements, 3763 bool &word_complete, 3764 StringList &matches) 3765 { 3766 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 3767 completion_str.erase (cursor_char_position); 3768 3769 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 3770 CommandCompletions::eDiskFileCompletion, 3771 completion_str.c_str(), 3772 match_start_point, 3773 max_return_elements, 3774 NULL, 3775 word_complete, 3776 matches); 3777 return matches.GetSize(); 3778 } 3779 3780 protected: 3781 virtual bool 3782 DoExecute (Args& args, 3783 CommandReturnObject &result) 3784 { 3785 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3786 Target *target = exe_ctx.GetTargetPtr(); 3787 if (target == NULL) 3788 { 3789 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3790 result.SetStatus (eReturnStatusFailed); 3791 } 3792 else 3793 { 3794 bool flush = false; 3795 const size_t argc = args.GetArgumentCount(); 3796 if (argc == 0) 3797 { 3798 result.AppendError ("one or more symbol file paths must be specified"); 3799 result.SetStatus (eReturnStatusFailed); 3800 } 3801 else 3802 { 3803 for (size_t i=0; i<argc; ++i) 3804 { 3805 const char *symfile_path = args.GetArgumentAtIndex(i); 3806 if (symfile_path) 3807 { 3808 FileSpec symfile_spec(symfile_path, true); 3809 ArchSpec arch; 3810 if (symfile_spec.Exists()) 3811 { 3812 ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture())); 3813 if (symfile_module_sp) 3814 { 3815 // We now have a module that represents a symbol file 3816 // that can be used for a module that might exist in the 3817 // current target, so we need to find that module in the 3818 // target 3819 3820 ModuleSP old_module_sp (target->GetImages().FindModule (symfile_module_sp->GetUUID())); 3821 if (old_module_sp) 3822 { 3823 // The module has not yet created its symbol vendor, we can just 3824 // give the existing target module the symfile path to use for 3825 // when it decides to create it! 3826 old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec()); 3827 3828 // Let clients know something changed in the module 3829 // if it is currently loaded 3830 ModuleList module_list; 3831 module_list.Append (old_module_sp); 3832 target->ModulesDidLoad (module_list); 3833 flush = true; 3834 } 3835 } 3836 else 3837 { 3838 result.AppendError ("one or more executable image paths must be specified"); 3839 result.SetStatus (eReturnStatusFailed); 3840 break; 3841 } 3842 result.SetStatus (eReturnStatusSuccessFinishResult); 3843 } 3844 else 3845 { 3846 char resolved_symfile_path[PATH_MAX]; 3847 result.SetStatus (eReturnStatusFailed); 3848 if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path))) 3849 { 3850 if (strcmp (resolved_symfile_path, symfile_path) != 0) 3851 { 3852 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path); 3853 break; 3854 } 3855 } 3856 result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path); 3857 break; 3858 } 3859 } 3860 } 3861 } 3862 3863 if (flush) 3864 { 3865 Process *process = exe_ctx.GetProcessPtr(); 3866 if (process) 3867 process->Flush(); 3868 } 3869 } 3870 return result.Succeeded(); 3871 } 3872 3873 }; 3874 3875 3876 #pragma mark CommandObjectTargetSymbols 3877 3878 //------------------------------------------------------------------------- 3879 // CommandObjectTargetSymbols 3880 //------------------------------------------------------------------------- 3881 3882 class CommandObjectTargetSymbols : public CommandObjectMultiword 3883 { 3884 public: 3885 //------------------------------------------------------------------ 3886 // Constructors and Destructors 3887 //------------------------------------------------------------------ 3888 CommandObjectTargetSymbols(CommandInterpreter &interpreter) : 3889 CommandObjectMultiword (interpreter, 3890 "target symbols", 3891 "A set of commands for adding and managing debug symbol files.", 3892 "target symbols <sub-command> ...") 3893 { 3894 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter))); 3895 3896 } 3897 virtual 3898 ~CommandObjectTargetSymbols() 3899 { 3900 } 3901 3902 private: 3903 //------------------------------------------------------------------ 3904 // For CommandObjectTargetModules only 3905 //------------------------------------------------------------------ 3906 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols); 3907 }; 3908 3909 3910 #pragma mark CommandObjectTargetStopHookAdd 3911 3912 //------------------------------------------------------------------------- 3913 // CommandObjectTargetStopHookAdd 3914 //------------------------------------------------------------------------- 3915 3916 class CommandObjectTargetStopHookAdd : public CommandObjectParsed 3917 { 3918 public: 3919 3920 class CommandOptions : public Options 3921 { 3922 public: 3923 CommandOptions (CommandInterpreter &interpreter) : 3924 Options(interpreter), 3925 m_line_start(0), 3926 m_line_end (UINT_MAX), 3927 m_func_name_type_mask (eFunctionNameTypeAuto), 3928 m_sym_ctx_specified (false), 3929 m_thread_specified (false), 3930 m_use_one_liner (false), 3931 m_one_liner() 3932 { 3933 } 3934 3935 ~CommandOptions () {} 3936 3937 const OptionDefinition* 3938 GetDefinitions () 3939 { 3940 return g_option_table; 3941 } 3942 3943 virtual Error 3944 SetOptionValue (uint32_t option_idx, const char *option_arg) 3945 { 3946 Error error; 3947 char short_option = (char) m_getopt_table[option_idx].val; 3948 bool success; 3949 3950 switch (short_option) 3951 { 3952 case 'c': 3953 m_class_name = option_arg; 3954 m_sym_ctx_specified = true; 3955 break; 3956 3957 case 'e': 3958 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success); 3959 if (!success) 3960 { 3961 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg); 3962 break; 3963 } 3964 m_sym_ctx_specified = true; 3965 break; 3966 3967 case 'l': 3968 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 3969 if (!success) 3970 { 3971 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg); 3972 break; 3973 } 3974 m_sym_ctx_specified = true; 3975 break; 3976 3977 case 'i': 3978 m_no_inlines = true; 3979 break; 3980 3981 case 'n': 3982 m_function_name = option_arg; 3983 m_func_name_type_mask |= eFunctionNameTypeAuto; 3984 m_sym_ctx_specified = true; 3985 break; 3986 3987 case 'f': 3988 m_file_name = option_arg; 3989 m_sym_ctx_specified = true; 3990 break; 3991 case 's': 3992 m_module_name = option_arg; 3993 m_sym_ctx_specified = true; 3994 break; 3995 case 't' : 3996 { 3997 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 3998 if (m_thread_id == LLDB_INVALID_THREAD_ID) 3999 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 4000 m_thread_specified = true; 4001 } 4002 break; 4003 case 'T': 4004 m_thread_name = option_arg; 4005 m_thread_specified = true; 4006 break; 4007 case 'q': 4008 m_queue_name = option_arg; 4009 m_thread_specified = true; 4010 break; 4011 case 'x': 4012 { 4013 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 4014 if (m_thread_id == UINT32_MAX) 4015 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 4016 m_thread_specified = true; 4017 } 4018 break; 4019 case 'o': 4020 m_use_one_liner = true; 4021 m_one_liner = option_arg; 4022 break; 4023 default: 4024 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option); 4025 break; 4026 } 4027 return error; 4028 } 4029 4030 void 4031 OptionParsingStarting () 4032 { 4033 m_class_name.clear(); 4034 m_function_name.clear(); 4035 m_line_start = 0; 4036 m_line_end = UINT_MAX; 4037 m_file_name.clear(); 4038 m_module_name.clear(); 4039 m_func_name_type_mask = eFunctionNameTypeAuto; 4040 m_thread_id = LLDB_INVALID_THREAD_ID; 4041 m_thread_index = UINT32_MAX; 4042 m_thread_name.clear(); 4043 m_queue_name.clear(); 4044 4045 m_no_inlines = false; 4046 m_sym_ctx_specified = false; 4047 m_thread_specified = false; 4048 4049 m_use_one_liner = false; 4050 m_one_liner.clear(); 4051 } 4052 4053 4054 static OptionDefinition g_option_table[]; 4055 4056 std::string m_class_name; 4057 std::string m_function_name; 4058 uint32_t m_line_start; 4059 uint32_t m_line_end; 4060 std::string m_file_name; 4061 std::string m_module_name; 4062 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 4063 lldb::tid_t m_thread_id; 4064 uint32_t m_thread_index; 4065 std::string m_thread_name; 4066 std::string m_queue_name; 4067 bool m_sym_ctx_specified; 4068 bool m_no_inlines; 4069 bool m_thread_specified; 4070 // Instance variables to hold the values for one_liner options. 4071 bool m_use_one_liner; 4072 std::string m_one_liner; 4073 }; 4074 4075 Options * 4076 GetOptions () 4077 { 4078 return &m_options; 4079 } 4080 4081 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 4082 CommandObjectParsed (interpreter, 4083 "target stop-hook add ", 4084 "Add a hook to be executed when the target stops.", 4085 "target stop-hook add"), 4086 m_options (interpreter) 4087 { 4088 } 4089 4090 ~CommandObjectTargetStopHookAdd () 4091 { 4092 } 4093 4094 static size_t 4095 ReadCommandsCallbackFunction (void *baton, 4096 InputReader &reader, 4097 lldb::InputReaderAction notification, 4098 const char *bytes, 4099 size_t bytes_len) 4100 { 4101 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 4102 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton); 4103 static bool got_interrupted; 4104 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 4105 4106 switch (notification) 4107 { 4108 case eInputReaderActivate: 4109 if (!batch_mode) 4110 { 4111 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end."); 4112 if (reader.GetPrompt()) 4113 out_stream->Printf ("%s", reader.GetPrompt()); 4114 out_stream->Flush(); 4115 } 4116 got_interrupted = false; 4117 break; 4118 4119 case eInputReaderDeactivate: 4120 break; 4121 4122 case eInputReaderReactivate: 4123 if (reader.GetPrompt() && !batch_mode) 4124 { 4125 out_stream->Printf ("%s", reader.GetPrompt()); 4126 out_stream->Flush(); 4127 } 4128 got_interrupted = false; 4129 break; 4130 4131 case eInputReaderAsynchronousOutputWritten: 4132 break; 4133 4134 case eInputReaderGotToken: 4135 if (bytes && bytes_len && baton) 4136 { 4137 StringList *commands = new_stop_hook->GetCommandPointer(); 4138 if (commands) 4139 { 4140 commands->AppendString (bytes, bytes_len); 4141 } 4142 } 4143 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode) 4144 { 4145 out_stream->Printf ("%s", reader.GetPrompt()); 4146 out_stream->Flush(); 4147 } 4148 break; 4149 4150 case eInputReaderInterrupt: 4151 { 4152 // Finish, and cancel the stop hook. 4153 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID()); 4154 if (!batch_mode) 4155 { 4156 out_stream->Printf ("Stop hook cancelled.\n"); 4157 out_stream->Flush(); 4158 } 4159 4160 reader.SetIsDone (true); 4161 } 4162 got_interrupted = true; 4163 break; 4164 4165 case eInputReaderEndOfFile: 4166 reader.SetIsDone (true); 4167 break; 4168 4169 case eInputReaderDone: 4170 if (!got_interrupted && !batch_mode) 4171 { 4172 out_stream->Printf ("Stop hook #%llu added.\n", new_stop_hook->GetID()); 4173 out_stream->Flush(); 4174 } 4175 break; 4176 } 4177 4178 return bytes_len; 4179 } 4180 4181 protected: 4182 bool 4183 DoExecute (Args& command, CommandReturnObject &result) 4184 { 4185 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4186 if (target) 4187 { 4188 Target::StopHookSP new_hook_sp; 4189 target->AddStopHook (new_hook_sp); 4190 4191 // First step, make the specifier. 4192 std::auto_ptr<SymbolContextSpecifier> specifier_ap; 4193 if (m_options.m_sym_ctx_specified) 4194 { 4195 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 4196 4197 if (!m_options.m_module_name.empty()) 4198 { 4199 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 4200 } 4201 4202 if (!m_options.m_class_name.empty()) 4203 { 4204 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 4205 } 4206 4207 if (!m_options.m_file_name.empty()) 4208 { 4209 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 4210 } 4211 4212 if (m_options.m_line_start != 0) 4213 { 4214 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 4215 } 4216 4217 if (m_options.m_line_end != UINT_MAX) 4218 { 4219 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 4220 } 4221 4222 if (!m_options.m_function_name.empty()) 4223 { 4224 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 4225 } 4226 } 4227 4228 if (specifier_ap.get()) 4229 new_hook_sp->SetSpecifier (specifier_ap.release()); 4230 4231 // Next see if any of the thread options have been entered: 4232 4233 if (m_options.m_thread_specified) 4234 { 4235 ThreadSpec *thread_spec = new ThreadSpec(); 4236 4237 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 4238 { 4239 thread_spec->SetTID (m_options.m_thread_id); 4240 } 4241 4242 if (m_options.m_thread_index != UINT32_MAX) 4243 thread_spec->SetIndex (m_options.m_thread_index); 4244 4245 if (!m_options.m_thread_name.empty()) 4246 thread_spec->SetName (m_options.m_thread_name.c_str()); 4247 4248 if (!m_options.m_queue_name.empty()) 4249 thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 4250 4251 new_hook_sp->SetThreadSpecifier (thread_spec); 4252 4253 } 4254 if (m_options.m_use_one_liner) 4255 { 4256 // Use one-liner. 4257 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 4258 result.AppendMessageWithFormat("Stop hook #%llu added.\n", new_hook_sp->GetID()); 4259 } 4260 else 4261 { 4262 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into 4263 // the new stop hook's command string. 4264 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 4265 if (!reader_sp) 4266 { 4267 result.AppendError("out of memory\n"); 4268 result.SetStatus (eReturnStatusFailed); 4269 target->RemoveStopHookByID (new_hook_sp->GetID()); 4270 return false; 4271 } 4272 4273 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction, 4274 new_hook_sp.get(), // baton 4275 eInputReaderGranularityLine, // token size, to pass to callback function 4276 "DONE", // end token 4277 "> ", // prompt 4278 true)); // echo input 4279 if (!err.Success()) 4280 { 4281 result.AppendError (err.AsCString()); 4282 result.SetStatus (eReturnStatusFailed); 4283 target->RemoveStopHookByID (new_hook_sp->GetID()); 4284 return false; 4285 } 4286 m_interpreter.GetDebugger().PushInputReader (reader_sp); 4287 } 4288 result.SetStatus (eReturnStatusSuccessFinishNoResult); 4289 } 4290 else 4291 { 4292 result.AppendError ("invalid target\n"); 4293 result.SetStatus (eReturnStatusFailed); 4294 } 4295 4296 return result.Succeeded(); 4297 } 4298 private: 4299 CommandOptions m_options; 4300 }; 4301 4302 OptionDefinition 4303 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 4304 { 4305 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner, 4306 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 4307 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 4308 "Set the module within which the stop-hook is to be run."}, 4309 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex, 4310 "The stop hook is run only for the thread whose index matches this argument."}, 4311 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID, 4312 "The stop hook is run only for the thread whose TID matches this argument."}, 4313 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName, 4314 "The stop hook is run only for the thread whose thread name matches this argument."}, 4315 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName, 4316 "The stop hook is run only for threads in the queue whose name is given by this argument."}, 4317 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 4318 "Specify the source file within which the stop-hook is to be run." }, 4319 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 4320 "Set the start of the line range for which the stop-hook is to be run."}, 4321 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum, 4322 "Set the end of the line range for which the stop-hook is to be run."}, 4323 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName, 4324 "Specify the class within which the stop-hook is to be run." }, 4325 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 4326 "Set the function name within which the stop hook will be run." }, 4327 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 4328 }; 4329 4330 #pragma mark CommandObjectTargetStopHookDelete 4331 4332 //------------------------------------------------------------------------- 4333 // CommandObjectTargetStopHookDelete 4334 //------------------------------------------------------------------------- 4335 4336 class CommandObjectTargetStopHookDelete : public CommandObjectParsed 4337 { 4338 public: 4339 4340 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 4341 CommandObjectParsed (interpreter, 4342 "target stop-hook delete", 4343 "Delete a stop-hook.", 4344 "target stop-hook delete [<idx>]") 4345 { 4346 } 4347 4348 ~CommandObjectTargetStopHookDelete () 4349 { 4350 } 4351 4352 protected: 4353 bool 4354 DoExecute (Args& command, CommandReturnObject &result) 4355 { 4356 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4357 if (target) 4358 { 4359 // FIXME: see if we can use the breakpoint id style parser? 4360 size_t num_args = command.GetArgumentCount(); 4361 if (num_args == 0) 4362 { 4363 if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 4364 { 4365 result.SetStatus (eReturnStatusFailed); 4366 return false; 4367 } 4368 else 4369 { 4370 target->RemoveAllStopHooks(); 4371 } 4372 } 4373 else 4374 { 4375 bool success; 4376 for (size_t i = 0; i < num_args; i++) 4377 { 4378 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 4379 if (!success) 4380 { 4381 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4382 result.SetStatus(eReturnStatusFailed); 4383 return false; 4384 } 4385 success = target->RemoveStopHookByID (user_id); 4386 if (!success) 4387 { 4388 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4389 result.SetStatus(eReturnStatusFailed); 4390 return false; 4391 } 4392 } 4393 } 4394 result.SetStatus (eReturnStatusSuccessFinishNoResult); 4395 } 4396 else 4397 { 4398 result.AppendError ("invalid target\n"); 4399 result.SetStatus (eReturnStatusFailed); 4400 } 4401 4402 return result.Succeeded(); 4403 } 4404 }; 4405 #pragma mark CommandObjectTargetStopHookEnableDisable 4406 4407 //------------------------------------------------------------------------- 4408 // CommandObjectTargetStopHookEnableDisable 4409 //------------------------------------------------------------------------- 4410 4411 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed 4412 { 4413 public: 4414 4415 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 4416 CommandObjectParsed (interpreter, 4417 name, 4418 help, 4419 syntax), 4420 m_enable (enable) 4421 { 4422 } 4423 4424 ~CommandObjectTargetStopHookEnableDisable () 4425 { 4426 } 4427 4428 protected: 4429 bool 4430 DoExecute (Args& command, CommandReturnObject &result) 4431 { 4432 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4433 if (target) 4434 { 4435 // FIXME: see if we can use the breakpoint id style parser? 4436 size_t num_args = command.GetArgumentCount(); 4437 bool success; 4438 4439 if (num_args == 0) 4440 { 4441 target->SetAllStopHooksActiveState (m_enable); 4442 } 4443 else 4444 { 4445 for (size_t i = 0; i < num_args; i++) 4446 { 4447 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 4448 if (!success) 4449 { 4450 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4451 result.SetStatus(eReturnStatusFailed); 4452 return false; 4453 } 4454 success = target->SetStopHookActiveStateByID (user_id, m_enable); 4455 if (!success) 4456 { 4457 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 4458 result.SetStatus(eReturnStatusFailed); 4459 return false; 4460 } 4461 } 4462 } 4463 result.SetStatus (eReturnStatusSuccessFinishNoResult); 4464 } 4465 else 4466 { 4467 result.AppendError ("invalid target\n"); 4468 result.SetStatus (eReturnStatusFailed); 4469 } 4470 return result.Succeeded(); 4471 } 4472 private: 4473 bool m_enable; 4474 }; 4475 4476 #pragma mark CommandObjectTargetStopHookList 4477 4478 //------------------------------------------------------------------------- 4479 // CommandObjectTargetStopHookList 4480 //------------------------------------------------------------------------- 4481 4482 class CommandObjectTargetStopHookList : public CommandObjectParsed 4483 { 4484 public: 4485 4486 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 4487 CommandObjectParsed (interpreter, 4488 "target stop-hook list", 4489 "List all stop-hooks.", 4490 "target stop-hook list [<type>]") 4491 { 4492 } 4493 4494 ~CommandObjectTargetStopHookList () 4495 { 4496 } 4497 4498 protected: 4499 bool 4500 DoExecute (Args& command, CommandReturnObject &result) 4501 { 4502 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4503 if (!target) 4504 { 4505 result.AppendError ("invalid target\n"); 4506 result.SetStatus (eReturnStatusFailed); 4507 return result.Succeeded(); 4508 } 4509 4510 size_t num_hooks = target->GetNumStopHooks (); 4511 if (num_hooks == 0) 4512 { 4513 result.GetOutputStream().PutCString ("No stop hooks.\n"); 4514 } 4515 else 4516 { 4517 for (size_t i = 0; i < num_hooks; i++) 4518 { 4519 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 4520 if (i > 0) 4521 result.GetOutputStream().PutCString ("\n"); 4522 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 4523 } 4524 } 4525 result.SetStatus (eReturnStatusSuccessFinishResult); 4526 return result.Succeeded(); 4527 } 4528 }; 4529 4530 #pragma mark CommandObjectMultiwordTargetStopHooks 4531 //------------------------------------------------------------------------- 4532 // CommandObjectMultiwordTargetStopHooks 4533 //------------------------------------------------------------------------- 4534 4535 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 4536 { 4537 public: 4538 4539 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 4540 CommandObjectMultiword (interpreter, 4541 "target stop-hook", 4542 "A set of commands for operating on debugger target stop-hooks.", 4543 "target stop-hook <subcommand> [<subcommand-options>]") 4544 { 4545 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 4546 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 4547 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 4548 false, 4549 "target stop-hook disable [<id>]", 4550 "Disable a stop-hook.", 4551 "target stop-hook disable"))); 4552 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 4553 true, 4554 "target stop-hook enable [<id>]", 4555 "Enable a stop-hook.", 4556 "target stop-hook enable"))); 4557 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 4558 } 4559 4560 ~CommandObjectMultiwordTargetStopHooks() 4561 { 4562 } 4563 }; 4564 4565 4566 4567 #pragma mark CommandObjectMultiwordTarget 4568 4569 //------------------------------------------------------------------------- 4570 // CommandObjectMultiwordTarget 4571 //------------------------------------------------------------------------- 4572 4573 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 4574 CommandObjectMultiword (interpreter, 4575 "target", 4576 "A set of commands for operating on debugger targets.", 4577 "target <subcommand> [<subcommand-options>]") 4578 { 4579 4580 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 4581 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 4582 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 4583 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 4584 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 4585 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 4586 LoadSubCommand ("symbols", CommandObjectSP (new CommandObjectTargetSymbols (interpreter))); 4587 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 4588 } 4589 4590 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 4591 { 4592 } 4593 4594 4595