1254721Semaste//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste#include "CommandObjectTarget.h" 13254721Semaste 14254721Semaste// C Includes 15254721Semaste#include <errno.h> 16254721Semaste 17254721Semaste// C++ Includes 18254721Semaste// Other libraries and framework includes 19254721Semaste// Project includes 20254721Semaste#include "lldb/Interpreter/Args.h" 21254721Semaste#include "lldb/Core/Debugger.h" 22254721Semaste#include "lldb/Core/InputReader.h" 23254721Semaste#include "lldb/Core/Module.h" 24254721Semaste#include "lldb/Core/ModuleSpec.h" 25254721Semaste#include "lldb/Core/Section.h" 26254721Semaste#include "lldb/Core/State.h" 27254721Semaste#include "lldb/Core/Timer.h" 28254721Semaste#include "lldb/Core/ValueObjectVariable.h" 29254721Semaste#include "lldb/Host/Symbols.h" 30254721Semaste#include "lldb/Interpreter/CommandInterpreter.h" 31254721Semaste#include "lldb/Interpreter/CommandReturnObject.h" 32254721Semaste#include "lldb/Interpreter/Options.h" 33254721Semaste#include "lldb/Interpreter/OptionGroupArchitecture.h" 34254721Semaste#include "lldb/Interpreter/OptionGroupBoolean.h" 35254721Semaste#include "lldb/Interpreter/OptionGroupFile.h" 36254721Semaste#include "lldb/Interpreter/OptionGroupFormat.h" 37254721Semaste#include "lldb/Interpreter/OptionGroupVariable.h" 38254721Semaste#include "lldb/Interpreter/OptionGroupPlatform.h" 39254721Semaste#include "lldb/Interpreter/OptionGroupUInt64.h" 40254721Semaste#include "lldb/Interpreter/OptionGroupUUID.h" 41254721Semaste#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" 42254721Semaste#include "lldb/Symbol/CompileUnit.h" 43254721Semaste#include "lldb/Symbol/FuncUnwinders.h" 44254721Semaste#include "lldb/Symbol/LineTable.h" 45254721Semaste#include "lldb/Symbol/ObjectFile.h" 46254721Semaste#include "lldb/Symbol/SymbolFile.h" 47254721Semaste#include "lldb/Symbol/SymbolVendor.h" 48254721Semaste#include "lldb/Symbol/UnwindPlan.h" 49254721Semaste#include "lldb/Symbol/VariableList.h" 50254721Semaste#include "lldb/Target/Process.h" 51254721Semaste#include "lldb/Target/StackFrame.h" 52254721Semaste#include "lldb/Target/Thread.h" 53254721Semaste#include "lldb/Target/ThreadSpec.h" 54254721Semaste 55254721Semasteusing namespace lldb; 56254721Semasteusing namespace lldb_private; 57254721Semaste 58254721Semaste 59254721Semaste 60254721Semastestatic void 61254721SemasteDumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm) 62254721Semaste{ 63254721Semaste const ArchSpec &target_arch = target->GetArchitecture(); 64254721Semaste 65254721Semaste Module *exe_module = target->GetExecutableModulePointer(); 66254721Semaste char exe_path[PATH_MAX]; 67254721Semaste bool exe_valid = false; 68254721Semaste if (exe_module) 69254721Semaste exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path)); 70254721Semaste 71254721Semaste if (!exe_valid) 72254721Semaste ::strcpy (exe_path, "<none>"); 73254721Semaste 74254721Semaste strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path); 75254721Semaste 76254721Semaste uint32_t properties = 0; 77254721Semaste if (target_arch.IsValid()) 78254721Semaste { 79254721Semaste strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str()); 80254721Semaste properties++; 81254721Semaste } 82254721Semaste PlatformSP platform_sp (target->GetPlatform()); 83254721Semaste if (platform_sp) 84254721Semaste strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName().GetCString()); 85254721Semaste 86254721Semaste ProcessSP process_sp (target->GetProcessSP()); 87254721Semaste bool show_process_status = false; 88254721Semaste if (process_sp) 89254721Semaste { 90254721Semaste lldb::pid_t pid = process_sp->GetID(); 91254721Semaste StateType state = process_sp->GetState(); 92254721Semaste if (show_stopped_process_status) 93254721Semaste show_process_status = StateIsStoppedState(state, true); 94254721Semaste const char *state_cstr = StateAsCString (state); 95254721Semaste if (pid != LLDB_INVALID_PROCESS_ID) 96254721Semaste strm.Printf ("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid); 97254721Semaste strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr); 98254721Semaste } 99254721Semaste if (properties > 0) 100254721Semaste strm.PutCString (" )\n"); 101254721Semaste else 102254721Semaste strm.EOL(); 103254721Semaste if (show_process_status) 104254721Semaste { 105254721Semaste const bool only_threads_with_stop_reason = true; 106254721Semaste const uint32_t start_frame = 0; 107254721Semaste const uint32_t num_frames = 1; 108254721Semaste const uint32_t num_frames_with_source = 1; 109254721Semaste process_sp->GetStatus (strm); 110254721Semaste process_sp->GetThreadStatus (strm, 111254721Semaste only_threads_with_stop_reason, 112254721Semaste start_frame, 113254721Semaste num_frames, 114254721Semaste num_frames_with_source); 115254721Semaste 116254721Semaste } 117254721Semaste} 118254721Semaste 119254721Semastestatic uint32_t 120254721SemasteDumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm) 121254721Semaste{ 122254721Semaste const uint32_t num_targets = target_list.GetNumTargets(); 123254721Semaste if (num_targets) 124254721Semaste { 125254721Semaste TargetSP selected_target_sp (target_list.GetSelectedTarget()); 126254721Semaste strm.PutCString ("Current targets:\n"); 127254721Semaste for (uint32_t i=0; i<num_targets; ++i) 128254721Semaste { 129254721Semaste TargetSP target_sp (target_list.GetTargetAtIndex (i)); 130254721Semaste if (target_sp) 131254721Semaste { 132254721Semaste bool is_selected = target_sp.get() == selected_target_sp.get(); 133254721Semaste DumpTargetInfo (i, 134254721Semaste target_sp.get(), 135254721Semaste is_selected ? "* " : " ", 136254721Semaste show_stopped_process_status, 137254721Semaste strm); 138254721Semaste } 139254721Semaste } 140254721Semaste } 141254721Semaste return num_targets; 142254721Semaste} 143254721Semaste#pragma mark CommandObjectTargetCreate 144254721Semaste 145254721Semaste//------------------------------------------------------------------------- 146254721Semaste// "target create" 147254721Semaste//------------------------------------------------------------------------- 148254721Semaste 149254721Semasteclass CommandObjectTargetCreate : public CommandObjectParsed 150254721Semaste{ 151254721Semastepublic: 152254721Semaste CommandObjectTargetCreate(CommandInterpreter &interpreter) : 153254721Semaste CommandObjectParsed (interpreter, 154254721Semaste "target create", 155254721Semaste "Create a target using the argument as the main executable.", 156254721Semaste NULL), 157254721Semaste m_option_group (interpreter), 158254721Semaste m_arch_option (), 159254721Semaste m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true 160254721Semaste m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename, "Fullpath to a core file to use for this target."), 161254721Semaste m_symbol_file (LLDB_OPT_SET_1, false, "symfile", 's', 0, eArgTypeFilename, "Fullpath to a stand alone debug symbols file for when debug symbols are not in the executable."), 162254721Semaste m_remote_file (LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename, "Fullpath to the file on the remote host if debugging remotely."), 163254721Semaste m_add_dependents (LLDB_OPT_SET_1, false, "no-dependents", 'd', "Don't load dependent files when creating the target, just add the specified executable.", true, true) 164254721Semaste { 165254721Semaste CommandArgumentEntry arg; 166254721Semaste CommandArgumentData file_arg; 167254721Semaste 168254721Semaste // Define the first (and only) variant of this arg. 169254721Semaste file_arg.arg_type = eArgTypeFilename; 170254721Semaste file_arg.arg_repetition = eArgRepeatPlain; 171254721Semaste 172254721Semaste // There is only one variant this argument could be; put it into the argument entry. 173254721Semaste arg.push_back (file_arg); 174254721Semaste 175254721Semaste // Push the data for the first argument into the m_arguments vector. 176254721Semaste m_arguments.push_back (arg); 177254721Semaste 178254721Semaste m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 179254721Semaste m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 180254721Semaste m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 181254721Semaste m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 182254721Semaste m_option_group.Append (&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 183254721Semaste m_option_group.Append (&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 184254721Semaste m_option_group.Finalize(); 185254721Semaste } 186254721Semaste 187254721Semaste ~CommandObjectTargetCreate () 188254721Semaste { 189254721Semaste } 190254721Semaste 191254721Semaste Options * 192254721Semaste GetOptions () 193254721Semaste { 194254721Semaste return &m_option_group; 195254721Semaste } 196254721Semaste 197254721Semaste virtual int 198254721Semaste HandleArgumentCompletion (Args &input, 199254721Semaste int &cursor_index, 200254721Semaste int &cursor_char_position, 201254721Semaste OptionElementVector &opt_element_vector, 202254721Semaste int match_start_point, 203254721Semaste int max_return_elements, 204254721Semaste bool &word_complete, 205254721Semaste StringList &matches) 206254721Semaste { 207254721Semaste std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 208254721Semaste completion_str.erase (cursor_char_position); 209254721Semaste 210254721Semaste CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 211254721Semaste CommandCompletions::eDiskFileCompletion, 212254721Semaste completion_str.c_str(), 213254721Semaste match_start_point, 214254721Semaste max_return_elements, 215254721Semaste NULL, 216254721Semaste word_complete, 217254721Semaste matches); 218254721Semaste return matches.GetSize(); 219254721Semaste } 220254721Semaste 221254721Semasteprotected: 222254721Semaste bool 223254721Semaste DoExecute (Args& command, CommandReturnObject &result) 224254721Semaste { 225254721Semaste const size_t argc = command.GetArgumentCount(); 226254721Semaste FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue()); 227254721Semaste FileSpec remote_file (m_remote_file.GetOptionValue().GetCurrentValue()); 228254721Semaste 229254721Semaste if (argc == 1 || core_file) 230254721Semaste { 231254721Semaste FileSpec symfile (m_symbol_file.GetOptionValue().GetCurrentValue()); 232254721Semaste if (symfile) 233254721Semaste { 234254721Semaste if (!symfile.Exists()) 235254721Semaste { 236254721Semaste char symfile_path[PATH_MAX]; 237254721Semaste symfile.GetPath(symfile_path, sizeof(symfile_path)); 238254721Semaste result.AppendErrorWithFormat("invalid symbol file path '%s'", symfile_path); 239254721Semaste result.SetStatus (eReturnStatusFailed); 240254721Semaste return false; 241254721Semaste } 242254721Semaste } 243254721Semaste 244254721Semaste const char *file_path = command.GetArgumentAtIndex(0); 245254721Semaste Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path); 246254721Semaste TargetSP target_sp; 247254721Semaste Debugger &debugger = m_interpreter.GetDebugger(); 248254721Semaste const char *arch_cstr = m_arch_option.GetArchitectureName(); 249254721Semaste const bool get_dependent_files = m_add_dependents.GetOptionValue().GetCurrentValue(); 250254721Semaste Error error (debugger.GetTargetList().CreateTarget (debugger, 251254721Semaste file_path, 252254721Semaste arch_cstr, 253254721Semaste get_dependent_files, 254254721Semaste &m_platform_options, 255254721Semaste target_sp)); 256254721Semaste 257254721Semaste if (target_sp) 258254721Semaste { 259254721Semaste if (symfile || remote_file) 260254721Semaste { 261254721Semaste ModuleSP module_sp (target_sp->GetExecutableModule()); 262254721Semaste if (module_sp) 263254721Semaste { 264254721Semaste if (symfile) 265254721Semaste module_sp->SetSymbolFileFileSpec(symfile); 266254721Semaste if (remote_file) 267254721Semaste { 268254721Semaste std::string remote_path = remote_file.GetPath(); 269254721Semaste target_sp->SetArg0(remote_path.c_str()); 270254721Semaste module_sp->SetPlatformFileSpec(remote_file); 271254721Semaste } 272254721Semaste } 273254721Semaste } 274254721Semaste 275254721Semaste debugger.GetTargetList().SetSelectedTarget(target_sp.get()); 276254721Semaste if (core_file) 277254721Semaste { 278254721Semaste char core_path[PATH_MAX]; 279254721Semaste core_file.GetPath(core_path, sizeof(core_path)); 280254721Semaste if (core_file.Exists()) 281254721Semaste { 282254721Semaste FileSpec core_file_dir; 283254721Semaste core_file_dir.GetDirectory() = core_file.GetDirectory(); 284254721Semaste target_sp->GetExecutableSearchPaths ().Append (core_file_dir); 285254721Semaste 286254721Semaste ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file)); 287254721Semaste 288254721Semaste if (process_sp) 289254721Semaste { 290254721Semaste // Seems wierd that we Launch a core file, but that is 291254721Semaste // what we do! 292254721Semaste error = process_sp->LoadCore(); 293254721Semaste 294254721Semaste if (error.Fail()) 295254721Semaste { 296254721Semaste result.AppendError(error.AsCString("can't find plug-in for core file")); 297254721Semaste result.SetStatus (eReturnStatusFailed); 298254721Semaste return false; 299254721Semaste } 300254721Semaste else 301254721Semaste { 302254721Semaste result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName()); 303254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 304254721Semaste } 305254721Semaste } 306254721Semaste else 307254721Semaste { 308254721Semaste result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path); 309254721Semaste result.SetStatus (eReturnStatusFailed); 310254721Semaste } 311254721Semaste } 312254721Semaste else 313254721Semaste { 314254721Semaste result.AppendErrorWithFormat ("Core file '%s' does not exist\n", core_path); 315254721Semaste result.SetStatus (eReturnStatusFailed); 316254721Semaste } 317254721Semaste } 318254721Semaste else 319254721Semaste { 320254721Semaste result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName()); 321254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 322254721Semaste } 323254721Semaste } 324254721Semaste else 325254721Semaste { 326254721Semaste result.AppendError(error.AsCString()); 327254721Semaste result.SetStatus (eReturnStatusFailed); 328254721Semaste } 329254721Semaste } 330254721Semaste else 331254721Semaste { 332254721Semaste result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core-file option.\n", m_cmd_name.c_str()); 333254721Semaste result.SetStatus (eReturnStatusFailed); 334254721Semaste } 335254721Semaste return result.Succeeded(); 336254721Semaste 337254721Semaste } 338254721Semaste 339254721Semasteprivate: 340254721Semaste OptionGroupOptions m_option_group; 341254721Semaste OptionGroupArchitecture m_arch_option; 342254721Semaste OptionGroupPlatform m_platform_options; 343254721Semaste OptionGroupFile m_core_file; 344254721Semaste OptionGroupFile m_symbol_file; 345254721Semaste OptionGroupFile m_remote_file; 346254721Semaste OptionGroupBoolean m_add_dependents; 347254721Semaste}; 348254721Semaste 349254721Semaste#pragma mark CommandObjectTargetList 350254721Semaste 351254721Semaste//---------------------------------------------------------------------- 352254721Semaste// "target list" 353254721Semaste//---------------------------------------------------------------------- 354254721Semaste 355254721Semasteclass CommandObjectTargetList : public CommandObjectParsed 356254721Semaste{ 357254721Semastepublic: 358254721Semaste CommandObjectTargetList (CommandInterpreter &interpreter) : 359254721Semaste CommandObjectParsed (interpreter, 360254721Semaste "target list", 361254721Semaste "List all current targets in the current debug session.", 362254721Semaste NULL, 363254721Semaste 0) 364254721Semaste { 365254721Semaste } 366254721Semaste 367254721Semaste virtual 368254721Semaste ~CommandObjectTargetList () 369254721Semaste { 370254721Semaste } 371254721Semaste 372254721Semasteprotected: 373254721Semaste virtual bool 374254721Semaste DoExecute (Args& args, CommandReturnObject &result) 375254721Semaste { 376254721Semaste if (args.GetArgumentCount() == 0) 377254721Semaste { 378254721Semaste Stream &strm = result.GetOutputStream(); 379254721Semaste 380254721Semaste bool show_stopped_process_status = false; 381254721Semaste if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0) 382254721Semaste { 383254721Semaste strm.PutCString ("No targets.\n"); 384254721Semaste } 385254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 386254721Semaste } 387254721Semaste else 388254721Semaste { 389254721Semaste result.AppendError ("the 'target list' command takes no arguments\n"); 390254721Semaste result.SetStatus (eReturnStatusFailed); 391254721Semaste } 392254721Semaste return result.Succeeded(); 393254721Semaste } 394254721Semaste}; 395254721Semaste 396254721Semaste 397254721Semaste#pragma mark CommandObjectTargetSelect 398254721Semaste 399254721Semaste//---------------------------------------------------------------------- 400254721Semaste// "target select" 401254721Semaste//---------------------------------------------------------------------- 402254721Semaste 403254721Semasteclass CommandObjectTargetSelect : public CommandObjectParsed 404254721Semaste{ 405254721Semastepublic: 406254721Semaste CommandObjectTargetSelect (CommandInterpreter &interpreter) : 407254721Semaste CommandObjectParsed (interpreter, 408254721Semaste "target select", 409254721Semaste "Select a target as the current target by target index.", 410254721Semaste NULL, 411254721Semaste 0) 412254721Semaste { 413254721Semaste } 414254721Semaste 415254721Semaste virtual 416254721Semaste ~CommandObjectTargetSelect () 417254721Semaste { 418254721Semaste } 419254721Semaste 420254721Semasteprotected: 421254721Semaste virtual bool 422254721Semaste DoExecute (Args& args, CommandReturnObject &result) 423254721Semaste { 424254721Semaste if (args.GetArgumentCount() == 1) 425254721Semaste { 426254721Semaste bool success = false; 427254721Semaste const char *target_idx_arg = args.GetArgumentAtIndex(0); 428254721Semaste uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success); 429254721Semaste if (success) 430254721Semaste { 431254721Semaste TargetList &target_list = m_interpreter.GetDebugger().GetTargetList(); 432254721Semaste const uint32_t num_targets = target_list.GetNumTargets(); 433254721Semaste if (target_idx < num_targets) 434254721Semaste { 435254721Semaste TargetSP target_sp (target_list.GetTargetAtIndex (target_idx)); 436254721Semaste if (target_sp) 437254721Semaste { 438254721Semaste Stream &strm = result.GetOutputStream(); 439254721Semaste target_list.SetSelectedTarget (target_sp.get()); 440254721Semaste bool show_stopped_process_status = false; 441254721Semaste DumpTargetList (target_list, show_stopped_process_status, strm); 442254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 443254721Semaste } 444254721Semaste else 445254721Semaste { 446254721Semaste result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx); 447254721Semaste result.SetStatus (eReturnStatusFailed); 448254721Semaste } 449254721Semaste } 450254721Semaste else 451254721Semaste { 452254721Semaste result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n", 453254721Semaste target_idx, 454254721Semaste num_targets - 1); 455254721Semaste result.SetStatus (eReturnStatusFailed); 456254721Semaste } 457254721Semaste } 458254721Semaste else 459254721Semaste { 460254721Semaste result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg); 461254721Semaste result.SetStatus (eReturnStatusFailed); 462254721Semaste } 463254721Semaste } 464254721Semaste else 465254721Semaste { 466254721Semaste result.AppendError ("'target select' takes a single argument: a target index\n"); 467254721Semaste result.SetStatus (eReturnStatusFailed); 468254721Semaste } 469254721Semaste return result.Succeeded(); 470254721Semaste } 471254721Semaste}; 472254721Semaste 473254721Semaste#pragma mark CommandObjectTargetSelect 474254721Semaste 475254721Semaste//---------------------------------------------------------------------- 476254721Semaste// "target delete" 477254721Semaste//---------------------------------------------------------------------- 478254721Semaste 479254721Semasteclass CommandObjectTargetDelete : public CommandObjectParsed 480254721Semaste{ 481254721Semastepublic: 482254721Semaste CommandObjectTargetDelete (CommandInterpreter &interpreter) : 483254721Semaste CommandObjectParsed (interpreter, 484254721Semaste "target delete", 485254721Semaste "Delete one or more targets by target index.", 486254721Semaste NULL, 487254721Semaste 0), 488254721Semaste m_option_group (interpreter), 489254721Semaste m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', "Perform extra cleanup to minimize memory consumption after deleting the target.", false, false) 490254721Semaste { 491254721Semaste m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 492254721Semaste m_option_group.Finalize(); 493254721Semaste } 494254721Semaste 495254721Semaste virtual 496254721Semaste ~CommandObjectTargetDelete () 497254721Semaste { 498254721Semaste } 499254721Semaste 500254721Semaste Options * 501254721Semaste GetOptions () 502254721Semaste { 503254721Semaste return &m_option_group; 504254721Semaste } 505254721Semaste 506254721Semasteprotected: 507254721Semaste virtual bool 508254721Semaste DoExecute (Args& args, CommandReturnObject &result) 509254721Semaste { 510254721Semaste const size_t argc = args.GetArgumentCount(); 511254721Semaste std::vector<TargetSP> delete_target_list; 512254721Semaste TargetList &target_list = m_interpreter.GetDebugger().GetTargetList(); 513254721Semaste bool success = true; 514254721Semaste TargetSP target_sp; 515254721Semaste if (argc > 0) 516254721Semaste { 517254721Semaste const uint32_t num_targets = target_list.GetNumTargets(); 518254721Semaste // Bail out if don't have any targets. 519254721Semaste if (num_targets == 0) { 520254721Semaste result.AppendError("no targets to delete"); 521254721Semaste result.SetStatus(eReturnStatusFailed); 522254721Semaste success = false; 523254721Semaste } 524254721Semaste 525254721Semaste for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx) 526254721Semaste { 527254721Semaste const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx); 528254721Semaste uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success); 529254721Semaste if (success) 530254721Semaste { 531254721Semaste if (target_idx < num_targets) 532254721Semaste { 533254721Semaste target_sp = target_list.GetTargetAtIndex (target_idx); 534254721Semaste if (target_sp) 535254721Semaste { 536254721Semaste delete_target_list.push_back (target_sp); 537254721Semaste continue; 538254721Semaste } 539254721Semaste } 540254721Semaste if (num_targets > 1) 541254721Semaste result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n", 542254721Semaste target_idx, 543254721Semaste num_targets - 1); 544254721Semaste else 545254721Semaste result.AppendErrorWithFormat("target index %u is out of range, the only valid index is 0\n", 546254721Semaste target_idx); 547254721Semaste 548254721Semaste result.SetStatus (eReturnStatusFailed); 549254721Semaste success = false; 550254721Semaste } 551254721Semaste else 552254721Semaste { 553254721Semaste result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg); 554254721Semaste result.SetStatus (eReturnStatusFailed); 555254721Semaste success = false; 556254721Semaste } 557254721Semaste } 558254721Semaste 559254721Semaste } 560254721Semaste else 561254721Semaste { 562254721Semaste target_sp = target_list.GetSelectedTarget(); 563254721Semaste if (target_sp) 564254721Semaste { 565254721Semaste delete_target_list.push_back (target_sp); 566254721Semaste } 567254721Semaste else 568254721Semaste { 569254721Semaste result.AppendErrorWithFormat("no target is currently selected\n"); 570254721Semaste result.SetStatus (eReturnStatusFailed); 571254721Semaste success = false; 572254721Semaste } 573254721Semaste } 574254721Semaste if (success) 575254721Semaste { 576254721Semaste const size_t num_targets_to_delete = delete_target_list.size(); 577254721Semaste for (size_t idx = 0; idx < num_targets_to_delete; ++idx) 578254721Semaste { 579254721Semaste target_sp = delete_target_list[idx]; 580254721Semaste target_list.DeleteTarget(target_sp); 581254721Semaste target_sp->Destroy(); 582254721Semaste } 583254721Semaste // If "--clean" was specified, prune any orphaned shared modules from 584254721Semaste // the global shared module list 585254721Semaste if (m_cleanup_option.GetOptionValue ()) 586254721Semaste { 587254721Semaste const bool mandatory = true; 588254721Semaste ModuleList::RemoveOrphanSharedModules(mandatory); 589254721Semaste } 590254721Semaste result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete); 591254721Semaste result.SetStatus(eReturnStatusSuccessFinishResult); 592254721Semaste } 593254721Semaste 594254721Semaste return result.Succeeded(); 595254721Semaste } 596254721Semaste 597254721Semaste OptionGroupOptions m_option_group; 598254721Semaste OptionGroupBoolean m_cleanup_option; 599254721Semaste}; 600254721Semaste 601254721Semaste 602254721Semaste#pragma mark CommandObjectTargetVariable 603254721Semaste 604254721Semaste//---------------------------------------------------------------------- 605254721Semaste// "target variable" 606254721Semaste//---------------------------------------------------------------------- 607254721Semaste 608254721Semasteclass CommandObjectTargetVariable : public CommandObjectParsed 609254721Semaste{ 610254721Semastepublic: 611254721Semaste CommandObjectTargetVariable (CommandInterpreter &interpreter) : 612254721Semaste CommandObjectParsed (interpreter, 613254721Semaste "target variable", 614254721Semaste "Read global variable(s) prior to, or while running your binary.", 615254721Semaste NULL, 616254721Semaste eFlagRequiresTarget), 617254721Semaste m_option_group (interpreter), 618254721Semaste m_option_variable (false), // Don't include frame options 619254721Semaste m_option_format (eFormatDefault), 620254721Semaste m_option_compile_units (LLDB_OPT_SET_1, false, "file", 'file', 0, eArgTypeFilename, "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."), 621254721Semaste m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",'shlb', 0, eArgTypeFilename, "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."), 622254721Semaste m_varobj_options() 623254721Semaste { 624254721Semaste CommandArgumentEntry arg; 625254721Semaste CommandArgumentData var_name_arg; 626254721Semaste 627254721Semaste // Define the first (and only) variant of this arg. 628254721Semaste var_name_arg.arg_type = eArgTypeVarName; 629254721Semaste var_name_arg.arg_repetition = eArgRepeatPlus; 630254721Semaste 631254721Semaste // There is only one variant this argument could be; put it into the argument entry. 632254721Semaste arg.push_back (var_name_arg); 633254721Semaste 634254721Semaste // Push the data for the first argument into the m_arguments vector. 635254721Semaste m_arguments.push_back (arg); 636254721Semaste 637254721Semaste m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 638254721Semaste m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 639254721Semaste m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1); 640254721Semaste m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 641254721Semaste m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 642254721Semaste m_option_group.Finalize(); 643254721Semaste } 644254721Semaste 645254721Semaste virtual 646254721Semaste ~CommandObjectTargetVariable () 647254721Semaste { 648254721Semaste } 649254721Semaste 650254721Semaste void 651254721Semaste DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name) 652254721Semaste { 653254721Semaste ValueObject::DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions()); 654254721Semaste 655254721Semaste switch (var_sp->GetScope()) 656254721Semaste { 657254721Semaste case eValueTypeVariableGlobal: 658254721Semaste if (m_option_variable.show_scope) 659254721Semaste s.PutCString("GLOBAL: "); 660254721Semaste break; 661254721Semaste 662254721Semaste case eValueTypeVariableStatic: 663254721Semaste if (m_option_variable.show_scope) 664254721Semaste s.PutCString("STATIC: "); 665254721Semaste break; 666254721Semaste 667254721Semaste case eValueTypeVariableArgument: 668254721Semaste if (m_option_variable.show_scope) 669254721Semaste s.PutCString(" ARG: "); 670254721Semaste break; 671254721Semaste 672254721Semaste case eValueTypeVariableLocal: 673254721Semaste if (m_option_variable.show_scope) 674254721Semaste s.PutCString(" LOCAL: "); 675254721Semaste break; 676254721Semaste 677254721Semaste default: 678254721Semaste break; 679254721Semaste } 680254721Semaste 681254721Semaste if (m_option_variable.show_decl) 682254721Semaste { 683254721Semaste bool show_fullpaths = false; 684254721Semaste bool show_module = true; 685254721Semaste if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module)) 686254721Semaste s.PutCString (": "); 687254721Semaste } 688254721Semaste 689254721Semaste const Format format = m_option_format.GetFormat(); 690254721Semaste if (format != eFormatDefault) 691254721Semaste options.SetFormat(format); 692254721Semaste 693254721Semaste options.SetRootValueObjectName(root_name); 694254721Semaste 695254721Semaste ValueObject::DumpValueObject (s, 696254721Semaste valobj_sp.get(), 697254721Semaste options); 698254721Semaste 699254721Semaste } 700254721Semaste 701254721Semaste 702254721Semaste static size_t GetVariableCallback (void *baton, 703254721Semaste const char *name, 704254721Semaste VariableList &variable_list) 705254721Semaste { 706254721Semaste Target *target = static_cast<Target *>(baton); 707254721Semaste if (target) 708254721Semaste { 709254721Semaste return target->GetImages().FindGlobalVariables (ConstString(name), 710254721Semaste true, 711254721Semaste UINT32_MAX, 712254721Semaste variable_list); 713254721Semaste } 714254721Semaste return 0; 715254721Semaste } 716254721Semaste 717254721Semaste 718254721Semaste 719254721Semaste Options * 720254721Semaste GetOptions () 721254721Semaste { 722254721Semaste return &m_option_group; 723254721Semaste } 724254721Semaste 725254721Semasteprotected: 726254721Semaste 727254721Semaste void 728254721Semaste DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, const VariableList &variable_list, Stream &s) 729254721Semaste { 730254721Semaste size_t count = variable_list.GetSize(); 731254721Semaste if (count > 0) 732254721Semaste { 733254721Semaste if (sc.module_sp) 734254721Semaste { 735254721Semaste if (sc.comp_unit) 736254721Semaste { 737254721Semaste s.Printf ("Global variables for %s in %s:\n", 738254721Semaste sc.comp_unit->GetPath().c_str(), 739254721Semaste sc.module_sp->GetFileSpec().GetPath().c_str()); 740254721Semaste } 741254721Semaste else 742254721Semaste { 743254721Semaste s.Printf ("Global variables for %s\n", 744254721Semaste sc.module_sp->GetFileSpec().GetPath().c_str()); 745254721Semaste } 746254721Semaste } 747254721Semaste else if (sc.comp_unit) 748254721Semaste { 749254721Semaste s.Printf ("Global variables for %s\n", 750254721Semaste sc.comp_unit->GetPath().c_str()); 751254721Semaste } 752254721Semaste 753254721Semaste for (uint32_t i=0; i<count; ++i) 754254721Semaste { 755254721Semaste VariableSP var_sp (variable_list.GetVariableAtIndex(i)); 756254721Semaste if (var_sp) 757254721Semaste { 758254721Semaste ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp)); 759254721Semaste 760254721Semaste if (valobj_sp) 761254721Semaste DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString()); 762254721Semaste } 763254721Semaste } 764254721Semaste } 765254721Semaste 766254721Semaste } 767254721Semaste virtual bool 768254721Semaste DoExecute (Args& args, CommandReturnObject &result) 769254721Semaste { 770254721Semaste Target *target = m_exe_ctx.GetTargetPtr(); 771254721Semaste const size_t argc = args.GetArgumentCount(); 772254721Semaste Stream &s = result.GetOutputStream(); 773254721Semaste 774254721Semaste if (argc > 0) 775254721Semaste { 776254721Semaste 777254721Semaste for (size_t idx = 0; idx < argc; ++idx) 778254721Semaste { 779254721Semaste VariableList variable_list; 780254721Semaste ValueObjectList valobj_list; 781254721Semaste 782254721Semaste const char *arg = args.GetArgumentAtIndex(idx); 783254721Semaste size_t matches = 0; 784254721Semaste bool use_var_name = false; 785254721Semaste if (m_option_variable.use_regex) 786254721Semaste { 787254721Semaste RegularExpression regex(arg); 788254721Semaste if (!regex.IsValid ()) 789254721Semaste { 790254721Semaste result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg); 791254721Semaste result.SetStatus (eReturnStatusFailed); 792254721Semaste return false; 793254721Semaste } 794254721Semaste use_var_name = true; 795254721Semaste matches = target->GetImages().FindGlobalVariables (regex, 796254721Semaste true, 797254721Semaste UINT32_MAX, 798254721Semaste variable_list); 799254721Semaste } 800254721Semaste else 801254721Semaste { 802254721Semaste Error error (Variable::GetValuesForVariableExpressionPath (arg, 803254721Semaste m_exe_ctx.GetBestExecutionContextScope(), 804254721Semaste GetVariableCallback, 805254721Semaste target, 806254721Semaste variable_list, 807254721Semaste valobj_list)); 808254721Semaste matches = variable_list.GetSize(); 809254721Semaste } 810254721Semaste 811254721Semaste if (matches == 0) 812254721Semaste { 813254721Semaste result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg); 814254721Semaste result.SetStatus (eReturnStatusFailed); 815254721Semaste return false; 816254721Semaste } 817254721Semaste else 818254721Semaste { 819254721Semaste for (uint32_t global_idx=0; global_idx<matches; ++global_idx) 820254721Semaste { 821254721Semaste VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx)); 822254721Semaste if (var_sp) 823254721Semaste { 824254721Semaste ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx)); 825254721Semaste if (!valobj_sp) 826254721Semaste valobj_sp = ValueObjectVariable::Create (m_exe_ctx.GetBestExecutionContextScope(), var_sp); 827254721Semaste 828254721Semaste if (valobj_sp) 829254721Semaste DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg); 830254721Semaste } 831254721Semaste } 832254721Semaste } 833254721Semaste } 834254721Semaste } 835254721Semaste else 836254721Semaste { 837254721Semaste const FileSpecList &compile_units = m_option_compile_units.GetOptionValue().GetCurrentValue(); 838254721Semaste const FileSpecList &shlibs = m_option_shared_libraries.GetOptionValue().GetCurrentValue(); 839254721Semaste SymbolContextList sc_list; 840254721Semaste const size_t num_compile_units = compile_units.GetSize(); 841254721Semaste const size_t num_shlibs = shlibs.GetSize(); 842254721Semaste if (num_compile_units == 0 && num_shlibs == 0) 843254721Semaste { 844254721Semaste bool success = false; 845254721Semaste StackFrame *frame = m_exe_ctx.GetFramePtr(); 846254721Semaste CompileUnit *comp_unit = NULL; 847254721Semaste if (frame) 848254721Semaste { 849254721Semaste SymbolContext sc = frame->GetSymbolContext (eSymbolContextCompUnit); 850254721Semaste if (sc.comp_unit) 851254721Semaste { 852254721Semaste const bool can_create = true; 853254721Semaste VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create)); 854254721Semaste if (comp_unit_varlist_sp) 855254721Semaste { 856254721Semaste size_t count = comp_unit_varlist_sp->GetSize(); 857254721Semaste if (count > 0) 858254721Semaste { 859254721Semaste DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s); 860254721Semaste success = true; 861254721Semaste } 862254721Semaste } 863254721Semaste } 864254721Semaste } 865254721Semaste if (!success) 866254721Semaste { 867254721Semaste if (frame) 868254721Semaste { 869254721Semaste if (comp_unit) 870254721Semaste result.AppendErrorWithFormat ("no global variables in current compile unit: %s\n", 871254721Semaste comp_unit->GetPath().c_str()); 872254721Semaste else 873254721Semaste result.AppendErrorWithFormat ("no debug information for frame %u\n", frame->GetFrameIndex()); 874254721Semaste } 875254721Semaste else 876254721Semaste result.AppendError ("'target variable' takes one or more global variable names as arguments\n"); 877254721Semaste result.SetStatus (eReturnStatusFailed); 878254721Semaste } 879254721Semaste } 880254721Semaste else 881254721Semaste { 882254721Semaste SymbolContextList sc_list; 883254721Semaste const bool append = true; 884254721Semaste // We have one or more compile unit or shlib 885254721Semaste if (num_shlibs > 0) 886254721Semaste { 887254721Semaste for (size_t shlib_idx=0; shlib_idx<num_shlibs; ++shlib_idx) 888254721Semaste { 889254721Semaste const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx)); 890254721Semaste ModuleSpec module_spec (module_file); 891254721Semaste 892254721Semaste ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); 893254721Semaste if (module_sp) 894254721Semaste { 895254721Semaste if (num_compile_units > 0) 896254721Semaste { 897254721Semaste for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx) 898254721Semaste module_sp->FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list); 899254721Semaste } 900254721Semaste else 901254721Semaste { 902254721Semaste SymbolContext sc; 903254721Semaste sc.module_sp = module_sp; 904254721Semaste sc_list.Append(sc); 905254721Semaste } 906254721Semaste } 907254721Semaste else 908254721Semaste { 909254721Semaste // Didn't find matching shlib/module in target... 910254721Semaste result.AppendErrorWithFormat ("target doesn't contain the specified shared library: %s\n", 911254721Semaste module_file.GetPath().c_str()); 912254721Semaste } 913254721Semaste } 914254721Semaste } 915254721Semaste else 916254721Semaste { 917254721Semaste // No shared libraries, we just want to find globals for the compile units files that were specified 918254721Semaste for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx) 919254721Semaste target->GetImages().FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list); 920254721Semaste } 921254721Semaste 922254721Semaste const uint32_t num_scs = sc_list.GetSize(); 923254721Semaste if (num_scs > 0) 924254721Semaste { 925254721Semaste SymbolContext sc; 926254721Semaste for (uint32_t sc_idx=0; sc_idx<num_scs; ++sc_idx) 927254721Semaste { 928254721Semaste if (sc_list.GetContextAtIndex(sc_idx, sc)) 929254721Semaste { 930254721Semaste if (sc.comp_unit) 931254721Semaste { 932254721Semaste const bool can_create = true; 933254721Semaste VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create)); 934254721Semaste if (comp_unit_varlist_sp) 935254721Semaste DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s); 936254721Semaste } 937254721Semaste else if (sc.module_sp) 938254721Semaste { 939254721Semaste // Get all global variables for this module 940254721Semaste lldb_private::RegularExpression all_globals_regex("."); // Any global with at least one character 941254721Semaste VariableList variable_list; 942254721Semaste sc.module_sp->FindGlobalVariables(all_globals_regex, append, UINT32_MAX, variable_list); 943254721Semaste DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s); 944254721Semaste } 945254721Semaste } 946254721Semaste } 947254721Semaste } 948254721Semaste } 949254721Semaste } 950254721Semaste 951254721Semaste if (m_interpreter.TruncationWarningNecessary()) 952254721Semaste { 953254721Semaste result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(), 954254721Semaste m_cmd_name.c_str()); 955254721Semaste m_interpreter.TruncationWarningGiven(); 956254721Semaste } 957254721Semaste 958254721Semaste return result.Succeeded(); 959254721Semaste } 960254721Semaste 961254721Semaste OptionGroupOptions m_option_group; 962254721Semaste OptionGroupVariable m_option_variable; 963254721Semaste OptionGroupFormat m_option_format; 964254721Semaste OptionGroupFileList m_option_compile_units; 965254721Semaste OptionGroupFileList m_option_shared_libraries; 966254721Semaste OptionGroupValueObjectDisplay m_varobj_options; 967254721Semaste 968254721Semaste}; 969254721Semaste 970254721Semaste 971254721Semaste#pragma mark CommandObjectTargetModulesSearchPathsAdd 972254721Semaste 973254721Semasteclass CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed 974254721Semaste{ 975254721Semastepublic: 976254721Semaste 977254721Semaste CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) : 978254721Semaste CommandObjectParsed (interpreter, 979254721Semaste "target modules search-paths add", 980254721Semaste "Add new image search paths substitution pairs to the current target.", 981254721Semaste NULL) 982254721Semaste { 983254721Semaste CommandArgumentEntry arg; 984254721Semaste CommandArgumentData old_prefix_arg; 985254721Semaste CommandArgumentData new_prefix_arg; 986254721Semaste 987254721Semaste // Define the first variant of this arg pair. 988254721Semaste old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 989254721Semaste old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 990254721Semaste 991254721Semaste // Define the first variant of this arg pair. 992254721Semaste new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 993254721Semaste new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 994254721Semaste 995254721Semaste // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 996254721Semaste // must always occur together, they are treated as two variants of one argument rather than two independent 997254721Semaste // arguments. Push them both into the first argument position for m_arguments... 998254721Semaste 999254721Semaste arg.push_back (old_prefix_arg); 1000254721Semaste arg.push_back (new_prefix_arg); 1001254721Semaste 1002254721Semaste m_arguments.push_back (arg); 1003254721Semaste } 1004254721Semaste 1005254721Semaste ~CommandObjectTargetModulesSearchPathsAdd () 1006254721Semaste { 1007254721Semaste } 1008254721Semaste 1009254721Semasteprotected: 1010254721Semaste bool 1011254721Semaste DoExecute (Args& command, 1012254721Semaste CommandReturnObject &result) 1013254721Semaste { 1014254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1015254721Semaste if (target) 1016254721Semaste { 1017254721Semaste const size_t argc = command.GetArgumentCount(); 1018254721Semaste if (argc & 1) 1019254721Semaste { 1020254721Semaste result.AppendError ("add requires an even number of arguments\n"); 1021254721Semaste result.SetStatus (eReturnStatusFailed); 1022254721Semaste } 1023254721Semaste else 1024254721Semaste { 1025254721Semaste for (size_t i=0; i<argc; i+=2) 1026254721Semaste { 1027254721Semaste const char *from = command.GetArgumentAtIndex(i); 1028254721Semaste const char *to = command.GetArgumentAtIndex(i+1); 1029254721Semaste 1030254721Semaste if (from[0] && to[0]) 1031254721Semaste { 1032254721Semaste bool last_pair = ((argc - i) == 2); 1033254721Semaste target->GetImageSearchPathList().Append (ConstString(from), 1034254721Semaste ConstString(to), 1035254721Semaste last_pair); // Notify if this is the last pair 1036254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1037254721Semaste } 1038254721Semaste else 1039254721Semaste { 1040254721Semaste if (from[0]) 1041254721Semaste result.AppendError ("<path-prefix> can't be empty\n"); 1042254721Semaste else 1043254721Semaste result.AppendError ("<new-path-prefix> can't be empty\n"); 1044254721Semaste result.SetStatus (eReturnStatusFailed); 1045254721Semaste } 1046254721Semaste } 1047254721Semaste } 1048254721Semaste } 1049254721Semaste else 1050254721Semaste { 1051254721Semaste result.AppendError ("invalid target\n"); 1052254721Semaste result.SetStatus (eReturnStatusFailed); 1053254721Semaste } 1054254721Semaste return result.Succeeded(); 1055254721Semaste } 1056254721Semaste}; 1057254721Semaste 1058254721Semaste#pragma mark CommandObjectTargetModulesSearchPathsClear 1059254721Semaste 1060254721Semasteclass CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed 1061254721Semaste{ 1062254721Semastepublic: 1063254721Semaste 1064254721Semaste CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) : 1065254721Semaste CommandObjectParsed (interpreter, 1066254721Semaste "target modules search-paths clear", 1067254721Semaste "Clear all current image search path substitution pairs from the current target.", 1068254721Semaste "target modules search-paths clear") 1069254721Semaste { 1070254721Semaste } 1071254721Semaste 1072254721Semaste ~CommandObjectTargetModulesSearchPathsClear () 1073254721Semaste { 1074254721Semaste } 1075254721Semaste 1076254721Semasteprotected: 1077254721Semaste bool 1078254721Semaste DoExecute (Args& command, 1079254721Semaste CommandReturnObject &result) 1080254721Semaste { 1081254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1082254721Semaste if (target) 1083254721Semaste { 1084254721Semaste bool notify = true; 1085254721Semaste target->GetImageSearchPathList().Clear(notify); 1086254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1087254721Semaste } 1088254721Semaste else 1089254721Semaste { 1090254721Semaste result.AppendError ("invalid target\n"); 1091254721Semaste result.SetStatus (eReturnStatusFailed); 1092254721Semaste } 1093254721Semaste return result.Succeeded(); 1094254721Semaste } 1095254721Semaste}; 1096254721Semaste 1097254721Semaste#pragma mark CommandObjectTargetModulesSearchPathsInsert 1098254721Semaste 1099254721Semasteclass CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed 1100254721Semaste{ 1101254721Semastepublic: 1102254721Semaste 1103254721Semaste CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) : 1104254721Semaste CommandObjectParsed (interpreter, 1105254721Semaste "target modules search-paths insert", 1106254721Semaste "Insert a new image search path substitution pair into the current target at the specified index.", 1107254721Semaste NULL) 1108254721Semaste { 1109254721Semaste CommandArgumentEntry arg1; 1110254721Semaste CommandArgumentEntry arg2; 1111254721Semaste CommandArgumentData index_arg; 1112254721Semaste CommandArgumentData old_prefix_arg; 1113254721Semaste CommandArgumentData new_prefix_arg; 1114254721Semaste 1115254721Semaste // Define the first and only variant of this arg. 1116254721Semaste index_arg.arg_type = eArgTypeIndex; 1117254721Semaste index_arg.arg_repetition = eArgRepeatPlain; 1118254721Semaste 1119254721Semaste // Put the one and only variant into the first arg for m_arguments: 1120254721Semaste arg1.push_back (index_arg); 1121254721Semaste 1122254721Semaste // Define the first variant of this arg pair. 1123254721Semaste old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 1124254721Semaste old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 1125254721Semaste 1126254721Semaste // Define the first variant of this arg pair. 1127254721Semaste new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 1128254721Semaste new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 1129254721Semaste 1130254721Semaste // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 1131254721Semaste // must always occur together, they are treated as two variants of one argument rather than two independent 1132254721Semaste // arguments. Push them both into the same argument position for m_arguments... 1133254721Semaste 1134254721Semaste arg2.push_back (old_prefix_arg); 1135254721Semaste arg2.push_back (new_prefix_arg); 1136254721Semaste 1137254721Semaste // Add arguments to m_arguments. 1138254721Semaste m_arguments.push_back (arg1); 1139254721Semaste m_arguments.push_back (arg2); 1140254721Semaste } 1141254721Semaste 1142254721Semaste ~CommandObjectTargetModulesSearchPathsInsert () 1143254721Semaste { 1144254721Semaste } 1145254721Semaste 1146254721Semasteprotected: 1147254721Semaste bool 1148254721Semaste DoExecute (Args& command, 1149254721Semaste CommandReturnObject &result) 1150254721Semaste { 1151254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1152254721Semaste if (target) 1153254721Semaste { 1154254721Semaste size_t argc = command.GetArgumentCount(); 1155254721Semaste // check for at least 3 arguments and an odd nubmer of parameters 1156254721Semaste if (argc >= 3 && argc & 1) 1157254721Semaste { 1158254721Semaste bool success = false; 1159254721Semaste 1160254721Semaste uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success); 1161254721Semaste 1162254721Semaste if (!success) 1163254721Semaste { 1164254721Semaste result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0)); 1165254721Semaste result.SetStatus (eReturnStatusFailed); 1166254721Semaste return result.Succeeded(); 1167254721Semaste } 1168254721Semaste 1169254721Semaste // shift off the index 1170254721Semaste command.Shift(); 1171254721Semaste argc = command.GetArgumentCount(); 1172254721Semaste 1173254721Semaste for (uint32_t i=0; i<argc; i+=2, ++insert_idx) 1174254721Semaste { 1175254721Semaste const char *from = command.GetArgumentAtIndex(i); 1176254721Semaste const char *to = command.GetArgumentAtIndex(i+1); 1177254721Semaste 1178254721Semaste if (from[0] && to[0]) 1179254721Semaste { 1180254721Semaste bool last_pair = ((argc - i) == 2); 1181254721Semaste target->GetImageSearchPathList().Insert (ConstString(from), 1182254721Semaste ConstString(to), 1183254721Semaste insert_idx, 1184254721Semaste last_pair); 1185254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1186254721Semaste } 1187254721Semaste else 1188254721Semaste { 1189254721Semaste if (from[0]) 1190254721Semaste result.AppendError ("<path-prefix> can't be empty\n"); 1191254721Semaste else 1192254721Semaste result.AppendError ("<new-path-prefix> can't be empty\n"); 1193254721Semaste result.SetStatus (eReturnStatusFailed); 1194254721Semaste return false; 1195254721Semaste } 1196254721Semaste } 1197254721Semaste } 1198254721Semaste else 1199254721Semaste { 1200254721Semaste result.AppendError ("insert requires at least three arguments\n"); 1201254721Semaste result.SetStatus (eReturnStatusFailed); 1202254721Semaste return result.Succeeded(); 1203254721Semaste } 1204254721Semaste 1205254721Semaste } 1206254721Semaste else 1207254721Semaste { 1208254721Semaste result.AppendError ("invalid target\n"); 1209254721Semaste result.SetStatus (eReturnStatusFailed); 1210254721Semaste } 1211254721Semaste return result.Succeeded(); 1212254721Semaste } 1213254721Semaste}; 1214254721Semaste 1215254721Semaste 1216254721Semaste#pragma mark CommandObjectTargetModulesSearchPathsList 1217254721Semaste 1218254721Semaste 1219254721Semasteclass CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed 1220254721Semaste{ 1221254721Semastepublic: 1222254721Semaste 1223254721Semaste CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) : 1224254721Semaste CommandObjectParsed (interpreter, 1225254721Semaste "target modules search-paths list", 1226254721Semaste "List all current image search path substitution pairs in the current target.", 1227254721Semaste "target modules search-paths list") 1228254721Semaste { 1229254721Semaste } 1230254721Semaste 1231254721Semaste ~CommandObjectTargetModulesSearchPathsList () 1232254721Semaste { 1233254721Semaste } 1234254721Semaste 1235254721Semasteprotected: 1236254721Semaste bool 1237254721Semaste DoExecute (Args& command, 1238254721Semaste CommandReturnObject &result) 1239254721Semaste { 1240254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1241254721Semaste if (target) 1242254721Semaste { 1243254721Semaste if (command.GetArgumentCount() != 0) 1244254721Semaste { 1245254721Semaste result.AppendError ("list takes no arguments\n"); 1246254721Semaste result.SetStatus (eReturnStatusFailed); 1247254721Semaste return result.Succeeded(); 1248254721Semaste } 1249254721Semaste 1250254721Semaste target->GetImageSearchPathList().Dump(&result.GetOutputStream()); 1251254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 1252254721Semaste } 1253254721Semaste else 1254254721Semaste { 1255254721Semaste result.AppendError ("invalid target\n"); 1256254721Semaste result.SetStatus (eReturnStatusFailed); 1257254721Semaste } 1258254721Semaste return result.Succeeded(); 1259254721Semaste } 1260254721Semaste}; 1261254721Semaste 1262254721Semaste#pragma mark CommandObjectTargetModulesSearchPathsQuery 1263254721Semaste 1264254721Semasteclass CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed 1265254721Semaste{ 1266254721Semastepublic: 1267254721Semaste 1268254721Semaste CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) : 1269254721Semaste CommandObjectParsed (interpreter, 1270254721Semaste "target modules search-paths query", 1271254721Semaste "Transform a path using the first applicable image search path.", 1272254721Semaste NULL) 1273254721Semaste { 1274254721Semaste CommandArgumentEntry arg; 1275254721Semaste CommandArgumentData path_arg; 1276254721Semaste 1277254721Semaste // Define the first (and only) variant of this arg. 1278254721Semaste path_arg.arg_type = eArgTypeDirectoryName; 1279254721Semaste path_arg.arg_repetition = eArgRepeatPlain; 1280254721Semaste 1281254721Semaste // There is only one variant this argument could be; put it into the argument entry. 1282254721Semaste arg.push_back (path_arg); 1283254721Semaste 1284254721Semaste // Push the data for the first argument into the m_arguments vector. 1285254721Semaste m_arguments.push_back (arg); 1286254721Semaste } 1287254721Semaste 1288254721Semaste ~CommandObjectTargetModulesSearchPathsQuery () 1289254721Semaste { 1290254721Semaste } 1291254721Semaste 1292254721Semasteprotected: 1293254721Semaste bool 1294254721Semaste DoExecute (Args& command, 1295254721Semaste CommandReturnObject &result) 1296254721Semaste { 1297254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1298254721Semaste if (target) 1299254721Semaste { 1300254721Semaste if (command.GetArgumentCount() != 1) 1301254721Semaste { 1302254721Semaste result.AppendError ("query requires one argument\n"); 1303254721Semaste result.SetStatus (eReturnStatusFailed); 1304254721Semaste return result.Succeeded(); 1305254721Semaste } 1306254721Semaste 1307254721Semaste ConstString orig(command.GetArgumentAtIndex(0)); 1308254721Semaste ConstString transformed; 1309254721Semaste if (target->GetImageSearchPathList().RemapPath(orig, transformed)) 1310254721Semaste result.GetOutputStream().Printf("%s\n", transformed.GetCString()); 1311254721Semaste else 1312254721Semaste result.GetOutputStream().Printf("%s\n", orig.GetCString()); 1313254721Semaste 1314254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 1315254721Semaste } 1316254721Semaste else 1317254721Semaste { 1318254721Semaste result.AppendError ("invalid target\n"); 1319254721Semaste result.SetStatus (eReturnStatusFailed); 1320254721Semaste } 1321254721Semaste return result.Succeeded(); 1322254721Semaste } 1323254721Semaste}; 1324254721Semaste 1325254721Semaste//---------------------------------------------------------------------- 1326254721Semaste// Static Helper functions 1327254721Semaste//---------------------------------------------------------------------- 1328254721Semastestatic void 1329254721SemasteDumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width) 1330254721Semaste{ 1331254721Semaste if (module) 1332254721Semaste { 1333254721Semaste const char *arch_cstr; 1334254721Semaste if (full_triple) 1335254721Semaste arch_cstr = module->GetArchitecture().GetTriple().str().c_str(); 1336254721Semaste else 1337254721Semaste arch_cstr = module->GetArchitecture().GetArchitectureName(); 1338254721Semaste if (width) 1339254721Semaste strm.Printf("%-*s", width, arch_cstr); 1340254721Semaste else 1341254721Semaste strm.PutCString(arch_cstr); 1342254721Semaste } 1343254721Semaste} 1344254721Semaste 1345254721Semastestatic void 1346254721SemasteDumpModuleUUID (Stream &strm, Module *module) 1347254721Semaste{ 1348254721Semaste if (module && module->GetUUID().IsValid()) 1349254721Semaste module->GetUUID().Dump (&strm); 1350254721Semaste else 1351254721Semaste strm.PutCString(" "); 1352254721Semaste} 1353254721Semaste 1354254721Semastestatic uint32_t 1355254721SemasteDumpCompileUnitLineTable (CommandInterpreter &interpreter, 1356254721Semaste Stream &strm, 1357254721Semaste Module *module, 1358254721Semaste const FileSpec &file_spec, 1359254721Semaste bool load_addresses) 1360254721Semaste{ 1361254721Semaste uint32_t num_matches = 0; 1362254721Semaste if (module) 1363254721Semaste { 1364254721Semaste SymbolContextList sc_list; 1365254721Semaste num_matches = module->ResolveSymbolContextsForFileSpec (file_spec, 1366254721Semaste 0, 1367254721Semaste false, 1368254721Semaste eSymbolContextCompUnit, 1369254721Semaste sc_list); 1370254721Semaste 1371254721Semaste for (uint32_t i=0; i<num_matches; ++i) 1372254721Semaste { 1373254721Semaste SymbolContext sc; 1374254721Semaste if (sc_list.GetContextAtIndex(i, sc)) 1375254721Semaste { 1376254721Semaste if (i > 0) 1377254721Semaste strm << "\n\n"; 1378254721Semaste 1379254721Semaste strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `" 1380254721Semaste << module->GetFileSpec().GetFilename() << "\n"; 1381254721Semaste LineTable *line_table = sc.comp_unit->GetLineTable(); 1382254721Semaste if (line_table) 1383254721Semaste line_table->GetDescription (&strm, 1384254721Semaste interpreter.GetExecutionContext().GetTargetPtr(), 1385254721Semaste lldb::eDescriptionLevelBrief); 1386254721Semaste else 1387254721Semaste strm << "No line table"; 1388254721Semaste } 1389254721Semaste } 1390254721Semaste } 1391254721Semaste return num_matches; 1392254721Semaste} 1393254721Semaste 1394254721Semastestatic void 1395254721SemasteDumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1396254721Semaste{ 1397254721Semaste if (file_spec_ptr) 1398254721Semaste { 1399254721Semaste if (width > 0) 1400254721Semaste { 1401254721Semaste std::string fullpath = file_spec_ptr->GetPath(); 1402254721Semaste strm.Printf("%-*s", width, fullpath.c_str()); 1403254721Semaste return; 1404254721Semaste } 1405254721Semaste else 1406254721Semaste { 1407254721Semaste file_spec_ptr->Dump(&strm); 1408254721Semaste return; 1409254721Semaste } 1410254721Semaste } 1411254721Semaste // Keep the width spacing correct if things go wrong... 1412254721Semaste if (width > 0) 1413254721Semaste strm.Printf("%-*s", width, ""); 1414254721Semaste} 1415254721Semaste 1416254721Semastestatic void 1417254721SemasteDumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1418254721Semaste{ 1419254721Semaste if (file_spec_ptr) 1420254721Semaste { 1421254721Semaste if (width > 0) 1422254721Semaste strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString("")); 1423254721Semaste else 1424254721Semaste file_spec_ptr->GetDirectory().Dump(&strm); 1425254721Semaste return; 1426254721Semaste } 1427254721Semaste // Keep the width spacing correct if things go wrong... 1428254721Semaste if (width > 0) 1429254721Semaste strm.Printf("%-*s", width, ""); 1430254721Semaste} 1431254721Semaste 1432254721Semastestatic void 1433254721SemasteDumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1434254721Semaste{ 1435254721Semaste if (file_spec_ptr) 1436254721Semaste { 1437254721Semaste if (width > 0) 1438254721Semaste strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString("")); 1439254721Semaste else 1440254721Semaste file_spec_ptr->GetFilename().Dump(&strm); 1441254721Semaste return; 1442254721Semaste } 1443254721Semaste // Keep the width spacing correct if things go wrong... 1444254721Semaste if (width > 0) 1445254721Semaste strm.Printf("%-*s", width, ""); 1446254721Semaste} 1447254721Semaste 1448254721Semaste 1449254721Semastestatic void 1450254721SemasteDumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order) 1451254721Semaste{ 1452254721Semaste if (module) 1453254721Semaste { 1454254721Semaste SymbolVendor *sym_vendor = module->GetSymbolVendor (); 1455254721Semaste if (sym_vendor) 1456254721Semaste { 1457254721Semaste Symtab *symtab = sym_vendor->GetSymtab(); 1458254721Semaste if (symtab) 1459254721Semaste symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order); 1460254721Semaste } 1461254721Semaste } 1462254721Semaste} 1463254721Semaste 1464254721Semastestatic void 1465254721SemasteDumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module) 1466254721Semaste{ 1467254721Semaste if (module) 1468254721Semaste { 1469254721Semaste SectionList *section_list = module->GetSectionList(); 1470254721Semaste if (section_list) 1471254721Semaste { 1472254721Semaste strm.Printf ("Sections for '%s' (%s):\n", 1473254721Semaste module->GetSpecificationDescription().c_str(), 1474254721Semaste module->GetArchitecture().GetArchitectureName()); 1475254721Semaste strm.IndentMore(); 1476254721Semaste section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX); 1477254721Semaste strm.IndentLess(); 1478254721Semaste } 1479254721Semaste } 1480254721Semaste} 1481254721Semaste 1482254721Semastestatic bool 1483254721SemasteDumpModuleSymbolVendor (Stream &strm, Module *module) 1484254721Semaste{ 1485254721Semaste if (module) 1486254721Semaste { 1487254721Semaste SymbolVendor *symbol_vendor = module->GetSymbolVendor(true); 1488254721Semaste if (symbol_vendor) 1489254721Semaste { 1490254721Semaste symbol_vendor->Dump(&strm); 1491254721Semaste return true; 1492254721Semaste } 1493254721Semaste } 1494254721Semaste return false; 1495254721Semaste} 1496254721Semaste 1497254721Semastestatic void 1498254721SemasteDumpAddress (ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, Stream &strm) 1499254721Semaste{ 1500254721Semaste strm.IndentMore(); 1501254721Semaste strm.Indent (" Address: "); 1502254721Semaste so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress); 1503254721Semaste strm.PutCString (" ("); 1504254721Semaste so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset); 1505254721Semaste strm.PutCString (")\n"); 1506254721Semaste strm.Indent (" Summary: "); 1507254721Semaste const uint32_t save_indent = strm.GetIndentLevel (); 1508254721Semaste strm.SetIndentLevel (save_indent + 13); 1509254721Semaste so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription); 1510254721Semaste strm.SetIndentLevel (save_indent); 1511254721Semaste // Print out detailed address information when verbose is enabled 1512254721Semaste if (verbose) 1513254721Semaste { 1514254721Semaste strm.EOL(); 1515254721Semaste so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext); 1516254721Semaste } 1517254721Semaste strm.IndentLess(); 1518254721Semaste} 1519254721Semaste 1520254721Semastestatic bool 1521254721SemasteLookupAddressInModule (CommandInterpreter &interpreter, 1522254721Semaste Stream &strm, 1523254721Semaste Module *module, 1524254721Semaste uint32_t resolve_mask, 1525254721Semaste lldb::addr_t raw_addr, 1526254721Semaste lldb::addr_t offset, 1527254721Semaste bool verbose) 1528254721Semaste{ 1529254721Semaste if (module) 1530254721Semaste { 1531254721Semaste lldb::addr_t addr = raw_addr - offset; 1532254721Semaste Address so_addr; 1533254721Semaste SymbolContext sc; 1534254721Semaste Target *target = interpreter.GetExecutionContext().GetTargetPtr(); 1535254721Semaste if (target && !target->GetSectionLoadList().IsEmpty()) 1536254721Semaste { 1537254721Semaste if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr)) 1538254721Semaste return false; 1539254721Semaste else if (so_addr.GetModule().get() != module) 1540254721Semaste return false; 1541254721Semaste } 1542254721Semaste else 1543254721Semaste { 1544254721Semaste if (!module->ResolveFileAddress (addr, so_addr)) 1545254721Semaste return false; 1546254721Semaste } 1547254721Semaste 1548254721Semaste ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); 1549254721Semaste DumpAddress (exe_scope, so_addr, verbose, strm); 1550254721Semaste// strm.IndentMore(); 1551254721Semaste// strm.Indent (" Address: "); 1552254721Semaste// so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress); 1553254721Semaste// strm.PutCString (" ("); 1554254721Semaste// so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset); 1555254721Semaste// strm.PutCString (")\n"); 1556254721Semaste// strm.Indent (" Summary: "); 1557254721Semaste// const uint32_t save_indent = strm.GetIndentLevel (); 1558254721Semaste// strm.SetIndentLevel (save_indent + 13); 1559254721Semaste// so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription); 1560254721Semaste// strm.SetIndentLevel (save_indent); 1561254721Semaste// // Print out detailed address information when verbose is enabled 1562254721Semaste// if (verbose) 1563254721Semaste// { 1564254721Semaste// strm.EOL(); 1565254721Semaste// so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext); 1566254721Semaste// } 1567254721Semaste// strm.IndentLess(); 1568254721Semaste return true; 1569254721Semaste } 1570254721Semaste 1571254721Semaste return false; 1572254721Semaste} 1573254721Semaste 1574254721Semastestatic uint32_t 1575254721SemasteLookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose) 1576254721Semaste{ 1577254721Semaste if (module) 1578254721Semaste { 1579254721Semaste SymbolContext sc; 1580254721Semaste 1581254721Semaste SymbolVendor *sym_vendor = module->GetSymbolVendor (); 1582254721Semaste if (sym_vendor) 1583254721Semaste { 1584254721Semaste Symtab *symtab = sym_vendor->GetSymtab(); 1585254721Semaste if (symtab) 1586254721Semaste { 1587254721Semaste uint32_t i; 1588254721Semaste std::vector<uint32_t> match_indexes; 1589254721Semaste ConstString symbol_name (name); 1590254721Semaste uint32_t num_matches = 0; 1591254721Semaste if (name_is_regex) 1592254721Semaste { 1593254721Semaste RegularExpression name_regexp(name); 1594254721Semaste num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp, 1595254721Semaste eSymbolTypeAny, 1596254721Semaste match_indexes); 1597254721Semaste } 1598254721Semaste else 1599254721Semaste { 1600254721Semaste num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes); 1601254721Semaste } 1602254721Semaste 1603254721Semaste 1604254721Semaste if (num_matches > 0) 1605254721Semaste { 1606254721Semaste strm.Indent (); 1607254721Semaste strm.Printf("%u symbols match %s'%s' in ", num_matches, 1608254721Semaste name_is_regex ? "the regular expression " : "", name); 1609254721Semaste DumpFullpath (strm, &module->GetFileSpec(), 0); 1610254721Semaste strm.PutCString(":\n"); 1611254721Semaste strm.IndentMore (); 1612254721Semaste //Symtab::DumpSymbolHeader (&strm); 1613254721Semaste for (i=0; i < num_matches; ++i) 1614254721Semaste { 1615254721Semaste Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); 1616254721Semaste DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(), 1617254721Semaste symbol->GetAddress(), 1618254721Semaste verbose, 1619254721Semaste strm); 1620254721Semaste 1621254721Semaste// strm.Indent (); 1622254721Semaste// symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i); 1623254721Semaste } 1624254721Semaste strm.IndentLess (); 1625254721Semaste return num_matches; 1626254721Semaste } 1627254721Semaste } 1628254721Semaste } 1629254721Semaste } 1630254721Semaste return 0; 1631254721Semaste} 1632254721Semaste 1633254721Semaste 1634254721Semastestatic void 1635254721SemasteDumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose) 1636254721Semaste{ 1637254721Semaste strm.IndentMore (); 1638254721Semaste uint32_t i; 1639254721Semaste const uint32_t num_matches = sc_list.GetSize(); 1640254721Semaste 1641254721Semaste for (i=0; i<num_matches; ++i) 1642254721Semaste { 1643254721Semaste SymbolContext sc; 1644254721Semaste if (sc_list.GetContextAtIndex(i, sc)) 1645254721Semaste { 1646254721Semaste AddressRange range; 1647254721Semaste 1648254721Semaste sc.GetAddressRange(eSymbolContextEverything, 1649254721Semaste 0, 1650254721Semaste true, 1651254721Semaste range); 1652254721Semaste 1653254721Semaste DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm); 1654254721Semaste } 1655254721Semaste } 1656254721Semaste strm.IndentLess (); 1657254721Semaste} 1658254721Semaste 1659254721Semastestatic size_t 1660254721SemasteLookupFunctionInModule (CommandInterpreter &interpreter, 1661254721Semaste Stream &strm, 1662254721Semaste Module *module, 1663254721Semaste const char *name, 1664254721Semaste bool name_is_regex, 1665254721Semaste bool include_inlines, 1666254721Semaste bool include_symbols, 1667254721Semaste bool verbose) 1668254721Semaste{ 1669254721Semaste if (module && name && name[0]) 1670254721Semaste { 1671254721Semaste SymbolContextList sc_list; 1672254721Semaste const bool append = true; 1673254721Semaste size_t num_matches = 0; 1674254721Semaste if (name_is_regex) 1675254721Semaste { 1676254721Semaste RegularExpression function_name_regex (name); 1677254721Semaste num_matches = module->FindFunctions (function_name_regex, 1678254721Semaste include_symbols, 1679254721Semaste include_inlines, 1680254721Semaste append, 1681254721Semaste sc_list); 1682254721Semaste } 1683254721Semaste else 1684254721Semaste { 1685254721Semaste ConstString function_name (name); 1686254721Semaste num_matches = module->FindFunctions (function_name, 1687254721Semaste NULL, 1688254721Semaste eFunctionNameTypeAuto, 1689254721Semaste include_symbols, 1690254721Semaste include_inlines, 1691254721Semaste append, 1692254721Semaste sc_list); 1693254721Semaste } 1694254721Semaste 1695254721Semaste if (num_matches) 1696254721Semaste { 1697254721Semaste strm.Indent (); 1698254721Semaste strm.Printf("%zu match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1699254721Semaste DumpFullpath (strm, &module->GetFileSpec(), 0); 1700254721Semaste strm.PutCString(":\n"); 1701254721Semaste DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose); 1702254721Semaste } 1703254721Semaste return num_matches; 1704254721Semaste } 1705254721Semaste return 0; 1706254721Semaste} 1707254721Semaste 1708254721Semastestatic size_t 1709254721SemasteLookupTypeInModule (CommandInterpreter &interpreter, 1710254721Semaste Stream &strm, 1711254721Semaste Module *module, 1712254721Semaste const char *name_cstr, 1713254721Semaste bool name_is_regex) 1714254721Semaste{ 1715254721Semaste if (module && name_cstr && name_cstr[0]) 1716254721Semaste { 1717254721Semaste TypeList type_list; 1718254721Semaste const uint32_t max_num_matches = UINT32_MAX; 1719254721Semaste size_t num_matches = 0; 1720254721Semaste bool name_is_fully_qualified = false; 1721254721Semaste SymbolContext sc; 1722254721Semaste 1723254721Semaste ConstString name(name_cstr); 1724254721Semaste num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list); 1725254721Semaste 1726254721Semaste if (num_matches) 1727254721Semaste { 1728254721Semaste strm.Indent (); 1729254721Semaste strm.Printf("%zu match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1730254721Semaste DumpFullpath (strm, &module->GetFileSpec(), 0); 1731254721Semaste strm.PutCString(":\n"); 1732254721Semaste const uint32_t num_types = type_list.GetSize(); 1733254721Semaste for (uint32_t i=0; i<num_types; ++i) 1734254721Semaste { 1735254721Semaste TypeSP type_sp (type_list.GetTypeAtIndex(i)); 1736254721Semaste if (type_sp) 1737254721Semaste { 1738254721Semaste // Resolve the clang type so that any forward references 1739254721Semaste // to types that haven't yet been parsed will get parsed. 1740254721Semaste type_sp->GetClangFullType (); 1741254721Semaste type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1742254721Semaste // Print all typedef chains 1743254721Semaste TypeSP typedef_type_sp (type_sp); 1744254721Semaste TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType()); 1745254721Semaste while (typedefed_type_sp) 1746254721Semaste { 1747254721Semaste strm.EOL(); 1748254721Semaste strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString()); 1749254721Semaste typedefed_type_sp->GetClangFullType (); 1750254721Semaste typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1751254721Semaste typedef_type_sp = typedefed_type_sp; 1752254721Semaste typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1753254721Semaste } 1754254721Semaste } 1755254721Semaste strm.EOL(); 1756254721Semaste } 1757254721Semaste } 1758254721Semaste return num_matches; 1759254721Semaste } 1760254721Semaste return 0; 1761254721Semaste} 1762254721Semaste 1763254721Semastestatic size_t 1764254721SemasteLookupTypeHere (CommandInterpreter &interpreter, 1765254721Semaste Stream &strm, 1766254721Semaste const SymbolContext &sym_ctx, 1767254721Semaste const char *name_cstr, 1768254721Semaste bool name_is_regex) 1769254721Semaste{ 1770254721Semaste if (!sym_ctx.module_sp) 1771254721Semaste return 0; 1772254721Semaste 1773254721Semaste TypeList type_list; 1774254721Semaste const uint32_t max_num_matches = UINT32_MAX; 1775254721Semaste size_t num_matches = 1; 1776254721Semaste bool name_is_fully_qualified = false; 1777254721Semaste 1778254721Semaste ConstString name(name_cstr); 1779254721Semaste num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list); 1780254721Semaste 1781254721Semaste if (num_matches) 1782254721Semaste { 1783254721Semaste strm.Indent (); 1784254721Semaste strm.PutCString("Best match found in "); 1785254721Semaste DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0); 1786254721Semaste strm.PutCString(":\n"); 1787254721Semaste 1788254721Semaste TypeSP type_sp (type_list.GetTypeAtIndex(0)); 1789254721Semaste if (type_sp) 1790254721Semaste { 1791254721Semaste // Resolve the clang type so that any forward references 1792254721Semaste // to types that haven't yet been parsed will get parsed. 1793254721Semaste type_sp->GetClangFullType (); 1794254721Semaste type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1795254721Semaste // Print all typedef chains 1796254721Semaste TypeSP typedef_type_sp (type_sp); 1797254721Semaste TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType()); 1798254721Semaste while (typedefed_type_sp) 1799254721Semaste { 1800254721Semaste strm.EOL(); 1801254721Semaste strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString()); 1802254721Semaste typedefed_type_sp->GetClangFullType (); 1803254721Semaste typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1804254721Semaste typedef_type_sp = typedefed_type_sp; 1805254721Semaste typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1806254721Semaste } 1807254721Semaste } 1808254721Semaste strm.EOL(); 1809254721Semaste } 1810254721Semaste return num_matches; 1811254721Semaste} 1812254721Semaste 1813254721Semastestatic uint32_t 1814254721SemasteLookupFileAndLineInModule (CommandInterpreter &interpreter, 1815254721Semaste Stream &strm, 1816254721Semaste Module *module, 1817254721Semaste const FileSpec &file_spec, 1818254721Semaste uint32_t line, 1819254721Semaste bool check_inlines, 1820254721Semaste bool verbose) 1821254721Semaste{ 1822254721Semaste if (module && file_spec) 1823254721Semaste { 1824254721Semaste SymbolContextList sc_list; 1825254721Semaste const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, 1826254721Semaste eSymbolContextEverything, sc_list); 1827254721Semaste if (num_matches > 0) 1828254721Semaste { 1829254721Semaste strm.Indent (); 1830254721Semaste strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1831254721Semaste strm << file_spec; 1832254721Semaste if (line > 0) 1833254721Semaste strm.Printf (":%u", line); 1834254721Semaste strm << " in "; 1835254721Semaste DumpFullpath (strm, &module->GetFileSpec(), 0); 1836254721Semaste strm.PutCString(":\n"); 1837254721Semaste DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose); 1838254721Semaste return num_matches; 1839254721Semaste } 1840254721Semaste } 1841254721Semaste return 0; 1842254721Semaste 1843254721Semaste} 1844254721Semaste 1845254721Semaste 1846254721Semastestatic size_t 1847254721SemasteFindModulesByName (Target *target, 1848254721Semaste const char *module_name, 1849254721Semaste ModuleList &module_list, 1850254721Semaste bool check_global_list) 1851254721Semaste{ 1852254721Semaste// Dump specified images (by basename or fullpath) 1853254721Semaste FileSpec module_file_spec(module_name, false); 1854254721Semaste ModuleSpec module_spec (module_file_spec); 1855254721Semaste 1856254721Semaste const size_t initial_size = module_list.GetSize (); 1857254721Semaste 1858254721Semaste if (check_global_list) 1859254721Semaste { 1860254721Semaste // Check the global list 1861254721Semaste Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 1862254721Semaste const size_t num_modules = Module::GetNumberAllocatedModules(); 1863254721Semaste ModuleSP module_sp; 1864254721Semaste for (size_t image_idx = 0; image_idx<num_modules; ++image_idx) 1865254721Semaste { 1866254721Semaste Module *module = Module::GetAllocatedModuleAtIndex(image_idx); 1867254721Semaste 1868254721Semaste if (module) 1869254721Semaste { 1870254721Semaste if (module->MatchesModuleSpec (module_spec)) 1871254721Semaste { 1872254721Semaste module_sp = module->shared_from_this(); 1873254721Semaste module_list.AppendIfNeeded(module_sp); 1874254721Semaste } 1875254721Semaste } 1876254721Semaste } 1877254721Semaste } 1878254721Semaste else 1879254721Semaste { 1880254721Semaste if (target) 1881254721Semaste { 1882254721Semaste const size_t num_matches = target->GetImages().FindModules (module_spec, module_list); 1883254721Semaste 1884254721Semaste // Not found in our module list for our target, check the main 1885254721Semaste // shared module list in case it is a extra file used somewhere 1886254721Semaste // else 1887254721Semaste if (num_matches == 0) 1888254721Semaste { 1889254721Semaste module_spec.GetArchitecture() = target->GetArchitecture(); 1890254721Semaste ModuleList::FindSharedModules (module_spec, module_list); 1891254721Semaste } 1892254721Semaste } 1893254721Semaste else 1894254721Semaste { 1895254721Semaste ModuleList::FindSharedModules (module_spec,module_list); 1896254721Semaste } 1897254721Semaste } 1898254721Semaste 1899254721Semaste return module_list.GetSize () - initial_size; 1900254721Semaste} 1901254721Semaste 1902254721Semaste#pragma mark CommandObjectTargetModulesModuleAutoComplete 1903254721Semaste 1904254721Semaste//---------------------------------------------------------------------- 1905254721Semaste// A base command object class that can auto complete with module file 1906254721Semaste// paths 1907254721Semaste//---------------------------------------------------------------------- 1908254721Semaste 1909254721Semasteclass CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed 1910254721Semaste{ 1911254721Semastepublic: 1912254721Semaste 1913254721Semaste CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter, 1914254721Semaste const char *name, 1915254721Semaste const char *help, 1916254721Semaste const char *syntax) : 1917254721Semaste CommandObjectParsed (interpreter, name, help, syntax) 1918254721Semaste { 1919254721Semaste CommandArgumentEntry arg; 1920254721Semaste CommandArgumentData file_arg; 1921254721Semaste 1922254721Semaste // Define the first (and only) variant of this arg. 1923254721Semaste file_arg.arg_type = eArgTypeFilename; 1924254721Semaste file_arg.arg_repetition = eArgRepeatStar; 1925254721Semaste 1926254721Semaste // There is only one variant this argument could be; put it into the argument entry. 1927254721Semaste arg.push_back (file_arg); 1928254721Semaste 1929254721Semaste // Push the data for the first argument into the m_arguments vector. 1930254721Semaste m_arguments.push_back (arg); 1931254721Semaste } 1932254721Semaste 1933254721Semaste virtual 1934254721Semaste ~CommandObjectTargetModulesModuleAutoComplete () 1935254721Semaste { 1936254721Semaste } 1937254721Semaste 1938254721Semaste virtual int 1939254721Semaste HandleArgumentCompletion (Args &input, 1940254721Semaste int &cursor_index, 1941254721Semaste int &cursor_char_position, 1942254721Semaste OptionElementVector &opt_element_vector, 1943254721Semaste int match_start_point, 1944254721Semaste int max_return_elements, 1945254721Semaste bool &word_complete, 1946254721Semaste StringList &matches) 1947254721Semaste { 1948254721Semaste // Arguments are the standard module completer. 1949254721Semaste std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1950254721Semaste completion_str.erase (cursor_char_position); 1951254721Semaste 1952254721Semaste CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1953254721Semaste CommandCompletions::eModuleCompletion, 1954254721Semaste completion_str.c_str(), 1955254721Semaste match_start_point, 1956254721Semaste max_return_elements, 1957254721Semaste NULL, 1958254721Semaste word_complete, 1959254721Semaste matches); 1960254721Semaste return matches.GetSize(); 1961254721Semaste } 1962254721Semaste}; 1963254721Semaste 1964254721Semaste#pragma mark CommandObjectTargetModulesSourceFileAutoComplete 1965254721Semaste 1966254721Semaste//---------------------------------------------------------------------- 1967254721Semaste// A base command object class that can auto complete with module source 1968254721Semaste// file paths 1969254721Semaste//---------------------------------------------------------------------- 1970254721Semaste 1971254721Semasteclass CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed 1972254721Semaste{ 1973254721Semastepublic: 1974254721Semaste 1975254721Semaste CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, 1976254721Semaste const char *name, 1977254721Semaste const char *help, 1978254721Semaste const char *syntax, 1979254721Semaste uint32_t flags) : 1980254721Semaste CommandObjectParsed (interpreter, name, help, syntax, flags) 1981254721Semaste { 1982254721Semaste CommandArgumentEntry arg; 1983254721Semaste CommandArgumentData source_file_arg; 1984254721Semaste 1985254721Semaste // Define the first (and only) variant of this arg. 1986254721Semaste source_file_arg.arg_type = eArgTypeSourceFile; 1987254721Semaste source_file_arg.arg_repetition = eArgRepeatPlus; 1988254721Semaste 1989254721Semaste // There is only one variant this argument could be; put it into the argument entry. 1990254721Semaste arg.push_back (source_file_arg); 1991254721Semaste 1992254721Semaste // Push the data for the first argument into the m_arguments vector. 1993254721Semaste m_arguments.push_back (arg); 1994254721Semaste } 1995254721Semaste 1996254721Semaste virtual 1997254721Semaste ~CommandObjectTargetModulesSourceFileAutoComplete () 1998254721Semaste { 1999254721Semaste } 2000254721Semaste 2001254721Semaste virtual int 2002254721Semaste HandleArgumentCompletion (Args &input, 2003254721Semaste int &cursor_index, 2004254721Semaste int &cursor_char_position, 2005254721Semaste OptionElementVector &opt_element_vector, 2006254721Semaste int match_start_point, 2007254721Semaste int max_return_elements, 2008254721Semaste bool &word_complete, 2009254721Semaste StringList &matches) 2010254721Semaste { 2011254721Semaste // Arguments are the standard source file completer. 2012254721Semaste std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2013254721Semaste completion_str.erase (cursor_char_position); 2014254721Semaste 2015254721Semaste CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2016254721Semaste CommandCompletions::eSourceFileCompletion, 2017254721Semaste completion_str.c_str(), 2018254721Semaste match_start_point, 2019254721Semaste max_return_elements, 2020254721Semaste NULL, 2021254721Semaste word_complete, 2022254721Semaste matches); 2023254721Semaste return matches.GetSize(); 2024254721Semaste } 2025254721Semaste}; 2026254721Semaste 2027254721Semaste 2028254721Semaste#pragma mark CommandObjectTargetModulesDumpSymtab 2029254721Semaste 2030254721Semaste 2031254721Semasteclass CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete 2032254721Semaste{ 2033254721Semastepublic: 2034254721Semaste CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) : 2035254721Semaste CommandObjectTargetModulesModuleAutoComplete (interpreter, 2036254721Semaste "target modules dump symtab", 2037254721Semaste "Dump the symbol table from one or more target modules.", 2038254721Semaste NULL), 2039254721Semaste m_options (interpreter) 2040254721Semaste { 2041254721Semaste } 2042254721Semaste 2043254721Semaste virtual 2044254721Semaste ~CommandObjectTargetModulesDumpSymtab () 2045254721Semaste { 2046254721Semaste } 2047254721Semaste 2048254721Semaste virtual Options * 2049254721Semaste GetOptions () 2050254721Semaste { 2051254721Semaste return &m_options; 2052254721Semaste } 2053254721Semaste 2054254721Semaste class CommandOptions : public Options 2055254721Semaste { 2056254721Semaste public: 2057254721Semaste 2058254721Semaste CommandOptions (CommandInterpreter &interpreter) : 2059254721Semaste Options(interpreter), 2060254721Semaste m_sort_order (eSortOrderNone) 2061254721Semaste { 2062254721Semaste } 2063254721Semaste 2064254721Semaste virtual 2065254721Semaste ~CommandOptions () 2066254721Semaste { 2067254721Semaste } 2068254721Semaste 2069254721Semaste virtual Error 2070254721Semaste SetOptionValue (uint32_t option_idx, const char *option_arg) 2071254721Semaste { 2072254721Semaste Error error; 2073254721Semaste const int short_option = m_getopt_table[option_idx].val; 2074254721Semaste 2075254721Semaste switch (short_option) 2076254721Semaste { 2077254721Semaste case 's': 2078254721Semaste m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg, 2079254721Semaste g_option_table[option_idx].enum_values, 2080254721Semaste eSortOrderNone, 2081254721Semaste error); 2082254721Semaste break; 2083254721Semaste 2084254721Semaste default: 2085254721Semaste error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 2086254721Semaste break; 2087254721Semaste 2088254721Semaste } 2089254721Semaste return error; 2090254721Semaste } 2091254721Semaste 2092254721Semaste void 2093254721Semaste OptionParsingStarting () 2094254721Semaste { 2095254721Semaste m_sort_order = eSortOrderNone; 2096254721Semaste } 2097254721Semaste 2098254721Semaste const OptionDefinition* 2099254721Semaste GetDefinitions () 2100254721Semaste { 2101254721Semaste return g_option_table; 2102254721Semaste } 2103254721Semaste 2104254721Semaste // Options table: Required for subclasses of Options. 2105254721Semaste static OptionDefinition g_option_table[]; 2106254721Semaste 2107254721Semaste SortOrder m_sort_order; 2108254721Semaste }; 2109254721Semaste 2110254721Semasteprotected: 2111254721Semaste virtual bool 2112254721Semaste DoExecute (Args& command, 2113254721Semaste CommandReturnObject &result) 2114254721Semaste { 2115254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2116254721Semaste if (target == NULL) 2117254721Semaste { 2118254721Semaste result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2119254721Semaste result.SetStatus (eReturnStatusFailed); 2120254721Semaste return false; 2121254721Semaste } 2122254721Semaste else 2123254721Semaste { 2124254721Semaste uint32_t num_dumped = 0; 2125254721Semaste 2126254721Semaste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2127254721Semaste result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2128254721Semaste result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2129254721Semaste 2130254721Semaste if (command.GetArgumentCount() == 0) 2131254721Semaste { 2132254721Semaste // Dump all sections for all modules images 2133254721Semaste Mutex::Locker modules_locker(target->GetImages().GetMutex()); 2134254721Semaste const size_t num_modules = target->GetImages().GetSize(); 2135254721Semaste if (num_modules > 0) 2136254721Semaste { 2137254721Semaste result.GetOutputStream().Printf("Dumping symbol table for %zu modules.\n", num_modules); 2138254721Semaste for (size_t image_idx = 0; image_idx<num_modules; ++image_idx) 2139254721Semaste { 2140254721Semaste if (num_dumped > 0) 2141254721Semaste { 2142254721Semaste result.GetOutputStream().EOL(); 2143254721Semaste result.GetOutputStream().EOL(); 2144254721Semaste } 2145254721Semaste num_dumped++; 2146254721Semaste DumpModuleSymtab (m_interpreter, 2147254721Semaste result.GetOutputStream(), 2148254721Semaste target->GetImages().GetModulePointerAtIndexUnlocked(image_idx), 2149254721Semaste m_options.m_sort_order); 2150254721Semaste } 2151254721Semaste } 2152254721Semaste else 2153254721Semaste { 2154254721Semaste result.AppendError ("the target has no associated executable images"); 2155254721Semaste result.SetStatus (eReturnStatusFailed); 2156254721Semaste return false; 2157254721Semaste } 2158254721Semaste } 2159254721Semaste else 2160254721Semaste { 2161254721Semaste // Dump specified images (by basename or fullpath) 2162254721Semaste const char *arg_cstr; 2163254721Semaste for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2164254721Semaste { 2165254721Semaste ModuleList module_list; 2166254721Semaste const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2167254721Semaste if (num_matches > 0) 2168254721Semaste { 2169254721Semaste for (size_t i=0; i<num_matches; ++i) 2170254721Semaste { 2171254721Semaste Module *module = module_list.GetModulePointerAtIndex(i); 2172254721Semaste if (module) 2173254721Semaste { 2174254721Semaste if (num_dumped > 0) 2175254721Semaste { 2176254721Semaste result.GetOutputStream().EOL(); 2177254721Semaste result.GetOutputStream().EOL(); 2178254721Semaste } 2179254721Semaste num_dumped++; 2180254721Semaste DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order); 2181254721Semaste } 2182254721Semaste } 2183254721Semaste } 2184254721Semaste else 2185254721Semaste result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2186254721Semaste } 2187254721Semaste } 2188254721Semaste 2189254721Semaste if (num_dumped > 0) 2190254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 2191254721Semaste else 2192254721Semaste { 2193254721Semaste result.AppendError ("no matching executable images found"); 2194254721Semaste result.SetStatus (eReturnStatusFailed); 2195254721Semaste } 2196254721Semaste } 2197254721Semaste return result.Succeeded(); 2198254721Semaste } 2199254721Semaste 2200254721Semaste 2201254721Semaste CommandOptions m_options; 2202254721Semaste}; 2203254721Semaste 2204254721Semastestatic OptionEnumValueElement 2205254721Semasteg_sort_option_enumeration[4] = 2206254721Semaste{ 2207254721Semaste { eSortOrderNone, "none", "No sorting, use the original symbol table order."}, 2208254721Semaste { eSortOrderByAddress, "address", "Sort output by symbol address."}, 2209254721Semaste { eSortOrderByName, "name", "Sort output by symbol name."}, 2210254721Semaste { 0, NULL, NULL } 2211254721Semaste}; 2212254721Semaste 2213254721Semaste 2214254721SemasteOptionDefinition 2215254721SemasteCommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] = 2216254721Semaste{ 2217254721Semaste { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."}, 2218254721Semaste { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2219254721Semaste}; 2220254721Semaste 2221254721Semaste#pragma mark CommandObjectTargetModulesDumpSections 2222254721Semaste 2223254721Semaste//---------------------------------------------------------------------- 2224254721Semaste// Image section dumping command 2225254721Semaste//---------------------------------------------------------------------- 2226254721Semaste 2227254721Semasteclass CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete 2228254721Semaste{ 2229254721Semastepublic: 2230254721Semaste CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) : 2231254721Semaste CommandObjectTargetModulesModuleAutoComplete (interpreter, 2232254721Semaste "target modules dump sections", 2233254721Semaste "Dump the sections from one or more target modules.", 2234254721Semaste //"target modules dump sections [<file1> ...]") 2235254721Semaste NULL) 2236254721Semaste { 2237254721Semaste } 2238254721Semaste 2239254721Semaste virtual 2240254721Semaste ~CommandObjectTargetModulesDumpSections () 2241254721Semaste { 2242254721Semaste } 2243254721Semaste 2244254721Semasteprotected: 2245254721Semaste virtual bool 2246254721Semaste DoExecute (Args& command, 2247254721Semaste CommandReturnObject &result) 2248254721Semaste { 2249254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2250254721Semaste if (target == NULL) 2251254721Semaste { 2252254721Semaste result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2253254721Semaste result.SetStatus (eReturnStatusFailed); 2254254721Semaste return false; 2255254721Semaste } 2256254721Semaste else 2257254721Semaste { 2258254721Semaste uint32_t num_dumped = 0; 2259254721Semaste 2260254721Semaste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2261254721Semaste result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2262254721Semaste result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2263254721Semaste 2264254721Semaste if (command.GetArgumentCount() == 0) 2265254721Semaste { 2266254721Semaste // Dump all sections for all modules images 2267254721Semaste const size_t num_modules = target->GetImages().GetSize(); 2268254721Semaste if (num_modules > 0) 2269254721Semaste { 2270254721Semaste result.GetOutputStream().Printf("Dumping sections for %zu modules.\n", num_modules); 2271254721Semaste for (size_t image_idx = 0; image_idx<num_modules; ++image_idx) 2272254721Semaste { 2273254721Semaste num_dumped++; 2274254721Semaste DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)); 2275254721Semaste } 2276254721Semaste } 2277254721Semaste else 2278254721Semaste { 2279254721Semaste result.AppendError ("the target has no associated executable images"); 2280254721Semaste result.SetStatus (eReturnStatusFailed); 2281254721Semaste return false; 2282254721Semaste } 2283254721Semaste } 2284254721Semaste else 2285254721Semaste { 2286254721Semaste // Dump specified images (by basename or fullpath) 2287254721Semaste const char *arg_cstr; 2288254721Semaste for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2289254721Semaste { 2290254721Semaste ModuleList module_list; 2291254721Semaste const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2292254721Semaste if (num_matches > 0) 2293254721Semaste { 2294254721Semaste for (size_t i=0; i<num_matches; ++i) 2295254721Semaste { 2296254721Semaste Module *module = module_list.GetModulePointerAtIndex(i); 2297254721Semaste if (module) 2298254721Semaste { 2299254721Semaste num_dumped++; 2300254721Semaste DumpModuleSections (m_interpreter, result.GetOutputStream(), module); 2301254721Semaste } 2302254721Semaste } 2303254721Semaste } 2304254721Semaste else 2305254721Semaste { 2306254721Semaste // Check the global list 2307254721Semaste Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 2308254721Semaste 2309254721Semaste result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2310254721Semaste } 2311254721Semaste } 2312254721Semaste } 2313254721Semaste 2314254721Semaste if (num_dumped > 0) 2315254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 2316254721Semaste else 2317254721Semaste { 2318254721Semaste result.AppendError ("no matching executable images found"); 2319254721Semaste result.SetStatus (eReturnStatusFailed); 2320254721Semaste } 2321254721Semaste } 2322254721Semaste return result.Succeeded(); 2323254721Semaste } 2324254721Semaste}; 2325254721Semaste 2326254721Semaste 2327254721Semaste#pragma mark CommandObjectTargetModulesDumpSymfile 2328254721Semaste 2329254721Semaste//---------------------------------------------------------------------- 2330254721Semaste// Image debug symbol dumping command 2331254721Semaste//---------------------------------------------------------------------- 2332254721Semaste 2333254721Semasteclass CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete 2334254721Semaste{ 2335254721Semastepublic: 2336254721Semaste CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) : 2337254721Semaste CommandObjectTargetModulesModuleAutoComplete (interpreter, 2338254721Semaste "target modules dump symfile", 2339254721Semaste "Dump the debug symbol file for one or more target modules.", 2340254721Semaste //"target modules dump symfile [<file1> ...]") 2341254721Semaste NULL) 2342254721Semaste { 2343254721Semaste } 2344254721Semaste 2345254721Semaste virtual 2346254721Semaste ~CommandObjectTargetModulesDumpSymfile () 2347254721Semaste { 2348254721Semaste } 2349254721Semaste 2350254721Semasteprotected: 2351254721Semaste virtual bool 2352254721Semaste DoExecute (Args& command, 2353254721Semaste CommandReturnObject &result) 2354254721Semaste { 2355254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2356254721Semaste if (target == NULL) 2357254721Semaste { 2358254721Semaste result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2359254721Semaste result.SetStatus (eReturnStatusFailed); 2360254721Semaste return false; 2361254721Semaste } 2362254721Semaste else 2363254721Semaste { 2364254721Semaste uint32_t num_dumped = 0; 2365254721Semaste 2366254721Semaste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2367254721Semaste result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2368254721Semaste result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2369254721Semaste 2370254721Semaste if (command.GetArgumentCount() == 0) 2371254721Semaste { 2372254721Semaste // Dump all sections for all modules images 2373254721Semaste const ModuleList &target_modules = target->GetImages(); 2374254721Semaste Mutex::Locker modules_locker (target_modules.GetMutex()); 2375254721Semaste const size_t num_modules = target_modules.GetSize(); 2376254721Semaste if (num_modules > 0) 2377254721Semaste { 2378254721Semaste result.GetOutputStream().Printf("Dumping debug symbols for %zu modules.\n", num_modules); 2379254721Semaste for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2380254721Semaste { 2381254721Semaste if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx))) 2382254721Semaste num_dumped++; 2383254721Semaste } 2384254721Semaste } 2385254721Semaste else 2386254721Semaste { 2387254721Semaste result.AppendError ("the target has no associated executable images"); 2388254721Semaste result.SetStatus (eReturnStatusFailed); 2389254721Semaste return false; 2390254721Semaste } 2391254721Semaste } 2392254721Semaste else 2393254721Semaste { 2394254721Semaste // Dump specified images (by basename or fullpath) 2395254721Semaste const char *arg_cstr; 2396254721Semaste for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2397254721Semaste { 2398254721Semaste ModuleList module_list; 2399254721Semaste const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2400254721Semaste if (num_matches > 0) 2401254721Semaste { 2402254721Semaste for (size_t i=0; i<num_matches; ++i) 2403254721Semaste { 2404254721Semaste Module *module = module_list.GetModulePointerAtIndex(i); 2405254721Semaste if (module) 2406254721Semaste { 2407254721Semaste if (DumpModuleSymbolVendor (result.GetOutputStream(), module)) 2408254721Semaste num_dumped++; 2409254721Semaste } 2410254721Semaste } 2411254721Semaste } 2412254721Semaste else 2413254721Semaste result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2414254721Semaste } 2415254721Semaste } 2416254721Semaste 2417254721Semaste if (num_dumped > 0) 2418254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 2419254721Semaste else 2420254721Semaste { 2421254721Semaste result.AppendError ("no matching executable images found"); 2422254721Semaste result.SetStatus (eReturnStatusFailed); 2423254721Semaste } 2424254721Semaste } 2425254721Semaste return result.Succeeded(); 2426254721Semaste } 2427254721Semaste}; 2428254721Semaste 2429254721Semaste 2430254721Semaste#pragma mark CommandObjectTargetModulesDumpLineTable 2431254721Semaste 2432254721Semaste//---------------------------------------------------------------------- 2433254721Semaste// Image debug line table dumping command 2434254721Semaste//---------------------------------------------------------------------- 2435254721Semaste 2436254721Semasteclass CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete 2437254721Semaste{ 2438254721Semastepublic: 2439254721Semaste CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) : 2440254721Semaste CommandObjectTargetModulesSourceFileAutoComplete (interpreter, 2441254721Semaste "target modules dump line-table", 2442254721Semaste "Dump the line table for one or more compilation units.", 2443254721Semaste NULL, 2444254721Semaste eFlagRequiresTarget) 2445254721Semaste { 2446254721Semaste } 2447254721Semaste 2448254721Semaste virtual 2449254721Semaste ~CommandObjectTargetModulesDumpLineTable () 2450254721Semaste { 2451254721Semaste } 2452254721Semaste 2453254721Semasteprotected: 2454254721Semaste virtual bool 2455254721Semaste DoExecute (Args& command, 2456254721Semaste CommandReturnObject &result) 2457254721Semaste { 2458254721Semaste Target *target = m_exe_ctx.GetTargetPtr(); 2459254721Semaste uint32_t total_num_dumped = 0; 2460254721Semaste 2461254721Semaste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2462254721Semaste result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2463254721Semaste result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2464254721Semaste 2465254721Semaste if (command.GetArgumentCount() == 0) 2466254721Semaste { 2467254721Semaste result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); 2468254721Semaste result.SetStatus (eReturnStatusFailed); 2469254721Semaste } 2470254721Semaste else 2471254721Semaste { 2472254721Semaste // Dump specified images (by basename or fullpath) 2473254721Semaste const char *arg_cstr; 2474254721Semaste for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2475254721Semaste { 2476254721Semaste FileSpec file_spec(arg_cstr, false); 2477254721Semaste 2478254721Semaste const ModuleList &target_modules = target->GetImages(); 2479254721Semaste Mutex::Locker modules_locker(target_modules.GetMutex()); 2480254721Semaste const size_t num_modules = target_modules.GetSize(); 2481254721Semaste if (num_modules > 0) 2482254721Semaste { 2483254721Semaste uint32_t num_dumped = 0; 2484254721Semaste for (uint32_t i = 0; i<num_modules; ++i) 2485254721Semaste { 2486254721Semaste if (DumpCompileUnitLineTable (m_interpreter, 2487254721Semaste result.GetOutputStream(), 2488254721Semaste target_modules.GetModulePointerAtIndexUnlocked(i), 2489254721Semaste file_spec, 2490254721Semaste m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive())) 2491254721Semaste num_dumped++; 2492254721Semaste } 2493254721Semaste if (num_dumped == 0) 2494254721Semaste result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); 2495254721Semaste else 2496254721Semaste total_num_dumped += num_dumped; 2497254721Semaste } 2498254721Semaste } 2499254721Semaste } 2500254721Semaste 2501254721Semaste if (total_num_dumped > 0) 2502254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 2503254721Semaste else 2504254721Semaste { 2505254721Semaste result.AppendError ("no source filenames matched any command arguments"); 2506254721Semaste result.SetStatus (eReturnStatusFailed); 2507254721Semaste } 2508254721Semaste return result.Succeeded(); 2509254721Semaste } 2510254721Semaste}; 2511254721Semaste 2512254721Semaste 2513254721Semaste#pragma mark CommandObjectTargetModulesDump 2514254721Semaste 2515254721Semaste//---------------------------------------------------------------------- 2516254721Semaste// Dump multi-word command for target modules 2517254721Semaste//---------------------------------------------------------------------- 2518254721Semaste 2519254721Semasteclass CommandObjectTargetModulesDump : public CommandObjectMultiword 2520254721Semaste{ 2521254721Semastepublic: 2522254721Semaste 2523254721Semaste //------------------------------------------------------------------ 2524254721Semaste // Constructors and Destructors 2525254721Semaste //------------------------------------------------------------------ 2526254721Semaste CommandObjectTargetModulesDump(CommandInterpreter &interpreter) : 2527254721Semaste CommandObjectMultiword (interpreter, 2528254721Semaste "target modules dump", 2529254721Semaste "A set of commands for dumping information about one or more target modules.", 2530254721Semaste "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]") 2531254721Semaste { 2532254721Semaste LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter))); 2533254721Semaste LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter))); 2534254721Semaste LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter))); 2535254721Semaste LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter))); 2536254721Semaste } 2537254721Semaste 2538254721Semaste virtual 2539254721Semaste ~CommandObjectTargetModulesDump() 2540254721Semaste { 2541254721Semaste } 2542254721Semaste}; 2543254721Semaste 2544254721Semasteclass CommandObjectTargetModulesAdd : public CommandObjectParsed 2545254721Semaste{ 2546254721Semastepublic: 2547254721Semaste CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) : 2548254721Semaste CommandObjectParsed (interpreter, 2549254721Semaste "target modules add", 2550254721Semaste "Add a new module to the current target's modules.", 2551254721Semaste "target modules add [<module>]"), 2552254721Semaste m_option_group (interpreter), 2553254721Semaste m_symbol_file (LLDB_OPT_SET_1, false, "symfile", 's', 0, eArgTypeFilename, "Fullpath to a stand alone debug symbols file for when debug symbols are not in the executable.") 2554254721Semaste { 2555254721Semaste m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2556254721Semaste m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2557254721Semaste m_option_group.Finalize(); 2558254721Semaste } 2559254721Semaste 2560254721Semaste virtual 2561254721Semaste ~CommandObjectTargetModulesAdd () 2562254721Semaste { 2563254721Semaste } 2564254721Semaste 2565254721Semaste virtual Options * 2566254721Semaste GetOptions () 2567254721Semaste { 2568254721Semaste return &m_option_group; 2569254721Semaste } 2570254721Semaste 2571254721Semaste virtual int 2572254721Semaste HandleArgumentCompletion (Args &input, 2573254721Semaste int &cursor_index, 2574254721Semaste int &cursor_char_position, 2575254721Semaste OptionElementVector &opt_element_vector, 2576254721Semaste int match_start_point, 2577254721Semaste int max_return_elements, 2578254721Semaste bool &word_complete, 2579254721Semaste StringList &matches) 2580254721Semaste { 2581254721Semaste std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2582254721Semaste completion_str.erase (cursor_char_position); 2583254721Semaste 2584254721Semaste CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2585254721Semaste CommandCompletions::eDiskFileCompletion, 2586254721Semaste completion_str.c_str(), 2587254721Semaste match_start_point, 2588254721Semaste max_return_elements, 2589254721Semaste NULL, 2590254721Semaste word_complete, 2591254721Semaste matches); 2592254721Semaste return matches.GetSize(); 2593254721Semaste } 2594254721Semaste 2595254721Semasteprotected: 2596254721Semaste 2597254721Semaste OptionGroupOptions m_option_group; 2598254721Semaste OptionGroupUUID m_uuid_option_group; 2599254721Semaste OptionGroupFile m_symbol_file; 2600254721Semaste 2601254721Semaste 2602254721Semaste virtual bool 2603254721Semaste DoExecute (Args& args, 2604254721Semaste CommandReturnObject &result) 2605254721Semaste { 2606254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2607254721Semaste if (target == NULL) 2608254721Semaste { 2609254721Semaste result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2610254721Semaste result.SetStatus (eReturnStatusFailed); 2611254721Semaste return false; 2612254721Semaste } 2613254721Semaste else 2614254721Semaste { 2615254721Semaste bool flush = false; 2616254721Semaste 2617254721Semaste const size_t argc = args.GetArgumentCount(); 2618254721Semaste if (argc == 0) 2619254721Semaste { 2620254721Semaste if (m_uuid_option_group.GetOptionValue ().OptionWasSet()) 2621254721Semaste { 2622254721Semaste // We are given a UUID only, go locate the file 2623254721Semaste ModuleSpec module_spec; 2624254721Semaste module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue(); 2625254721Semaste if (m_symbol_file.GetOptionValue().OptionWasSet()) 2626254721Semaste module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue(); 2627254721Semaste if (Symbols::DownloadObjectAndSymbolFile (module_spec)) 2628254721Semaste { 2629254721Semaste ModuleSP module_sp (target->GetSharedModule (module_spec)); 2630254721Semaste if (module_sp) 2631254721Semaste { 2632254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 2633254721Semaste return true; 2634254721Semaste } 2635254721Semaste else 2636254721Semaste { 2637254721Semaste flush = true; 2638254721Semaste 2639254721Semaste StreamString strm; 2640254721Semaste module_spec.GetUUID().Dump (&strm); 2641254721Semaste if (module_spec.GetFileSpec()) 2642254721Semaste { 2643254721Semaste if (module_spec.GetSymbolFileSpec()) 2644254721Semaste { 2645254721Semaste result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s and symbol file %s", 2646254721Semaste strm.GetString().c_str(), 2647254721Semaste module_spec.GetFileSpec().GetPath().c_str(), 2648254721Semaste module_spec.GetSymbolFileSpec().GetPath().c_str()); 2649254721Semaste } 2650254721Semaste else 2651254721Semaste { 2652254721Semaste result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s", 2653254721Semaste strm.GetString().c_str(), 2654254721Semaste module_spec.GetFileSpec().GetPath().c_str()); 2655254721Semaste } 2656254721Semaste } 2657254721Semaste else 2658254721Semaste { 2659254721Semaste result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s", 2660254721Semaste strm.GetString().c_str()); 2661254721Semaste } 2662254721Semaste result.SetStatus (eReturnStatusFailed); 2663254721Semaste return false; 2664254721Semaste } 2665254721Semaste } 2666254721Semaste else 2667254721Semaste { 2668254721Semaste StreamString strm; 2669254721Semaste module_spec.GetUUID().Dump (&strm); 2670254721Semaste result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str()); 2671254721Semaste result.SetStatus (eReturnStatusFailed); 2672254721Semaste return false; 2673254721Semaste } 2674254721Semaste } 2675254721Semaste else 2676254721Semaste { 2677254721Semaste result.AppendError ("one or more executable image paths must be specified"); 2678254721Semaste result.SetStatus (eReturnStatusFailed); 2679254721Semaste return false; 2680254721Semaste } 2681254721Semaste } 2682254721Semaste else 2683254721Semaste { 2684254721Semaste for (size_t i=0; i<argc; ++i) 2685254721Semaste { 2686254721Semaste const char *path = args.GetArgumentAtIndex(i); 2687254721Semaste if (path) 2688254721Semaste { 2689254721Semaste FileSpec file_spec(path, true); 2690254721Semaste if (file_spec.Exists()) 2691254721Semaste { 2692254721Semaste ModuleSpec module_spec (file_spec); 2693254721Semaste if (m_uuid_option_group.GetOptionValue ().OptionWasSet()) 2694254721Semaste module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue(); 2695254721Semaste if (m_symbol_file.GetOptionValue().OptionWasSet()) 2696254721Semaste module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue(); 2697254721Semaste Error error; 2698254721Semaste ModuleSP module_sp (target->GetSharedModule (module_spec, &error)); 2699254721Semaste if (!module_sp) 2700254721Semaste { 2701254721Semaste const char *error_cstr = error.AsCString(); 2702254721Semaste if (error_cstr) 2703254721Semaste result.AppendError (error_cstr); 2704254721Semaste else 2705254721Semaste result.AppendErrorWithFormat ("unsupported module: %s", path); 2706254721Semaste result.SetStatus (eReturnStatusFailed); 2707254721Semaste return false; 2708254721Semaste } 2709254721Semaste else 2710254721Semaste { 2711254721Semaste flush = true; 2712254721Semaste } 2713254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 2714254721Semaste } 2715254721Semaste else 2716254721Semaste { 2717254721Semaste char resolved_path[PATH_MAX]; 2718254721Semaste result.SetStatus (eReturnStatusFailed); 2719254721Semaste if (file_spec.GetPath (resolved_path, sizeof(resolved_path))) 2720254721Semaste { 2721254721Semaste if (strcmp (resolved_path, path) != 0) 2722254721Semaste { 2723254721Semaste result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path); 2724254721Semaste break; 2725254721Semaste } 2726254721Semaste } 2727254721Semaste result.AppendErrorWithFormat ("invalid module path '%s'\n", path); 2728254721Semaste break; 2729254721Semaste } 2730254721Semaste } 2731254721Semaste } 2732254721Semaste } 2733254721Semaste 2734254721Semaste if (flush) 2735254721Semaste { 2736254721Semaste ProcessSP process = target->GetProcessSP(); 2737254721Semaste if (process) 2738254721Semaste process->Flush(); 2739254721Semaste } 2740254721Semaste } 2741254721Semaste 2742254721Semaste return result.Succeeded(); 2743254721Semaste } 2744254721Semaste 2745254721Semaste}; 2746254721Semaste 2747254721Semasteclass CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete 2748254721Semaste{ 2749254721Semastepublic: 2750254721Semaste CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) : 2751254721Semaste CommandObjectTargetModulesModuleAutoComplete (interpreter, 2752254721Semaste "target modules load", 2753254721Semaste "Set the load addresses for one or more sections in a target module.", 2754254721Semaste "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"), 2755254721Semaste m_option_group (interpreter), 2756254721Semaste m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeFilename, "Fullpath or basename for module to load."), 2757254721Semaste 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) 2758254721Semaste { 2759254721Semaste m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2760254721Semaste m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2761254721Semaste m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2762254721Semaste m_option_group.Finalize(); 2763254721Semaste } 2764254721Semaste 2765254721Semaste virtual 2766254721Semaste ~CommandObjectTargetModulesLoad () 2767254721Semaste { 2768254721Semaste } 2769254721Semaste 2770254721Semaste virtual Options * 2771254721Semaste GetOptions () 2772254721Semaste { 2773254721Semaste return &m_option_group; 2774254721Semaste } 2775254721Semaste 2776254721Semasteprotected: 2777254721Semaste virtual bool 2778254721Semaste DoExecute (Args& args, 2779254721Semaste CommandReturnObject &result) 2780254721Semaste { 2781254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2782254721Semaste if (target == NULL) 2783254721Semaste { 2784254721Semaste result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2785254721Semaste result.SetStatus (eReturnStatusFailed); 2786254721Semaste return false; 2787254721Semaste } 2788254721Semaste else 2789254721Semaste { 2790254721Semaste const size_t argc = args.GetArgumentCount(); 2791254721Semaste ModuleSpec module_spec; 2792254721Semaste bool search_using_module_spec = false; 2793254721Semaste if (m_file_option.GetOptionValue().OptionWasSet()) 2794254721Semaste { 2795254721Semaste search_using_module_spec = true; 2796254721Semaste module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 2797254721Semaste } 2798254721Semaste 2799254721Semaste if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2800254721Semaste { 2801254721Semaste search_using_module_spec = true; 2802254721Semaste module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2803254721Semaste } 2804254721Semaste 2805254721Semaste if (search_using_module_spec) 2806254721Semaste { 2807254721Semaste 2808254721Semaste ModuleList matching_modules; 2809254721Semaste const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules); 2810254721Semaste 2811254721Semaste char path[PATH_MAX]; 2812254721Semaste if (num_matches == 1) 2813254721Semaste { 2814254721Semaste Module *module = matching_modules.GetModulePointerAtIndex(0); 2815254721Semaste if (module) 2816254721Semaste { 2817254721Semaste ObjectFile *objfile = module->GetObjectFile(); 2818254721Semaste if (objfile) 2819254721Semaste { 2820254721Semaste SectionList *section_list = module->GetSectionList(); 2821254721Semaste if (section_list) 2822254721Semaste { 2823254721Semaste bool changed = false; 2824254721Semaste if (argc == 0) 2825254721Semaste { 2826254721Semaste if (m_slide_option.GetOptionValue().OptionWasSet()) 2827254721Semaste { 2828254721Semaste const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue(); 2829254721Semaste module->SetLoadAddress (*target, slide, changed); 2830254721Semaste } 2831254721Semaste else 2832254721Semaste { 2833254721Semaste result.AppendError ("one or more section name + load address pair must be specified"); 2834254721Semaste result.SetStatus (eReturnStatusFailed); 2835254721Semaste return false; 2836254721Semaste } 2837254721Semaste } 2838254721Semaste else 2839254721Semaste { 2840254721Semaste if (m_slide_option.GetOptionValue().OptionWasSet()) 2841254721Semaste { 2842254721Semaste result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n"); 2843254721Semaste result.SetStatus (eReturnStatusFailed); 2844254721Semaste return false; 2845254721Semaste } 2846254721Semaste 2847254721Semaste for (size_t i=0; i<argc; i += 2) 2848254721Semaste { 2849254721Semaste const char *sect_name = args.GetArgumentAtIndex(i); 2850254721Semaste const char *load_addr_cstr = args.GetArgumentAtIndex(i+1); 2851254721Semaste if (sect_name && load_addr_cstr) 2852254721Semaste { 2853254721Semaste ConstString const_sect_name(sect_name); 2854254721Semaste bool success = false; 2855254721Semaste addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); 2856254721Semaste if (success) 2857254721Semaste { 2858254721Semaste SectionSP section_sp (section_list->FindSectionByName(const_sect_name)); 2859254721Semaste if (section_sp) 2860254721Semaste { 2861254721Semaste if (section_sp->IsThreadSpecific()) 2862254721Semaste { 2863254721Semaste result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name); 2864254721Semaste result.SetStatus (eReturnStatusFailed); 2865254721Semaste break; 2866254721Semaste } 2867254721Semaste else 2868254721Semaste { 2869254721Semaste if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr)) 2870254721Semaste changed = true; 2871254721Semaste result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr); 2872254721Semaste } 2873254721Semaste } 2874254721Semaste else 2875254721Semaste { 2876254721Semaste result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name); 2877254721Semaste result.SetStatus (eReturnStatusFailed); 2878254721Semaste break; 2879254721Semaste } 2880254721Semaste } 2881254721Semaste else 2882254721Semaste { 2883254721Semaste result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr); 2884254721Semaste result.SetStatus (eReturnStatusFailed); 2885254721Semaste break; 2886254721Semaste } 2887254721Semaste } 2888254721Semaste else 2889254721Semaste { 2890254721Semaste if (sect_name) 2891254721Semaste result.AppendError ("section names must be followed by a load address.\n"); 2892254721Semaste else 2893254721Semaste result.AppendError ("one or more section name + load address pair must be specified.\n"); 2894254721Semaste result.SetStatus (eReturnStatusFailed); 2895254721Semaste break; 2896254721Semaste } 2897254721Semaste } 2898254721Semaste } 2899254721Semaste 2900254721Semaste if (changed) 2901254721Semaste { 2902254721Semaste target->ModulesDidLoad (matching_modules); 2903254721Semaste Process *process = m_exe_ctx.GetProcessPtr(); 2904254721Semaste if (process) 2905254721Semaste process->Flush(); 2906254721Semaste } 2907254721Semaste } 2908254721Semaste else 2909254721Semaste { 2910254721Semaste module->GetFileSpec().GetPath (path, sizeof(path)); 2911254721Semaste result.AppendErrorWithFormat ("no sections in object file '%s'\n", path); 2912254721Semaste result.SetStatus (eReturnStatusFailed); 2913254721Semaste } 2914254721Semaste } 2915254721Semaste else 2916254721Semaste { 2917254721Semaste module->GetFileSpec().GetPath (path, sizeof(path)); 2918254721Semaste result.AppendErrorWithFormat ("no object file for module '%s'\n", path); 2919254721Semaste result.SetStatus (eReturnStatusFailed); 2920254721Semaste } 2921254721Semaste } 2922254721Semaste else 2923254721Semaste { 2924254721Semaste FileSpec *module_spec_file = module_spec.GetFileSpecPtr(); 2925254721Semaste if (module_spec_file) 2926254721Semaste { 2927254721Semaste module_spec_file->GetPath (path, sizeof(path)); 2928254721Semaste result.AppendErrorWithFormat ("invalid module '%s'.\n", path); 2929254721Semaste } 2930254721Semaste else 2931254721Semaste result.AppendError ("no module spec"); 2932254721Semaste result.SetStatus (eReturnStatusFailed); 2933254721Semaste } 2934254721Semaste } 2935254721Semaste else 2936254721Semaste { 2937254721Semaste std::string uuid_str; 2938254721Semaste 2939254721Semaste if (module_spec.GetFileSpec()) 2940254721Semaste module_spec.GetFileSpec().GetPath (path, sizeof(path)); 2941254721Semaste else 2942254721Semaste path[0] = '\0'; 2943254721Semaste 2944254721Semaste if (module_spec.GetUUIDPtr()) 2945254721Semaste uuid_str = module_spec.GetUUID().GetAsString(); 2946254721Semaste if (num_matches > 1) 2947254721Semaste { 2948254721Semaste result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", 2949254721Semaste path[0] ? " file=" : "", 2950254721Semaste path, 2951254721Semaste !uuid_str.empty() ? " uuid=" : "", 2952254721Semaste uuid_str.c_str()); 2953254721Semaste for (size_t i=0; i<num_matches; ++i) 2954254721Semaste { 2955254721Semaste if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path))) 2956254721Semaste result.AppendMessageWithFormat("%s\n", path); 2957254721Semaste } 2958254721Semaste } 2959254721Semaste else 2960254721Semaste { 2961254721Semaste result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n", 2962254721Semaste path[0] ? " file=" : "", 2963254721Semaste path, 2964254721Semaste !uuid_str.empty() ? " uuid=" : "", 2965254721Semaste uuid_str.c_str()); 2966254721Semaste } 2967254721Semaste result.SetStatus (eReturnStatusFailed); 2968254721Semaste } 2969254721Semaste } 2970254721Semaste else 2971254721Semaste { 2972254721Semaste result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n"); 2973254721Semaste result.SetStatus (eReturnStatusFailed); 2974254721Semaste return false; 2975254721Semaste } 2976254721Semaste } 2977254721Semaste return result.Succeeded(); 2978254721Semaste } 2979254721Semaste 2980254721Semaste OptionGroupOptions m_option_group; 2981254721Semaste OptionGroupUUID m_uuid_option_group; 2982254721Semaste OptionGroupFile m_file_option; 2983254721Semaste OptionGroupUInt64 m_slide_option; 2984254721Semaste}; 2985254721Semaste 2986254721Semaste//---------------------------------------------------------------------- 2987254721Semaste// List images with associated information 2988254721Semaste//---------------------------------------------------------------------- 2989254721Semasteclass CommandObjectTargetModulesList : public CommandObjectParsed 2990254721Semaste{ 2991254721Semastepublic: 2992254721Semaste 2993254721Semaste class CommandOptions : public Options 2994254721Semaste { 2995254721Semaste public: 2996254721Semaste 2997254721Semaste CommandOptions (CommandInterpreter &interpreter) : 2998254721Semaste Options(interpreter), 2999254721Semaste m_format_array(), 3000254721Semaste m_use_global_module_list (false), 3001254721Semaste m_module_addr (LLDB_INVALID_ADDRESS) 3002254721Semaste { 3003254721Semaste } 3004254721Semaste 3005254721Semaste virtual 3006254721Semaste ~CommandOptions () 3007254721Semaste { 3008254721Semaste } 3009254721Semaste 3010254721Semaste virtual Error 3011254721Semaste SetOptionValue (uint32_t option_idx, const char *option_arg) 3012254721Semaste { 3013254721Semaste Error error; 3014254721Semaste 3015254721Semaste const int short_option = m_getopt_table[option_idx].val; 3016254721Semaste if (short_option == 'g') 3017254721Semaste { 3018254721Semaste m_use_global_module_list = true; 3019254721Semaste } 3020254721Semaste else if (short_option == 'a') 3021254721Semaste { 3022254721Semaste ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3023254721Semaste m_module_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3024254721Semaste } 3025254721Semaste else 3026254721Semaste { 3027254721Semaste unsigned long width = 0; 3028254721Semaste if (option_arg) 3029254721Semaste width = strtoul (option_arg, NULL, 0); 3030254721Semaste m_format_array.push_back(std::make_pair(short_option, width)); 3031254721Semaste } 3032254721Semaste return error; 3033254721Semaste } 3034254721Semaste 3035254721Semaste void 3036254721Semaste OptionParsingStarting () 3037254721Semaste { 3038254721Semaste m_format_array.clear(); 3039254721Semaste m_use_global_module_list = false; 3040254721Semaste m_module_addr = LLDB_INVALID_ADDRESS; 3041254721Semaste } 3042254721Semaste 3043254721Semaste const OptionDefinition* 3044254721Semaste GetDefinitions () 3045254721Semaste { 3046254721Semaste return g_option_table; 3047254721Semaste } 3048254721Semaste 3049254721Semaste // Options table: Required for subclasses of Options. 3050254721Semaste 3051254721Semaste static OptionDefinition g_option_table[]; 3052254721Semaste 3053254721Semaste // Instance variables to hold the values for command options. 3054254721Semaste typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection; 3055254721Semaste FormatWidthCollection m_format_array; 3056254721Semaste bool m_use_global_module_list; 3057254721Semaste lldb::addr_t m_module_addr; 3058254721Semaste }; 3059254721Semaste 3060254721Semaste CommandObjectTargetModulesList (CommandInterpreter &interpreter) : 3061254721Semaste CommandObjectParsed (interpreter, 3062254721Semaste "target modules list", 3063254721Semaste "List current executable and dependent shared library images.", 3064254721Semaste "target modules list [<cmd-options>]"), 3065254721Semaste m_options (interpreter) 3066254721Semaste { 3067254721Semaste } 3068254721Semaste 3069254721Semaste virtual 3070254721Semaste ~CommandObjectTargetModulesList () 3071254721Semaste { 3072254721Semaste } 3073254721Semaste 3074254721Semaste virtual 3075254721Semaste Options * 3076254721Semaste GetOptions () 3077254721Semaste { 3078254721Semaste return &m_options; 3079254721Semaste } 3080254721Semaste 3081254721Semasteprotected: 3082254721Semaste virtual bool 3083254721Semaste DoExecute (Args& command, 3084254721Semaste CommandReturnObject &result) 3085254721Semaste { 3086254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3087254721Semaste const bool use_global_module_list = m_options.m_use_global_module_list; 3088254721Semaste // Define a local module list here to ensure it lives longer than any "locker" 3089254721Semaste // object which might lock its contents below (through the "module_list_ptr" 3090254721Semaste // variable). 3091254721Semaste ModuleList module_list; 3092254721Semaste if (target == NULL && use_global_module_list == false) 3093254721Semaste { 3094254721Semaste result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3095254721Semaste result.SetStatus (eReturnStatusFailed); 3096254721Semaste return false; 3097254721Semaste } 3098254721Semaste else 3099254721Semaste { 3100254721Semaste if (target) 3101254721Semaste { 3102254721Semaste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3103254721Semaste result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3104254721Semaste result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3105254721Semaste } 3106254721Semaste // Dump all sections for all modules images 3107254721Semaste Stream &strm = result.GetOutputStream(); 3108254721Semaste 3109254721Semaste if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) 3110254721Semaste { 3111254721Semaste if (target) 3112254721Semaste { 3113254721Semaste Address module_address; 3114254721Semaste if (module_address.SetLoadAddress(m_options.m_module_addr, target)) 3115254721Semaste { 3116254721Semaste ModuleSP module_sp (module_address.GetModule()); 3117254721Semaste if (module_sp) 3118254721Semaste { 3119254721Semaste PrintModule (target, module_sp.get(), 0, strm); 3120254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 3121254721Semaste } 3122254721Semaste else 3123254721Semaste { 3124254721Semaste result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr); 3125254721Semaste result.SetStatus (eReturnStatusFailed); 3126254721Semaste } 3127254721Semaste } 3128254721Semaste else 3129254721Semaste { 3130254721Semaste result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr); 3131254721Semaste result.SetStatus (eReturnStatusFailed); 3132254721Semaste } 3133254721Semaste } 3134254721Semaste else 3135254721Semaste { 3136254721Semaste result.AppendError ("Can only look up modules by address with a valid target."); 3137254721Semaste result.SetStatus (eReturnStatusFailed); 3138254721Semaste } 3139254721Semaste return result.Succeeded(); 3140254721Semaste } 3141254721Semaste 3142254721Semaste size_t num_modules = 0; 3143254721Semaste Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL. 3144254721Semaste // Otherwise it will lock the AllocationModuleCollectionMutex when accessing 3145254721Semaste // the global module list directly. 3146254721Semaste const ModuleList *module_list_ptr = NULL; 3147254721Semaste const size_t argc = command.GetArgumentCount(); 3148254721Semaste if (argc == 0) 3149254721Semaste { 3150254721Semaste if (use_global_module_list) 3151254721Semaste { 3152254721Semaste locker.Lock (Module::GetAllocationModuleCollectionMutex()); 3153254721Semaste num_modules = Module::GetNumberAllocatedModules(); 3154254721Semaste } 3155254721Semaste else 3156254721Semaste { 3157254721Semaste module_list_ptr = &target->GetImages(); 3158254721Semaste } 3159254721Semaste } 3160254721Semaste else 3161254721Semaste { 3162254721Semaste for (size_t i=0; i<argc; ++i) 3163254721Semaste { 3164254721Semaste // Dump specified images (by basename or fullpath) 3165254721Semaste const char *arg_cstr = command.GetArgumentAtIndex(i); 3166254721Semaste const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list); 3167254721Semaste if (num_matches == 0) 3168254721Semaste { 3169254721Semaste if (argc == 1) 3170254721Semaste { 3171254721Semaste result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr); 3172254721Semaste result.SetStatus (eReturnStatusFailed); 3173254721Semaste return false; 3174254721Semaste } 3175254721Semaste } 3176254721Semaste } 3177254721Semaste 3178254721Semaste module_list_ptr = &module_list; 3179254721Semaste } 3180254721Semaste 3181254721Semaste if (module_list_ptr != NULL) 3182254721Semaste { 3183254721Semaste locker.Lock(module_list_ptr->GetMutex()); 3184254721Semaste num_modules = module_list_ptr->GetSize(); 3185254721Semaste } 3186254721Semaste 3187254721Semaste if (num_modules > 0) 3188254721Semaste { 3189254721Semaste for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 3190254721Semaste { 3191254721Semaste ModuleSP module_sp; 3192254721Semaste Module *module; 3193254721Semaste if (module_list_ptr) 3194254721Semaste { 3195254721Semaste module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx); 3196254721Semaste module = module_sp.get(); 3197254721Semaste } 3198254721Semaste else 3199254721Semaste { 3200254721Semaste module = Module::GetAllocatedModuleAtIndex(image_idx); 3201254721Semaste module_sp = module->shared_from_this(); 3202254721Semaste } 3203254721Semaste 3204254721Semaste const size_t indent = strm.Printf("[%3u] ", image_idx); 3205254721Semaste PrintModule (target, module, indent, strm); 3206254721Semaste 3207254721Semaste } 3208254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 3209254721Semaste } 3210254721Semaste else 3211254721Semaste { 3212254721Semaste if (argc) 3213254721Semaste { 3214254721Semaste if (use_global_module_list) 3215254721Semaste result.AppendError ("the global module list has no matching modules"); 3216254721Semaste else 3217254721Semaste result.AppendError ("the target has no matching modules"); 3218254721Semaste } 3219254721Semaste else 3220254721Semaste { 3221254721Semaste if (use_global_module_list) 3222254721Semaste result.AppendError ("the global module list is empty"); 3223254721Semaste else 3224254721Semaste result.AppendError ("the target has no associated executable images"); 3225254721Semaste } 3226254721Semaste result.SetStatus (eReturnStatusFailed); 3227254721Semaste return false; 3228254721Semaste } 3229254721Semaste } 3230254721Semaste return result.Succeeded(); 3231254721Semaste } 3232254721Semaste 3233254721Semaste void 3234254721Semaste PrintModule (Target *target, Module *module, int indent, Stream &strm) 3235254721Semaste { 3236254721Semaste 3237254721Semaste if (module == NULL) 3238254721Semaste { 3239254721Semaste strm.PutCString("Null module"); 3240254721Semaste return; 3241254721Semaste } 3242254721Semaste 3243254721Semaste bool dump_object_name = false; 3244254721Semaste if (m_options.m_format_array.empty()) 3245254721Semaste { 3246254721Semaste m_options.m_format_array.push_back(std::make_pair('u', 0)); 3247254721Semaste m_options.m_format_array.push_back(std::make_pair('h', 0)); 3248254721Semaste m_options.m_format_array.push_back(std::make_pair('f', 0)); 3249254721Semaste m_options.m_format_array.push_back(std::make_pair('S', 0)); 3250254721Semaste } 3251254721Semaste const size_t num_entries = m_options.m_format_array.size(); 3252254721Semaste bool print_space = false; 3253254721Semaste for (size_t i=0; i<num_entries; ++i) 3254254721Semaste { 3255254721Semaste if (print_space) 3256254721Semaste strm.PutChar(' '); 3257254721Semaste print_space = true; 3258254721Semaste const char format_char = m_options.m_format_array[i].first; 3259254721Semaste uint32_t width = m_options.m_format_array[i].second; 3260254721Semaste switch (format_char) 3261254721Semaste { 3262254721Semaste case 'A': 3263254721Semaste DumpModuleArchitecture (strm, module, false, width); 3264254721Semaste break; 3265254721Semaste 3266254721Semaste case 't': 3267254721Semaste DumpModuleArchitecture (strm, module, true, width); 3268254721Semaste break; 3269254721Semaste 3270254721Semaste case 'f': 3271254721Semaste DumpFullpath (strm, &module->GetFileSpec(), width); 3272254721Semaste dump_object_name = true; 3273254721Semaste break; 3274254721Semaste 3275254721Semaste case 'd': 3276254721Semaste DumpDirectory (strm, &module->GetFileSpec(), width); 3277254721Semaste break; 3278254721Semaste 3279254721Semaste case 'b': 3280254721Semaste DumpBasename (strm, &module->GetFileSpec(), width); 3281254721Semaste dump_object_name = true; 3282254721Semaste break; 3283254721Semaste 3284254721Semaste case 'h': 3285254721Semaste case 'o': 3286254721Semaste // Image header address 3287254721Semaste { 3288254721Semaste uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16; 3289254721Semaste 3290254721Semaste ObjectFile *objfile = module->GetObjectFile (); 3291254721Semaste if (objfile) 3292254721Semaste { 3293254721Semaste Address header_addr(objfile->GetHeaderAddress()); 3294254721Semaste if (header_addr.IsValid()) 3295254721Semaste { 3296254721Semaste if (target && !target->GetSectionLoadList().IsEmpty()) 3297254721Semaste { 3298254721Semaste lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target); 3299254721Semaste if (header_load_addr == LLDB_INVALID_ADDRESS) 3300254721Semaste { 3301254721Semaste header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress); 3302254721Semaste } 3303254721Semaste else 3304254721Semaste { 3305254721Semaste if (format_char == 'o') 3306254721Semaste { 3307254721Semaste // Show the offset of slide for the image 3308254721Semaste strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress()); 3309254721Semaste } 3310254721Semaste else 3311254721Semaste { 3312254721Semaste // Show the load address of the image 3313254721Semaste strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr); 3314254721Semaste } 3315254721Semaste } 3316254721Semaste break; 3317254721Semaste } 3318254721Semaste // The address was valid, but the image isn't loaded, output the address in an appropriate format 3319254721Semaste header_addr.Dump (&strm, target, Address::DumpStyleFileAddress); 3320254721Semaste break; 3321254721Semaste } 3322254721Semaste } 3323254721Semaste strm.Printf ("%*s", addr_nibble_width + 2, ""); 3324254721Semaste } 3325254721Semaste break; 3326254721Semaste case 'r': 3327254721Semaste { 3328254721Semaste size_t ref_count = 0; 3329254721Semaste ModuleSP module_sp (module->shared_from_this()); 3330254721Semaste if (module_sp) 3331254721Semaste { 3332254721Semaste // Take one away to make sure we don't count our local "module_sp" 3333254721Semaste ref_count = module_sp.use_count() - 1; 3334254721Semaste } 3335254721Semaste if (width) 3336254721Semaste strm.Printf("{%*zu}", width, ref_count); 3337254721Semaste else 3338254721Semaste strm.Printf("{%zu}", ref_count); 3339254721Semaste } 3340254721Semaste break; 3341254721Semaste 3342254721Semaste case 's': 3343254721Semaste case 'S': 3344254721Semaste { 3345254721Semaste SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 3346254721Semaste if (symbol_vendor) 3347254721Semaste { 3348254721Semaste SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 3349254721Semaste if (symbol_file) 3350254721Semaste { 3351254721Semaste if (format_char == 'S') 3352254721Semaste { 3353254721Semaste FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec(); 3354254721Semaste // Dump symbol file only if different from module file 3355254721Semaste if (!symfile_spec || symfile_spec == module->GetFileSpec()) 3356254721Semaste { 3357254721Semaste print_space = false; 3358254721Semaste break; 3359254721Semaste } 3360254721Semaste // Add a newline and indent past the index 3361254721Semaste strm.Printf ("\n%*s", indent, ""); 3362254721Semaste } 3363254721Semaste DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 3364254721Semaste dump_object_name = true; 3365254721Semaste break; 3366254721Semaste } 3367254721Semaste } 3368254721Semaste strm.Printf("%.*s", width, "<NONE>"); 3369254721Semaste } 3370254721Semaste break; 3371254721Semaste 3372254721Semaste case 'm': 3373254721Semaste module->GetModificationTime().Dump(&strm, width); 3374254721Semaste break; 3375254721Semaste 3376254721Semaste case 'p': 3377254721Semaste strm.Printf("%p", module); 3378254721Semaste break; 3379254721Semaste 3380254721Semaste case 'u': 3381254721Semaste DumpModuleUUID(strm, module); 3382254721Semaste break; 3383254721Semaste 3384254721Semaste default: 3385254721Semaste break; 3386254721Semaste } 3387254721Semaste 3388254721Semaste } 3389254721Semaste if (dump_object_name) 3390254721Semaste { 3391254721Semaste const char *object_name = module->GetObjectName().GetCString(); 3392254721Semaste if (object_name) 3393254721Semaste strm.Printf ("(%s)", object_name); 3394254721Semaste } 3395254721Semaste strm.EOL(); 3396254721Semaste } 3397254721Semaste 3398254721Semaste CommandOptions m_options; 3399254721Semaste}; 3400254721Semaste 3401254721SemasteOptionDefinition 3402254721SemasteCommandObjectTargetModulesList::CommandOptions::g_option_table[] = 3403254721Semaste{ 3404254721Semaste { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."}, 3405254721Semaste { LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, 3406254721Semaste { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, 3407254721Semaste { LLDB_OPT_SET_1, false, "header", 'h', no_argument, NULL, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."}, 3408254721Semaste { LLDB_OPT_SET_1, false, "offset", 'o', no_argument, NULL, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."}, 3409254721Semaste { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, 3410254721Semaste { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, 3411254721Semaste { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, 3412254721Semaste { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, 3413254721Semaste { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, 3414254721Semaste { LLDB_OPT_SET_1, false, "symfile-unique", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."}, 3415254721Semaste { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, 3416254721Semaste { 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."}, 3417254721Semaste { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."}, 3418254721Semaste { 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."}, 3419254721Semaste { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3420254721Semaste}; 3421254721Semaste 3422254721Semaste#pragma mark CommandObjectTargetModulesShowUnwind 3423254721Semaste 3424254721Semaste//---------------------------------------------------------------------- 3425254721Semaste// Lookup unwind information in images 3426254721Semaste//---------------------------------------------------------------------- 3427254721Semaste 3428254721Semasteclass CommandObjectTargetModulesShowUnwind : public CommandObjectParsed 3429254721Semaste{ 3430254721Semastepublic: 3431254721Semaste 3432254721Semaste enum 3433254721Semaste { 3434254721Semaste eLookupTypeInvalid = -1, 3435254721Semaste eLookupTypeAddress = 0, 3436254721Semaste eLookupTypeSymbol, 3437254721Semaste eLookupTypeFunction, 3438254721Semaste eLookupTypeFunctionOrSymbol, 3439254721Semaste kNumLookupTypes 3440254721Semaste }; 3441254721Semaste 3442254721Semaste class CommandOptions : public Options 3443254721Semaste { 3444254721Semaste public: 3445254721Semaste 3446254721Semaste CommandOptions (CommandInterpreter &interpreter) : 3447254721Semaste Options(interpreter), 3448254721Semaste m_type(eLookupTypeInvalid), 3449254721Semaste m_str(), 3450254721Semaste m_addr(LLDB_INVALID_ADDRESS) 3451254721Semaste { 3452254721Semaste } 3453254721Semaste 3454254721Semaste virtual 3455254721Semaste ~CommandOptions () 3456254721Semaste { 3457254721Semaste } 3458254721Semaste 3459254721Semaste virtual Error 3460254721Semaste SetOptionValue (uint32_t option_idx, const char *option_arg) 3461254721Semaste { 3462254721Semaste Error error; 3463254721Semaste 3464254721Semaste const int short_option = m_getopt_table[option_idx].val; 3465254721Semaste 3466254721Semaste switch (short_option) 3467254721Semaste { 3468254721Semaste case 'a': 3469254721Semaste { 3470254721Semaste ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3471254721Semaste m_type = eLookupTypeAddress; 3472254721Semaste m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3473254721Semaste if (m_addr == LLDB_INVALID_ADDRESS) 3474254721Semaste error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg); 3475254721Semaste break; 3476254721Semaste } 3477254721Semaste 3478254721Semaste case 'n': 3479254721Semaste { 3480254721Semaste m_str = option_arg; 3481254721Semaste m_type = eLookupTypeFunctionOrSymbol; 3482254721Semaste break; 3483254721Semaste } 3484254721Semaste } 3485254721Semaste 3486254721Semaste return error; 3487254721Semaste } 3488254721Semaste 3489254721Semaste void 3490254721Semaste OptionParsingStarting () 3491254721Semaste { 3492254721Semaste m_type = eLookupTypeInvalid; 3493254721Semaste m_str.clear(); 3494254721Semaste m_addr = LLDB_INVALID_ADDRESS; 3495254721Semaste } 3496254721Semaste 3497254721Semaste const OptionDefinition* 3498254721Semaste GetDefinitions () 3499254721Semaste { 3500254721Semaste return g_option_table; 3501254721Semaste } 3502254721Semaste 3503254721Semaste // Options table: Required for subclasses of Options. 3504254721Semaste 3505254721Semaste static OptionDefinition g_option_table[]; 3506254721Semaste 3507254721Semaste // Instance variables to hold the values for command options. 3508254721Semaste 3509254721Semaste int m_type; // Should be a eLookupTypeXXX enum after parsing options 3510254721Semaste std::string m_str; // Holds name lookup 3511254721Semaste lldb::addr_t m_addr; // Holds the address to lookup 3512254721Semaste }; 3513254721Semaste 3514254721Semaste CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) : 3515254721Semaste CommandObjectParsed (interpreter, 3516254721Semaste "target modules show-unwind", 3517254721Semaste "Show synthesized unwind instructions for a function.", 3518254721Semaste NULL, 3519254721Semaste eFlagRequiresTarget | 3520254721Semaste eFlagRequiresProcess | 3521254721Semaste eFlagProcessMustBeLaunched | 3522254721Semaste eFlagProcessMustBePaused ), 3523254721Semaste m_options (interpreter) 3524254721Semaste { 3525254721Semaste } 3526254721Semaste 3527254721Semaste virtual 3528254721Semaste ~CommandObjectTargetModulesShowUnwind () 3529254721Semaste { 3530254721Semaste } 3531254721Semaste 3532254721Semaste virtual 3533254721Semaste Options * 3534254721Semaste GetOptions () 3535254721Semaste { 3536254721Semaste return &m_options; 3537254721Semaste } 3538254721Semaste 3539254721Semasteprotected: 3540254721Semaste bool 3541254721Semaste DoExecute (Args& command, 3542254721Semaste CommandReturnObject &result) 3543254721Semaste { 3544254721Semaste Target *target = m_exe_ctx.GetTargetPtr(); 3545254721Semaste Process *process = m_exe_ctx.GetProcessPtr(); 3546254721Semaste ABI *abi = NULL; 3547254721Semaste if (process) 3548254721Semaste abi = process->GetABI().get(); 3549254721Semaste 3550254721Semaste if (process == NULL) 3551254721Semaste { 3552254721Semaste result.AppendError ("You must have a process running to use this command."); 3553254721Semaste result.SetStatus (eReturnStatusFailed); 3554254721Semaste return false; 3555254721Semaste } 3556254721Semaste 3557254721Semaste ThreadList threads(process->GetThreadList()); 3558254721Semaste if (threads.GetSize() == 0) 3559254721Semaste { 3560254721Semaste result.AppendError ("The process must be paused to use this command."); 3561254721Semaste result.SetStatus (eReturnStatusFailed); 3562254721Semaste return false; 3563254721Semaste } 3564254721Semaste 3565254721Semaste ThreadSP thread(threads.GetThreadAtIndex(0)); 3566254721Semaste if (thread.get() == NULL) 3567254721Semaste { 3568254721Semaste result.AppendError ("The process must be paused to use this command."); 3569254721Semaste result.SetStatus (eReturnStatusFailed); 3570254721Semaste return false; 3571254721Semaste } 3572254721Semaste 3573254721Semaste SymbolContextList sc_list; 3574254721Semaste 3575254721Semaste if (m_options.m_type == eLookupTypeFunctionOrSymbol) 3576254721Semaste { 3577254721Semaste ConstString function_name (m_options.m_str.c_str()); 3578254721Semaste target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list); 3579254721Semaste } 3580254721Semaste else if (m_options.m_type == eLookupTypeAddress && target) 3581254721Semaste { 3582254721Semaste Address addr; 3583254721Semaste if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr)) 3584254721Semaste { 3585254721Semaste SymbolContext sc; 3586254721Semaste ModuleSP module_sp (addr.GetModule()); 3587254721Semaste module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc); 3588254721Semaste if (sc.function || sc.symbol) 3589254721Semaste { 3590254721Semaste sc_list.Append(sc); 3591254721Semaste } 3592254721Semaste } 3593254721Semaste } 3594254721Semaste 3595254721Semaste size_t num_matches = sc_list.GetSize(); 3596254721Semaste for (uint32_t idx = 0; idx < num_matches; idx++) 3597254721Semaste { 3598254721Semaste SymbolContext sc; 3599254721Semaste sc_list.GetContextAtIndex(idx, sc); 3600254721Semaste if (sc.symbol == NULL && sc.function == NULL) 3601254721Semaste continue; 3602254721Semaste if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL) 3603254721Semaste continue; 3604254721Semaste AddressRange range; 3605254721Semaste if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range)) 3606254721Semaste continue; 3607254721Semaste if (!range.GetBaseAddress().IsValid()) 3608254721Semaste continue; 3609254721Semaste ConstString funcname(sc.GetFunctionName()); 3610254721Semaste if (funcname.IsEmpty()) 3611254721Semaste continue; 3612254721Semaste addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target); 3613254721Semaste if (abi) 3614254721Semaste start_addr = abi->FixCodeAddress(start_addr); 3615254721Semaste 3616254721Semaste FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc)); 3617254721Semaste if (func_unwinders_sp.get() == NULL) 3618254721Semaste continue; 3619254721Semaste 3620254721Semaste Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target)); 3621254721Semaste if (first_non_prologue_insn.IsValid()) 3622254721Semaste { 3623254721Semaste result.GetOutputStream().Printf("First non-prologue instruction is at address 0x%" PRIx64 " or offset %" PRId64 " into the function.\n", first_non_prologue_insn.GetLoadAddress(target), first_non_prologue_insn.GetLoadAddress(target) - start_addr); 3624254721Semaste result.GetOutputStream().Printf ("\n"); 3625254721Semaste } 3626254721Semaste 3627254721Semaste UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*thread.get()); 3628254721Semaste if (non_callsite_unwind_plan.get()) 3629254721Semaste { 3630254721Semaste result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3631254721Semaste non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3632254721Semaste result.GetOutputStream().Printf ("\n"); 3633254721Semaste } 3634254721Semaste 3635254721Semaste UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(-1); 3636254721Semaste if (callsite_unwind_plan.get()) 3637254721Semaste { 3638254721Semaste result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3639254721Semaste callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3640254721Semaste result.GetOutputStream().Printf ("\n"); 3641254721Semaste } 3642254721Semaste 3643254721Semaste UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get()); 3644254721Semaste if (arch_default_unwind_plan.get()) 3645254721Semaste { 3646254721Semaste result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3647254721Semaste arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3648254721Semaste result.GetOutputStream().Printf ("\n"); 3649254721Semaste } 3650254721Semaste 3651254721Semaste UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get()); 3652254721Semaste if (fast_unwind_plan.get()) 3653254721Semaste { 3654254721Semaste result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3655254721Semaste fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3656254721Semaste result.GetOutputStream().Printf ("\n"); 3657254721Semaste } 3658254721Semaste 3659254721Semaste 3660254721Semaste result.GetOutputStream().Printf ("\n"); 3661254721Semaste } 3662254721Semaste return result.Succeeded(); 3663254721Semaste } 3664254721Semaste 3665254721Semaste CommandOptions m_options; 3666254721Semaste}; 3667254721Semaste 3668254721SemasteOptionDefinition 3669254721SemasteCommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] = 3670254721Semaste{ 3671254721Semaste { LLDB_OPT_SET_1, false, "name", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."}, 3672254721Semaste { LLDB_OPT_SET_2, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"}, 3673254721Semaste { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3674254721Semaste}; 3675254721Semaste 3676254721Semaste//---------------------------------------------------------------------- 3677254721Semaste// Lookup information in images 3678254721Semaste//---------------------------------------------------------------------- 3679254721Semasteclass CommandObjectTargetModulesLookup : public CommandObjectParsed 3680254721Semaste{ 3681254721Semastepublic: 3682254721Semaste 3683254721Semaste enum 3684254721Semaste { 3685254721Semaste eLookupTypeInvalid = -1, 3686254721Semaste eLookupTypeAddress = 0, 3687254721Semaste eLookupTypeSymbol, 3688254721Semaste eLookupTypeFileLine, // Line is optional 3689254721Semaste eLookupTypeFunction, 3690254721Semaste eLookupTypeFunctionOrSymbol, 3691254721Semaste eLookupTypeType, 3692254721Semaste kNumLookupTypes 3693254721Semaste }; 3694254721Semaste 3695254721Semaste class CommandOptions : public Options 3696254721Semaste { 3697254721Semaste public: 3698254721Semaste 3699254721Semaste CommandOptions (CommandInterpreter &interpreter) : 3700254721Semaste Options(interpreter) 3701254721Semaste { 3702254721Semaste OptionParsingStarting(); 3703254721Semaste } 3704254721Semaste 3705254721Semaste virtual 3706254721Semaste ~CommandOptions () 3707254721Semaste { 3708254721Semaste } 3709254721Semaste 3710254721Semaste virtual Error 3711254721Semaste SetOptionValue (uint32_t option_idx, const char *option_arg) 3712254721Semaste { 3713254721Semaste Error error; 3714254721Semaste 3715254721Semaste const int short_option = m_getopt_table[option_idx].val; 3716254721Semaste 3717254721Semaste switch (short_option) 3718254721Semaste { 3719254721Semaste case 'a': 3720254721Semaste { 3721254721Semaste m_type = eLookupTypeAddress; 3722254721Semaste ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3723254721Semaste m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3724254721Semaste } 3725254721Semaste break; 3726254721Semaste 3727254721Semaste case 'o': 3728254721Semaste m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3729254721Semaste if (m_offset == LLDB_INVALID_ADDRESS) 3730254721Semaste error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg); 3731254721Semaste break; 3732254721Semaste 3733254721Semaste case 's': 3734254721Semaste m_str = option_arg; 3735254721Semaste m_type = eLookupTypeSymbol; 3736254721Semaste break; 3737254721Semaste 3738254721Semaste case 'f': 3739254721Semaste m_file.SetFile (option_arg, false); 3740254721Semaste m_type = eLookupTypeFileLine; 3741254721Semaste break; 3742254721Semaste 3743254721Semaste case 'i': 3744254721Semaste m_include_inlines = false; 3745254721Semaste break; 3746254721Semaste 3747254721Semaste case 'l': 3748254721Semaste m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); 3749254721Semaste if (m_line_number == UINT32_MAX) 3750254721Semaste error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg); 3751254721Semaste else if (m_line_number == 0) 3752254721Semaste error.SetErrorString ("zero is an invalid line number"); 3753254721Semaste m_type = eLookupTypeFileLine; 3754254721Semaste break; 3755254721Semaste 3756254721Semaste case 'F': 3757254721Semaste m_str = option_arg; 3758254721Semaste m_type = eLookupTypeFunction; 3759254721Semaste break; 3760254721Semaste 3761254721Semaste case 'n': 3762254721Semaste m_str = option_arg; 3763254721Semaste m_type = eLookupTypeFunctionOrSymbol; 3764254721Semaste break; 3765254721Semaste 3766254721Semaste case 't': 3767254721Semaste m_str = option_arg; 3768254721Semaste m_type = eLookupTypeType; 3769254721Semaste break; 3770254721Semaste 3771254721Semaste case 'v': 3772254721Semaste m_verbose = 1; 3773254721Semaste break; 3774254721Semaste 3775254721Semaste case 'A': 3776254721Semaste m_print_all = true; 3777254721Semaste break; 3778254721Semaste 3779254721Semaste case 'r': 3780254721Semaste m_use_regex = true; 3781254721Semaste break; 3782254721Semaste } 3783254721Semaste 3784254721Semaste return error; 3785254721Semaste } 3786254721Semaste 3787254721Semaste void 3788254721Semaste OptionParsingStarting () 3789254721Semaste { 3790254721Semaste m_type = eLookupTypeInvalid; 3791254721Semaste m_str.clear(); 3792254721Semaste m_file.Clear(); 3793254721Semaste m_addr = LLDB_INVALID_ADDRESS; 3794254721Semaste m_offset = 0; 3795254721Semaste m_line_number = 0; 3796254721Semaste m_use_regex = false; 3797254721Semaste m_include_inlines = true; 3798254721Semaste m_verbose = false; 3799254721Semaste m_print_all = false; 3800254721Semaste } 3801254721Semaste 3802254721Semaste const OptionDefinition* 3803254721Semaste GetDefinitions () 3804254721Semaste { 3805254721Semaste return g_option_table; 3806254721Semaste } 3807254721Semaste 3808254721Semaste // Options table: Required for subclasses of Options. 3809254721Semaste 3810254721Semaste static OptionDefinition g_option_table[]; 3811254721Semaste int m_type; // Should be a eLookupTypeXXX enum after parsing options 3812254721Semaste std::string m_str; // Holds name lookup 3813254721Semaste FileSpec m_file; // Files for file lookups 3814254721Semaste lldb::addr_t m_addr; // Holds the address to lookup 3815254721Semaste lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 3816254721Semaste uint32_t m_line_number; // Line number for file+line lookups 3817254721Semaste bool m_use_regex; // Name lookups in m_str are regular expressions. 3818254721Semaste bool m_include_inlines;// Check for inline entries when looking up by file/line. 3819254721Semaste bool m_verbose; // Enable verbose lookup info 3820254721Semaste bool m_print_all; // Print all matches, even in cases where there's a best match. 3821254721Semaste 3822254721Semaste }; 3823254721Semaste 3824254721Semaste CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 3825254721Semaste CommandObjectParsed (interpreter, 3826254721Semaste "target modules lookup", 3827254721Semaste "Look up information within executable and dependent shared library images.", 3828254721Semaste NULL, 3829254721Semaste eFlagRequiresTarget), 3830254721Semaste m_options (interpreter) 3831254721Semaste { 3832254721Semaste CommandArgumentEntry arg; 3833254721Semaste CommandArgumentData file_arg; 3834254721Semaste 3835254721Semaste // Define the first (and only) variant of this arg. 3836254721Semaste file_arg.arg_type = eArgTypeFilename; 3837254721Semaste file_arg.arg_repetition = eArgRepeatStar; 3838254721Semaste 3839254721Semaste // There is only one variant this argument could be; put it into the argument entry. 3840254721Semaste arg.push_back (file_arg); 3841254721Semaste 3842254721Semaste // Push the data for the first argument into the m_arguments vector. 3843254721Semaste m_arguments.push_back (arg); 3844254721Semaste } 3845254721Semaste 3846254721Semaste virtual 3847254721Semaste ~CommandObjectTargetModulesLookup () 3848254721Semaste { 3849254721Semaste } 3850254721Semaste 3851254721Semaste virtual Options * 3852254721Semaste GetOptions () 3853254721Semaste { 3854254721Semaste return &m_options; 3855254721Semaste } 3856254721Semaste 3857254721Semaste bool 3858254721Semaste LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error) 3859254721Semaste { 3860254721Semaste switch (m_options.m_type) 3861254721Semaste { 3862254721Semaste case eLookupTypeAddress: 3863254721Semaste case eLookupTypeFileLine: 3864254721Semaste case eLookupTypeFunction: 3865254721Semaste case eLookupTypeFunctionOrSymbol: 3866254721Semaste case eLookupTypeSymbol: 3867254721Semaste default: 3868254721Semaste return false; 3869254721Semaste case eLookupTypeType: 3870254721Semaste break; 3871254721Semaste } 3872254721Semaste 3873254721Semaste StackFrameSP frame = m_exe_ctx.GetFrameSP(); 3874254721Semaste 3875254721Semaste if (!frame) 3876254721Semaste return false; 3877254721Semaste 3878254721Semaste const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule)); 3879254721Semaste 3880254721Semaste if (!sym_ctx.module_sp) 3881254721Semaste return false; 3882254721Semaste 3883254721Semaste switch (m_options.m_type) 3884254721Semaste { 3885254721Semaste default: 3886254721Semaste return false; 3887254721Semaste case eLookupTypeType: 3888254721Semaste if (!m_options.m_str.empty()) 3889254721Semaste { 3890254721Semaste if (LookupTypeHere (m_interpreter, 3891254721Semaste result.GetOutputStream(), 3892254721Semaste sym_ctx, 3893254721Semaste m_options.m_str.c_str(), 3894254721Semaste m_options.m_use_regex)) 3895254721Semaste { 3896254721Semaste result.SetStatus(eReturnStatusSuccessFinishResult); 3897254721Semaste return true; 3898254721Semaste } 3899254721Semaste } 3900254721Semaste break; 3901254721Semaste } 3902254721Semaste 3903254721Semaste return true; 3904254721Semaste } 3905254721Semaste 3906254721Semaste bool 3907254721Semaste LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 3908254721Semaste { 3909254721Semaste switch (m_options.m_type) 3910254721Semaste { 3911254721Semaste case eLookupTypeAddress: 3912254721Semaste if (m_options.m_addr != LLDB_INVALID_ADDRESS) 3913254721Semaste { 3914254721Semaste if (LookupAddressInModule (m_interpreter, 3915254721Semaste result.GetOutputStream(), 3916254721Semaste module, 3917254721Semaste eSymbolContextEverything, 3918254721Semaste m_options.m_addr, 3919254721Semaste m_options.m_offset, 3920254721Semaste m_options.m_verbose)) 3921254721Semaste { 3922254721Semaste result.SetStatus(eReturnStatusSuccessFinishResult); 3923254721Semaste return true; 3924254721Semaste } 3925254721Semaste } 3926254721Semaste break; 3927254721Semaste 3928254721Semaste case eLookupTypeSymbol: 3929254721Semaste if (!m_options.m_str.empty()) 3930254721Semaste { 3931254721Semaste if (LookupSymbolInModule (m_interpreter, 3932254721Semaste result.GetOutputStream(), 3933254721Semaste module, 3934254721Semaste m_options.m_str.c_str(), 3935254721Semaste m_options.m_use_regex, 3936254721Semaste m_options.m_verbose)) 3937254721Semaste { 3938254721Semaste result.SetStatus(eReturnStatusSuccessFinishResult); 3939254721Semaste return true; 3940254721Semaste } 3941254721Semaste } 3942254721Semaste break; 3943254721Semaste 3944254721Semaste case eLookupTypeFileLine: 3945254721Semaste if (m_options.m_file) 3946254721Semaste { 3947254721Semaste 3948254721Semaste if (LookupFileAndLineInModule (m_interpreter, 3949254721Semaste result.GetOutputStream(), 3950254721Semaste module, 3951254721Semaste m_options.m_file, 3952254721Semaste m_options.m_line_number, 3953254721Semaste m_options.m_include_inlines, 3954254721Semaste m_options.m_verbose)) 3955254721Semaste { 3956254721Semaste result.SetStatus(eReturnStatusSuccessFinishResult); 3957254721Semaste return true; 3958254721Semaste } 3959254721Semaste } 3960254721Semaste break; 3961254721Semaste 3962254721Semaste case eLookupTypeFunctionOrSymbol: 3963254721Semaste case eLookupTypeFunction: 3964254721Semaste if (!m_options.m_str.empty()) 3965254721Semaste { 3966254721Semaste if (LookupFunctionInModule (m_interpreter, 3967254721Semaste result.GetOutputStream(), 3968254721Semaste module, 3969254721Semaste m_options.m_str.c_str(), 3970254721Semaste m_options.m_use_regex, 3971254721Semaste m_options.m_include_inlines, 3972254721Semaste m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols 3973254721Semaste m_options.m_verbose)) 3974254721Semaste { 3975254721Semaste result.SetStatus(eReturnStatusSuccessFinishResult); 3976254721Semaste return true; 3977254721Semaste } 3978254721Semaste } 3979254721Semaste break; 3980254721Semaste 3981254721Semaste 3982254721Semaste case eLookupTypeType: 3983254721Semaste if (!m_options.m_str.empty()) 3984254721Semaste { 3985254721Semaste if (LookupTypeInModule (m_interpreter, 3986254721Semaste result.GetOutputStream(), 3987254721Semaste module, 3988254721Semaste m_options.m_str.c_str(), 3989254721Semaste m_options.m_use_regex)) 3990254721Semaste { 3991254721Semaste result.SetStatus(eReturnStatusSuccessFinishResult); 3992254721Semaste return true; 3993254721Semaste } 3994254721Semaste } 3995254721Semaste break; 3996254721Semaste 3997254721Semaste default: 3998254721Semaste m_options.GenerateOptionUsage (result.GetErrorStream(), this); 3999254721Semaste syntax_error = true; 4000254721Semaste break; 4001254721Semaste } 4002254721Semaste 4003254721Semaste result.SetStatus (eReturnStatusFailed); 4004254721Semaste return false; 4005254721Semaste } 4006254721Semaste 4007254721Semasteprotected: 4008254721Semaste virtual bool 4009254721Semaste DoExecute (Args& command, 4010254721Semaste CommandReturnObject &result) 4011254721Semaste { 4012254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4013254721Semaste if (target == NULL) 4014254721Semaste { 4015254721Semaste result.AppendError ("invalid target, create a debug target using the 'target create' command"); 4016254721Semaste result.SetStatus (eReturnStatusFailed); 4017254721Semaste return false; 4018254721Semaste } 4019254721Semaste else 4020254721Semaste { 4021254721Semaste bool syntax_error = false; 4022254721Semaste uint32_t i; 4023254721Semaste uint32_t num_successful_lookups = 0; 4024254721Semaste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 4025254721Semaste result.GetOutputStream().SetAddressByteSize(addr_byte_size); 4026254721Semaste result.GetErrorStream().SetAddressByteSize(addr_byte_size); 4027254721Semaste // Dump all sections for all modules images 4028254721Semaste 4029254721Semaste if (command.GetArgumentCount() == 0) 4030254721Semaste { 4031254721Semaste ModuleSP current_module; 4032254721Semaste 4033254721Semaste // Where it is possible to look in the current symbol context 4034254721Semaste // first, try that. If this search was successful and --all 4035254721Semaste // was not passed, don't print anything else. 4036254721Semaste if (LookupHere (m_interpreter, result, syntax_error)) 4037254721Semaste { 4038254721Semaste result.GetOutputStream().EOL(); 4039254721Semaste num_successful_lookups++; 4040254721Semaste if (!m_options.m_print_all) 4041254721Semaste { 4042254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 4043254721Semaste return result.Succeeded(); 4044254721Semaste } 4045254721Semaste } 4046254721Semaste 4047254721Semaste // Dump all sections for all other modules 4048254721Semaste 4049254721Semaste const ModuleList &target_modules = target->GetImages(); 4050254721Semaste Mutex::Locker modules_locker(target_modules.GetMutex()); 4051254721Semaste const size_t num_modules = target_modules.GetSize(); 4052254721Semaste if (num_modules > 0) 4053254721Semaste { 4054254721Semaste for (i = 0; i<num_modules && syntax_error == false; ++i) 4055254721Semaste { 4056254721Semaste Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i); 4057254721Semaste 4058254721Semaste if (module_pointer != current_module.get() && 4059254721Semaste LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error)) 4060254721Semaste { 4061254721Semaste result.GetOutputStream().EOL(); 4062254721Semaste num_successful_lookups++; 4063254721Semaste } 4064254721Semaste } 4065254721Semaste } 4066254721Semaste else 4067254721Semaste { 4068254721Semaste result.AppendError ("the target has no associated executable images"); 4069254721Semaste result.SetStatus (eReturnStatusFailed); 4070254721Semaste return false; 4071254721Semaste } 4072254721Semaste } 4073254721Semaste else 4074254721Semaste { 4075254721Semaste // Dump specified images (by basename or fullpath) 4076254721Semaste const char *arg_cstr; 4077254721Semaste for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 4078254721Semaste { 4079254721Semaste ModuleList module_list; 4080254721Semaste const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false); 4081254721Semaste if (num_matches > 0) 4082254721Semaste { 4083254721Semaste for (size_t j=0; j<num_matches; ++j) 4084254721Semaste { 4085254721Semaste Module *module = module_list.GetModulePointerAtIndex(j); 4086254721Semaste if (module) 4087254721Semaste { 4088254721Semaste if (LookupInModule (m_interpreter, module, result, syntax_error)) 4089254721Semaste { 4090254721Semaste result.GetOutputStream().EOL(); 4091254721Semaste num_successful_lookups++; 4092254721Semaste } 4093254721Semaste } 4094254721Semaste } 4095254721Semaste } 4096254721Semaste else 4097254721Semaste result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 4098254721Semaste } 4099254721Semaste } 4100254721Semaste 4101254721Semaste if (num_successful_lookups > 0) 4102254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 4103254721Semaste else 4104254721Semaste result.SetStatus (eReturnStatusFailed); 4105254721Semaste } 4106254721Semaste return result.Succeeded(); 4107254721Semaste } 4108254721Semaste 4109254721Semaste CommandOptions m_options; 4110254721Semaste}; 4111254721Semaste 4112254721SemasteOptionDefinition 4113254721SemasteCommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 4114254721Semaste{ 4115254721Semaste { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."}, 4116254721Semaste { 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."}, 4117254721Semaste { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5 4118254721Semaste /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ , 4119254721Semaste false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 4120254721Semaste { 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."}, 4121254721Semaste { 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."}, 4122254721Semaste { 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)."}, 4123254721Semaste { LLDB_OPT_SET_FROM_TO(3,5), 4124254721Semaste false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."}, 4125254721Semaste { LLDB_OPT_SET_4, true, "function", 'F', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."}, 4126254721Semaste { LLDB_OPT_SET_5, true, "name", 'n', required_argument, NULL, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules."}, 4127254721Semaste { LLDB_OPT_SET_6, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."}, 4128254721Semaste { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 4129254721Semaste { LLDB_OPT_SET_ALL, false, "all", 'A', no_argument, NULL, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available."}, 4130254721Semaste { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 4131254721Semaste}; 4132254721Semaste 4133254721Semaste 4134254721Semaste#pragma mark CommandObjectMultiwordImageSearchPaths 4135254721Semaste 4136254721Semaste//------------------------------------------------------------------------- 4137254721Semaste// CommandObjectMultiwordImageSearchPaths 4138254721Semaste//------------------------------------------------------------------------- 4139254721Semaste 4140254721Semasteclass CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 4141254721Semaste{ 4142254721Semastepublic: 4143254721Semaste 4144254721Semaste CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 4145254721Semaste CommandObjectMultiword (interpreter, 4146254721Semaste "target modules search-paths", 4147254721Semaste "A set of commands for operating on debugger target image search paths.", 4148254721Semaste "target modules search-paths <subcommand> [<subcommand-options>]") 4149254721Semaste { 4150254721Semaste LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 4151254721Semaste LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 4152254721Semaste LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 4153254721Semaste LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 4154254721Semaste LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 4155254721Semaste } 4156254721Semaste 4157254721Semaste ~CommandObjectTargetModulesImageSearchPaths() 4158254721Semaste { 4159254721Semaste } 4160254721Semaste}; 4161254721Semaste 4162254721Semaste 4163254721Semaste 4164254721Semaste#pragma mark CommandObjectTargetModules 4165254721Semaste 4166254721Semaste//------------------------------------------------------------------------- 4167254721Semaste// CommandObjectTargetModules 4168254721Semaste//------------------------------------------------------------------------- 4169254721Semaste 4170254721Semasteclass CommandObjectTargetModules : public CommandObjectMultiword 4171254721Semaste{ 4172254721Semastepublic: 4173254721Semaste //------------------------------------------------------------------ 4174254721Semaste // Constructors and Destructors 4175254721Semaste //------------------------------------------------------------------ 4176254721Semaste CommandObjectTargetModules(CommandInterpreter &interpreter) : 4177254721Semaste CommandObjectMultiword (interpreter, 4178254721Semaste "target modules", 4179254721Semaste "A set of commands for accessing information for one or more target modules.", 4180254721Semaste "target modules <sub-command> ...") 4181254721Semaste { 4182254721Semaste LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 4183254721Semaste LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 4184254721Semaste LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 4185254721Semaste LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 4186254721Semaste LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 4187254721Semaste LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 4188254721Semaste LoadSubCommand ("show-unwind", CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter))); 4189254721Semaste 4190254721Semaste } 4191254721Semaste virtual 4192254721Semaste ~CommandObjectTargetModules() 4193254721Semaste { 4194254721Semaste } 4195254721Semaste 4196254721Semasteprivate: 4197254721Semaste //------------------------------------------------------------------ 4198254721Semaste // For CommandObjectTargetModules only 4199254721Semaste //------------------------------------------------------------------ 4200254721Semaste DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 4201254721Semaste}; 4202254721Semaste 4203254721Semaste 4204254721Semaste 4205254721Semasteclass CommandObjectTargetSymbolsAdd : public CommandObjectParsed 4206254721Semaste{ 4207254721Semastepublic: 4208254721Semaste CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) : 4209254721Semaste CommandObjectParsed (interpreter, 4210254721Semaste "target symbols add", 4211254721Semaste "Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for.", 4212254721Semaste "target symbols add [<symfile>]", eFlagRequiresTarget), 4213254721Semaste m_option_group (interpreter), 4214254721Semaste m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."), 4215254721Semaste m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true) 4216254721Semaste 4217254721Semaste { 4218254721Semaste m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4219254721Semaste m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4220254721Semaste m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2); 4221254721Semaste m_option_group.Finalize(); 4222254721Semaste } 4223254721Semaste 4224254721Semaste virtual 4225254721Semaste ~CommandObjectTargetSymbolsAdd () 4226254721Semaste { 4227254721Semaste } 4228254721Semaste 4229254721Semaste virtual int 4230254721Semaste HandleArgumentCompletion (Args &input, 4231254721Semaste int &cursor_index, 4232254721Semaste int &cursor_char_position, 4233254721Semaste OptionElementVector &opt_element_vector, 4234254721Semaste int match_start_point, 4235254721Semaste int max_return_elements, 4236254721Semaste bool &word_complete, 4237254721Semaste StringList &matches) 4238254721Semaste { 4239254721Semaste std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 4240254721Semaste completion_str.erase (cursor_char_position); 4241254721Semaste 4242254721Semaste CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 4243254721Semaste CommandCompletions::eDiskFileCompletion, 4244254721Semaste completion_str.c_str(), 4245254721Semaste match_start_point, 4246254721Semaste max_return_elements, 4247254721Semaste NULL, 4248254721Semaste word_complete, 4249254721Semaste matches); 4250254721Semaste return matches.GetSize(); 4251254721Semaste } 4252254721Semaste 4253254721Semaste virtual Options * 4254254721Semaste GetOptions () 4255254721Semaste { 4256254721Semaste return &m_option_group; 4257254721Semaste } 4258254721Semaste 4259254721Semaste 4260254721Semasteprotected: 4261254721Semaste 4262254721Semaste bool 4263254721Semaste AddModuleSymbols (Target *target, 4264254721Semaste ModuleSpec &module_spec, 4265254721Semaste bool &flush, 4266254721Semaste CommandReturnObject &result) 4267254721Semaste { 4268254721Semaste const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec(); 4269254721Semaste if (symbol_fspec) 4270254721Semaste { 4271254721Semaste char symfile_path[PATH_MAX]; 4272254721Semaste symbol_fspec.GetPath (symfile_path, sizeof(symfile_path)); 4273254721Semaste 4274254721Semaste if (!module_spec.GetUUID().IsValid()) 4275254721Semaste { 4276254721Semaste if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec()) 4277254721Semaste module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename(); 4278254721Semaste } 4279254721Semaste // We now have a module that represents a symbol file 4280254721Semaste // that can be used for a module that might exist in the 4281254721Semaste // current target, so we need to find that module in the 4282254721Semaste // target 4283254721Semaste ModuleList matching_module_list; 4284254721Semaste 4285254721Semaste size_t num_matches = 0; 4286254721Semaste // First extract all module specs from the symbol file 4287254721Semaste lldb_private::ModuleSpecList symfile_module_specs; 4288254721Semaste if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs)) 4289254721Semaste { 4290254721Semaste // Now extract the module spec that matches the target architecture 4291254721Semaste ModuleSpec target_arch_module_spec; 4292254721Semaste ModuleSpec symfile_module_spec; 4293254721Semaste target_arch_module_spec.GetArchitecture() = target->GetArchitecture(); 4294254721Semaste if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec)) 4295254721Semaste { 4296254721Semaste // See if it has a UUID? 4297254721Semaste if (symfile_module_spec.GetUUID().IsValid()) 4298254721Semaste { 4299254721Semaste // It has a UUID, look for this UUID in the target modules 4300254721Semaste ModuleSpec symfile_uuid_module_spec; 4301254721Semaste symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4302254721Semaste num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); 4303254721Semaste } 4304254721Semaste } 4305254721Semaste 4306254721Semaste if (num_matches == 0) 4307254721Semaste { 4308254721Semaste // No matches yet, iterate through the module specs to find a UUID value that 4309254721Semaste // we can match up to an image in our target 4310254721Semaste const size_t num_symfile_module_specs = symfile_module_specs.GetSize(); 4311254721Semaste for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i) 4312254721Semaste { 4313254721Semaste if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec)) 4314254721Semaste { 4315254721Semaste if (symfile_module_spec.GetUUID().IsValid()) 4316254721Semaste { 4317254721Semaste // It has a UUID, look for this UUID in the target modules 4318254721Semaste ModuleSpec symfile_uuid_module_spec; 4319254721Semaste symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4320254721Semaste num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); 4321254721Semaste } 4322254721Semaste } 4323254721Semaste } 4324254721Semaste } 4325254721Semaste } 4326254721Semaste 4327254721Semaste // Just try to match up the file by basename if we have no matches at this point 4328254721Semaste if (num_matches == 0) 4329254721Semaste num_matches = target->GetImages().FindModules (module_spec, matching_module_list); 4330254721Semaste 4331254721Semaste while (num_matches == 0) 4332254721Semaste { 4333254721Semaste ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension()); 4334254721Semaste // Empty string returned, lets bail 4335254721Semaste if (!filename_no_extension) 4336254721Semaste break; 4337254721Semaste 4338254721Semaste // Check if there was no extension to strip and the basename is the same 4339254721Semaste if (filename_no_extension == module_spec.GetFileSpec().GetFilename()) 4340254721Semaste break; 4341254721Semaste 4342254721Semaste // Replace basename with one less extension 4343254721Semaste module_spec.GetFileSpec().GetFilename() = filename_no_extension; 4344254721Semaste 4345254721Semaste num_matches = target->GetImages().FindModules (module_spec, matching_module_list); 4346254721Semaste 4347254721Semaste } 4348254721Semaste 4349254721Semaste if (num_matches > 1) 4350254721Semaste { 4351254721Semaste result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path); 4352254721Semaste } 4353254721Semaste else if (num_matches == 1) 4354254721Semaste { 4355254721Semaste ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0)); 4356254721Semaste 4357254721Semaste // The module has not yet created its symbol vendor, we can just 4358254721Semaste // give the existing target module the symfile path to use for 4359254721Semaste // when it decides to create it! 4360254721Semaste module_sp->SetSymbolFileFileSpec (symbol_fspec); 4361254721Semaste 4362254721Semaste SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream()); 4363254721Semaste if (symbol_vendor) 4364254721Semaste { 4365254721Semaste SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 4366254721Semaste 4367254721Semaste if (symbol_file) 4368254721Semaste { 4369254721Semaste ObjectFile *object_file = symbol_file->GetObjectFile(); 4370254721Semaste 4371254721Semaste if (object_file && object_file->GetFileSpec() == symbol_fspec) 4372254721Semaste { 4373254721Semaste // Provide feedback that the symfile has been successfully added. 4374254721Semaste const FileSpec &module_fs = module_sp->GetFileSpec(); 4375254721Semaste result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n", 4376254721Semaste symfile_path, 4377254721Semaste module_fs.GetPath().c_str()); 4378254721Semaste 4379254721Semaste // Let clients know something changed in the module 4380254721Semaste // if it is currently loaded 4381254721Semaste ModuleList module_list; 4382254721Semaste module_list.Append (module_sp); 4383254721Semaste target->SymbolsDidLoad (module_list); 4384254721Semaste 4385254721Semaste // Make sure we load any scripting resources that may be embedded 4386254721Semaste // in the debug info files in case the platform supports that. 4387254721Semaste Error error; 4388254721Semaste StreamString feedback_stream; 4389254721Semaste module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream); 4390254721Semaste if (error.Fail() && error.AsCString()) 4391254721Semaste result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s", 4392254721Semaste module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(), 4393254721Semaste error.AsCString()); 4394254721Semaste else if (feedback_stream.GetSize()) 4395254721Semaste result.AppendWarningWithFormat("%s",feedback_stream.GetData()); 4396254721Semaste 4397254721Semaste flush = true; 4398254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 4399254721Semaste return true; 4400254721Semaste } 4401254721Semaste } 4402254721Semaste } 4403254721Semaste // Clear the symbol file spec if anything went wrong 4404254721Semaste module_sp->SetSymbolFileFileSpec (FileSpec()); 4405254721Semaste } 4406254721Semaste 4407254721Semaste if (module_spec.GetUUID().IsValid()) 4408254721Semaste { 4409254721Semaste StreamString ss_symfile_uuid; 4410254721Semaste module_spec.GetUUID().Dump(&ss_symfile_uuid); 4411254721Semaste result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n", 4412254721Semaste symfile_path, 4413254721Semaste ss_symfile_uuid.GetData(), 4414254721Semaste (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) 4415254721Semaste ? "\n please specify the full path to the symbol file" 4416254721Semaste : ""); 4417254721Semaste } 4418254721Semaste else 4419254721Semaste { 4420254721Semaste result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n", 4421254721Semaste symfile_path, 4422254721Semaste (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) 4423254721Semaste ? "\n please specify the full path to the symbol file" 4424254721Semaste : ""); 4425254721Semaste } 4426254721Semaste } 4427254721Semaste else 4428254721Semaste { 4429254721Semaste result.AppendError ("one or more executable image paths must be specified"); 4430254721Semaste } 4431254721Semaste result.SetStatus (eReturnStatusFailed); 4432254721Semaste return false; 4433254721Semaste } 4434254721Semaste 4435254721Semaste virtual bool 4436254721Semaste DoExecute (Args& args, 4437254721Semaste CommandReturnObject &result) 4438254721Semaste { 4439254721Semaste Target *target = m_exe_ctx.GetTargetPtr(); 4440254721Semaste result.SetStatus (eReturnStatusFailed); 4441254721Semaste bool flush = false; 4442254721Semaste ModuleSpec module_spec; 4443254721Semaste const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet(); 4444254721Semaste const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); 4445254721Semaste const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet(); 4446254721Semaste 4447254721Semaste const size_t argc = args.GetArgumentCount(); 4448254721Semaste if (argc == 0) 4449254721Semaste { 4450254721Semaste if (uuid_option_set || file_option_set || frame_option_set) 4451254721Semaste { 4452254721Semaste bool success = false; 4453254721Semaste bool error_set = false; 4454254721Semaste if (frame_option_set) 4455254721Semaste { 4456254721Semaste Process *process = m_exe_ctx.GetProcessPtr(); 4457254721Semaste if (process) 4458254721Semaste { 4459254721Semaste const StateType process_state = process->GetState(); 4460254721Semaste if (StateIsStoppedState (process_state, true)) 4461254721Semaste { 4462254721Semaste StackFrame *frame = m_exe_ctx.GetFramePtr(); 4463254721Semaste if (frame) 4464254721Semaste { 4465254721Semaste ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp); 4466254721Semaste if (frame_module_sp) 4467254721Semaste { 4468254721Semaste if (frame_module_sp->GetPlatformFileSpec().Exists()) 4469254721Semaste { 4470254721Semaste module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); 4471254721Semaste module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); 4472254721Semaste } 4473254721Semaste module_spec.GetUUID() = frame_module_sp->GetUUID(); 4474254721Semaste success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec(); 4475254721Semaste } 4476254721Semaste else 4477254721Semaste { 4478254721Semaste result.AppendError ("frame has no module"); 4479254721Semaste error_set = true; 4480254721Semaste } 4481254721Semaste } 4482254721Semaste else 4483254721Semaste { 4484254721Semaste result.AppendError ("invalid current frame"); 4485254721Semaste error_set = true; 4486254721Semaste } 4487254721Semaste } 4488254721Semaste else 4489254721Semaste { 4490254721Semaste result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state)); 4491254721Semaste error_set = true; 4492254721Semaste } 4493254721Semaste } 4494254721Semaste else 4495254721Semaste { 4496254721Semaste result.AppendError ("a process must exist in order to use the --frame option"); 4497254721Semaste error_set = true; 4498254721Semaste } 4499254721Semaste } 4500254721Semaste else 4501254721Semaste { 4502254721Semaste if (uuid_option_set) 4503254721Semaste { 4504254721Semaste module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 4505254721Semaste success |= module_spec.GetUUID().IsValid(); 4506254721Semaste } 4507254721Semaste else if (file_option_set) 4508254721Semaste { 4509254721Semaste module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 4510254721Semaste ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); 4511254721Semaste if (module_sp) 4512254721Semaste { 4513254721Semaste module_spec.GetFileSpec() = module_sp->GetFileSpec(); 4514254721Semaste module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); 4515254721Semaste module_spec.GetUUID() = module_sp->GetUUID(); 4516254721Semaste module_spec.GetArchitecture() = module_sp->GetArchitecture(); 4517254721Semaste } 4518254721Semaste else 4519254721Semaste { 4520254721Semaste module_spec.GetArchitecture() = target->GetArchitecture(); 4521254721Semaste } 4522254721Semaste success |= module_spec.GetFileSpec().Exists(); 4523254721Semaste } 4524254721Semaste } 4525254721Semaste 4526254721Semaste if (success) 4527254721Semaste { 4528254721Semaste if (Symbols::DownloadObjectAndSymbolFile (module_spec)) 4529254721Semaste { 4530254721Semaste if (module_spec.GetSymbolFileSpec()) 4531254721Semaste success = AddModuleSymbols (target, module_spec, flush, result); 4532254721Semaste } 4533254721Semaste } 4534254721Semaste 4535254721Semaste if (!success && !error_set) 4536254721Semaste { 4537254721Semaste StreamString error_strm; 4538254721Semaste if (uuid_option_set) 4539254721Semaste { 4540254721Semaste error_strm.PutCString("unable to find debug symbols for UUID "); 4541254721Semaste module_spec.GetUUID().Dump (&error_strm); 4542254721Semaste } 4543254721Semaste else if (file_option_set) 4544254721Semaste { 4545254721Semaste error_strm.PutCString("unable to find debug symbols for the executable file "); 4546254721Semaste error_strm << module_spec.GetFileSpec(); 4547254721Semaste } 4548254721Semaste else if (frame_option_set) 4549254721Semaste { 4550254721Semaste error_strm.PutCString("unable to find debug symbols for the current frame"); 4551254721Semaste } 4552254721Semaste result.AppendError (error_strm.GetData()); 4553254721Semaste } 4554254721Semaste } 4555254721Semaste else 4556254721Semaste { 4557254721Semaste result.AppendError ("one or more symbol file paths must be specified, or options must be specified"); 4558254721Semaste } 4559254721Semaste } 4560254721Semaste else 4561254721Semaste { 4562254721Semaste if (uuid_option_set) 4563254721Semaste { 4564254721Semaste result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments"); 4565254721Semaste } 4566254721Semaste else if (file_option_set) 4567254721Semaste { 4568254721Semaste result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments"); 4569254721Semaste } 4570254721Semaste else if (frame_option_set) 4571254721Semaste { 4572254721Semaste result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments"); 4573254721Semaste } 4574254721Semaste else 4575254721Semaste { 4576254721Semaste PlatformSP platform_sp (target->GetPlatform()); 4577254721Semaste 4578254721Semaste for (size_t i=0; i<argc; ++i) 4579254721Semaste { 4580254721Semaste const char *symfile_path = args.GetArgumentAtIndex(i); 4581254721Semaste if (symfile_path) 4582254721Semaste { 4583254721Semaste module_spec.GetSymbolFileSpec().SetFile(symfile_path, true); 4584254721Semaste if (platform_sp) 4585254721Semaste { 4586254721Semaste FileSpec symfile_spec; 4587254721Semaste if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success()) 4588254721Semaste module_spec.GetSymbolFileSpec() = symfile_spec; 4589254721Semaste } 4590254721Semaste 4591254721Semaste ArchSpec arch; 4592254721Semaste bool symfile_exists = module_spec.GetSymbolFileSpec().Exists(); 4593254721Semaste 4594254721Semaste if (symfile_exists) 4595254721Semaste { 4596254721Semaste if (!AddModuleSymbols (target, module_spec, flush, result)) 4597254721Semaste break; 4598254721Semaste } 4599254721Semaste else 4600254721Semaste { 4601254721Semaste char resolved_symfile_path[PATH_MAX]; 4602254721Semaste if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path))) 4603254721Semaste { 4604254721Semaste if (strcmp (resolved_symfile_path, symfile_path) != 0) 4605254721Semaste { 4606254721Semaste result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path); 4607254721Semaste break; 4608254721Semaste } 4609254721Semaste } 4610254721Semaste result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path); 4611254721Semaste break; 4612254721Semaste } 4613254721Semaste } 4614254721Semaste } 4615254721Semaste } 4616254721Semaste } 4617254721Semaste 4618254721Semaste if (flush) 4619254721Semaste { 4620254721Semaste Process *process = m_exe_ctx.GetProcessPtr(); 4621254721Semaste if (process) 4622254721Semaste process->Flush(); 4623254721Semaste } 4624254721Semaste return result.Succeeded(); 4625254721Semaste } 4626254721Semaste 4627254721Semaste OptionGroupOptions m_option_group; 4628254721Semaste OptionGroupUUID m_uuid_option_group; 4629254721Semaste OptionGroupFile m_file_option; 4630254721Semaste OptionGroupBoolean m_current_frame_option; 4631254721Semaste 4632254721Semaste 4633254721Semaste}; 4634254721Semaste 4635254721Semaste 4636254721Semaste#pragma mark CommandObjectTargetSymbols 4637254721Semaste 4638254721Semaste//------------------------------------------------------------------------- 4639254721Semaste// CommandObjectTargetSymbols 4640254721Semaste//------------------------------------------------------------------------- 4641254721Semaste 4642254721Semasteclass CommandObjectTargetSymbols : public CommandObjectMultiword 4643254721Semaste{ 4644254721Semastepublic: 4645254721Semaste //------------------------------------------------------------------ 4646254721Semaste // Constructors and Destructors 4647254721Semaste //------------------------------------------------------------------ 4648254721Semaste CommandObjectTargetSymbols(CommandInterpreter &interpreter) : 4649254721Semaste CommandObjectMultiword (interpreter, 4650254721Semaste "target symbols", 4651254721Semaste "A set of commands for adding and managing debug symbol files.", 4652254721Semaste "target symbols <sub-command> ...") 4653254721Semaste { 4654254721Semaste LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter))); 4655254721Semaste 4656254721Semaste } 4657254721Semaste virtual 4658254721Semaste ~CommandObjectTargetSymbols() 4659254721Semaste { 4660254721Semaste } 4661254721Semaste 4662254721Semasteprivate: 4663254721Semaste //------------------------------------------------------------------ 4664254721Semaste // For CommandObjectTargetModules only 4665254721Semaste //------------------------------------------------------------------ 4666254721Semaste DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols); 4667254721Semaste}; 4668254721Semaste 4669254721Semaste 4670254721Semaste#pragma mark CommandObjectTargetStopHookAdd 4671254721Semaste 4672254721Semaste//------------------------------------------------------------------------- 4673254721Semaste// CommandObjectTargetStopHookAdd 4674254721Semaste//------------------------------------------------------------------------- 4675254721Semaste 4676254721Semasteclass CommandObjectTargetStopHookAdd : public CommandObjectParsed 4677254721Semaste{ 4678254721Semastepublic: 4679254721Semaste 4680254721Semaste class CommandOptions : public Options 4681254721Semaste { 4682254721Semaste public: 4683254721Semaste CommandOptions (CommandInterpreter &interpreter) : 4684254721Semaste Options(interpreter), 4685254721Semaste m_line_start(0), 4686254721Semaste m_line_end (UINT_MAX), 4687254721Semaste m_func_name_type_mask (eFunctionNameTypeAuto), 4688254721Semaste m_sym_ctx_specified (false), 4689254721Semaste m_thread_specified (false), 4690254721Semaste m_use_one_liner (false), 4691254721Semaste m_one_liner() 4692254721Semaste { 4693254721Semaste } 4694254721Semaste 4695254721Semaste ~CommandOptions () {} 4696254721Semaste 4697254721Semaste const OptionDefinition* 4698254721Semaste GetDefinitions () 4699254721Semaste { 4700254721Semaste return g_option_table; 4701254721Semaste } 4702254721Semaste 4703254721Semaste virtual Error 4704254721Semaste SetOptionValue (uint32_t option_idx, const char *option_arg) 4705254721Semaste { 4706254721Semaste Error error; 4707254721Semaste const int short_option = m_getopt_table[option_idx].val; 4708254721Semaste bool success; 4709254721Semaste 4710254721Semaste switch (short_option) 4711254721Semaste { 4712254721Semaste case 'c': 4713254721Semaste m_class_name = option_arg; 4714254721Semaste m_sym_ctx_specified = true; 4715254721Semaste break; 4716254721Semaste 4717254721Semaste case 'e': 4718254721Semaste m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success); 4719254721Semaste if (!success) 4720254721Semaste { 4721254721Semaste error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg); 4722254721Semaste break; 4723254721Semaste } 4724254721Semaste m_sym_ctx_specified = true; 4725254721Semaste break; 4726254721Semaste 4727254721Semaste case 'l': 4728254721Semaste m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 4729254721Semaste if (!success) 4730254721Semaste { 4731254721Semaste error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg); 4732254721Semaste break; 4733254721Semaste } 4734254721Semaste m_sym_ctx_specified = true; 4735254721Semaste break; 4736254721Semaste 4737254721Semaste case 'i': 4738254721Semaste m_no_inlines = true; 4739254721Semaste break; 4740254721Semaste 4741254721Semaste case 'n': 4742254721Semaste m_function_name = option_arg; 4743254721Semaste m_func_name_type_mask |= eFunctionNameTypeAuto; 4744254721Semaste m_sym_ctx_specified = true; 4745254721Semaste break; 4746254721Semaste 4747254721Semaste case 'f': 4748254721Semaste m_file_name = option_arg; 4749254721Semaste m_sym_ctx_specified = true; 4750254721Semaste break; 4751254721Semaste case 's': 4752254721Semaste m_module_name = option_arg; 4753254721Semaste m_sym_ctx_specified = true; 4754254721Semaste break; 4755254721Semaste case 't' : 4756254721Semaste { 4757254721Semaste m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 4758254721Semaste if (m_thread_id == LLDB_INVALID_THREAD_ID) 4759254721Semaste error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 4760254721Semaste m_thread_specified = true; 4761254721Semaste } 4762254721Semaste break; 4763254721Semaste case 'T': 4764254721Semaste m_thread_name = option_arg; 4765254721Semaste m_thread_specified = true; 4766254721Semaste break; 4767254721Semaste case 'q': 4768254721Semaste m_queue_name = option_arg; 4769254721Semaste m_thread_specified = true; 4770254721Semaste break; 4771254721Semaste case 'x': 4772254721Semaste { 4773254721Semaste m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 4774254721Semaste if (m_thread_id == UINT32_MAX) 4775254721Semaste error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 4776254721Semaste m_thread_specified = true; 4777254721Semaste } 4778254721Semaste break; 4779254721Semaste case 'o': 4780254721Semaste m_use_one_liner = true; 4781254721Semaste m_one_liner = option_arg; 4782254721Semaste break; 4783254721Semaste default: 4784254721Semaste error.SetErrorStringWithFormat ("unrecognized option %c.", short_option); 4785254721Semaste break; 4786254721Semaste } 4787254721Semaste return error; 4788254721Semaste } 4789254721Semaste 4790254721Semaste void 4791254721Semaste OptionParsingStarting () 4792254721Semaste { 4793254721Semaste m_class_name.clear(); 4794254721Semaste m_function_name.clear(); 4795254721Semaste m_line_start = 0; 4796254721Semaste m_line_end = UINT_MAX; 4797254721Semaste m_file_name.clear(); 4798254721Semaste m_module_name.clear(); 4799254721Semaste m_func_name_type_mask = eFunctionNameTypeAuto; 4800254721Semaste m_thread_id = LLDB_INVALID_THREAD_ID; 4801254721Semaste m_thread_index = UINT32_MAX; 4802254721Semaste m_thread_name.clear(); 4803254721Semaste m_queue_name.clear(); 4804254721Semaste 4805254721Semaste m_no_inlines = false; 4806254721Semaste m_sym_ctx_specified = false; 4807254721Semaste m_thread_specified = false; 4808254721Semaste 4809254721Semaste m_use_one_liner = false; 4810254721Semaste m_one_liner.clear(); 4811254721Semaste } 4812254721Semaste 4813254721Semaste 4814254721Semaste static OptionDefinition g_option_table[]; 4815254721Semaste 4816254721Semaste std::string m_class_name; 4817254721Semaste std::string m_function_name; 4818254721Semaste uint32_t m_line_start; 4819254721Semaste uint32_t m_line_end; 4820254721Semaste std::string m_file_name; 4821254721Semaste std::string m_module_name; 4822254721Semaste uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 4823254721Semaste lldb::tid_t m_thread_id; 4824254721Semaste uint32_t m_thread_index; 4825254721Semaste std::string m_thread_name; 4826254721Semaste std::string m_queue_name; 4827254721Semaste bool m_sym_ctx_specified; 4828254721Semaste bool m_no_inlines; 4829254721Semaste bool m_thread_specified; 4830254721Semaste // Instance variables to hold the values for one_liner options. 4831254721Semaste bool m_use_one_liner; 4832254721Semaste std::string m_one_liner; 4833254721Semaste }; 4834254721Semaste 4835254721Semaste Options * 4836254721Semaste GetOptions () 4837254721Semaste { 4838254721Semaste return &m_options; 4839254721Semaste } 4840254721Semaste 4841254721Semaste CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 4842254721Semaste CommandObjectParsed (interpreter, 4843254721Semaste "target stop-hook add ", 4844254721Semaste "Add a hook to be executed when the target stops.", 4845254721Semaste "target stop-hook add"), 4846254721Semaste m_options (interpreter) 4847254721Semaste { 4848254721Semaste } 4849254721Semaste 4850254721Semaste ~CommandObjectTargetStopHookAdd () 4851254721Semaste { 4852254721Semaste } 4853254721Semaste 4854254721Semaste static size_t 4855254721Semaste ReadCommandsCallbackFunction (void *baton, 4856254721Semaste InputReader &reader, 4857254721Semaste lldb::InputReaderAction notification, 4858254721Semaste const char *bytes, 4859254721Semaste size_t bytes_len) 4860254721Semaste { 4861254721Semaste StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 4862254721Semaste Target::StopHook *new_stop_hook = ((Target::StopHook *) baton); 4863254721Semaste static bool got_interrupted; 4864254721Semaste bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 4865254721Semaste 4866254721Semaste switch (notification) 4867254721Semaste { 4868254721Semaste case eInputReaderActivate: 4869254721Semaste if (!batch_mode) 4870254721Semaste { 4871254721Semaste out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end."); 4872254721Semaste if (reader.GetPrompt()) 4873254721Semaste out_stream->Printf ("%s", reader.GetPrompt()); 4874254721Semaste out_stream->Flush(); 4875254721Semaste } 4876254721Semaste got_interrupted = false; 4877254721Semaste break; 4878254721Semaste 4879254721Semaste case eInputReaderDeactivate: 4880254721Semaste break; 4881254721Semaste 4882254721Semaste case eInputReaderReactivate: 4883254721Semaste if (reader.GetPrompt() && !batch_mode) 4884254721Semaste { 4885254721Semaste out_stream->Printf ("%s", reader.GetPrompt()); 4886254721Semaste out_stream->Flush(); 4887254721Semaste } 4888254721Semaste got_interrupted = false; 4889254721Semaste break; 4890254721Semaste 4891254721Semaste case eInputReaderAsynchronousOutputWritten: 4892254721Semaste break; 4893254721Semaste 4894254721Semaste case eInputReaderGotToken: 4895254721Semaste if (bytes && bytes_len && baton) 4896254721Semaste { 4897254721Semaste StringList *commands = new_stop_hook->GetCommandPointer(); 4898254721Semaste if (commands) 4899254721Semaste { 4900254721Semaste commands->AppendString (bytes, bytes_len); 4901254721Semaste } 4902254721Semaste } 4903254721Semaste if (!reader.IsDone() && reader.GetPrompt() && !batch_mode) 4904254721Semaste { 4905254721Semaste out_stream->Printf ("%s", reader.GetPrompt()); 4906254721Semaste out_stream->Flush(); 4907254721Semaste } 4908254721Semaste break; 4909254721Semaste 4910254721Semaste case eInputReaderInterrupt: 4911254721Semaste { 4912254721Semaste // Finish, and cancel the stop hook. 4913254721Semaste new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID()); 4914254721Semaste if (!batch_mode) 4915254721Semaste { 4916254721Semaste out_stream->Printf ("Stop hook cancelled.\n"); 4917254721Semaste out_stream->Flush(); 4918254721Semaste } 4919254721Semaste 4920254721Semaste reader.SetIsDone (true); 4921254721Semaste } 4922254721Semaste got_interrupted = true; 4923254721Semaste break; 4924254721Semaste 4925254721Semaste case eInputReaderEndOfFile: 4926254721Semaste reader.SetIsDone (true); 4927254721Semaste break; 4928254721Semaste 4929254721Semaste case eInputReaderDone: 4930254721Semaste if (!got_interrupted && !batch_mode) 4931254721Semaste { 4932254721Semaste out_stream->Printf ("Stop hook #%" PRIu64 " added.\n", new_stop_hook->GetID()); 4933254721Semaste out_stream->Flush(); 4934254721Semaste } 4935254721Semaste break; 4936254721Semaste } 4937254721Semaste 4938254721Semaste return bytes_len; 4939254721Semaste } 4940254721Semaste 4941254721Semasteprotected: 4942254721Semaste bool 4943254721Semaste DoExecute (Args& command, CommandReturnObject &result) 4944254721Semaste { 4945254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4946254721Semaste if (target) 4947254721Semaste { 4948254721Semaste Target::StopHookSP new_hook_sp; 4949254721Semaste target->AddStopHook (new_hook_sp); 4950254721Semaste 4951254721Semaste // First step, make the specifier. 4952254721Semaste std::unique_ptr<SymbolContextSpecifier> specifier_ap; 4953254721Semaste if (m_options.m_sym_ctx_specified) 4954254721Semaste { 4955254721Semaste specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 4956254721Semaste 4957254721Semaste if (!m_options.m_module_name.empty()) 4958254721Semaste { 4959254721Semaste specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 4960254721Semaste } 4961254721Semaste 4962254721Semaste if (!m_options.m_class_name.empty()) 4963254721Semaste { 4964254721Semaste specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 4965254721Semaste } 4966254721Semaste 4967254721Semaste if (!m_options.m_file_name.empty()) 4968254721Semaste { 4969254721Semaste specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 4970254721Semaste } 4971254721Semaste 4972254721Semaste if (m_options.m_line_start != 0) 4973254721Semaste { 4974254721Semaste specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 4975254721Semaste } 4976254721Semaste 4977254721Semaste if (m_options.m_line_end != UINT_MAX) 4978254721Semaste { 4979254721Semaste specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 4980254721Semaste } 4981254721Semaste 4982254721Semaste if (!m_options.m_function_name.empty()) 4983254721Semaste { 4984254721Semaste specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 4985254721Semaste } 4986254721Semaste } 4987254721Semaste 4988254721Semaste if (specifier_ap.get()) 4989254721Semaste new_hook_sp->SetSpecifier (specifier_ap.release()); 4990254721Semaste 4991254721Semaste // Next see if any of the thread options have been entered: 4992254721Semaste 4993254721Semaste if (m_options.m_thread_specified) 4994254721Semaste { 4995254721Semaste ThreadSpec *thread_spec = new ThreadSpec(); 4996254721Semaste 4997254721Semaste if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 4998254721Semaste { 4999254721Semaste thread_spec->SetTID (m_options.m_thread_id); 5000254721Semaste } 5001254721Semaste 5002254721Semaste if (m_options.m_thread_index != UINT32_MAX) 5003254721Semaste thread_spec->SetIndex (m_options.m_thread_index); 5004254721Semaste 5005254721Semaste if (!m_options.m_thread_name.empty()) 5006254721Semaste thread_spec->SetName (m_options.m_thread_name.c_str()); 5007254721Semaste 5008254721Semaste if (!m_options.m_queue_name.empty()) 5009254721Semaste thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 5010254721Semaste 5011254721Semaste new_hook_sp->SetThreadSpecifier (thread_spec); 5012254721Semaste 5013254721Semaste } 5014254721Semaste if (m_options.m_use_one_liner) 5015254721Semaste { 5016254721Semaste // Use one-liner. 5017254721Semaste new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 5018254721Semaste result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID()); 5019254721Semaste } 5020254721Semaste else 5021254721Semaste { 5022254721Semaste // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into 5023254721Semaste // the new stop hook's command string. 5024254721Semaste InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 5025254721Semaste if (!reader_sp) 5026254721Semaste { 5027254721Semaste result.AppendError("out of memory\n"); 5028254721Semaste result.SetStatus (eReturnStatusFailed); 5029254721Semaste target->RemoveStopHookByID (new_hook_sp->GetID()); 5030254721Semaste return false; 5031254721Semaste } 5032254721Semaste 5033254721Semaste Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction, 5034254721Semaste new_hook_sp.get(), // baton 5035254721Semaste eInputReaderGranularityLine, // token size, to pass to callback function 5036254721Semaste "DONE", // end token 5037254721Semaste "> ", // prompt 5038254721Semaste true)); // echo input 5039254721Semaste if (!err.Success()) 5040254721Semaste { 5041254721Semaste result.AppendError (err.AsCString()); 5042254721Semaste result.SetStatus (eReturnStatusFailed); 5043254721Semaste target->RemoveStopHookByID (new_hook_sp->GetID()); 5044254721Semaste return false; 5045254721Semaste } 5046254721Semaste m_interpreter.GetDebugger().PushInputReader (reader_sp); 5047254721Semaste } 5048254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 5049254721Semaste } 5050254721Semaste else 5051254721Semaste { 5052254721Semaste result.AppendError ("invalid target\n"); 5053254721Semaste result.SetStatus (eReturnStatusFailed); 5054254721Semaste } 5055254721Semaste 5056254721Semaste return result.Succeeded(); 5057254721Semaste } 5058254721Semasteprivate: 5059254721Semaste CommandOptions m_options; 5060254721Semaste}; 5061254721Semaste 5062254721SemasteOptionDefinition 5063254721SemasteCommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 5064254721Semaste{ 5065254721Semaste { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, 0, eArgTypeOneLiner, 5066254721Semaste "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 5067254721Semaste { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 5068254721Semaste "Set the module within which the stop-hook is to be run."}, 5069254721Semaste { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex, 5070254721Semaste "The stop hook is run only for the thread whose index matches this argument."}, 5071254721Semaste { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID, 5072254721Semaste "The stop hook is run only for the thread whose TID matches this argument."}, 5073254721Semaste { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName, 5074254721Semaste "The stop hook is run only for the thread whose thread name matches this argument."}, 5075254721Semaste { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName, 5076254721Semaste "The stop hook is run only for threads in the queue whose name is given by this argument."}, 5077254721Semaste { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 5078254721Semaste "Specify the source file within which the stop-hook is to be run." }, 5079254721Semaste { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 5080254721Semaste "Set the start of the line range for which the stop-hook is to be run."}, 5081254721Semaste { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum, 5082254721Semaste "Set the end of the line range for which the stop-hook is to be run."}, 5083254721Semaste { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, 0, eArgTypeClassName, 5084254721Semaste "Specify the class within which the stop-hook is to be run." }, 5085254721Semaste { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 5086254721Semaste "Set the function name within which the stop hook will be run." }, 5087254721Semaste { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 5088254721Semaste}; 5089254721Semaste 5090254721Semaste#pragma mark CommandObjectTargetStopHookDelete 5091254721Semaste 5092254721Semaste//------------------------------------------------------------------------- 5093254721Semaste// CommandObjectTargetStopHookDelete 5094254721Semaste//------------------------------------------------------------------------- 5095254721Semaste 5096254721Semasteclass CommandObjectTargetStopHookDelete : public CommandObjectParsed 5097254721Semaste{ 5098254721Semastepublic: 5099254721Semaste 5100254721Semaste CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 5101254721Semaste CommandObjectParsed (interpreter, 5102254721Semaste "target stop-hook delete", 5103254721Semaste "Delete a stop-hook.", 5104254721Semaste "target stop-hook delete [<idx>]") 5105254721Semaste { 5106254721Semaste } 5107254721Semaste 5108254721Semaste ~CommandObjectTargetStopHookDelete () 5109254721Semaste { 5110254721Semaste } 5111254721Semaste 5112254721Semasteprotected: 5113254721Semaste bool 5114254721Semaste DoExecute (Args& command, CommandReturnObject &result) 5115254721Semaste { 5116254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5117254721Semaste if (target) 5118254721Semaste { 5119254721Semaste // FIXME: see if we can use the breakpoint id style parser? 5120254721Semaste size_t num_args = command.GetArgumentCount(); 5121254721Semaste if (num_args == 0) 5122254721Semaste { 5123254721Semaste if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 5124254721Semaste { 5125254721Semaste result.SetStatus (eReturnStatusFailed); 5126254721Semaste return false; 5127254721Semaste } 5128254721Semaste else 5129254721Semaste { 5130254721Semaste target->RemoveAllStopHooks(); 5131254721Semaste } 5132254721Semaste } 5133254721Semaste else 5134254721Semaste { 5135254721Semaste bool success; 5136254721Semaste for (size_t i = 0; i < num_args; i++) 5137254721Semaste { 5138254721Semaste lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 5139254721Semaste if (!success) 5140254721Semaste { 5141254721Semaste result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5142254721Semaste result.SetStatus(eReturnStatusFailed); 5143254721Semaste return false; 5144254721Semaste } 5145254721Semaste success = target->RemoveStopHookByID (user_id); 5146254721Semaste if (!success) 5147254721Semaste { 5148254721Semaste result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5149254721Semaste result.SetStatus(eReturnStatusFailed); 5150254721Semaste return false; 5151254721Semaste } 5152254721Semaste } 5153254721Semaste } 5154254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 5155254721Semaste } 5156254721Semaste else 5157254721Semaste { 5158254721Semaste result.AppendError ("invalid target\n"); 5159254721Semaste result.SetStatus (eReturnStatusFailed); 5160254721Semaste } 5161254721Semaste 5162254721Semaste return result.Succeeded(); 5163254721Semaste } 5164254721Semaste}; 5165254721Semaste#pragma mark CommandObjectTargetStopHookEnableDisable 5166254721Semaste 5167254721Semaste//------------------------------------------------------------------------- 5168254721Semaste// CommandObjectTargetStopHookEnableDisable 5169254721Semaste//------------------------------------------------------------------------- 5170254721Semaste 5171254721Semasteclass CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed 5172254721Semaste{ 5173254721Semastepublic: 5174254721Semaste 5175254721Semaste CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 5176254721Semaste CommandObjectParsed (interpreter, 5177254721Semaste name, 5178254721Semaste help, 5179254721Semaste syntax), 5180254721Semaste m_enable (enable) 5181254721Semaste { 5182254721Semaste } 5183254721Semaste 5184254721Semaste ~CommandObjectTargetStopHookEnableDisable () 5185254721Semaste { 5186254721Semaste } 5187254721Semaste 5188254721Semasteprotected: 5189254721Semaste bool 5190254721Semaste DoExecute (Args& command, CommandReturnObject &result) 5191254721Semaste { 5192254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5193254721Semaste if (target) 5194254721Semaste { 5195254721Semaste // FIXME: see if we can use the breakpoint id style parser? 5196254721Semaste size_t num_args = command.GetArgumentCount(); 5197254721Semaste bool success; 5198254721Semaste 5199254721Semaste if (num_args == 0) 5200254721Semaste { 5201254721Semaste target->SetAllStopHooksActiveState (m_enable); 5202254721Semaste } 5203254721Semaste else 5204254721Semaste { 5205254721Semaste for (size_t i = 0; i < num_args; i++) 5206254721Semaste { 5207254721Semaste lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 5208254721Semaste if (!success) 5209254721Semaste { 5210254721Semaste result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5211254721Semaste result.SetStatus(eReturnStatusFailed); 5212254721Semaste return false; 5213254721Semaste } 5214254721Semaste success = target->SetStopHookActiveStateByID (user_id, m_enable); 5215254721Semaste if (!success) 5216254721Semaste { 5217254721Semaste result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5218254721Semaste result.SetStatus(eReturnStatusFailed); 5219254721Semaste return false; 5220254721Semaste } 5221254721Semaste } 5222254721Semaste } 5223254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 5224254721Semaste } 5225254721Semaste else 5226254721Semaste { 5227254721Semaste result.AppendError ("invalid target\n"); 5228254721Semaste result.SetStatus (eReturnStatusFailed); 5229254721Semaste } 5230254721Semaste return result.Succeeded(); 5231254721Semaste } 5232254721Semasteprivate: 5233254721Semaste bool m_enable; 5234254721Semaste}; 5235254721Semaste 5236254721Semaste#pragma mark CommandObjectTargetStopHookList 5237254721Semaste 5238254721Semaste//------------------------------------------------------------------------- 5239254721Semaste// CommandObjectTargetStopHookList 5240254721Semaste//------------------------------------------------------------------------- 5241254721Semaste 5242254721Semasteclass CommandObjectTargetStopHookList : public CommandObjectParsed 5243254721Semaste{ 5244254721Semastepublic: 5245254721Semaste 5246254721Semaste CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 5247254721Semaste CommandObjectParsed (interpreter, 5248254721Semaste "target stop-hook list", 5249254721Semaste "List all stop-hooks.", 5250254721Semaste "target stop-hook list [<type>]") 5251254721Semaste { 5252254721Semaste } 5253254721Semaste 5254254721Semaste ~CommandObjectTargetStopHookList () 5255254721Semaste { 5256254721Semaste } 5257254721Semaste 5258254721Semasteprotected: 5259254721Semaste bool 5260254721Semaste DoExecute (Args& command, CommandReturnObject &result) 5261254721Semaste { 5262254721Semaste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5263254721Semaste if (!target) 5264254721Semaste { 5265254721Semaste result.AppendError ("invalid target\n"); 5266254721Semaste result.SetStatus (eReturnStatusFailed); 5267254721Semaste return result.Succeeded(); 5268254721Semaste } 5269254721Semaste 5270254721Semaste size_t num_hooks = target->GetNumStopHooks (); 5271254721Semaste if (num_hooks == 0) 5272254721Semaste { 5273254721Semaste result.GetOutputStream().PutCString ("No stop hooks.\n"); 5274254721Semaste } 5275254721Semaste else 5276254721Semaste { 5277254721Semaste for (size_t i = 0; i < num_hooks; i++) 5278254721Semaste { 5279254721Semaste Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 5280254721Semaste if (i > 0) 5281254721Semaste result.GetOutputStream().PutCString ("\n"); 5282254721Semaste this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 5283254721Semaste } 5284254721Semaste } 5285254721Semaste result.SetStatus (eReturnStatusSuccessFinishResult); 5286254721Semaste return result.Succeeded(); 5287254721Semaste } 5288254721Semaste}; 5289254721Semaste 5290254721Semaste#pragma mark CommandObjectMultiwordTargetStopHooks 5291254721Semaste//------------------------------------------------------------------------- 5292254721Semaste// CommandObjectMultiwordTargetStopHooks 5293254721Semaste//------------------------------------------------------------------------- 5294254721Semaste 5295254721Semasteclass CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 5296254721Semaste{ 5297254721Semastepublic: 5298254721Semaste 5299254721Semaste CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 5300254721Semaste CommandObjectMultiword (interpreter, 5301254721Semaste "target stop-hook", 5302254721Semaste "A set of commands for operating on debugger target stop-hooks.", 5303254721Semaste "target stop-hook <subcommand> [<subcommand-options>]") 5304254721Semaste { 5305254721Semaste LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 5306254721Semaste LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 5307254721Semaste LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 5308254721Semaste false, 5309254721Semaste "target stop-hook disable [<id>]", 5310254721Semaste "Disable a stop-hook.", 5311254721Semaste "target stop-hook disable"))); 5312254721Semaste LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 5313254721Semaste true, 5314254721Semaste "target stop-hook enable [<id>]", 5315254721Semaste "Enable a stop-hook.", 5316254721Semaste "target stop-hook enable"))); 5317254721Semaste LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 5318254721Semaste } 5319254721Semaste 5320254721Semaste ~CommandObjectMultiwordTargetStopHooks() 5321254721Semaste { 5322254721Semaste } 5323254721Semaste}; 5324254721Semaste 5325254721Semaste 5326254721Semaste 5327254721Semaste#pragma mark CommandObjectMultiwordTarget 5328254721Semaste 5329254721Semaste//------------------------------------------------------------------------- 5330254721Semaste// CommandObjectMultiwordTarget 5331254721Semaste//------------------------------------------------------------------------- 5332254721Semaste 5333254721SemasteCommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 5334254721Semaste CommandObjectMultiword (interpreter, 5335254721Semaste "target", 5336254721Semaste "A set of commands for operating on debugger targets.", 5337254721Semaste "target <subcommand> [<subcommand-options>]") 5338254721Semaste{ 5339254721Semaste 5340254721Semaste LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 5341254721Semaste LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 5342254721Semaste LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 5343254721Semaste LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 5344254721Semaste LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 5345254721Semaste LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 5346254721Semaste LoadSubCommand ("symbols", CommandObjectSP (new CommandObjectTargetSymbols (interpreter))); 5347254721Semaste LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 5348254721Semaste} 5349254721Semaste 5350254721SemasteCommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 5351254721Semaste{ 5352254721Semaste} 5353254721Semaste 5354254721Semaste 5355