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