CommandObjectTarget.cpp revision 43b014aa33e20e61790e16ed69a2c57aae2fbc6e
1//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "CommandObjectTarget.h" 11 12// C Includes 13#include <errno.h> 14#include <sys/errno.h> 15// C++ Includes 16// Other libraries and framework includes 17// Project includes 18#include "lldb/Interpreter/Args.h" 19#include "lldb/Core/Debugger.h" 20#include "lldb/Core/Timer.h" 21#include "lldb/Core/Debugger.h" 22#include "lldb/Interpreter/CommandInterpreter.h" 23#include "lldb/Interpreter/CommandReturnObject.h" 24#include "lldb/Target/Process.h" 25#include "lldb/Target/StackFrame.h" 26#include "lldb/Target/Thread.h" 27 28using namespace lldb; 29using namespace lldb_private; 30 31#pragma mark CommandObjectTargetImageSearchPaths 32 33class CommandObjectTargetImageSearchPathsAdd : public CommandObject 34{ 35public: 36 37 CommandObjectTargetImageSearchPathsAdd (CommandInterpreter &interpreter) : 38 CommandObject (interpreter, 39 "target image-search-paths add", 40 "Add new image search paths substitution pairs to the current target.", 41 NULL) 42 { 43 CommandArgumentEntry arg; 44 CommandArgumentData old_prefix_arg; 45 CommandArgumentData new_prefix_arg; 46 47 // Define the first variant of this arg pair. 48 old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 49 old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 50 51 // Define the first variant of this arg pair. 52 new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 53 new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 54 55 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 56 // must always occur together, they are treated as two variants of one argument rather than two independent 57 // arguments. Push them both into the first argument position for m_arguments... 58 59 arg.push_back (old_prefix_arg); 60 arg.push_back (new_prefix_arg); 61 62 m_arguments.push_back (arg); 63 } 64 65 ~CommandObjectTargetImageSearchPathsAdd () 66 { 67 } 68 69 bool 70 Execute (Args& command, 71 CommandReturnObject &result) 72 { 73 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 74 if (target) 75 { 76 uint32_t argc = command.GetArgumentCount(); 77 if (argc & 1) 78 { 79 result.AppendError ("add requires an even number of arguments"); 80 result.SetStatus (eReturnStatusFailed); 81 } 82 else 83 { 84 for (uint32_t i=0; i<argc; i+=2) 85 { 86 const char *from = command.GetArgumentAtIndex(i); 87 const char *to = command.GetArgumentAtIndex(i+1); 88 89 if (from[0] && to[0]) 90 { 91 bool last_pair = ((argc - i) == 2); 92 target->GetImageSearchPathList().Append (ConstString(from), 93 ConstString(to), 94 last_pair); // Notify if this is the last pair 95 } 96 else 97 { 98 if (from[0]) 99 result.AppendError ("<path-prefix> can't be empty"); 100 else 101 result.AppendError ("<new-path-prefix> can't be empty"); 102 result.SetStatus (eReturnStatusFailed); 103 } 104 } 105 } 106 } 107 else 108 { 109 result.AppendError ("invalid target"); 110 result.SetStatus (eReturnStatusFailed); 111 } 112 return result.Succeeded(); 113 } 114}; 115 116class CommandObjectTargetImageSearchPathsClear : public CommandObject 117{ 118public: 119 120 CommandObjectTargetImageSearchPathsClear (CommandInterpreter &interpreter) : 121 CommandObject (interpreter, 122 "target image-search-paths clear", 123 "Clear all current image search path substitution pairs from the current target.", 124 "target image-search-paths clear") 125 { 126 } 127 128 ~CommandObjectTargetImageSearchPathsClear () 129 { 130 } 131 132 bool 133 Execute (Args& command, 134 CommandReturnObject &result) 135 { 136 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 137 if (target) 138 { 139 bool notify = true; 140 target->GetImageSearchPathList().Clear(notify); 141 } 142 else 143 { 144 result.AppendError ("invalid target"); 145 result.SetStatus (eReturnStatusFailed); 146 } 147 return result.Succeeded(); 148 } 149}; 150 151class CommandObjectTargetImageSearchPathsInsert : public CommandObject 152{ 153public: 154 155 CommandObjectTargetImageSearchPathsInsert (CommandInterpreter &interpreter) : 156 CommandObject (interpreter, 157 "target image-search-paths insert", 158 "Insert a new image search path substitution pair into the current target at the specified index.", 159 NULL) 160 { 161 CommandArgumentEntry arg1; 162 CommandArgumentEntry arg2; 163 CommandArgumentData index_arg; 164 CommandArgumentData old_prefix_arg; 165 CommandArgumentData new_prefix_arg; 166 167 // Define the first and only variant of this arg. 168 index_arg.arg_type = eArgTypeIndex; 169 index_arg.arg_repetition = eArgRepeatPlain; 170 171 // Put the one and only variant into the first arg for m_arguments: 172 arg1.push_back (index_arg); 173 174 // Define the first variant of this arg pair. 175 old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 176 old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 177 178 // Define the first variant of this arg pair. 179 new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 180 new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 181 182 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 183 // must always occur together, they are treated as two variants of one argument rather than two independent 184 // arguments. Push them both into the same argument position for m_arguments... 185 186 arg2.push_back (old_prefix_arg); 187 arg2.push_back (new_prefix_arg); 188 189 // Add arguments to m_arguments. 190 m_arguments.push_back (arg1); 191 m_arguments.push_back (arg2); 192 } 193 194 ~CommandObjectTargetImageSearchPathsInsert () 195 { 196 } 197 198 bool 199 Execute (Args& command, 200 CommandReturnObject &result) 201 { 202 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 203 if (target) 204 { 205 uint32_t argc = command.GetArgumentCount(); 206 // check for at least 3 arguments and an odd nubmer of parameters 207 if (argc >= 3 && argc & 1) 208 { 209 bool success = false; 210 211 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success); 212 213 if (!success) 214 { 215 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0)); 216 result.SetStatus (eReturnStatusFailed); 217 return result.Succeeded(); 218 } 219 220 // shift off the index 221 command.Shift(); 222 argc = command.GetArgumentCount(); 223 224 for (uint32_t i=0; i<argc; i+=2, ++insert_idx) 225 { 226 const char *from = command.GetArgumentAtIndex(i); 227 const char *to = command.GetArgumentAtIndex(i+1); 228 229 if (from[0] && to[0]) 230 { 231 bool last_pair = ((argc - i) == 2); 232 target->GetImageSearchPathList().Insert (ConstString(from), 233 ConstString(to), 234 insert_idx, 235 last_pair); 236 } 237 else 238 { 239 if (from[0]) 240 result.AppendError ("<path-prefix> can't be empty"); 241 else 242 result.AppendError ("<new-path-prefix> can't be empty"); 243 result.SetStatus (eReturnStatusFailed); 244 return false; 245 } 246 } 247 } 248 else 249 { 250 result.AppendError ("insert requires at least three arguments"); 251 result.SetStatus (eReturnStatusFailed); 252 return result.Succeeded(); 253 } 254 255 } 256 else 257 { 258 result.AppendError ("invalid target"); 259 result.SetStatus (eReturnStatusFailed); 260 } 261 return result.Succeeded(); 262 } 263}; 264 265class CommandObjectTargetImageSearchPathsList : public CommandObject 266{ 267public: 268 269 CommandObjectTargetImageSearchPathsList (CommandInterpreter &interpreter) : 270 CommandObject (interpreter, 271 "target image-search-paths list", 272 "List all current image search path substitution pairs in the current target.", 273 "target image-search-paths list") 274 { 275 } 276 277 ~CommandObjectTargetImageSearchPathsList () 278 { 279 } 280 281 bool 282 Execute (Args& command, 283 CommandReturnObject &result) 284 { 285 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 286 if (target) 287 { 288 if (command.GetArgumentCount() != 0) 289 { 290 result.AppendError ("list takes no arguments"); 291 result.SetStatus (eReturnStatusFailed); 292 return result.Succeeded(); 293 } 294 295 target->GetImageSearchPathList().Dump(&result.GetOutputStream()); 296 } 297 else 298 { 299 result.AppendError ("invalid target"); 300 result.SetStatus (eReturnStatusFailed); 301 } 302 return result.Succeeded(); 303 } 304}; 305 306class CommandObjectTargetImageSearchPathsQuery : public CommandObject 307{ 308public: 309 310 CommandObjectTargetImageSearchPathsQuery (CommandInterpreter &interpreter) : 311 CommandObject (interpreter, 312 "target image-search-paths query", 313 "Transform a path using the first applicable image search path.", 314 NULL) 315 { 316 CommandArgumentEntry arg; 317 CommandArgumentData path_arg; 318 319 // Define the first (and only) variant of this arg. 320 path_arg.arg_type = eArgTypePath; 321 path_arg.arg_repetition = eArgRepeatPlain; 322 323 // There is only one variant this argument could be; put it into the argument entry. 324 arg.push_back (path_arg); 325 326 // Push the data for the first argument into the m_arguments vector. 327 m_arguments.push_back (arg); 328 } 329 330 ~CommandObjectTargetImageSearchPathsQuery () 331 { 332 } 333 334 bool 335 Execute (Args& command, 336 CommandReturnObject &result) 337 { 338 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 339 if (target) 340 { 341 if (command.GetArgumentCount() != 1) 342 { 343 result.AppendError ("query requires one argument"); 344 result.SetStatus (eReturnStatusFailed); 345 return result.Succeeded(); 346 } 347 348 ConstString orig(command.GetArgumentAtIndex(0)); 349 ConstString transformed; 350 if (target->GetImageSearchPathList().RemapPath(orig, transformed)) 351 result.GetOutputStream().Printf("%s\n", transformed.GetCString()); 352 else 353 result.GetOutputStream().Printf("%s\n", orig.GetCString()); 354 } 355 else 356 { 357 result.AppendError ("invalid target"); 358 result.SetStatus (eReturnStatusFailed); 359 } 360 return result.Succeeded(); 361 } 362}; 363 364// TODO: implement the target select later when we start doing multiple targets 365//#pragma mark CommandObjectTargetSelect 366// 367////------------------------------------------------------------------------- 368//// CommandObjectTargetSelect 369////------------------------------------------------------------------------- 370// 371//class CommandObjectTargetSelect : public CommandObject 372//{ 373//public: 374// 375// CommandObjectTargetSelect () : 376// CommandObject (interpreter, 377// frame select", 378// "Select the current frame by index in the current thread.", 379// "frame select <frame-index>") 380// { 381// } 382// 383// ~CommandObjectTargetSelect () 384// { 385// } 386// 387// bool 388// Execute (Args& command, 389// Debugger *context, 390// CommandInterpreter &m_interpreter, 391// CommandReturnObject &result) 392// { 393// ExecutionContext exe_ctx (context->GetExecutionContext()); 394// if (exe_ctx.thread) 395// { 396// if (command.GetArgumentCount() == 1) 397// { 398// const char *frame_idx_cstr = command.GetArgumentAtIndex(0); 399// 400// const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount(); 401// const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0); 402// if (frame_idx < num_frames) 403// { 404// exe_ctx.thread->SetSelectedFrameByIndex (frame_idx); 405// exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get(); 406// 407// if (exe_ctx.frame) 408// { 409// if (DisplayFrameForExecutionContext (exe_ctx.thread, 410// exe_ctx.frame, 411// m_interpreter, 412// result.GetOutputStream(), 413// true, 414// true, 415// 3, 416// 3)) 417// { 418// result.SetStatus (eReturnStatusSuccessFinishResult); 419// return result.Succeeded(); 420// } 421// } 422// } 423// if (frame_idx == UINT32_MAX) 424// result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr); 425// else 426// result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx); 427// } 428// else 429// { 430// result.AppendError ("invalid arguments"); 431// result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str()); 432// } 433// } 434// else 435// { 436// result.AppendError ("no current thread"); 437// } 438// result.SetStatus (eReturnStatusFailed); 439// return false; 440// } 441//}; 442 443 444#pragma mark CommandObjectMultiwordTarget 445 446//------------------------------------------------------------------------- 447// CommandObjectMultiwordImageSearchPaths 448//------------------------------------------------------------------------- 449 450class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword 451{ 452public: 453 454 CommandObjectMultiwordImageSearchPaths (CommandInterpreter &interpreter) : 455 CommandObjectMultiword (interpreter, 456 "target image-search-paths", 457 "A set of commands for operating on debugger target image search paths.", 458 "target image-search-paths <subcommand> [<subcommand-options>]") 459 { 460 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetImageSearchPathsAdd (interpreter))); 461 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetImageSearchPathsClear (interpreter))); 462 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetImageSearchPathsInsert (interpreter))); 463 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetImageSearchPathsList (interpreter))); 464 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetImageSearchPathsQuery (interpreter))); 465 } 466 467 ~CommandObjectMultiwordImageSearchPaths() 468 { 469 } 470}; 471 472 473#pragma mark CommandObjectMultiwordTarget 474 475//------------------------------------------------------------------------- 476// CommandObjectMultiwordTarget 477//------------------------------------------------------------------------- 478 479CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 480 CommandObjectMultiword (interpreter, 481 "target", 482 "A set of commands for operating on debugger targets.", 483 "target <subcommand> [<subcommand-options>]") 484{ 485 LoadSubCommand ("image-search-paths", CommandObjectSP (new CommandObjectMultiwordImageSearchPaths (interpreter))); 486} 487 488CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 489{ 490} 491 492