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