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