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