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 () : 38 CommandObject ("target image-search-paths add", 39 "Add new image search paths substitution pairs to the current target.", 40 "target image-search-paths add <path-prefix> <new-path-prefix> [<path-prefix> <new-path-prefix>] ...") 41 { 42 } 43 44 ~CommandObjectTargetImageSearchPathsAdd () 45 { 46 } 47 48 bool 49 Execute (CommandInterpreter &interpreter, 50 Args& command, 51 CommandReturnObject &result) 52 { 53 Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); 54 if (target) 55 { 56 uint32_t argc = command.GetArgumentCount(); 57 if (argc & 1) 58 { 59 result.AppendError ("add requires an even number of arguments"); 60 result.SetStatus (eReturnStatusFailed); 61 } 62 else 63 { 64 for (uint32_t i=0; i<argc; i+=2) 65 { 66 const char *from = command.GetArgumentAtIndex(i); 67 const char *to = command.GetArgumentAtIndex(i+1); 68 69 if (from[0] && to[0]) 70 { 71 bool last_pair = ((argc - i) == 2); 72 target->GetImageSearchPathList().Append (ConstString(from), 73 ConstString(to), 74 last_pair); // Notify if this is the last pair 75 } 76 else 77 { 78 if (from[0]) 79 result.AppendError ("<path-prefix> can't be empty"); 80 else 81 result.AppendError ("<new-path-prefix> can't be empty"); 82 result.SetStatus (eReturnStatusFailed); 83 } 84 } 85 } 86 } 87 else 88 { 89 result.AppendError ("invalid target"); 90 result.SetStatus (eReturnStatusFailed); 91 } 92 return result.Succeeded(); 93 } 94 }; 95 96 class CommandObjectTargetImageSearchPathsClear : public CommandObject 97 { 98 public: 99 100 CommandObjectTargetImageSearchPathsClear () : 101 CommandObject ("target image-search-paths clear", 102 "Clears all current image search paths substitution pairs from the current target.", 103 "target image-search-paths clear") 104 { 105 } 106 107 ~CommandObjectTargetImageSearchPathsClear () 108 { 109 } 110 111 bool 112 Execute (CommandInterpreter &interpreter, 113 Args& command, 114 CommandReturnObject &result) 115 { 116 Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); 117 if (target) 118 { 119 bool notify = true; 120 target->GetImageSearchPathList().Clear(notify); 121 } 122 else 123 { 124 result.AppendError ("invalid target"); 125 result.SetStatus (eReturnStatusFailed); 126 } 127 return result.Succeeded(); 128 } 129 }; 130 131 class CommandObjectTargetImageSearchPathsInsert : public CommandObject 132 { 133 public: 134 135 CommandObjectTargetImageSearchPathsInsert () : 136 CommandObject ("target image-search-paths insert", 137 "Inserts a new image search paths substitution pair to the current target at the specified index.", 138 "target image-search-paths insert <index> <path-prefix> <new-path-prefix> [<path-prefix> <new-path-prefix>] ...") 139 { 140 } 141 142 ~CommandObjectTargetImageSearchPathsInsert () 143 { 144 } 145 146 bool 147 Execute (CommandInterpreter &interpreter, 148 Args& command, 149 CommandReturnObject &result) 150 { 151 Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); 152 if (target) 153 { 154 uint32_t argc = command.GetArgumentCount(); 155 // check for at least 3 arguments and an odd nubmer of parameters 156 if (argc >= 3 && argc & 1) 157 { 158 bool success = false; 159 160 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success); 161 162 if (!success) 163 { 164 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0)); 165 result.SetStatus (eReturnStatusFailed); 166 return result.Succeeded(); 167 } 168 169 // shift off the index 170 command.Shift(); 171 argc = command.GetArgumentCount(); 172 173 for (uint32_t i=0; i<argc; i+=2, ++insert_idx) 174 { 175 const char *from = command.GetArgumentAtIndex(i); 176 const char *to = command.GetArgumentAtIndex(i+1); 177 178 if (from[0] && to[0]) 179 { 180 bool last_pair = ((argc - i) == 2); 181 target->GetImageSearchPathList().Insert (ConstString(from), 182 ConstString(to), 183 insert_idx, 184 last_pair); 185 } 186 else 187 { 188 if (from[0]) 189 result.AppendError ("<path-prefix> can't be empty"); 190 else 191 result.AppendError ("<new-path-prefix> can't be empty"); 192 result.SetStatus (eReturnStatusFailed); 193 return false; 194 } 195 } 196 } 197 else 198 { 199 result.AppendError ("insert requires at least three arguments"); 200 result.SetStatus (eReturnStatusFailed); 201 return result.Succeeded(); 202 } 203 204 } 205 else 206 { 207 result.AppendError ("invalid target"); 208 result.SetStatus (eReturnStatusFailed); 209 } 210 return result.Succeeded(); 211 } 212 }; 213 214 class CommandObjectTargetImageSearchPathsList : public CommandObject 215 { 216 public: 217 218 CommandObjectTargetImageSearchPathsList () : 219 CommandObject ("target image-search-paths list", 220 "Lists all current image search paths substitution pairs in the current target.", 221 "target image-search-paths list") 222 { 223 } 224 225 ~CommandObjectTargetImageSearchPathsList () 226 { 227 } 228 229 bool 230 Execute (CommandInterpreter &interpreter, 231 Args& command, 232 CommandReturnObject &result) 233 { 234 Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); 235 if (target) 236 { 237 if (command.GetArgumentCount() != 0) 238 { 239 result.AppendError ("list takes no arguments"); 240 result.SetStatus (eReturnStatusFailed); 241 return result.Succeeded(); 242 } 243 244 target->GetImageSearchPathList().Dump(&result.GetOutputStream()); 245 } 246 else 247 { 248 result.AppendError ("invalid target"); 249 result.SetStatus (eReturnStatusFailed); 250 } 251 return result.Succeeded(); 252 } 253 }; 254 255 class CommandObjectTargetImageSearchPathsQuery : public CommandObject 256 { 257 public: 258 259 CommandObjectTargetImageSearchPathsQuery () : 260 CommandObject ("target image-search-paths query", 261 "Transforms a path using the first applicable image search path.", 262 "target image-search-paths query <path>") 263 { 264 } 265 266 ~CommandObjectTargetImageSearchPathsQuery () 267 { 268 } 269 270 bool 271 Execute (CommandInterpreter &interpreter, 272 Args& command, 273 CommandReturnObject &result) 274 { 275 Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); 276 if (target) 277 { 278 if (command.GetArgumentCount() != 1) 279 { 280 result.AppendError ("query requires one argument"); 281 result.SetStatus (eReturnStatusFailed); 282 return result.Succeeded(); 283 } 284 285 ConstString orig(command.GetArgumentAtIndex(0)); 286 ConstString transformed; 287 if (target->GetImageSearchPathList().RemapPath(orig, transformed)) 288 result.GetOutputStream().Printf("%s\n", transformed.GetCString()); 289 else 290 result.GetOutputStream().Printf("%s\n", orig.GetCString()); 291 } 292 else 293 { 294 result.AppendError ("invalid target"); 295 result.SetStatus (eReturnStatusFailed); 296 } 297 return result.Succeeded(); 298 } 299 }; 300 301 // TODO: implement the target select later when we start doing multiple targets 302 //#pragma mark CommandObjectTargetSelect 303 // 304 ////------------------------------------------------------------------------- 305 //// CommandObjectTargetSelect 306 ////------------------------------------------------------------------------- 307 // 308 //class CommandObjectTargetSelect : public CommandObject 309 //{ 310 //public: 311 // 312 // CommandObjectTargetSelect () : 313 // CommandObject ("frame select", 314 // "Select the current frame by index in the current thread.", 315 // "frame select <frame-index>") 316 // { 317 // } 318 // 319 // ~CommandObjectTargetSelect () 320 // { 321 // } 322 // 323 // bool 324 // Execute (Args& command, 325 // Debugger *context, 326 // CommandInterpreter &interpreter, 327 // CommandReturnObject &result) 328 // { 329 // ExecutionContext exe_ctx (context->GetExecutionContext()); 330 // if (exe_ctx.thread) 331 // { 332 // if (command.GetArgumentCount() == 1) 333 // { 334 // const char *frame_idx_cstr = command.GetArgumentAtIndex(0); 335 // 336 // const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount(); 337 // const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0); 338 // if (frame_idx < num_frames) 339 // { 340 // exe_ctx.thread->SetCurrentFrameByIndex (frame_idx); 341 // exe_ctx.frame = exe_ctx.thread->GetCurrentFrame ().get(); 342 // 343 // if (exe_ctx.frame) 344 // { 345 // if (DisplayFrameForExecutionContext (exe_ctx.thread, 346 // exe_ctx.frame, 347 // interpreter, 348 // result.GetOutputStream(), 349 // true, 350 // true, 351 // 3, 352 // 3)) 353 // { 354 // result.SetStatus (eReturnStatusSuccessFinishResult); 355 // return result.Succeeded(); 356 // } 357 // } 358 // } 359 // if (frame_idx == UINT32_MAX) 360 // result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr); 361 // else 362 // result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx); 363 // } 364 // else 365 // { 366 // result.AppendError ("invalid arguments"); 367 // result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str()); 368 // } 369 // } 370 // else 371 // { 372 // result.AppendError ("no current thread"); 373 // } 374 // result.SetStatus (eReturnStatusFailed); 375 // return false; 376 // } 377 //}; 378 379 380 #pragma mark CommandObjectMultiwordTarget 381 382 //------------------------------------------------------------------------- 383 // CommandObjectMultiwordImageSearchPaths 384 //------------------------------------------------------------------------- 385 386 class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword 387 { 388 public: 389 390 CommandObjectMultiwordImageSearchPaths (CommandInterpreter &interpreter) : 391 CommandObjectMultiword ("target image-search-paths", 392 "A set of commands for operating on debugger target image search paths.", 393 "target image-search-paths <subcommand> [<subcommand-options>]") 394 { 395 LoadSubCommand (interpreter, "add", CommandObjectSP (new CommandObjectTargetImageSearchPathsAdd ())); 396 LoadSubCommand (interpreter, "clear", CommandObjectSP (new CommandObjectTargetImageSearchPathsClear ())); 397 LoadSubCommand (interpreter, "insert", CommandObjectSP (new CommandObjectTargetImageSearchPathsInsert ())); 398 LoadSubCommand (interpreter, "list", CommandObjectSP (new CommandObjectTargetImageSearchPathsList ())); 399 LoadSubCommand (interpreter, "query", CommandObjectSP (new CommandObjectTargetImageSearchPathsQuery ())); 400 } 401 402 ~CommandObjectMultiwordImageSearchPaths() 403 { 404 } 405 }; 406 407 408 #pragma mark CommandObjectMultiwordTarget 409 410 //------------------------------------------------------------------------- 411 // CommandObjectMultiwordTarget 412 //------------------------------------------------------------------------- 413 414 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 415 CommandObjectMultiword ("target", 416 "A set of commands for operating on debugger targets.", 417 "target <subcommand> [<subcommand-options>]") 418 { 419 LoadSubCommand (interpreter, "image-search-paths", CommandObjectSP (new CommandObjectMultiwordImageSearchPaths (interpreter))); 420 } 421 422 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 423 { 424 } 425 426