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