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_format_array() 2621 { 2622 } 2623 2624 virtual 2625 ~CommandOptions () 2626 { 2627 } 2628 2629 virtual Error 2630 SetOptionValue (uint32_t option_idx, const char *option_arg) 2631 { 2632 char short_option = (char) m_getopt_table[option_idx].val; 2633 if (short_option == 'g') 2634 { 2635 m_use_global_module_list = true; 2636 } 2637 else 2638 { 2639 uint32_t width = 0; 2640 if (option_arg) 2641 width = strtoul (option_arg, NULL, 0); 2642 m_format_array.push_back(std::make_pair(short_option, width)); 2643 } 2644 Error error; 2645 return error; 2646 } 2647 2648 void 2649 OptionParsingStarting () 2650 { 2651 m_format_array.clear(); 2652 m_use_global_module_list = false; 2653 } 2654 2655 const OptionDefinition* 2656 GetDefinitions () 2657 { 2658 return g_option_table; 2659 } 2660 2661 // Options table: Required for subclasses of Options. 2662 2663 static OptionDefinition g_option_table[]; 2664 2665 // Instance variables to hold the values for command options. 2666 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection; 2667 FormatWidthCollection m_format_array; 2668 bool m_use_global_module_list; 2669 }; 2670 2671 CommandObjectTargetModulesList (CommandInterpreter &interpreter) : 2672 CommandObject (interpreter, 2673 "target modules list", 2674 "List current executable and dependent shared library images.", 2675 "target modules list [<cmd-options>]"), 2676 m_options (interpreter) 2677 { 2678 } 2679 2680 virtual 2681 ~CommandObjectTargetModulesList () 2682 { 2683 } 2684 2685 virtual 2686 Options * 2687 GetOptions () 2688 { 2689 return &m_options; 2690 } 2691 2692 virtual bool 2693 Execute (Args& command, 2694 CommandReturnObject &result) 2695 { 2696 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2697 const bool use_global_module_list = m_options.m_use_global_module_list; 2698 if (target == NULL && use_global_module_list == false) 2699 { 2700 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2701 result.SetStatus (eReturnStatusFailed); 2702 return false; 2703 } 2704 else 2705 { 2706 if (target) 2707 { 2708 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2709 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2710 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2711 } 2712 // Dump all sections for all modules images 2713 uint32_t num_modules = 0; 2714 Mutex::Locker locker; 2715 if (use_global_module_list) 2716 { 2717 locker.Reset (Module::GetAllocationModuleCollectionMutex().GetMutex()); 2718 num_modules = Module::GetNumberAllocatedModules(); 2719 } 2720 else 2721 num_modules = target->GetImages().GetSize(); 2722 2723 if (num_modules > 0) 2724 { 2725 Stream &strm = result.GetOutputStream(); 2726 2727 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2728 { 2729 ModuleSP module_sp; 2730 Module *module; 2731 if (use_global_module_list) 2732 { 2733 module = Module::GetAllocatedModuleAtIndex(image_idx); 2734 module_sp = module; 2735 } 2736 else 2737 { 2738 module_sp = target->GetImages().GetModuleAtIndex(image_idx); 2739 module = module_sp.get(); 2740 } 2741 2742 strm.Printf("[%3u] ", image_idx); 2743 2744 bool dump_object_name = false; 2745 if (m_options.m_format_array.empty()) 2746 { 2747 DumpFullpath(strm, &module->GetFileSpec(), 0); 2748 dump_object_name = true; 2749 } 2750 else 2751 { 2752 const size_t num_entries = m_options.m_format_array.size(); 2753 for (size_t i=0; i<num_entries; ++i) 2754 { 2755 if (i > 0) 2756 strm.PutChar(' '); 2757 char format_char = m_options.m_format_array[i].first; 2758 uint32_t width = m_options.m_format_array[i].second; 2759 switch (format_char) 2760 { 2761 case 'a': 2762 DumpModuleArchitecture (strm, module, false, width); 2763 break; 2764 2765 case 't': 2766 DumpModuleArchitecture (strm, module, true, width); 2767 break; 2768 2769 case 'f': 2770 DumpFullpath (strm, &module->GetFileSpec(), width); 2771 dump_object_name = true; 2772 break; 2773 2774 case 'd': 2775 DumpDirectory (strm, &module->GetFileSpec(), width); 2776 break; 2777 2778 case 'b': 2779 DumpBasename (strm, &module->GetFileSpec(), width); 2780 dump_object_name = true; 2781 break; 2782 2783 case 'r': 2784 { 2785 uint32_t ref_count = 0; 2786 if (module_sp) 2787 { 2788 // Take one away to make sure we don't count our local "module_sp" 2789 ref_count = module_sp.use_count() - 1; 2790 } 2791 if (width) 2792 strm.Printf("{%*u}", width, ref_count); 2793 else 2794 strm.Printf("{%u}", ref_count); 2795 } 2796 break; 2797 2798 case 's': 2799 case 'S': 2800 { 2801 SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 2802 if (symbol_vendor) 2803 { 2804 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 2805 if (symbol_file) 2806 { 2807 if (format_char == 'S') 2808 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 2809 else 2810 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 2811 dump_object_name = true; 2812 break; 2813 } 2814 } 2815 strm.Printf("%.*s", width, "<NONE>"); 2816 } 2817 break; 2818 2819 case 'm': 2820 module->GetModificationTime().Dump(&strm, width); 2821 break; 2822 2823 case 'p': 2824 strm.Printf("%p", module); 2825 break; 2826 2827 case 'u': 2828 DumpModuleUUID(strm, module); 2829 break; 2830 2831 default: 2832 break; 2833 } 2834 2835 } 2836 } 2837 if (dump_object_name) 2838 { 2839 const char *object_name = module->GetObjectName().GetCString(); 2840 if (object_name) 2841 strm.Printf ("(%s)", object_name); 2842 } 2843 strm.EOL(); 2844 } 2845 result.SetStatus (eReturnStatusSuccessFinishResult); 2846 } 2847 else 2848 { 2849 if (use_global_module_list) 2850 result.AppendError ("the global module list is empty"); 2851 else 2852 result.AppendError ("the target has no associated executable images"); 2853 result.SetStatus (eReturnStatusFailed); 2854 return false; 2855 } 2856 } 2857 return result.Succeeded(); 2858 } 2859 protected: 2860 2861 CommandOptions m_options; 2862 }; 2863 2864 OptionDefinition 2865 CommandObjectTargetModulesList::CommandOptions::g_option_table[] = 2866 { 2867 { LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, 2868 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, 2869 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, 2870 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, 2871 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, 2872 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, 2873 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, 2874 { LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."}, 2875 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, 2876 { 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."}, 2877 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."}, 2878 { 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."}, 2879 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2880 }; 2881 2882 2883 2884 //---------------------------------------------------------------------- 2885 // Lookup information in images 2886 //---------------------------------------------------------------------- 2887 class CommandObjectTargetModulesLookup : public CommandObject 2888 { 2889 public: 2890 2891 enum 2892 { 2893 eLookupTypeInvalid = -1, 2894 eLookupTypeAddress = 0, 2895 eLookupTypeSymbol, 2896 eLookupTypeFileLine, // Line is optional 2897 eLookupTypeFunction, 2898 eLookupTypeType, 2899 kNumLookupTypes 2900 }; 2901 2902 class CommandOptions : public Options 2903 { 2904 public: 2905 2906 CommandOptions (CommandInterpreter &interpreter) : 2907 Options(interpreter) 2908 { 2909 OptionParsingStarting(); 2910 } 2911 2912 virtual 2913 ~CommandOptions () 2914 { 2915 } 2916 2917 virtual Error 2918 SetOptionValue (uint32_t option_idx, const char *option_arg) 2919 { 2920 Error error; 2921 2922 char short_option = (char) m_getopt_table[option_idx].val; 2923 2924 switch (short_option) 2925 { 2926 case 'a': 2927 m_type = eLookupTypeAddress; 2928 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 2929 if (m_addr == LLDB_INVALID_ADDRESS) 2930 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg); 2931 break; 2932 2933 case 'o': 2934 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 2935 if (m_offset == LLDB_INVALID_ADDRESS) 2936 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg); 2937 break; 2938 2939 case 's': 2940 m_str = option_arg; 2941 m_type = eLookupTypeSymbol; 2942 break; 2943 2944 case 'f': 2945 m_file.SetFile (option_arg, false); 2946 m_type = eLookupTypeFileLine; 2947 break; 2948 2949 case 'i': 2950 m_check_inlines = false; 2951 break; 2952 2953 case 'l': 2954 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); 2955 if (m_line_number == UINT32_MAX) 2956 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg); 2957 else if (m_line_number == 0) 2958 error.SetErrorString ("Zero is an invalid line number."); 2959 m_type = eLookupTypeFileLine; 2960 break; 2961 2962 case 'n': 2963 m_str = option_arg; 2964 m_type = eLookupTypeFunction; 2965 break; 2966 2967 case 't': 2968 m_str = option_arg; 2969 m_type = eLookupTypeType; 2970 break; 2971 2972 case 'v': 2973 m_verbose = 1; 2974 break; 2975 2976 case 'r': 2977 m_use_regex = true; 2978 break; 2979 } 2980 2981 return error; 2982 } 2983 2984 void 2985 OptionParsingStarting () 2986 { 2987 m_type = eLookupTypeInvalid; 2988 m_str.clear(); 2989 m_file.Clear(); 2990 m_addr = LLDB_INVALID_ADDRESS; 2991 m_offset = 0; 2992 m_line_number = 0; 2993 m_use_regex = false; 2994 m_check_inlines = true; 2995 m_verbose = false; 2996 } 2997 2998 const OptionDefinition* 2999 GetDefinitions () 3000 { 3001 return g_option_table; 3002 } 3003 3004 // Options table: Required for subclasses of Options. 3005 3006 static OptionDefinition g_option_table[]; 3007 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3008 std::string m_str; // Holds name lookup 3009 FileSpec m_file; // Files for file lookups 3010 lldb::addr_t m_addr; // Holds the address to lookup 3011 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 3012 uint32_t m_line_number; // Line number for file+line lookups 3013 bool m_use_regex; // Name lookups in m_str are regular expressions. 3014 bool m_check_inlines;// Check for inline entries when looking up by file/line. 3015 bool m_verbose; // Enable verbose lookup info 3016 3017 }; 3018 3019 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 3020 CommandObject (interpreter, 3021 "target modules lookup", 3022 "Look up information within executable and dependent shared library images.", 3023 NULL), 3024 m_options (interpreter) 3025 { 3026 CommandArgumentEntry arg; 3027 CommandArgumentData file_arg; 3028 3029 // Define the first (and only) variant of this arg. 3030 file_arg.arg_type = eArgTypeFilename; 3031 file_arg.arg_repetition = eArgRepeatStar; 3032 3033 // There is only one variant this argument could be; put it into the argument entry. 3034 arg.push_back (file_arg); 3035 3036 // Push the data for the first argument into the m_arguments vector. 3037 m_arguments.push_back (arg); 3038 } 3039 3040 virtual 3041 ~CommandObjectTargetModulesLookup () 3042 { 3043 } 3044 3045 virtual Options * 3046 GetOptions () 3047 { 3048 return &m_options; 3049 } 3050 3051 3052 bool 3053 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 3054 { 3055 switch (m_options.m_type) 3056 { 3057 case eLookupTypeAddress: 3058 if (m_options.m_addr != LLDB_INVALID_ADDRESS) 3059 { 3060 if (LookupAddressInModule (m_interpreter, 3061 result.GetOutputStream(), 3062 module, 3063 eSymbolContextEverything, 3064 m_options.m_addr, 3065 m_options.m_offset, 3066 m_options.m_verbose)) 3067 { 3068 result.SetStatus(eReturnStatusSuccessFinishResult); 3069 return true; 3070 } 3071 } 3072 break; 3073 3074 case eLookupTypeSymbol: 3075 if (!m_options.m_str.empty()) 3076 { 3077 if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex)) 3078 { 3079 result.SetStatus(eReturnStatusSuccessFinishResult); 3080 return true; 3081 } 3082 } 3083 break; 3084 3085 case eLookupTypeFileLine: 3086 if (m_options.m_file) 3087 { 3088 3089 if (LookupFileAndLineInModule (m_interpreter, 3090 result.GetOutputStream(), 3091 module, 3092 m_options.m_file, 3093 m_options.m_line_number, 3094 m_options.m_check_inlines, 3095 m_options.m_verbose)) 3096 { 3097 result.SetStatus(eReturnStatusSuccessFinishResult); 3098 return true; 3099 } 3100 } 3101 break; 3102 3103 case eLookupTypeFunction: 3104 if (!m_options.m_str.empty()) 3105 { 3106 if (LookupFunctionInModule (m_interpreter, 3107 result.GetOutputStream(), 3108 module, 3109 m_options.m_str.c_str(), 3110 m_options.m_use_regex, 3111 m_options.m_verbose)) 3112 { 3113 result.SetStatus(eReturnStatusSuccessFinishResult); 3114 return true; 3115 } 3116 } 3117 break; 3118 3119 case eLookupTypeType: 3120 if (!m_options.m_str.empty()) 3121 { 3122 if (LookupTypeInModule (m_interpreter, 3123 result.GetOutputStream(), 3124 module, 3125 m_options.m_str.c_str(), 3126 m_options.m_use_regex)) 3127 { 3128 result.SetStatus(eReturnStatusSuccessFinishResult); 3129 return true; 3130 } 3131 } 3132 break; 3133 3134 default: 3135 m_options.GenerateOptionUsage (result.GetErrorStream(), this); 3136 syntax_error = true; 3137 break; 3138 } 3139 3140 result.SetStatus (eReturnStatusFailed); 3141 return false; 3142 } 3143 3144 virtual bool 3145 Execute (Args& command, 3146 CommandReturnObject &result) 3147 { 3148 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3149 if (target == NULL) 3150 { 3151 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3152 result.SetStatus (eReturnStatusFailed); 3153 return false; 3154 } 3155 else 3156 { 3157 bool syntax_error = false; 3158 uint32_t i; 3159 uint32_t num_successful_lookups = 0; 3160 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3161 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3162 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3163 // Dump all sections for all modules images 3164 3165 if (command.GetArgumentCount() == 0) 3166 { 3167 // Dump all sections for all modules images 3168 const uint32_t num_modules = target->GetImages().GetSize(); 3169 if (num_modules > 0) 3170 { 3171 for (i = 0; i<num_modules && syntax_error == false; ++i) 3172 { 3173 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error)) 3174 { 3175 result.GetOutputStream().EOL(); 3176 num_successful_lookups++; 3177 } 3178 } 3179 } 3180 else 3181 { 3182 result.AppendError ("the target has no associated executable images"); 3183 result.SetStatus (eReturnStatusFailed); 3184 return false; 3185 } 3186 } 3187 else 3188 { 3189 // Dump specified images (by basename or fullpath) 3190 const char *arg_cstr; 3191 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 3192 { 3193 FileSpec image_file(arg_cstr, false); 3194 ModuleList matching_modules; 3195 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); 3196 3197 // Not found in our module list for our target, check the main 3198 // shared module list in case it is a extra file used somewhere 3199 // else 3200 if (num_matching_modules == 0) 3201 num_matching_modules = ModuleList::FindSharedModules (image_file, 3202 target->GetArchitecture(), 3203 NULL, 3204 NULL, 3205 matching_modules); 3206 3207 if (num_matching_modules > 0) 3208 { 3209 for (size_t j=0; j<num_matching_modules; ++j) 3210 { 3211 Module * image_module = matching_modules.GetModulePointerAtIndex(j); 3212 if (image_module) 3213 { 3214 if (LookupInModule (m_interpreter, image_module, result, syntax_error)) 3215 { 3216 result.GetOutputStream().EOL(); 3217 num_successful_lookups++; 3218 } 3219 } 3220 } 3221 } 3222 else 3223 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 3224 } 3225 } 3226 3227 if (num_successful_lookups > 0) 3228 result.SetStatus (eReturnStatusSuccessFinishResult); 3229 else 3230 result.SetStatus (eReturnStatusFailed); 3231 } 3232 return result.Succeeded(); 3233 } 3234 protected: 3235 3236 CommandOptions m_options; 3237 }; 3238 3239 OptionDefinition 3240 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 3241 { 3242 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."}, 3243 { 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."}, 3244 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 3245 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_5 */ , 3246 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 3247 { 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."}, 3248 { 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."}, 3249 { 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)."}, 3250 { LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."}, 3251 { 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."}, 3252 { 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."}, 3253 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 3254 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3255 }; 3256 3257 3258 #pragma mark CommandObjectMultiwordImageSearchPaths 3259 3260 //------------------------------------------------------------------------- 3261 // CommandObjectMultiwordImageSearchPaths 3262 //------------------------------------------------------------------------- 3263 3264 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 3265 { 3266 public: 3267 3268 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 3269 CommandObjectMultiword (interpreter, 3270 "target modules search-paths", 3271 "A set of commands for operating on debugger target image search paths.", 3272 "target modules search-paths <subcommand> [<subcommand-options>]") 3273 { 3274 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 3275 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 3276 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 3277 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 3278 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 3279 } 3280 3281 ~CommandObjectTargetModulesImageSearchPaths() 3282 { 3283 } 3284 }; 3285 3286 3287 3288 #pragma mark CommandObjectTargetModules 3289 3290 //------------------------------------------------------------------------- 3291 // CommandObjectTargetModules 3292 //------------------------------------------------------------------------- 3293 3294 class CommandObjectTargetModules : public CommandObjectMultiword 3295 { 3296 public: 3297 //------------------------------------------------------------------ 3298 // Constructors and Destructors 3299 //------------------------------------------------------------------ 3300 CommandObjectTargetModules(CommandInterpreter &interpreter) : 3301 CommandObjectMultiword (interpreter, 3302 "target modules", 3303 "A set of commands for accessing information for one or more target modules.", 3304 "target modules <sub-command> ...") 3305 { 3306 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 3307 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 3308 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter))); 3309 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 3310 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 3311 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 3312 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 3313 3314 } 3315 virtual 3316 ~CommandObjectTargetModules() 3317 { 3318 } 3319 3320 private: 3321 //------------------------------------------------------------------ 3322 // For CommandObjectTargetModules only 3323 //------------------------------------------------------------------ 3324 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 3325 }; 3326 3327 3328 #pragma mark CommandObjectTargetStopHookAdd 3329 3330 //------------------------------------------------------------------------- 3331 // CommandObjectTargetStopHookAdd 3332 //------------------------------------------------------------------------- 3333 3334 class CommandObjectTargetStopHookAdd : public CommandObject 3335 { 3336 public: 3337 3338 class CommandOptions : public Options 3339 { 3340 public: 3341 CommandOptions (CommandInterpreter &interpreter) : 3342 Options(interpreter), 3343 m_line_start(0), 3344 m_line_end (UINT_MAX), 3345 m_func_name_type_mask (eFunctionNameTypeAuto), 3346 m_sym_ctx_specified (false), 3347 m_thread_specified (false), 3348 m_use_one_liner (false), 3349 m_one_liner() 3350 { 3351 } 3352 3353 ~CommandOptions () {} 3354 3355 const OptionDefinition* 3356 GetDefinitions () 3357 { 3358 return g_option_table; 3359 } 3360 3361 virtual Error 3362 SetOptionValue (uint32_t option_idx, const char *option_arg) 3363 { 3364 Error error; 3365 char short_option = (char) m_getopt_table[option_idx].val; 3366 bool success; 3367 3368 switch (short_option) 3369 { 3370 case 'c': 3371 m_class_name = option_arg; 3372 m_sym_ctx_specified = true; 3373 break; 3374 3375 case 'e': 3376 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success); 3377 if (!success) 3378 { 3379 error.SetErrorStringWithFormat ("Invalid end line number: \"%s\".", option_arg); 3380 break; 3381 } 3382 m_sym_ctx_specified = true; 3383 break; 3384 3385 case 'l': 3386 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 3387 if (!success) 3388 { 3389 error.SetErrorStringWithFormat ("Invalid start line number: \"%s\".", option_arg); 3390 break; 3391 } 3392 m_sym_ctx_specified = true; 3393 break; 3394 3395 case 'n': 3396 m_function_name = option_arg; 3397 m_func_name_type_mask |= eFunctionNameTypeAuto; 3398 m_sym_ctx_specified = true; 3399 break; 3400 3401 case 'f': 3402 m_file_name = option_arg; 3403 m_sym_ctx_specified = true; 3404 break; 3405 case 's': 3406 m_module_name = option_arg; 3407 m_sym_ctx_specified = true; 3408 break; 3409 case 't' : 3410 { 3411 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 3412 if (m_thread_id == LLDB_INVALID_THREAD_ID) 3413 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg); 3414 m_thread_specified = true; 3415 } 3416 break; 3417 case 'T': 3418 m_thread_name = option_arg; 3419 m_thread_specified = true; 3420 break; 3421 case 'q': 3422 m_queue_name = option_arg; 3423 m_thread_specified = true; 3424 break; 3425 case 'x': 3426 { 3427 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 3428 if (m_thread_id == UINT32_MAX) 3429 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg); 3430 m_thread_specified = true; 3431 } 3432 break; 3433 case 'o': 3434 m_use_one_liner = true; 3435 m_one_liner = option_arg; 3436 break; 3437 default: 3438 error.SetErrorStringWithFormat ("Unrecognized option %c.", short_option); 3439 break; 3440 } 3441 return error; 3442 } 3443 3444 void 3445 OptionParsingStarting () 3446 { 3447 m_class_name.clear(); 3448 m_function_name.clear(); 3449 m_line_start = 0; 3450 m_line_end = UINT_MAX; 3451 m_file_name.clear(); 3452 m_module_name.clear(); 3453 m_func_name_type_mask = eFunctionNameTypeAuto; 3454 m_thread_id = LLDB_INVALID_THREAD_ID; 3455 m_thread_index = UINT32_MAX; 3456 m_thread_name.clear(); 3457 m_queue_name.clear(); 3458 3459 m_sym_ctx_specified = false; 3460 m_thread_specified = false; 3461 3462 m_use_one_liner = false; 3463 m_one_liner.clear(); 3464 } 3465 3466 3467 static OptionDefinition g_option_table[]; 3468 3469 std::string m_class_name; 3470 std::string m_function_name; 3471 uint32_t m_line_start; 3472 uint32_t m_line_end; 3473 std::string m_file_name; 3474 std::string m_module_name; 3475 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 3476 lldb::tid_t m_thread_id; 3477 uint32_t m_thread_index; 3478 std::string m_thread_name; 3479 std::string m_queue_name; 3480 bool m_sym_ctx_specified; 3481 bool m_thread_specified; 3482 // Instance variables to hold the values for one_liner options. 3483 bool m_use_one_liner; 3484 std::string m_one_liner; 3485 }; 3486 3487 Options * 3488 GetOptions () 3489 { 3490 return &m_options; 3491 } 3492 3493 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 3494 CommandObject (interpreter, 3495 "target stop-hook add ", 3496 "Add a hook to be executed when the target stops.", 3497 "target stop-hook add"), 3498 m_options (interpreter) 3499 { 3500 } 3501 3502 ~CommandObjectTargetStopHookAdd () 3503 { 3504 } 3505 3506 static size_t 3507 ReadCommandsCallbackFunction (void *baton, 3508 InputReader &reader, 3509 lldb::InputReaderAction notification, 3510 const char *bytes, 3511 size_t bytes_len) 3512 { 3513 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 3514 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton); 3515 static bool got_interrupted; 3516 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 3517 3518 switch (notification) 3519 { 3520 case eInputReaderActivate: 3521 if (!batch_mode) 3522 { 3523 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end."); 3524 if (reader.GetPrompt()) 3525 out_stream->Printf ("%s", reader.GetPrompt()); 3526 out_stream->Flush(); 3527 } 3528 got_interrupted = false; 3529 break; 3530 3531 case eInputReaderDeactivate: 3532 break; 3533 3534 case eInputReaderReactivate: 3535 if (reader.GetPrompt() && !batch_mode) 3536 { 3537 out_stream->Printf ("%s", reader.GetPrompt()); 3538 out_stream->Flush(); 3539 } 3540 got_interrupted = false; 3541 break; 3542 3543 case eInputReaderAsynchronousOutputWritten: 3544 break; 3545 3546 case eInputReaderGotToken: 3547 if (bytes && bytes_len && baton) 3548 { 3549 StringList *commands = new_stop_hook->GetCommandPointer(); 3550 if (commands) 3551 { 3552 commands->AppendString (bytes, bytes_len); 3553 } 3554 } 3555 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode) 3556 { 3557 out_stream->Printf ("%s", reader.GetPrompt()); 3558 out_stream->Flush(); 3559 } 3560 break; 3561 3562 case eInputReaderInterrupt: 3563 { 3564 // Finish, and cancel the stop hook. 3565 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID()); 3566 if (!batch_mode) 3567 { 3568 out_stream->Printf ("Stop hook cancelled.\n"); 3569 out_stream->Flush(); 3570 } 3571 3572 reader.SetIsDone (true); 3573 } 3574 got_interrupted = true; 3575 break; 3576 3577 case eInputReaderEndOfFile: 3578 reader.SetIsDone (true); 3579 break; 3580 3581 case eInputReaderDone: 3582 if (!got_interrupted && !batch_mode) 3583 { 3584 out_stream->Printf ("Stop hook #%d added.\n", new_stop_hook->GetID()); 3585 out_stream->Flush(); 3586 } 3587 break; 3588 } 3589 3590 return bytes_len; 3591 } 3592 3593 bool 3594 Execute (Args& command, 3595 CommandReturnObject &result) 3596 { 3597 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3598 if (target) 3599 { 3600 Target::StopHookSP new_hook_sp; 3601 target->AddStopHook (new_hook_sp); 3602 3603 // First step, make the specifier. 3604 std::auto_ptr<SymbolContextSpecifier> specifier_ap; 3605 if (m_options.m_sym_ctx_specified) 3606 { 3607 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 3608 3609 if (!m_options.m_module_name.empty()) 3610 { 3611 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 3612 } 3613 3614 if (!m_options.m_class_name.empty()) 3615 { 3616 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 3617 } 3618 3619 if (!m_options.m_file_name.empty()) 3620 { 3621 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 3622 } 3623 3624 if (m_options.m_line_start != 0) 3625 { 3626 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 3627 } 3628 3629 if (m_options.m_line_end != UINT_MAX) 3630 { 3631 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 3632 } 3633 3634 if (!m_options.m_function_name.empty()) 3635 { 3636 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 3637 } 3638 } 3639 3640 if (specifier_ap.get()) 3641 new_hook_sp->SetSpecifier (specifier_ap.release()); 3642 3643 // Next see if any of the thread options have been entered: 3644 3645 if (m_options.m_thread_specified) 3646 { 3647 ThreadSpec *thread_spec = new ThreadSpec(); 3648 3649 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 3650 { 3651 thread_spec->SetTID (m_options.m_thread_id); 3652 } 3653 3654 if (m_options.m_thread_index != UINT32_MAX) 3655 thread_spec->SetIndex (m_options.m_thread_index); 3656 3657 if (!m_options.m_thread_name.empty()) 3658 thread_spec->SetName (m_options.m_thread_name.c_str()); 3659 3660 if (!m_options.m_queue_name.empty()) 3661 thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 3662 3663 new_hook_sp->SetThreadSpecifier (thread_spec); 3664 3665 } 3666 if (m_options.m_use_one_liner) 3667 { 3668 // Use one-liner. 3669 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 3670 result.AppendMessageWithFormat("Stop hook #%d added.\n", new_hook_sp->GetID()); 3671 } 3672 else 3673 { 3674 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into 3675 // the new stop hook's command string. 3676 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 3677 if (!reader_sp) 3678 { 3679 result.AppendError("out of memory\n"); 3680 result.SetStatus (eReturnStatusFailed); 3681 target->RemoveStopHookByID (new_hook_sp->GetID()); 3682 return false; 3683 } 3684 3685 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction, 3686 new_hook_sp.get(), // baton 3687 eInputReaderGranularityLine, // token size, to pass to callback function 3688 "DONE", // end token 3689 "> ", // prompt 3690 true)); // echo input 3691 if (!err.Success()) 3692 { 3693 result.AppendError (err.AsCString()); 3694 result.SetStatus (eReturnStatusFailed); 3695 target->RemoveStopHookByID (new_hook_sp->GetID()); 3696 return false; 3697 } 3698 m_interpreter.GetDebugger().PushInputReader (reader_sp); 3699 } 3700 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3701 } 3702 else 3703 { 3704 result.AppendError ("invalid target\n"); 3705 result.SetStatus (eReturnStatusFailed); 3706 } 3707 3708 return result.Succeeded(); 3709 } 3710 private: 3711 CommandOptions m_options; 3712 }; 3713 3714 OptionDefinition 3715 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 3716 { 3717 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner, 3718 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 3719 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 3720 "Set the module within which the stop-hook is to be run."}, 3721 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex, 3722 "The stop hook is run only for the thread whose index matches this argument."}, 3723 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID, 3724 "The stop hook is run only for the thread whose TID matches this argument."}, 3725 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName, 3726 "The stop hook is run only for the thread whose thread name matches this argument."}, 3727 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName, 3728 "The stop hook is run only for threads in the queue whose name is given by this argument."}, 3729 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 3730 "Specify the source file within which the stop-hook is to be run." }, 3731 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 3732 "Set the start of the line range for which the stop-hook is to be run."}, 3733 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum, 3734 "Set the end of the line range for which the stop-hook is to be run."}, 3735 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName, 3736 "Specify the class within which the stop-hook is to be run." }, 3737 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 3738 "Set the function name within which the stop hook will be run." }, 3739 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3740 }; 3741 3742 #pragma mark CommandObjectTargetStopHookDelete 3743 3744 //------------------------------------------------------------------------- 3745 // CommandObjectTargetStopHookDelete 3746 //------------------------------------------------------------------------- 3747 3748 class CommandObjectTargetStopHookDelete : public CommandObject 3749 { 3750 public: 3751 3752 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 3753 CommandObject (interpreter, 3754 "target stop-hook delete [<id>]", 3755 "Delete a stop-hook.", 3756 "target stop-hook delete") 3757 { 3758 } 3759 3760 ~CommandObjectTargetStopHookDelete () 3761 { 3762 } 3763 3764 bool 3765 Execute (Args& command, 3766 CommandReturnObject &result) 3767 { 3768 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3769 if (target) 3770 { 3771 // FIXME: see if we can use the breakpoint id style parser? 3772 size_t num_args = command.GetArgumentCount(); 3773 if (num_args == 0) 3774 { 3775 if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 3776 { 3777 result.SetStatus (eReturnStatusFailed); 3778 return false; 3779 } 3780 else 3781 { 3782 target->RemoveAllStopHooks(); 3783 } 3784 } 3785 else 3786 { 3787 bool success; 3788 for (size_t i = 0; i < num_args; i++) 3789 { 3790 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 3791 if (!success) 3792 { 3793 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3794 result.SetStatus(eReturnStatusFailed); 3795 return false; 3796 } 3797 success = target->RemoveStopHookByID (user_id); 3798 if (!success) 3799 { 3800 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3801 result.SetStatus(eReturnStatusFailed); 3802 return false; 3803 } 3804 } 3805 } 3806 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3807 } 3808 else 3809 { 3810 result.AppendError ("invalid target\n"); 3811 result.SetStatus (eReturnStatusFailed); 3812 } 3813 3814 return result.Succeeded(); 3815 } 3816 }; 3817 #pragma mark CommandObjectTargetStopHookEnableDisable 3818 3819 //------------------------------------------------------------------------- 3820 // CommandObjectTargetStopHookEnableDisable 3821 //------------------------------------------------------------------------- 3822 3823 class CommandObjectTargetStopHookEnableDisable : public CommandObject 3824 { 3825 public: 3826 3827 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 3828 CommandObject (interpreter, 3829 name, 3830 help, 3831 syntax), 3832 m_enable (enable) 3833 { 3834 } 3835 3836 ~CommandObjectTargetStopHookEnableDisable () 3837 { 3838 } 3839 3840 bool 3841 Execute (Args& command, 3842 CommandReturnObject &result) 3843 { 3844 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3845 if (target) 3846 { 3847 // FIXME: see if we can use the breakpoint id style parser? 3848 size_t num_args = command.GetArgumentCount(); 3849 bool success; 3850 3851 if (num_args == 0) 3852 { 3853 target->SetAllStopHooksActiveState (m_enable); 3854 } 3855 else 3856 { 3857 for (size_t i = 0; i < num_args; i++) 3858 { 3859 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 3860 if (!success) 3861 { 3862 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3863 result.SetStatus(eReturnStatusFailed); 3864 return false; 3865 } 3866 success = target->SetStopHookActiveStateByID (user_id, m_enable); 3867 if (!success) 3868 { 3869 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3870 result.SetStatus(eReturnStatusFailed); 3871 return false; 3872 } 3873 } 3874 } 3875 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3876 } 3877 else 3878 { 3879 result.AppendError ("invalid target\n"); 3880 result.SetStatus (eReturnStatusFailed); 3881 } 3882 return result.Succeeded(); 3883 } 3884 private: 3885 bool m_enable; 3886 }; 3887 3888 #pragma mark CommandObjectTargetStopHookList 3889 3890 //------------------------------------------------------------------------- 3891 // CommandObjectTargetStopHookList 3892 //------------------------------------------------------------------------- 3893 3894 class CommandObjectTargetStopHookList : public CommandObject 3895 { 3896 public: 3897 3898 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 3899 CommandObject (interpreter, 3900 "target stop-hook list [<type>]", 3901 "List all stop-hooks.", 3902 "target stop-hook list") 3903 { 3904 } 3905 3906 ~CommandObjectTargetStopHookList () 3907 { 3908 } 3909 3910 bool 3911 Execute (Args& command, 3912 CommandReturnObject &result) 3913 { 3914 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3915 if (target) 3916 { 3917 bool notify = true; 3918 target->GetImageSearchPathList().Clear(notify); 3919 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3920 } 3921 else 3922 { 3923 result.AppendError ("invalid target\n"); 3924 result.SetStatus (eReturnStatusFailed); 3925 return result.Succeeded(); 3926 } 3927 3928 size_t num_hooks = target->GetNumStopHooks (); 3929 if (num_hooks == 0) 3930 { 3931 result.GetOutputStream().PutCString ("No stop hooks.\n"); 3932 } 3933 else 3934 { 3935 for (size_t i = 0; i < num_hooks; i++) 3936 { 3937 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 3938 if (i > 0) 3939 result.GetOutputStream().PutCString ("\n"); 3940 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 3941 } 3942 } 3943 return result.Succeeded(); 3944 } 3945 }; 3946 3947 #pragma mark CommandObjectMultiwordTargetStopHooks 3948 //------------------------------------------------------------------------- 3949 // CommandObjectMultiwordTargetStopHooks 3950 //------------------------------------------------------------------------- 3951 3952 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 3953 { 3954 public: 3955 3956 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 3957 CommandObjectMultiword (interpreter, 3958 "target stop-hook", 3959 "A set of commands for operating on debugger target stop-hooks.", 3960 "target stop-hook <subcommand> [<subcommand-options>]") 3961 { 3962 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 3963 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 3964 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 3965 false, 3966 "target stop-hook disable [<id>]", 3967 "Disable a stop-hook.", 3968 "target stop-hook disable"))); 3969 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 3970 true, 3971 "target stop-hook enable [<id>]", 3972 "Enable a stop-hook.", 3973 "target stop-hook enable"))); 3974 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 3975 } 3976 3977 ~CommandObjectMultiwordTargetStopHooks() 3978 { 3979 } 3980 }; 3981 3982 3983 3984 #pragma mark CommandObjectMultiwordTarget 3985 3986 //------------------------------------------------------------------------- 3987 // CommandObjectMultiwordTarget 3988 //------------------------------------------------------------------------- 3989 3990 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 3991 CommandObjectMultiword (interpreter, 3992 "target", 3993 "A set of commands for operating on debugger targets.", 3994 "target <subcommand> [<subcommand-options>]") 3995 { 3996 3997 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 3998 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 3999 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 4000 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 4001 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 4002 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 4003 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 4004 } 4005 4006 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 4007 { 4008 } 4009 4010 4011