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 28 using namespace lldb; 29 using namespace lldb_private; 30 31 #pragma mark CommandObjectTargetImageSearchPaths 32 33 class CommandObjectTargetImageSearchPathsAdd : public CommandObject 34 { 35 public: 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 116 class CommandObjectTargetImageSearchPathsClear : public CommandObject 117 { 118 public: 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 151 class CommandObjectTargetImageSearchPathsInsert : public CommandObject 152 { 153 public: 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 265 class CommandObjectTargetImageSearchPathsList : public CommandObject 266 { 267 public: 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 306 class CommandObjectTargetImageSearchPathsQuery : public CommandObject 307 { 308 public: 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 450 class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword 451 { 452 public: 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 479 CommandObjectMultiwordTarget::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 488 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 489 { 490 } 491 492