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 NULL, 1503 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, 1504 include_symbols, 1505 append, 1506 sc_list); 1507 } 1508 1509 if (num_matches) 1510 { 1511 strm.Indent (); 1512 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1513 DumpFullpath (strm, &module->GetFileSpec(), 0); 1514 strm.PutCString(":\n"); 1515 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); 1516 } 1517 return num_matches; 1518 } 1519 return 0; 1520 } 1521 1522 static uint32_t 1523 LookupTypeInModule (CommandInterpreter &interpreter, 1524 Stream &strm, 1525 Module *module, 1526 const char *name_cstr, 1527 bool name_is_regex) 1528 { 1529 if (module && name_cstr && name_cstr[0]) 1530 { 1531 /*SymbolContextList sc_list; 1532 1533 SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 1534 if (symbol_vendor) 1535 {*/ 1536 TypeList type_list; 1537 uint32_t num_matches = 0; 1538 SymbolContext sc; 1539 // if (name_is_regex) 1540 // { 1541 // RegularExpression name_regex (name_cstr); 1542 // num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list); 1543 // } 1544 // else 1545 // { 1546 ConstString name(name_cstr); 1547 num_matches = module->FindTypes(sc, name, NULL, true, UINT32_MAX, type_list); 1548 // } 1549 1550 if (num_matches) 1551 { 1552 strm.Indent (); 1553 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1554 DumpFullpath (strm, &module->GetFileSpec(), 0); 1555 strm.PutCString(":\n"); 1556 const uint32_t num_types = type_list.GetSize(); 1557 for (uint32_t i=0; i<num_types; ++i) 1558 { 1559 TypeSP type_sp (type_list.GetTypeAtIndex(i)); 1560 if (type_sp) 1561 { 1562 // Resolve the clang type so that any forward references 1563 // to types that haven't yet been parsed will get parsed. 1564 type_sp->GetClangFullType (); 1565 type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1566 } 1567 strm.EOL(); 1568 } 1569 } 1570 return num_matches; 1571 //} 1572 } 1573 return 0; 1574 } 1575 1576 static uint32_t 1577 LookupFileAndLineInModule (CommandInterpreter &interpreter, 1578 Stream &strm, 1579 Module *module, 1580 const FileSpec &file_spec, 1581 uint32_t line, 1582 bool check_inlines, 1583 bool verbose) 1584 { 1585 if (module && file_spec) 1586 { 1587 SymbolContextList sc_list; 1588 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, 1589 eSymbolContextEverything, sc_list); 1590 if (num_matches > 0) 1591 { 1592 strm.Indent (); 1593 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1594 strm << file_spec; 1595 if (line > 0) 1596 strm.Printf (":%u", line); 1597 strm << " in "; 1598 DumpFullpath (strm, &module->GetFileSpec(), 0); 1599 strm.PutCString(":\n"); 1600 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); 1601 return num_matches; 1602 } 1603 } 1604 return 0; 1605 1606 } 1607 1608 #pragma mark CommandObjectTargetModulesModuleAutoComplete 1609 1610 //---------------------------------------------------------------------- 1611 // A base command object class that can auto complete with module file 1612 // paths 1613 //---------------------------------------------------------------------- 1614 1615 class CommandObjectTargetModulesModuleAutoComplete : public CommandObject 1616 { 1617 public: 1618 1619 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter, 1620 const char *name, 1621 const char *help, 1622 const char *syntax) : 1623 CommandObject (interpreter, name, help, syntax) 1624 { 1625 CommandArgumentEntry arg; 1626 CommandArgumentData file_arg; 1627 1628 // Define the first (and only) variant of this arg. 1629 file_arg.arg_type = eArgTypeFilename; 1630 file_arg.arg_repetition = eArgRepeatStar; 1631 1632 // There is only one variant this argument could be; put it into the argument entry. 1633 arg.push_back (file_arg); 1634 1635 // Push the data for the first argument into the m_arguments vector. 1636 m_arguments.push_back (arg); 1637 } 1638 1639 virtual 1640 ~CommandObjectTargetModulesModuleAutoComplete () 1641 { 1642 } 1643 1644 virtual int 1645 HandleArgumentCompletion (Args &input, 1646 int &cursor_index, 1647 int &cursor_char_position, 1648 OptionElementVector &opt_element_vector, 1649 int match_start_point, 1650 int max_return_elements, 1651 bool &word_complete, 1652 StringList &matches) 1653 { 1654 // Arguments are the standard module completer. 1655 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1656 completion_str.erase (cursor_char_position); 1657 1658 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1659 CommandCompletions::eModuleCompletion, 1660 completion_str.c_str(), 1661 match_start_point, 1662 max_return_elements, 1663 NULL, 1664 word_complete, 1665 matches); 1666 return matches.GetSize(); 1667 } 1668 }; 1669 1670 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete 1671 1672 //---------------------------------------------------------------------- 1673 // A base command object class that can auto complete with module source 1674 // file paths 1675 //---------------------------------------------------------------------- 1676 1677 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObject 1678 { 1679 public: 1680 1681 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, 1682 const char *name, 1683 const char *help, 1684 const char *syntax) : 1685 CommandObject (interpreter, name, help, syntax) 1686 { 1687 CommandArgumentEntry arg; 1688 CommandArgumentData source_file_arg; 1689 1690 // Define the first (and only) variant of this arg. 1691 source_file_arg.arg_type = eArgTypeSourceFile; 1692 source_file_arg.arg_repetition = eArgRepeatPlus; 1693 1694 // There is only one variant this argument could be; put it into the argument entry. 1695 arg.push_back (source_file_arg); 1696 1697 // Push the data for the first argument into the m_arguments vector. 1698 m_arguments.push_back (arg); 1699 } 1700 1701 virtual 1702 ~CommandObjectTargetModulesSourceFileAutoComplete () 1703 { 1704 } 1705 1706 virtual int 1707 HandleArgumentCompletion (Args &input, 1708 int &cursor_index, 1709 int &cursor_char_position, 1710 OptionElementVector &opt_element_vector, 1711 int match_start_point, 1712 int max_return_elements, 1713 bool &word_complete, 1714 StringList &matches) 1715 { 1716 // Arguments are the standard source file completer. 1717 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1718 completion_str.erase (cursor_char_position); 1719 1720 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1721 CommandCompletions::eSourceFileCompletion, 1722 completion_str.c_str(), 1723 match_start_point, 1724 max_return_elements, 1725 NULL, 1726 word_complete, 1727 matches); 1728 return matches.GetSize(); 1729 } 1730 }; 1731 1732 1733 #pragma mark CommandObjectTargetModulesDumpSymtab 1734 1735 1736 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete 1737 { 1738 public: 1739 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) : 1740 CommandObjectTargetModulesModuleAutoComplete (interpreter, 1741 "target modules dump symtab", 1742 "Dump the symbol table from one or more target modules.", 1743 NULL), 1744 m_options (interpreter) 1745 { 1746 } 1747 1748 virtual 1749 ~CommandObjectTargetModulesDumpSymtab () 1750 { 1751 } 1752 1753 virtual bool 1754 Execute (Args& command, 1755 CommandReturnObject &result) 1756 { 1757 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1758 if (target == NULL) 1759 { 1760 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 1761 result.SetStatus (eReturnStatusFailed); 1762 return false; 1763 } 1764 else 1765 { 1766 uint32_t num_dumped = 0; 1767 1768 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 1769 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 1770 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 1771 1772 if (command.GetArgumentCount() == 0) 1773 { 1774 // Dump all sections for all modules images 1775 const uint32_t num_modules = target->GetImages().GetSize(); 1776 if (num_modules > 0) 1777 { 1778 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules); 1779 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 1780 { 1781 if (num_dumped > 0) 1782 { 1783 result.GetOutputStream().EOL(); 1784 result.GetOutputStream().EOL(); 1785 } 1786 num_dumped++; 1787 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order); 1788 } 1789 } 1790 else 1791 { 1792 result.AppendError ("the target has no associated executable images"); 1793 result.SetStatus (eReturnStatusFailed); 1794 return false; 1795 } 1796 } 1797 else 1798 { 1799 // Dump specified images (by basename or fullpath) 1800 const char *arg_cstr; 1801 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 1802 { 1803 FileSpec image_file(arg_cstr, false); 1804 ModuleList matching_modules; 1805 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); 1806 1807 // Not found in our module list for our target, check the main 1808 // shared module list in case it is a extra file used somewhere 1809 // else 1810 if (num_matching_modules == 0) 1811 num_matching_modules = ModuleList::FindSharedModules (image_file, 1812 target->GetArchitecture(), 1813 NULL, 1814 NULL, 1815 matching_modules); 1816 1817 if (num_matching_modules > 0) 1818 { 1819 for (size_t i=0; i<num_matching_modules; ++i) 1820 { 1821 Module *image_module = matching_modules.GetModulePointerAtIndex(i); 1822 if (image_module) 1823 { 1824 if (num_dumped > 0) 1825 { 1826 result.GetOutputStream().EOL(); 1827 result.GetOutputStream().EOL(); 1828 } 1829 num_dumped++; 1830 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order); 1831 } 1832 } 1833 } 1834 else 1835 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 1836 } 1837 } 1838 1839 if (num_dumped > 0) 1840 result.SetStatus (eReturnStatusSuccessFinishResult); 1841 else 1842 { 1843 result.AppendError ("no matching executable images found"); 1844 result.SetStatus (eReturnStatusFailed); 1845 } 1846 } 1847 return result.Succeeded(); 1848 } 1849 1850 virtual Options * 1851 GetOptions () 1852 { 1853 return &m_options; 1854 } 1855 1856 class CommandOptions : public Options 1857 { 1858 public: 1859 1860 CommandOptions (CommandInterpreter &interpreter) : 1861 Options(interpreter), 1862 m_sort_order (eSortOrderNone) 1863 { 1864 } 1865 1866 virtual 1867 ~CommandOptions () 1868 { 1869 } 1870 1871 virtual Error 1872 SetOptionValue (uint32_t option_idx, const char *option_arg) 1873 { 1874 Error error; 1875 char short_option = (char) m_getopt_table[option_idx].val; 1876 1877 switch (short_option) 1878 { 1879 case 's': 1880 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg, 1881 g_option_table[option_idx].enum_values, 1882 eSortOrderNone, 1883 error); 1884 break; 1885 1886 default: 1887 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 1888 break; 1889 1890 } 1891 return error; 1892 } 1893 1894 void 1895 OptionParsingStarting () 1896 { 1897 m_sort_order = eSortOrderNone; 1898 } 1899 1900 const OptionDefinition* 1901 GetDefinitions () 1902 { 1903 return g_option_table; 1904 } 1905 1906 // Options table: Required for subclasses of Options. 1907 static OptionDefinition g_option_table[]; 1908 1909 SortOrder m_sort_order; 1910 }; 1911 1912 protected: 1913 1914 CommandOptions m_options; 1915 }; 1916 1917 static OptionEnumValueElement 1918 g_sort_option_enumeration[4] = 1919 { 1920 { eSortOrderNone, "none", "No sorting, use the original symbol table order."}, 1921 { eSortOrderByAddress, "address", "Sort output by symbol address."}, 1922 { eSortOrderByName, "name", "Sort output by symbol name."}, 1923 { 0, NULL, NULL } 1924 }; 1925 1926 1927 OptionDefinition 1928 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] = 1929 { 1930 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."}, 1931 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1932 }; 1933 1934 #pragma mark CommandObjectTargetModulesDumpSections 1935 1936 //---------------------------------------------------------------------- 1937 // Image section dumping command 1938 //---------------------------------------------------------------------- 1939 1940 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete 1941 { 1942 public: 1943 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) : 1944 CommandObjectTargetModulesModuleAutoComplete (interpreter, 1945 "target modules dump sections", 1946 "Dump the sections from one or more target modules.", 1947 //"target modules dump sections [<file1> ...]") 1948 NULL) 1949 { 1950 } 1951 1952 virtual 1953 ~CommandObjectTargetModulesDumpSections () 1954 { 1955 } 1956 1957 virtual bool 1958 Execute (Args& command, 1959 CommandReturnObject &result) 1960 { 1961 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1962 if (target == NULL) 1963 { 1964 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 1965 result.SetStatus (eReturnStatusFailed); 1966 return false; 1967 } 1968 else 1969 { 1970 uint32_t num_dumped = 0; 1971 1972 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 1973 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 1974 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 1975 1976 if (command.GetArgumentCount() == 0) 1977 { 1978 // Dump all sections for all modules images 1979 const uint32_t num_modules = target->GetImages().GetSize(); 1980 if (num_modules > 0) 1981 { 1982 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules); 1983 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 1984 { 1985 num_dumped++; 1986 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)); 1987 } 1988 } 1989 else 1990 { 1991 result.AppendError ("the target has no associated executable images"); 1992 result.SetStatus (eReturnStatusFailed); 1993 return false; 1994 } 1995 } 1996 else 1997 { 1998 // Dump specified images (by basename or fullpath) 1999 const char *arg_cstr; 2000 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2001 { 2002 FileSpec image_file(arg_cstr, false); 2003 ModuleList matching_modules; 2004 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); 2005 2006 // Not found in our module list for our target, check the main 2007 // shared module list in case it is a extra file used somewhere 2008 // else 2009 if (num_matching_modules == 0) 2010 num_matching_modules = ModuleList::FindSharedModules (image_file, 2011 target->GetArchitecture(), 2012 NULL, 2013 NULL, 2014 matching_modules); 2015 2016 if (num_matching_modules > 0) 2017 { 2018 for (size_t i=0; i<num_matching_modules; ++i) 2019 { 2020 Module * image_module = matching_modules.GetModulePointerAtIndex(i); 2021 if (image_module) 2022 { 2023 num_dumped++; 2024 DumpModuleSections (m_interpreter, result.GetOutputStream(), image_module); 2025 } 2026 } 2027 } 2028 else 2029 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2030 } 2031 } 2032 2033 if (num_dumped > 0) 2034 result.SetStatus (eReturnStatusSuccessFinishResult); 2035 else 2036 { 2037 result.AppendError ("no matching executable images found"); 2038 result.SetStatus (eReturnStatusFailed); 2039 } 2040 } 2041 return result.Succeeded(); 2042 } 2043 }; 2044 2045 2046 #pragma mark CommandObjectTargetModulesDumpSymfile 2047 2048 //---------------------------------------------------------------------- 2049 // Image debug symbol dumping command 2050 //---------------------------------------------------------------------- 2051 2052 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete 2053 { 2054 public: 2055 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) : 2056 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2057 "target modules dump symfile", 2058 "Dump the debug symbol file for one or more target modules.", 2059 //"target modules dump symfile [<file1> ...]") 2060 NULL) 2061 { 2062 } 2063 2064 virtual 2065 ~CommandObjectTargetModulesDumpSymfile () 2066 { 2067 } 2068 2069 virtual bool 2070 Execute (Args& command, 2071 CommandReturnObject &result) 2072 { 2073 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2074 if (target == NULL) 2075 { 2076 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2077 result.SetStatus (eReturnStatusFailed); 2078 return false; 2079 } 2080 else 2081 { 2082 uint32_t num_dumped = 0; 2083 2084 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2085 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2086 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2087 2088 if (command.GetArgumentCount() == 0) 2089 { 2090 // Dump all sections for all modules images 2091 const uint32_t num_modules = target->GetImages().GetSize(); 2092 if (num_modules > 0) 2093 { 2094 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules); 2095 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2096 { 2097 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx))) 2098 num_dumped++; 2099 } 2100 } 2101 else 2102 { 2103 result.AppendError ("the target has no associated executable images"); 2104 result.SetStatus (eReturnStatusFailed); 2105 return false; 2106 } 2107 } 2108 else 2109 { 2110 // Dump specified images (by basename or fullpath) 2111 const char *arg_cstr; 2112 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2113 { 2114 FileSpec image_file(arg_cstr, false); 2115 ModuleList matching_modules; 2116 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); 2117 2118 // Not found in our module list for our target, check the main 2119 // shared module list in case it is a extra file used somewhere 2120 // else 2121 if (num_matching_modules == 0) 2122 num_matching_modules = ModuleList::FindSharedModules (image_file, 2123 target->GetArchitecture(), 2124 NULL, 2125 NULL, 2126 matching_modules); 2127 2128 if (num_matching_modules > 0) 2129 { 2130 for (size_t i=0; i<num_matching_modules; ++i) 2131 { 2132 Module * image_module = matching_modules.GetModulePointerAtIndex(i); 2133 if (image_module) 2134 { 2135 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module)) 2136 num_dumped++; 2137 } 2138 } 2139 } 2140 else 2141 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2142 } 2143 } 2144 2145 if (num_dumped > 0) 2146 result.SetStatus (eReturnStatusSuccessFinishResult); 2147 else 2148 { 2149 result.AppendError ("no matching executable images found"); 2150 result.SetStatus (eReturnStatusFailed); 2151 } 2152 } 2153 return result.Succeeded(); 2154 } 2155 }; 2156 2157 2158 #pragma mark CommandObjectTargetModulesDumpLineTable 2159 2160 //---------------------------------------------------------------------- 2161 // Image debug line table dumping command 2162 //---------------------------------------------------------------------- 2163 2164 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete 2165 { 2166 public: 2167 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) : 2168 CommandObjectTargetModulesSourceFileAutoComplete (interpreter, 2169 "target modules dump line-table", 2170 "Dump the debug symbol file for one or more target modules.", 2171 NULL) 2172 { 2173 } 2174 2175 virtual 2176 ~CommandObjectTargetModulesDumpLineTable () 2177 { 2178 } 2179 2180 virtual bool 2181 Execute (Args& command, 2182 CommandReturnObject &result) 2183 { 2184 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2185 if (target == NULL) 2186 { 2187 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2188 result.SetStatus (eReturnStatusFailed); 2189 return false; 2190 } 2191 else 2192 { 2193 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 2194 uint32_t total_num_dumped = 0; 2195 2196 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2197 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2198 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2199 2200 if (command.GetArgumentCount() == 0) 2201 { 2202 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); 2203 result.SetStatus (eReturnStatusFailed); 2204 } 2205 else 2206 { 2207 // Dump specified images (by basename or fullpath) 2208 const char *arg_cstr; 2209 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2210 { 2211 FileSpec file_spec(arg_cstr, false); 2212 const uint32_t num_modules = target->GetImages().GetSize(); 2213 if (num_modules > 0) 2214 { 2215 uint32_t num_dumped = 0; 2216 for (uint32_t i = 0; i<num_modules; ++i) 2217 { 2218 if (DumpCompileUnitLineTable (m_interpreter, 2219 result.GetOutputStream(), 2220 target->GetImages().GetModulePointerAtIndex(i), 2221 file_spec, 2222 exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive())) 2223 num_dumped++; 2224 } 2225 if (num_dumped == 0) 2226 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); 2227 else 2228 total_num_dumped += num_dumped; 2229 } 2230 } 2231 } 2232 2233 if (total_num_dumped > 0) 2234 result.SetStatus (eReturnStatusSuccessFinishResult); 2235 else 2236 { 2237 result.AppendError ("no source filenames matched any command arguments"); 2238 result.SetStatus (eReturnStatusFailed); 2239 } 2240 } 2241 return result.Succeeded(); 2242 } 2243 }; 2244 2245 2246 #pragma mark CommandObjectTargetModulesDump 2247 2248 //---------------------------------------------------------------------- 2249 // Dump multi-word command for target modules 2250 //---------------------------------------------------------------------- 2251 2252 class CommandObjectTargetModulesDump : public CommandObjectMultiword 2253 { 2254 public: 2255 2256 //------------------------------------------------------------------ 2257 // Constructors and Destructors 2258 //------------------------------------------------------------------ 2259 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) : 2260 CommandObjectMultiword (interpreter, 2261 "target modules dump", 2262 "A set of commands for dumping information about one or more target modules.", 2263 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]") 2264 { 2265 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter))); 2266 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter))); 2267 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter))); 2268 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter))); 2269 } 2270 2271 virtual 2272 ~CommandObjectTargetModulesDump() 2273 { 2274 } 2275 }; 2276 2277 class CommandObjectTargetModulesAdd : public CommandObject 2278 { 2279 public: 2280 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) : 2281 CommandObject (interpreter, 2282 "target modules add", 2283 "Add a new module to the current target's modules.", 2284 "target modules add [<module>]") 2285 { 2286 } 2287 2288 virtual 2289 ~CommandObjectTargetModulesAdd () 2290 { 2291 } 2292 2293 virtual bool 2294 Execute (Args& args, 2295 CommandReturnObject &result) 2296 { 2297 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2298 if (target == NULL) 2299 { 2300 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2301 result.SetStatus (eReturnStatusFailed); 2302 return false; 2303 } 2304 else 2305 { 2306 const size_t argc = args.GetArgumentCount(); 2307 if (argc == 0) 2308 { 2309 result.AppendError ("one or more executable image paths must be specified"); 2310 result.SetStatus (eReturnStatusFailed); 2311 return false; 2312 } 2313 else 2314 { 2315 for (size_t i=0; i<argc; ++i) 2316 { 2317 const char *path = args.GetArgumentAtIndex(i); 2318 if (path) 2319 { 2320 FileSpec file_spec(path, true); 2321 ArchSpec arch; 2322 if (file_spec.Exists()) 2323 { 2324 ModuleSP module_sp (target->GetSharedModule(file_spec, arch)); 2325 if (!module_sp) 2326 { 2327 result.AppendError ("one or more executable image paths must be specified"); 2328 result.SetStatus (eReturnStatusFailed); 2329 return false; 2330 } 2331 result.SetStatus (eReturnStatusSuccessFinishResult); 2332 } 2333 else 2334 { 2335 char resolved_path[PATH_MAX]; 2336 result.SetStatus (eReturnStatusFailed); 2337 if (file_spec.GetPath (resolved_path, sizeof(resolved_path))) 2338 { 2339 if (strcmp (resolved_path, path) != 0) 2340 { 2341 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path); 2342 break; 2343 } 2344 } 2345 result.AppendErrorWithFormat ("invalid module path '%s'\n", path); 2346 break; 2347 } 2348 } 2349 } 2350 } 2351 } 2352 return result.Succeeded(); 2353 } 2354 2355 int 2356 HandleArgumentCompletion (Args &input, 2357 int &cursor_index, 2358 int &cursor_char_position, 2359 OptionElementVector &opt_element_vector, 2360 int match_start_point, 2361 int max_return_elements, 2362 bool &word_complete, 2363 StringList &matches) 2364 { 2365 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2366 completion_str.erase (cursor_char_position); 2367 2368 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2369 CommandCompletions::eDiskFileCompletion, 2370 completion_str.c_str(), 2371 match_start_point, 2372 max_return_elements, 2373 NULL, 2374 word_complete, 2375 matches); 2376 return matches.GetSize(); 2377 } 2378 2379 }; 2380 2381 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete 2382 { 2383 public: 2384 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) : 2385 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2386 "target modules load", 2387 "Set the load addresses for one or more sections in a target module.", 2388 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"), 2389 m_option_group (interpreter), 2390 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."), 2391 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) 2392 { 2393 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2394 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2395 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2396 m_option_group.Finalize(); 2397 } 2398 2399 virtual 2400 ~CommandObjectTargetModulesLoad () 2401 { 2402 } 2403 2404 virtual bool 2405 Execute (Args& args, 2406 CommandReturnObject &result) 2407 { 2408 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2409 if (target == NULL) 2410 { 2411 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2412 result.SetStatus (eReturnStatusFailed); 2413 return false; 2414 } 2415 else 2416 { 2417 const size_t argc = args.GetArgumentCount(); 2418 const FileSpec *file_ptr = NULL; 2419 const UUID *uuid_ptr = NULL; 2420 if (m_file_option.GetOptionValue().OptionWasSet()) 2421 file_ptr = &m_file_option.GetOptionValue().GetCurrentValue(); 2422 2423 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2424 uuid_ptr = &m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2425 2426 if (file_ptr || uuid_ptr) 2427 { 2428 2429 ModuleList matching_modules; 2430 const size_t num_matches = target->GetImages().FindModules (file_ptr, // File spec to match (can be NULL to match by UUID only) 2431 NULL, // Architecture 2432 uuid_ptr, // UUID to match (can be NULL to not match on UUID) 2433 NULL, // Object name 2434 matching_modules); 2435 2436 char path[PATH_MAX]; 2437 if (num_matches == 1) 2438 { 2439 Module *module = matching_modules.GetModulePointerAtIndex(0); 2440 if (module) 2441 { 2442 ObjectFile *objfile = module->GetObjectFile(); 2443 if (objfile) 2444 { 2445 SectionList *section_list = objfile->GetSectionList(); 2446 if (section_list) 2447 { 2448 if (argc == 0) 2449 { 2450 if (m_slide_option.GetOptionValue().OptionWasSet()) 2451 { 2452 Module *module = matching_modules.GetModulePointerAtIndex(0); 2453 if (module) 2454 { 2455 ObjectFile *objfile = module->GetObjectFile(); 2456 if (objfile) 2457 { 2458 SectionList *section_list = objfile->GetSectionList(); 2459 if (section_list) 2460 { 2461 const size_t num_sections = section_list->GetSize(); 2462 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue(); 2463 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) 2464 { 2465 SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx)); 2466 if (section_sp) 2467 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide); 2468 } 2469 } 2470 } 2471 } 2472 } 2473 else 2474 { 2475 result.AppendError ("one or more section name + load address pair must be specified"); 2476 result.SetStatus (eReturnStatusFailed); 2477 return false; 2478 } 2479 } 2480 else 2481 { 2482 if (m_slide_option.GetOptionValue().OptionWasSet()) 2483 { 2484 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n"); 2485 result.SetStatus (eReturnStatusFailed); 2486 return false; 2487 } 2488 2489 for (size_t i=0; i<argc; i += 2) 2490 { 2491 const char *sect_name = args.GetArgumentAtIndex(i); 2492 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1); 2493 if (sect_name && load_addr_cstr) 2494 { 2495 ConstString const_sect_name(sect_name); 2496 bool success = false; 2497 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); 2498 if (success) 2499 { 2500 SectionSP section_sp (section_list->FindSectionByName(const_sect_name)); 2501 if (section_sp) 2502 { 2503 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), load_addr); 2504 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr); 2505 } 2506 else 2507 { 2508 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name); 2509 result.SetStatus (eReturnStatusFailed); 2510 break; 2511 } 2512 } 2513 else 2514 { 2515 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr); 2516 result.SetStatus (eReturnStatusFailed); 2517 break; 2518 } 2519 } 2520 else 2521 { 2522 if (sect_name) 2523 result.AppendError ("section names must be followed by a load address.\n"); 2524 else 2525 result.AppendError ("one or more section name + load address pair must be specified.\n"); 2526 result.SetStatus (eReturnStatusFailed); 2527 break; 2528 } 2529 } 2530 } 2531 } 2532 else 2533 { 2534 module->GetFileSpec().GetPath (path, sizeof(path)); 2535 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path); 2536 result.SetStatus (eReturnStatusFailed); 2537 } 2538 } 2539 else 2540 { 2541 module->GetFileSpec().GetPath (path, sizeof(path)); 2542 result.AppendErrorWithFormat ("no object file for module '%s'\n", path); 2543 result.SetStatus (eReturnStatusFailed); 2544 } 2545 } 2546 else 2547 { 2548 module->GetFileSpec().GetPath (path, sizeof(path)); 2549 result.AppendErrorWithFormat ("invalid module '%s'.\n", path); 2550 result.SetStatus (eReturnStatusFailed); 2551 } 2552 } 2553 else 2554 { 2555 char uuid_cstr[64]; 2556 if (file_ptr) 2557 file_ptr->GetPath (path, sizeof(path)); 2558 else 2559 path[0] = '\0'; 2560 2561 if (uuid_ptr) 2562 uuid_ptr->GetAsCString(uuid_cstr, sizeof(uuid_cstr)); 2563 else 2564 uuid_cstr[0] = '\0'; 2565 if (num_matches > 1) 2566 { 2567 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", 2568 path[0] ? " file=" : "", 2569 path, 2570 uuid_cstr[0] ? " uuid=" : "", 2571 uuid_cstr); 2572 for (size_t i=0; i<num_matches; ++i) 2573 { 2574 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path))) 2575 result.AppendMessageWithFormat("%s\n", path); 2576 } 2577 } 2578 else 2579 { 2580 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n", 2581 path[0] ? " file=" : "", 2582 path, 2583 uuid_cstr[0] ? " uuid=" : "", 2584 uuid_cstr); 2585 } 2586 result.SetStatus (eReturnStatusFailed); 2587 } 2588 } 2589 else 2590 { 2591 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n"); 2592 result.SetStatus (eReturnStatusFailed); 2593 return false; 2594 } 2595 } 2596 return result.Succeeded(); 2597 } 2598 2599 virtual Options * 2600 GetOptions () 2601 { 2602 return &m_option_group; 2603 } 2604 2605 protected: 2606 OptionGroupOptions m_option_group; 2607 OptionGroupUUID m_uuid_option_group; 2608 OptionGroupFile m_file_option; 2609 OptionGroupUInt64 m_slide_option; 2610 }; 2611 2612 //---------------------------------------------------------------------- 2613 // List images with associated information 2614 //---------------------------------------------------------------------- 2615 class CommandObjectTargetModulesList : public CommandObject 2616 { 2617 public: 2618 2619 class CommandOptions : public Options 2620 { 2621 public: 2622 2623 CommandOptions (CommandInterpreter &interpreter) : 2624 Options(interpreter), 2625 m_format_array() 2626 { 2627 } 2628 2629 virtual 2630 ~CommandOptions () 2631 { 2632 } 2633 2634 virtual Error 2635 SetOptionValue (uint32_t option_idx, const char *option_arg) 2636 { 2637 char short_option = (char) m_getopt_table[option_idx].val; 2638 if (short_option == 'g') 2639 { 2640 m_use_global_module_list = true; 2641 } 2642 else 2643 { 2644 uint32_t width = 0; 2645 if (option_arg) 2646 width = strtoul (option_arg, NULL, 0); 2647 m_format_array.push_back(std::make_pair(short_option, width)); 2648 } 2649 Error error; 2650 return error; 2651 } 2652 2653 void 2654 OptionParsingStarting () 2655 { 2656 m_format_array.clear(); 2657 m_use_global_module_list = false; 2658 } 2659 2660 const OptionDefinition* 2661 GetDefinitions () 2662 { 2663 return g_option_table; 2664 } 2665 2666 // Options table: Required for subclasses of Options. 2667 2668 static OptionDefinition g_option_table[]; 2669 2670 // Instance variables to hold the values for command options. 2671 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection; 2672 FormatWidthCollection m_format_array; 2673 bool m_use_global_module_list; 2674 }; 2675 2676 CommandObjectTargetModulesList (CommandInterpreter &interpreter) : 2677 CommandObject (interpreter, 2678 "target modules list", 2679 "List current executable and dependent shared library images.", 2680 "target modules list [<cmd-options>]"), 2681 m_options (interpreter) 2682 { 2683 } 2684 2685 virtual 2686 ~CommandObjectTargetModulesList () 2687 { 2688 } 2689 2690 virtual 2691 Options * 2692 GetOptions () 2693 { 2694 return &m_options; 2695 } 2696 2697 virtual bool 2698 Execute (Args& command, 2699 CommandReturnObject &result) 2700 { 2701 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2702 const bool use_global_module_list = m_options.m_use_global_module_list; 2703 if (target == NULL && use_global_module_list == false) 2704 { 2705 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2706 result.SetStatus (eReturnStatusFailed); 2707 return false; 2708 } 2709 else 2710 { 2711 if (target) 2712 { 2713 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2714 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2715 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2716 } 2717 // Dump all sections for all modules images 2718 uint32_t num_modules = 0; 2719 Mutex::Locker locker; 2720 if (use_global_module_list) 2721 { 2722 locker.Reset (Module::GetAllocationModuleCollectionMutex().GetMutex()); 2723 num_modules = Module::GetNumberAllocatedModules(); 2724 } 2725 else 2726 num_modules = target->GetImages().GetSize(); 2727 2728 if (num_modules > 0) 2729 { 2730 Stream &strm = result.GetOutputStream(); 2731 2732 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2733 { 2734 ModuleSP module_sp; 2735 Module *module; 2736 if (use_global_module_list) 2737 { 2738 module = Module::GetAllocatedModuleAtIndex(image_idx); 2739 module_sp = module; 2740 } 2741 else 2742 { 2743 module_sp = target->GetImages().GetModuleAtIndex(image_idx); 2744 module = module_sp.get(); 2745 } 2746 2747 strm.Printf("[%3u] ", image_idx); 2748 2749 bool dump_object_name = false; 2750 if (m_options.m_format_array.empty()) 2751 { 2752 DumpFullpath(strm, &module->GetFileSpec(), 0); 2753 dump_object_name = true; 2754 } 2755 else 2756 { 2757 const size_t num_entries = m_options.m_format_array.size(); 2758 for (size_t i=0; i<num_entries; ++i) 2759 { 2760 if (i > 0) 2761 strm.PutChar(' '); 2762 char format_char = m_options.m_format_array[i].first; 2763 uint32_t width = m_options.m_format_array[i].second; 2764 switch (format_char) 2765 { 2766 case 'a': 2767 DumpModuleArchitecture (strm, module, false, width); 2768 break; 2769 2770 case 't': 2771 DumpModuleArchitecture (strm, module, true, width); 2772 break; 2773 2774 case 'f': 2775 DumpFullpath (strm, &module->GetFileSpec(), width); 2776 dump_object_name = true; 2777 break; 2778 2779 case 'd': 2780 DumpDirectory (strm, &module->GetFileSpec(), width); 2781 break; 2782 2783 case 'b': 2784 DumpBasename (strm, &module->GetFileSpec(), width); 2785 dump_object_name = true; 2786 break; 2787 2788 case 'r': 2789 { 2790 uint32_t ref_count = 0; 2791 if (module_sp) 2792 { 2793 // Take one away to make sure we don't count our local "module_sp" 2794 ref_count = module_sp.use_count() - 1; 2795 } 2796 if (width) 2797 strm.Printf("{%*u}", width, ref_count); 2798 else 2799 strm.Printf("{%u}", ref_count); 2800 } 2801 break; 2802 2803 case 's': 2804 case 'S': 2805 { 2806 SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 2807 if (symbol_vendor) 2808 { 2809 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 2810 if (symbol_file) 2811 { 2812 if (format_char == 'S') 2813 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 2814 else 2815 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 2816 dump_object_name = true; 2817 break; 2818 } 2819 } 2820 strm.Printf("%.*s", width, "<NONE>"); 2821 } 2822 break; 2823 2824 case 'm': 2825 module->GetModificationTime().Dump(&strm, width); 2826 break; 2827 2828 case 'p': 2829 strm.Printf("%p", module); 2830 break; 2831 2832 case 'u': 2833 DumpModuleUUID(strm, module); 2834 break; 2835 2836 default: 2837 break; 2838 } 2839 2840 } 2841 } 2842 if (dump_object_name) 2843 { 2844 const char *object_name = module->GetObjectName().GetCString(); 2845 if (object_name) 2846 strm.Printf ("(%s)", object_name); 2847 } 2848 strm.EOL(); 2849 } 2850 result.SetStatus (eReturnStatusSuccessFinishResult); 2851 } 2852 else 2853 { 2854 if (use_global_module_list) 2855 result.AppendError ("the global module list is empty"); 2856 else 2857 result.AppendError ("the target has no associated executable images"); 2858 result.SetStatus (eReturnStatusFailed); 2859 return false; 2860 } 2861 } 2862 return result.Succeeded(); 2863 } 2864 protected: 2865 2866 CommandOptions m_options; 2867 }; 2868 2869 OptionDefinition 2870 CommandObjectTargetModulesList::CommandOptions::g_option_table[] = 2871 { 2872 { LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, 2873 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, 2874 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, 2875 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, 2876 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, 2877 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, 2878 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, 2879 { LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."}, 2880 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, 2881 { 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."}, 2882 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."}, 2883 { 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."}, 2884 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2885 }; 2886 2887 2888 2889 //---------------------------------------------------------------------- 2890 // Lookup information in images 2891 //---------------------------------------------------------------------- 2892 class CommandObjectTargetModulesLookup : public CommandObject 2893 { 2894 public: 2895 2896 enum 2897 { 2898 eLookupTypeInvalid = -1, 2899 eLookupTypeAddress = 0, 2900 eLookupTypeSymbol, 2901 eLookupTypeFileLine, // Line is optional 2902 eLookupTypeFunction, 2903 eLookupTypeType, 2904 kNumLookupTypes 2905 }; 2906 2907 class CommandOptions : public Options 2908 { 2909 public: 2910 2911 CommandOptions (CommandInterpreter &interpreter) : 2912 Options(interpreter) 2913 { 2914 OptionParsingStarting(); 2915 } 2916 2917 virtual 2918 ~CommandOptions () 2919 { 2920 } 2921 2922 virtual Error 2923 SetOptionValue (uint32_t option_idx, const char *option_arg) 2924 { 2925 Error error; 2926 2927 char short_option = (char) m_getopt_table[option_idx].val; 2928 2929 switch (short_option) 2930 { 2931 case 'a': 2932 m_type = eLookupTypeAddress; 2933 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 2934 if (m_addr == LLDB_INVALID_ADDRESS) 2935 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg); 2936 break; 2937 2938 case 'o': 2939 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 2940 if (m_offset == LLDB_INVALID_ADDRESS) 2941 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg); 2942 break; 2943 2944 case 's': 2945 m_str = option_arg; 2946 m_type = eLookupTypeSymbol; 2947 break; 2948 2949 case 'f': 2950 m_file.SetFile (option_arg, false); 2951 m_type = eLookupTypeFileLine; 2952 break; 2953 2954 case 'i': 2955 m_check_inlines = false; 2956 break; 2957 2958 case 'l': 2959 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); 2960 if (m_line_number == UINT32_MAX) 2961 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg); 2962 else if (m_line_number == 0) 2963 error.SetErrorString ("Zero is an invalid line number."); 2964 m_type = eLookupTypeFileLine; 2965 break; 2966 2967 case 'n': 2968 m_str = option_arg; 2969 m_type = eLookupTypeFunction; 2970 break; 2971 2972 case 't': 2973 m_str = option_arg; 2974 m_type = eLookupTypeType; 2975 break; 2976 2977 case 'v': 2978 m_verbose = 1; 2979 break; 2980 2981 case 'r': 2982 m_use_regex = true; 2983 break; 2984 } 2985 2986 return error; 2987 } 2988 2989 void 2990 OptionParsingStarting () 2991 { 2992 m_type = eLookupTypeInvalid; 2993 m_str.clear(); 2994 m_file.Clear(); 2995 m_addr = LLDB_INVALID_ADDRESS; 2996 m_offset = 0; 2997 m_line_number = 0; 2998 m_use_regex = false; 2999 m_check_inlines = true; 3000 m_verbose = false; 3001 } 3002 3003 const OptionDefinition* 3004 GetDefinitions () 3005 { 3006 return g_option_table; 3007 } 3008 3009 // Options table: Required for subclasses of Options. 3010 3011 static OptionDefinition g_option_table[]; 3012 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3013 std::string m_str; // Holds name lookup 3014 FileSpec m_file; // Files for file lookups 3015 lldb::addr_t m_addr; // Holds the address to lookup 3016 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 3017 uint32_t m_line_number; // Line number for file+line lookups 3018 bool m_use_regex; // Name lookups in m_str are regular expressions. 3019 bool m_check_inlines;// Check for inline entries when looking up by file/line. 3020 bool m_verbose; // Enable verbose lookup info 3021 3022 }; 3023 3024 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 3025 CommandObject (interpreter, 3026 "target modules lookup", 3027 "Look up information within executable and dependent shared library images.", 3028 NULL), 3029 m_options (interpreter) 3030 { 3031 CommandArgumentEntry arg; 3032 CommandArgumentData file_arg; 3033 3034 // Define the first (and only) variant of this arg. 3035 file_arg.arg_type = eArgTypeFilename; 3036 file_arg.arg_repetition = eArgRepeatStar; 3037 3038 // There is only one variant this argument could be; put it into the argument entry. 3039 arg.push_back (file_arg); 3040 3041 // Push the data for the first argument into the m_arguments vector. 3042 m_arguments.push_back (arg); 3043 } 3044 3045 virtual 3046 ~CommandObjectTargetModulesLookup () 3047 { 3048 } 3049 3050 virtual Options * 3051 GetOptions () 3052 { 3053 return &m_options; 3054 } 3055 3056 3057 bool 3058 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 3059 { 3060 switch (m_options.m_type) 3061 { 3062 case eLookupTypeAddress: 3063 if (m_options.m_addr != LLDB_INVALID_ADDRESS) 3064 { 3065 if (LookupAddressInModule (m_interpreter, 3066 result.GetOutputStream(), 3067 module, 3068 eSymbolContextEverything, 3069 m_options.m_addr, 3070 m_options.m_offset, 3071 m_options.m_verbose)) 3072 { 3073 result.SetStatus(eReturnStatusSuccessFinishResult); 3074 return true; 3075 } 3076 } 3077 break; 3078 3079 case eLookupTypeSymbol: 3080 if (!m_options.m_str.empty()) 3081 { 3082 if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex)) 3083 { 3084 result.SetStatus(eReturnStatusSuccessFinishResult); 3085 return true; 3086 } 3087 } 3088 break; 3089 3090 case eLookupTypeFileLine: 3091 if (m_options.m_file) 3092 { 3093 3094 if (LookupFileAndLineInModule (m_interpreter, 3095 result.GetOutputStream(), 3096 module, 3097 m_options.m_file, 3098 m_options.m_line_number, 3099 m_options.m_check_inlines, 3100 m_options.m_verbose)) 3101 { 3102 result.SetStatus(eReturnStatusSuccessFinishResult); 3103 return true; 3104 } 3105 } 3106 break; 3107 3108 case eLookupTypeFunction: 3109 if (!m_options.m_str.empty()) 3110 { 3111 if (LookupFunctionInModule (m_interpreter, 3112 result.GetOutputStream(), 3113 module, 3114 m_options.m_str.c_str(), 3115 m_options.m_use_regex, 3116 m_options.m_verbose)) 3117 { 3118 result.SetStatus(eReturnStatusSuccessFinishResult); 3119 return true; 3120 } 3121 } 3122 break; 3123 3124 case eLookupTypeType: 3125 if (!m_options.m_str.empty()) 3126 { 3127 if (LookupTypeInModule (m_interpreter, 3128 result.GetOutputStream(), 3129 module, 3130 m_options.m_str.c_str(), 3131 m_options.m_use_regex)) 3132 { 3133 result.SetStatus(eReturnStatusSuccessFinishResult); 3134 return true; 3135 } 3136 } 3137 break; 3138 3139 default: 3140 m_options.GenerateOptionUsage (result.GetErrorStream(), this); 3141 syntax_error = true; 3142 break; 3143 } 3144 3145 result.SetStatus (eReturnStatusFailed); 3146 return false; 3147 } 3148 3149 virtual bool 3150 Execute (Args& command, 3151 CommandReturnObject &result) 3152 { 3153 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3154 if (target == NULL) 3155 { 3156 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3157 result.SetStatus (eReturnStatusFailed); 3158 return false; 3159 } 3160 else 3161 { 3162 bool syntax_error = false; 3163 uint32_t i; 3164 uint32_t num_successful_lookups = 0; 3165 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3166 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3167 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3168 // Dump all sections for all modules images 3169 3170 if (command.GetArgumentCount() == 0) 3171 { 3172 // Dump all sections for all modules images 3173 const uint32_t num_modules = target->GetImages().GetSize(); 3174 if (num_modules > 0) 3175 { 3176 for (i = 0; i<num_modules && syntax_error == false; ++i) 3177 { 3178 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error)) 3179 { 3180 result.GetOutputStream().EOL(); 3181 num_successful_lookups++; 3182 } 3183 } 3184 } 3185 else 3186 { 3187 result.AppendError ("the target has no associated executable images"); 3188 result.SetStatus (eReturnStatusFailed); 3189 return false; 3190 } 3191 } 3192 else 3193 { 3194 // Dump specified images (by basename or fullpath) 3195 const char *arg_cstr; 3196 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 3197 { 3198 FileSpec image_file(arg_cstr, false); 3199 ModuleList matching_modules; 3200 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules); 3201 3202 // Not found in our module list for our target, check the main 3203 // shared module list in case it is a extra file used somewhere 3204 // else 3205 if (num_matching_modules == 0) 3206 num_matching_modules = ModuleList::FindSharedModules (image_file, 3207 target->GetArchitecture(), 3208 NULL, 3209 NULL, 3210 matching_modules); 3211 3212 if (num_matching_modules > 0) 3213 { 3214 for (size_t j=0; j<num_matching_modules; ++j) 3215 { 3216 Module * image_module = matching_modules.GetModulePointerAtIndex(j); 3217 if (image_module) 3218 { 3219 if (LookupInModule (m_interpreter, image_module, result, syntax_error)) 3220 { 3221 result.GetOutputStream().EOL(); 3222 num_successful_lookups++; 3223 } 3224 } 3225 } 3226 } 3227 else 3228 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 3229 } 3230 } 3231 3232 if (num_successful_lookups > 0) 3233 result.SetStatus (eReturnStatusSuccessFinishResult); 3234 else 3235 result.SetStatus (eReturnStatusFailed); 3236 } 3237 return result.Succeeded(); 3238 } 3239 protected: 3240 3241 CommandOptions m_options; 3242 }; 3243 3244 OptionDefinition 3245 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 3246 { 3247 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."}, 3248 { 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."}, 3249 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 3250 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_5 */ , 3251 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 3252 { 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."}, 3253 { 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."}, 3254 { 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)."}, 3255 { LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."}, 3256 { 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."}, 3257 { 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."}, 3258 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 3259 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3260 }; 3261 3262 3263 #pragma mark CommandObjectMultiwordImageSearchPaths 3264 3265 //------------------------------------------------------------------------- 3266 // CommandObjectMultiwordImageSearchPaths 3267 //------------------------------------------------------------------------- 3268 3269 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 3270 { 3271 public: 3272 3273 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 3274 CommandObjectMultiword (interpreter, 3275 "target modules search-paths", 3276 "A set of commands for operating on debugger target image search paths.", 3277 "target modules search-paths <subcommand> [<subcommand-options>]") 3278 { 3279 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 3280 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 3281 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 3282 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 3283 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 3284 } 3285 3286 ~CommandObjectTargetModulesImageSearchPaths() 3287 { 3288 } 3289 }; 3290 3291 3292 3293 #pragma mark CommandObjectTargetModules 3294 3295 //------------------------------------------------------------------------- 3296 // CommandObjectTargetModules 3297 //------------------------------------------------------------------------- 3298 3299 class CommandObjectTargetModules : public CommandObjectMultiword 3300 { 3301 public: 3302 //------------------------------------------------------------------ 3303 // Constructors and Destructors 3304 //------------------------------------------------------------------ 3305 CommandObjectTargetModules(CommandInterpreter &interpreter) : 3306 CommandObjectMultiword (interpreter, 3307 "target modules", 3308 "A set of commands for accessing information for one or more target modules.", 3309 "target modules <sub-command> ...") 3310 { 3311 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 3312 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 3313 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter))); 3314 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 3315 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 3316 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 3317 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 3318 3319 } 3320 virtual 3321 ~CommandObjectTargetModules() 3322 { 3323 } 3324 3325 private: 3326 //------------------------------------------------------------------ 3327 // For CommandObjectTargetModules only 3328 //------------------------------------------------------------------ 3329 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 3330 }; 3331 3332 3333 #pragma mark CommandObjectTargetStopHookAdd 3334 3335 //------------------------------------------------------------------------- 3336 // CommandObjectTargetStopHookAdd 3337 //------------------------------------------------------------------------- 3338 3339 class CommandObjectTargetStopHookAdd : public CommandObject 3340 { 3341 public: 3342 3343 class CommandOptions : public Options 3344 { 3345 public: 3346 CommandOptions (CommandInterpreter &interpreter) : 3347 Options(interpreter), 3348 m_line_start(0), 3349 m_line_end (UINT_MAX), 3350 m_func_name_type_mask (eFunctionNameTypeAuto), 3351 m_sym_ctx_specified (false), 3352 m_thread_specified (false), 3353 m_use_one_liner (false), 3354 m_one_liner() 3355 { 3356 } 3357 3358 ~CommandOptions () {} 3359 3360 const OptionDefinition* 3361 GetDefinitions () 3362 { 3363 return g_option_table; 3364 } 3365 3366 virtual Error 3367 SetOptionValue (uint32_t option_idx, const char *option_arg) 3368 { 3369 Error error; 3370 char short_option = (char) m_getopt_table[option_idx].val; 3371 bool success; 3372 3373 switch (short_option) 3374 { 3375 case 'c': 3376 m_class_name = option_arg; 3377 m_sym_ctx_specified = true; 3378 break; 3379 3380 case 'e': 3381 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success); 3382 if (!success) 3383 { 3384 error.SetErrorStringWithFormat ("Invalid end line number: \"%s\".", option_arg); 3385 break; 3386 } 3387 m_sym_ctx_specified = true; 3388 break; 3389 3390 case 'l': 3391 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 3392 if (!success) 3393 { 3394 error.SetErrorStringWithFormat ("Invalid start line number: \"%s\".", option_arg); 3395 break; 3396 } 3397 m_sym_ctx_specified = true; 3398 break; 3399 3400 case 'n': 3401 m_function_name = option_arg; 3402 m_func_name_type_mask |= eFunctionNameTypeAuto; 3403 m_sym_ctx_specified = true; 3404 break; 3405 3406 case 'f': 3407 m_file_name = option_arg; 3408 m_sym_ctx_specified = true; 3409 break; 3410 case 's': 3411 m_module_name = option_arg; 3412 m_sym_ctx_specified = true; 3413 break; 3414 case 't' : 3415 { 3416 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 3417 if (m_thread_id == LLDB_INVALID_THREAD_ID) 3418 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg); 3419 m_thread_specified = true; 3420 } 3421 break; 3422 case 'T': 3423 m_thread_name = option_arg; 3424 m_thread_specified = true; 3425 break; 3426 case 'q': 3427 m_queue_name = option_arg; 3428 m_thread_specified = true; 3429 break; 3430 case 'x': 3431 { 3432 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 3433 if (m_thread_id == UINT32_MAX) 3434 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg); 3435 m_thread_specified = true; 3436 } 3437 break; 3438 case 'o': 3439 m_use_one_liner = true; 3440 m_one_liner = option_arg; 3441 break; 3442 default: 3443 error.SetErrorStringWithFormat ("Unrecognized option %c.", short_option); 3444 break; 3445 } 3446 return error; 3447 } 3448 3449 void 3450 OptionParsingStarting () 3451 { 3452 m_class_name.clear(); 3453 m_function_name.clear(); 3454 m_line_start = 0; 3455 m_line_end = UINT_MAX; 3456 m_file_name.clear(); 3457 m_module_name.clear(); 3458 m_func_name_type_mask = eFunctionNameTypeAuto; 3459 m_thread_id = LLDB_INVALID_THREAD_ID; 3460 m_thread_index = UINT32_MAX; 3461 m_thread_name.clear(); 3462 m_queue_name.clear(); 3463 3464 m_sym_ctx_specified = false; 3465 m_thread_specified = false; 3466 3467 m_use_one_liner = false; 3468 m_one_liner.clear(); 3469 } 3470 3471 3472 static OptionDefinition g_option_table[]; 3473 3474 std::string m_class_name; 3475 std::string m_function_name; 3476 uint32_t m_line_start; 3477 uint32_t m_line_end; 3478 std::string m_file_name; 3479 std::string m_module_name; 3480 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 3481 lldb::tid_t m_thread_id; 3482 uint32_t m_thread_index; 3483 std::string m_thread_name; 3484 std::string m_queue_name; 3485 bool m_sym_ctx_specified; 3486 bool m_thread_specified; 3487 // Instance variables to hold the values for one_liner options. 3488 bool m_use_one_liner; 3489 std::string m_one_liner; 3490 }; 3491 3492 Options * 3493 GetOptions () 3494 { 3495 return &m_options; 3496 } 3497 3498 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 3499 CommandObject (interpreter, 3500 "target stop-hook add ", 3501 "Add a hook to be executed when the target stops.", 3502 "target stop-hook add"), 3503 m_options (interpreter) 3504 { 3505 } 3506 3507 ~CommandObjectTargetStopHookAdd () 3508 { 3509 } 3510 3511 static size_t 3512 ReadCommandsCallbackFunction (void *baton, 3513 InputReader &reader, 3514 lldb::InputReaderAction notification, 3515 const char *bytes, 3516 size_t bytes_len) 3517 { 3518 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 3519 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton); 3520 static bool got_interrupted; 3521 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 3522 3523 switch (notification) 3524 { 3525 case eInputReaderActivate: 3526 if (!batch_mode) 3527 { 3528 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end."); 3529 if (reader.GetPrompt()) 3530 out_stream->Printf ("%s", reader.GetPrompt()); 3531 out_stream->Flush(); 3532 } 3533 got_interrupted = false; 3534 break; 3535 3536 case eInputReaderDeactivate: 3537 break; 3538 3539 case eInputReaderReactivate: 3540 if (reader.GetPrompt() && !batch_mode) 3541 { 3542 out_stream->Printf ("%s", reader.GetPrompt()); 3543 out_stream->Flush(); 3544 } 3545 got_interrupted = false; 3546 break; 3547 3548 case eInputReaderAsynchronousOutputWritten: 3549 break; 3550 3551 case eInputReaderGotToken: 3552 if (bytes && bytes_len && baton) 3553 { 3554 StringList *commands = new_stop_hook->GetCommandPointer(); 3555 if (commands) 3556 { 3557 commands->AppendString (bytes, bytes_len); 3558 } 3559 } 3560 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode) 3561 { 3562 out_stream->Printf ("%s", reader.GetPrompt()); 3563 out_stream->Flush(); 3564 } 3565 break; 3566 3567 case eInputReaderInterrupt: 3568 { 3569 // Finish, and cancel the stop hook. 3570 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID()); 3571 if (!batch_mode) 3572 { 3573 out_stream->Printf ("Stop hook cancelled.\n"); 3574 out_stream->Flush(); 3575 } 3576 3577 reader.SetIsDone (true); 3578 } 3579 got_interrupted = true; 3580 break; 3581 3582 case eInputReaderEndOfFile: 3583 reader.SetIsDone (true); 3584 break; 3585 3586 case eInputReaderDone: 3587 if (!got_interrupted && !batch_mode) 3588 { 3589 out_stream->Printf ("Stop hook #%d added.\n", new_stop_hook->GetID()); 3590 out_stream->Flush(); 3591 } 3592 break; 3593 } 3594 3595 return bytes_len; 3596 } 3597 3598 bool 3599 Execute (Args& command, 3600 CommandReturnObject &result) 3601 { 3602 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3603 if (target) 3604 { 3605 Target::StopHookSP new_hook_sp; 3606 target->AddStopHook (new_hook_sp); 3607 3608 // First step, make the specifier. 3609 std::auto_ptr<SymbolContextSpecifier> specifier_ap; 3610 if (m_options.m_sym_ctx_specified) 3611 { 3612 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 3613 3614 if (!m_options.m_module_name.empty()) 3615 { 3616 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 3617 } 3618 3619 if (!m_options.m_class_name.empty()) 3620 { 3621 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 3622 } 3623 3624 if (!m_options.m_file_name.empty()) 3625 { 3626 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 3627 } 3628 3629 if (m_options.m_line_start != 0) 3630 { 3631 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 3632 } 3633 3634 if (m_options.m_line_end != UINT_MAX) 3635 { 3636 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 3637 } 3638 3639 if (!m_options.m_function_name.empty()) 3640 { 3641 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 3642 } 3643 } 3644 3645 if (specifier_ap.get()) 3646 new_hook_sp->SetSpecifier (specifier_ap.release()); 3647 3648 // Next see if any of the thread options have been entered: 3649 3650 if (m_options.m_thread_specified) 3651 { 3652 ThreadSpec *thread_spec = new ThreadSpec(); 3653 3654 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 3655 { 3656 thread_spec->SetTID (m_options.m_thread_id); 3657 } 3658 3659 if (m_options.m_thread_index != UINT32_MAX) 3660 thread_spec->SetIndex (m_options.m_thread_index); 3661 3662 if (!m_options.m_thread_name.empty()) 3663 thread_spec->SetName (m_options.m_thread_name.c_str()); 3664 3665 if (!m_options.m_queue_name.empty()) 3666 thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 3667 3668 new_hook_sp->SetThreadSpecifier (thread_spec); 3669 3670 } 3671 if (m_options.m_use_one_liner) 3672 { 3673 // Use one-liner. 3674 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 3675 result.AppendMessageWithFormat("Stop hook #%d added.\n", new_hook_sp->GetID()); 3676 } 3677 else 3678 { 3679 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into 3680 // the new stop hook's command string. 3681 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 3682 if (!reader_sp) 3683 { 3684 result.AppendError("out of memory\n"); 3685 result.SetStatus (eReturnStatusFailed); 3686 target->RemoveStopHookByID (new_hook_sp->GetID()); 3687 return false; 3688 } 3689 3690 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction, 3691 new_hook_sp.get(), // baton 3692 eInputReaderGranularityLine, // token size, to pass to callback function 3693 "DONE", // end token 3694 "> ", // prompt 3695 true)); // echo input 3696 if (!err.Success()) 3697 { 3698 result.AppendError (err.AsCString()); 3699 result.SetStatus (eReturnStatusFailed); 3700 target->RemoveStopHookByID (new_hook_sp->GetID()); 3701 return false; 3702 } 3703 m_interpreter.GetDebugger().PushInputReader (reader_sp); 3704 } 3705 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3706 } 3707 else 3708 { 3709 result.AppendError ("invalid target\n"); 3710 result.SetStatus (eReturnStatusFailed); 3711 } 3712 3713 return result.Succeeded(); 3714 } 3715 private: 3716 CommandOptions m_options; 3717 }; 3718 3719 OptionDefinition 3720 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 3721 { 3722 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner, 3723 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 3724 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 3725 "Set the module within which the stop-hook is to be run."}, 3726 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex, 3727 "The stop hook is run only for the thread whose index matches this argument."}, 3728 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID, 3729 "The stop hook is run only for the thread whose TID matches this argument."}, 3730 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName, 3731 "The stop hook is run only for the thread whose thread name matches this argument."}, 3732 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName, 3733 "The stop hook is run only for threads in the queue whose name is given by this argument."}, 3734 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 3735 "Specify the source file within which the stop-hook is to be run." }, 3736 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 3737 "Set the start of the line range for which the stop-hook is to be run."}, 3738 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum, 3739 "Set the end of the line range for which the stop-hook is to be run."}, 3740 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName, 3741 "Specify the class within which the stop-hook is to be run." }, 3742 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 3743 "Set the function name within which the stop hook will be run." }, 3744 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3745 }; 3746 3747 #pragma mark CommandObjectTargetStopHookDelete 3748 3749 //------------------------------------------------------------------------- 3750 // CommandObjectTargetStopHookDelete 3751 //------------------------------------------------------------------------- 3752 3753 class CommandObjectTargetStopHookDelete : public CommandObject 3754 { 3755 public: 3756 3757 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 3758 CommandObject (interpreter, 3759 "target stop-hook delete [<id>]", 3760 "Delete a stop-hook.", 3761 "target stop-hook delete") 3762 { 3763 } 3764 3765 ~CommandObjectTargetStopHookDelete () 3766 { 3767 } 3768 3769 bool 3770 Execute (Args& command, 3771 CommandReturnObject &result) 3772 { 3773 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3774 if (target) 3775 { 3776 // FIXME: see if we can use the breakpoint id style parser? 3777 size_t num_args = command.GetArgumentCount(); 3778 if (num_args == 0) 3779 { 3780 if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 3781 { 3782 result.SetStatus (eReturnStatusFailed); 3783 return false; 3784 } 3785 else 3786 { 3787 target->RemoveAllStopHooks(); 3788 } 3789 } 3790 else 3791 { 3792 bool success; 3793 for (size_t i = 0; i < num_args; i++) 3794 { 3795 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 3796 if (!success) 3797 { 3798 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3799 result.SetStatus(eReturnStatusFailed); 3800 return false; 3801 } 3802 success = target->RemoveStopHookByID (user_id); 3803 if (!success) 3804 { 3805 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3806 result.SetStatus(eReturnStatusFailed); 3807 return false; 3808 } 3809 } 3810 } 3811 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3812 } 3813 else 3814 { 3815 result.AppendError ("invalid target\n"); 3816 result.SetStatus (eReturnStatusFailed); 3817 } 3818 3819 return result.Succeeded(); 3820 } 3821 }; 3822 #pragma mark CommandObjectTargetStopHookEnableDisable 3823 3824 //------------------------------------------------------------------------- 3825 // CommandObjectTargetStopHookEnableDisable 3826 //------------------------------------------------------------------------- 3827 3828 class CommandObjectTargetStopHookEnableDisable : public CommandObject 3829 { 3830 public: 3831 3832 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 3833 CommandObject (interpreter, 3834 name, 3835 help, 3836 syntax), 3837 m_enable (enable) 3838 { 3839 } 3840 3841 ~CommandObjectTargetStopHookEnableDisable () 3842 { 3843 } 3844 3845 bool 3846 Execute (Args& command, 3847 CommandReturnObject &result) 3848 { 3849 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3850 if (target) 3851 { 3852 // FIXME: see if we can use the breakpoint id style parser? 3853 size_t num_args = command.GetArgumentCount(); 3854 bool success; 3855 3856 if (num_args == 0) 3857 { 3858 target->SetAllStopHooksActiveState (m_enable); 3859 } 3860 else 3861 { 3862 for (size_t i = 0; i < num_args; i++) 3863 { 3864 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 3865 if (!success) 3866 { 3867 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3868 result.SetStatus(eReturnStatusFailed); 3869 return false; 3870 } 3871 success = target->SetStopHookActiveStateByID (user_id, m_enable); 3872 if (!success) 3873 { 3874 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3875 result.SetStatus(eReturnStatusFailed); 3876 return false; 3877 } 3878 } 3879 } 3880 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3881 } 3882 else 3883 { 3884 result.AppendError ("invalid target\n"); 3885 result.SetStatus (eReturnStatusFailed); 3886 } 3887 return result.Succeeded(); 3888 } 3889 private: 3890 bool m_enable; 3891 }; 3892 3893 #pragma mark CommandObjectTargetStopHookList 3894 3895 //------------------------------------------------------------------------- 3896 // CommandObjectTargetStopHookList 3897 //------------------------------------------------------------------------- 3898 3899 class CommandObjectTargetStopHookList : public CommandObject 3900 { 3901 public: 3902 3903 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 3904 CommandObject (interpreter, 3905 "target stop-hook list [<type>]", 3906 "List all stop-hooks.", 3907 "target stop-hook list") 3908 { 3909 } 3910 3911 ~CommandObjectTargetStopHookList () 3912 { 3913 } 3914 3915 bool 3916 Execute (Args& command, 3917 CommandReturnObject &result) 3918 { 3919 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3920 if (target) 3921 { 3922 bool notify = true; 3923 target->GetImageSearchPathList().Clear(notify); 3924 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3925 } 3926 else 3927 { 3928 result.AppendError ("invalid target\n"); 3929 result.SetStatus (eReturnStatusFailed); 3930 return result.Succeeded(); 3931 } 3932 3933 size_t num_hooks = target->GetNumStopHooks (); 3934 if (num_hooks == 0) 3935 { 3936 result.GetOutputStream().PutCString ("No stop hooks.\n"); 3937 } 3938 else 3939 { 3940 for (size_t i = 0; i < num_hooks; i++) 3941 { 3942 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 3943 if (i > 0) 3944 result.GetOutputStream().PutCString ("\n"); 3945 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 3946 } 3947 } 3948 return result.Succeeded(); 3949 } 3950 }; 3951 3952 #pragma mark CommandObjectMultiwordTargetStopHooks 3953 //------------------------------------------------------------------------- 3954 // CommandObjectMultiwordTargetStopHooks 3955 //------------------------------------------------------------------------- 3956 3957 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 3958 { 3959 public: 3960 3961 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 3962 CommandObjectMultiword (interpreter, 3963 "target stop-hook", 3964 "A set of commands for operating on debugger target stop-hooks.", 3965 "target stop-hook <subcommand> [<subcommand-options>]") 3966 { 3967 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 3968 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 3969 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 3970 false, 3971 "target stop-hook disable [<id>]", 3972 "Disable a stop-hook.", 3973 "target stop-hook disable"))); 3974 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 3975 true, 3976 "target stop-hook enable [<id>]", 3977 "Enable a stop-hook.", 3978 "target stop-hook enable"))); 3979 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 3980 } 3981 3982 ~CommandObjectMultiwordTargetStopHooks() 3983 { 3984 } 3985 }; 3986 3987 3988 3989 #pragma mark CommandObjectMultiwordTarget 3990 3991 //------------------------------------------------------------------------- 3992 // CommandObjectMultiwordTarget 3993 //------------------------------------------------------------------------- 3994 3995 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 3996 CommandObjectMultiword (interpreter, 3997 "target", 3998 "A set of commands for operating on debugger targets.", 3999 "target <subcommand> [<subcommand-options>]") 4000 { 4001 4002 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 4003 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 4004 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 4005 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 4006 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 4007 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 4008 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 4009 } 4010 4011 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 4012 { 4013 } 4014 4015 4016