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