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