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