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