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