1 //===-- CommandObjectMemory.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 "CommandObjectMemory.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/DataBufferHeap.h" 17 #include "lldb/Core/DataExtractor.h" 18 #include "lldb/Core/Debugger.h" 19 #include "lldb/Core/StreamString.h" 20 #include "lldb/Interpreter/Args.h" 21 #include "lldb/Interpreter/CommandReturnObject.h" 22 #include "lldb/Interpreter/CommandInterpreter.h" 23 #include "lldb/Interpreter/Options.h" 24 #include "lldb/Target/Process.h" 25 26 using namespace lldb; 27 using namespace lldb_private; 28 29 //---------------------------------------------------------------------- 30 // Read memory from the inferior process 31 //---------------------------------------------------------------------- 32 class CommandObjectMemoryRead : public CommandObject 33 { 34 public: 35 36 class CommandOptions : public Options 37 { 38 public: 39 CommandOptions () : 40 Options() 41 { 42 ResetOptionValues(); 43 } 44 45 virtual 46 ~CommandOptions () 47 { 48 } 49 50 virtual Error 51 SetOptionValue (int option_idx, const char *option_arg) 52 { 53 Error error; 54 char short_option = (char) m_getopt_table[option_idx].val; 55 56 switch (short_option) 57 { 58 case 'f': 59 error = Args::StringToFormat (option_arg, m_format); 60 61 switch (m_format) 62 { 63 default: 64 break; 65 66 case eFormatBoolean: 67 if (m_byte_size == 0) 68 m_byte_size = 1; 69 if (m_num_per_line == 0) 70 m_num_per_line = 1; 71 break; 72 73 case eFormatCString: 74 if (m_num_per_line == 0) 75 m_num_per_line = 1; 76 break; 77 78 case eFormatPointer: 79 break; 80 81 case eFormatBinary: 82 case eFormatFloat: 83 case eFormatOctal: 84 case eFormatDecimal: 85 case eFormatEnum: 86 case eFormatUnicode16: 87 case eFormatUnicode32: 88 case eFormatUnsigned: 89 if (m_byte_size == 0) 90 m_byte_size = 4; 91 if (m_num_per_line == 0) 92 m_num_per_line = 1; 93 break; 94 95 case eFormatBytes: 96 case eFormatBytesWithASCII: 97 case eFormatChar: 98 case eFormatCharPrintable: 99 if (m_byte_size == 0) 100 m_byte_size = 1; 101 break; 102 case eFormatComplex: 103 if (m_byte_size == 0) 104 m_byte_size = 8; 105 break; 106 case eFormatHex: 107 if (m_byte_size == 0) 108 m_byte_size = 4; 109 break; 110 111 case eFormatVectorOfChar: 112 case eFormatVectorOfSInt8: 113 case eFormatVectorOfUInt8: 114 case eFormatVectorOfSInt16: 115 case eFormatVectorOfUInt16: 116 case eFormatVectorOfSInt32: 117 case eFormatVectorOfUInt32: 118 case eFormatVectorOfSInt64: 119 case eFormatVectorOfUInt64: 120 case eFormatVectorOfFloat32: 121 case eFormatVectorOfFloat64: 122 case eFormatVectorOfUInt128: 123 break; 124 } 125 break; 126 127 case 'l': 128 m_num_per_line = Args::StringToUInt32 (option_arg, 0); 129 if (m_num_per_line == 0) 130 error.SetErrorStringWithFormat("Invalid value for --num-per-line option '%s'. Must be positive integer value.\n", option_arg); 131 break; 132 133 case 'c': 134 m_count = Args::StringToUInt32 (option_arg, 0); 135 if (m_count == 0) 136 error.SetErrorStringWithFormat("Invalid value for --count option '%s'. Must be positive integer value.\n", option_arg); 137 break; 138 139 case 's': 140 m_byte_size = Args::StringToUInt32 (option_arg, 0); 141 if (m_byte_size == 0) 142 error.SetErrorStringWithFormat("Invalid value for --size option '%s'. Must be positive integer value.\n", option_arg); 143 break; 144 145 default: 146 error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option); 147 break; 148 } 149 return error; 150 } 151 152 void 153 ResetOptionValues () 154 { 155 Options::ResetOptionValues(); 156 m_format = eFormatBytesWithASCII; 157 m_byte_size = 0; 158 m_count = 0; 159 m_num_per_line = 0; 160 } 161 162 const lldb::OptionDefinition* 163 GetDefinitions () 164 { 165 return g_option_table; 166 } 167 168 // Options table: Required for subclasses of Options. 169 170 static lldb::OptionDefinition g_option_table[]; 171 172 // Instance variables to hold the values for command options. 173 lldb::Format m_format; 174 uint32_t m_byte_size; 175 uint32_t m_count; 176 uint32_t m_num_per_line; 177 }; 178 179 CommandObjectMemoryRead () : 180 CommandObject ("memory read", 181 "Read memory from the process being debugged.", 182 "memory read [<cmd-options>] <start-addr> [<end-addr>]", 183 eFlagProcessMustBeLaunched) 184 { 185 } 186 187 virtual 188 ~CommandObjectMemoryRead () 189 { 190 } 191 192 Options * 193 GetOptions () 194 { 195 return &m_options; 196 } 197 198 virtual bool 199 Execute (CommandInterpreter &interpreter, 200 Args& command, 201 CommandReturnObject &result) 202 { 203 Process *process = interpreter.GetDebugger().GetExecutionContext().process; 204 if (process == NULL) 205 { 206 result.AppendError("need a process to read memory"); 207 result.SetStatus(eReturnStatusFailed); 208 return false; 209 } 210 const size_t argc = command.GetArgumentCount(); 211 212 if (argc == 0 || argc > 2) 213 { 214 result.AppendErrorWithFormat ("%s takes 1 or two args.\n", m_cmd_name.c_str()); 215 result.SetStatus(eReturnStatusFailed); 216 return false; 217 } 218 219 size_t item_byte_size = m_options.m_byte_size; 220 if (item_byte_size == 0) 221 { 222 if (m_options.m_format == eFormatPointer) 223 item_byte_size = process->GetAddressByteSize(); 224 else 225 item_byte_size = 1; 226 } 227 228 size_t item_count = m_options.m_count; 229 230 size_t num_per_line = m_options.m_num_per_line; 231 if (num_per_line == 0) 232 { 233 num_per_line = (16/item_byte_size); 234 if (num_per_line == 0) 235 num_per_line = 1; 236 } 237 238 size_t total_byte_size = m_options.m_count * item_byte_size; 239 if (total_byte_size == 0) 240 total_byte_size = 32; 241 242 lldb::addr_t addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0); 243 244 if (addr == LLDB_INVALID_ADDRESS) 245 { 246 result.AppendErrorWithFormat("invalid start address string '%s'.\n", command.GetArgumentAtIndex(0)); 247 result.SetStatus(eReturnStatusFailed); 248 return false; 249 } 250 251 if (argc == 2) 252 { 253 lldb::addr_t end_addr = Args::StringToUInt64(command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0); 254 if (end_addr == LLDB_INVALID_ADDRESS) 255 { 256 result.AppendErrorWithFormat("Invalid end address string '%s'.\n", command.GetArgumentAtIndex(1)); 257 result.SetStatus(eReturnStatusFailed); 258 return false; 259 } 260 else if (end_addr <= addr) 261 { 262 result.AppendErrorWithFormat("End address (0x%llx) must be greater that the start address (0x%llx).\n", end_addr, addr); 263 result.SetStatus(eReturnStatusFailed); 264 return false; 265 } 266 else if (item_count != 0) 267 { 268 result.AppendErrorWithFormat("Specify either the end address (0x%llx) or the count (--count %u), not both.\n", end_addr, item_count); 269 result.SetStatus(eReturnStatusFailed); 270 return false; 271 } 272 273 total_byte_size = end_addr - addr; 274 item_count = total_byte_size / item_byte_size; 275 } 276 else 277 { 278 if (item_count == 0) 279 item_count = 32; 280 } 281 282 DataBufferSP data_sp(new DataBufferHeap (total_byte_size, '\0')); 283 Error error; 284 size_t bytes_read = process->ReadMemory(addr, data_sp->GetBytes (), data_sp->GetByteSize(), error); 285 if (bytes_read == 0) 286 { 287 result.AppendWarningWithFormat("Read from 0x%llx failed.\n", addr); 288 result.AppendError(error.AsCString()); 289 result.SetStatus(eReturnStatusFailed); 290 return false; 291 } 292 293 if (bytes_read < total_byte_size) 294 result.AppendWarningWithFormat("Not all bytes (%u/%u) were able to be read from 0x%llx.\n", bytes_read, total_byte_size, addr); 295 296 result.SetStatus(eReturnStatusSuccessFinishResult); 297 DataExtractor data(data_sp, process->GetByteOrder(), process->GetAddressByteSize()); 298 299 Stream &output_stream = result.GetOutputStream(); 300 data.Dump(&output_stream, 301 0, 302 m_options.m_format, 303 item_byte_size, 304 item_count, 305 num_per_line, 306 addr, 307 0, 308 0); 309 output_stream.EOL(); 310 return true; 311 } 312 313 protected: 314 CommandOptions m_options; 315 }; 316 317 lldb::OptionDefinition 318 CommandObjectMemoryRead::CommandOptions::g_option_table[] = 319 { 320 { LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, "<format>", "The format that will be used to display the memory. Defaults to bytes with ASCII (--format=Y)."}, 321 { LLDB_OPT_SET_1, false, "size", 's', required_argument, NULL, 0, "<byte-size>","The size in bytes to use when displaying with the selected format."}, 322 { LLDB_OPT_SET_1, false, "num-per-line", 'l', required_argument, NULL, 0, "<N>", "The number of items per line to display."}, 323 { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, "<N>", "The number of total items to display."}, 324 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } 325 }; 326 327 328 //---------------------------------------------------------------------- 329 // Write memory to the inferior process 330 //---------------------------------------------------------------------- 331 class CommandObjectMemoryWrite : public CommandObject 332 { 333 public: 334 335 class CommandOptions : public Options 336 { 337 public: 338 CommandOptions () : 339 Options() 340 { 341 ResetOptionValues(); 342 } 343 344 virtual 345 ~CommandOptions () 346 { 347 } 348 349 virtual Error 350 SetOptionValue (int option_idx, const char *option_arg) 351 { 352 Error error; 353 char short_option = (char) m_getopt_table[option_idx].val; 354 switch (short_option) 355 { 356 case 'f': 357 error = Args::StringToFormat (option_arg, m_format); 358 break; 359 360 case 's': 361 m_byte_size = Args::StringToUInt32 (option_arg, 0); 362 if (m_byte_size == 0) 363 error.SetErrorStringWithFormat("Invalid value for --size option '%s'. Must be positive integer value.\n", option_arg); 364 break; 365 366 367 default: 368 error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option); 369 break; 370 } 371 return error; 372 } 373 374 void 375 ResetOptionValues () 376 { 377 Options::ResetOptionValues(); 378 m_format = eFormatBytes; 379 m_byte_size = 1; 380 } 381 382 const lldb::OptionDefinition* 383 GetDefinitions () 384 { 385 return g_option_table; 386 } 387 388 // Options table: Required for subclasses of Options. 389 390 static lldb::OptionDefinition g_option_table[]; 391 392 // Instance variables to hold the values for command options. 393 lldb::Format m_format; 394 uint32_t m_byte_size; 395 }; 396 397 CommandObjectMemoryWrite () : 398 CommandObject ("memory write", 399 "Write memory to the process being debugged.", 400 "memory write [<cmd-options>] <addr> [value1 value2 ...]", 401 eFlagProcessMustBeLaunched) 402 { 403 } 404 405 virtual 406 ~CommandObjectMemoryWrite () 407 { 408 } 409 410 Options * 411 GetOptions () 412 { 413 return &m_options; 414 } 415 416 bool 417 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size) 418 { 419 if (total_byte_size > 8) 420 return false; 421 422 if (total_byte_size == 8) 423 return true; 424 425 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1; 426 return uval64 <= max; 427 } 428 429 bool 430 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size) 431 { 432 if (total_byte_size > 8) 433 return false; 434 435 if (total_byte_size == 8) 436 return true; 437 438 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1; 439 const int64_t min = ~(max); 440 return min <= sval64 && sval64 <= max; 441 } 442 443 virtual bool 444 Execute (CommandInterpreter &interpreter, 445 Args& command, 446 CommandReturnObject &result) 447 { 448 Process *process = interpreter.GetDebugger().GetExecutionContext().process; 449 if (process == NULL) 450 { 451 result.AppendError("need a process to read memory"); 452 result.SetStatus(eReturnStatusFailed); 453 return false; 454 } 455 456 const size_t argc = command.GetArgumentCount(); 457 458 if (argc < 2) 459 { 460 result.AppendErrorWithFormat ("%s takes an address and at least one value.\n", m_cmd_name.c_str()); 461 result.SetStatus(eReturnStatusFailed); 462 return false; 463 } 464 465 size_t item_byte_size = m_options.m_byte_size ? m_options.m_byte_size : 1; 466 StreamString buffer (Stream::eBinary, 467 process->GetAddressByteSize(), 468 process->GetByteOrder()); 469 470 lldb::addr_t addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0); 471 472 if (addr == LLDB_INVALID_ADDRESS) 473 { 474 result.AppendErrorWithFormat("Invalid address string '%s'.\n", command.GetArgumentAtIndex(0)); 475 result.SetStatus(eReturnStatusFailed); 476 return false; 477 } 478 command.Shift(); // shift off the address argument 479 uint64_t uval64; 480 int64_t sval64; 481 bool success = false; 482 const uint32_t num_value_args = command.GetArgumentCount(); 483 uint32_t i; 484 for (i=0; i<num_value_args; ++i) 485 { 486 const char *value_str = command.GetArgumentAtIndex(i); 487 488 switch (m_options.m_format) 489 { 490 case eFormatFloat: // TODO: add support for floats soon 491 case eFormatCharPrintable: 492 case eFormatBytesWithASCII: 493 case eFormatComplex: 494 case eFormatEnum: 495 case eFormatUnicode16: 496 case eFormatUnicode32: 497 case eFormatVectorOfChar: 498 case eFormatVectorOfSInt8: 499 case eFormatVectorOfUInt8: 500 case eFormatVectorOfSInt16: 501 case eFormatVectorOfUInt16: 502 case eFormatVectorOfSInt32: 503 case eFormatVectorOfUInt32: 504 case eFormatVectorOfSInt64: 505 case eFormatVectorOfUInt64: 506 case eFormatVectorOfFloat32: 507 case eFormatVectorOfFloat64: 508 case eFormatVectorOfUInt128: 509 result.AppendError("unsupported format for writing memory"); 510 result.SetStatus(eReturnStatusFailed); 511 return false; 512 513 case eFormatDefault: 514 case eFormatBytes: 515 case eFormatHex: 516 // Decode hex bytes 517 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success); 518 if (!success) 519 { 520 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str); 521 result.SetStatus(eReturnStatusFailed); 522 return false; 523 } 524 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 525 { 526 result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); 527 result.SetStatus(eReturnStatusFailed); 528 return false; 529 } 530 buffer.PutMaxHex64 (uval64, item_byte_size); 531 break; 532 533 case eFormatBoolean: 534 uval64 = Args::StringToBoolean(value_str, false, &success); 535 if (!success) 536 { 537 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str); 538 result.SetStatus(eReturnStatusFailed); 539 return false; 540 } 541 buffer.PutMaxHex64 (uval64, item_byte_size); 542 break; 543 544 case eFormatBinary: 545 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success); 546 if (!success) 547 { 548 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str); 549 result.SetStatus(eReturnStatusFailed); 550 return false; 551 } 552 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 553 { 554 result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); 555 result.SetStatus(eReturnStatusFailed); 556 return false; 557 } 558 buffer.PutMaxHex64 (uval64, item_byte_size); 559 break; 560 561 case eFormatChar: 562 case eFormatCString: 563 if (value_str[0]) 564 { 565 size_t len = strlen (value_str); 566 // Include the NULL for C strings... 567 if (m_options.m_format == eFormatCString) 568 ++len; 569 Error error; 570 if (process->WriteMemory (addr, value_str, len, error) == len) 571 { 572 addr += len; 573 } 574 else 575 { 576 result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString()); 577 result.SetStatus(eReturnStatusFailed); 578 return false; 579 } 580 } 581 break; 582 583 case eFormatDecimal: 584 sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success); 585 if (!success) 586 { 587 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str); 588 result.SetStatus(eReturnStatusFailed); 589 return false; 590 } 591 else if (!SIntValueIsValidForSize (sval64, item_byte_size)) 592 { 593 result.AppendErrorWithFormat ("Value %lli is too large or small to fit in a %u byte signed integer value.\n", sval64, item_byte_size); 594 result.SetStatus(eReturnStatusFailed); 595 return false; 596 } 597 buffer.PutMaxHex64 (sval64, item_byte_size); 598 break; 599 600 case eFormatUnsigned: 601 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success); 602 if (!success) 603 { 604 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str); 605 result.SetStatus(eReturnStatusFailed); 606 return false; 607 } 608 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 609 { 610 result.AppendErrorWithFormat ("Value %llu is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); 611 result.SetStatus(eReturnStatusFailed); 612 return false; 613 } 614 buffer.PutMaxHex64 (uval64, item_byte_size); 615 break; 616 617 case eFormatOctal: 618 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success); 619 if (!success) 620 { 621 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str); 622 result.SetStatus(eReturnStatusFailed); 623 return false; 624 } 625 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 626 { 627 result.AppendErrorWithFormat ("Value %llo is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); 628 result.SetStatus(eReturnStatusFailed); 629 return false; 630 } 631 buffer.PutMaxHex64 (uval64, item_byte_size); 632 break; 633 } 634 } 635 636 if (!buffer.GetString().empty()) 637 { 638 Error error; 639 if (process->WriteMemory (addr, buffer.GetString().data(), buffer.GetString().size(), error) == buffer.GetString().size()) 640 return true; 641 else 642 { 643 result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString()); 644 result.SetStatus(eReturnStatusFailed); 645 return false; 646 } 647 } 648 return true; 649 } 650 651 protected: 652 CommandOptions m_options; 653 }; 654 655 lldb::OptionDefinition 656 CommandObjectMemoryWrite::CommandOptions::g_option_table[] = 657 { 658 { LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, "<format>", "The format value types that will be decoded and written to memory."}, 659 { LLDB_OPT_SET_1, false, "size", 's', required_argument, NULL, 0, "<byte-size>","The size in bytes of the values to write to memory."}, 660 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } 661 }; 662 663 664 //------------------------------------------------------------------------- 665 // CommandObjectMemory 666 //------------------------------------------------------------------------- 667 668 CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) : 669 CommandObjectMultiword ("memory", 670 "A set of commands for operating on a memory.", 671 "memory <subcommand> [<subcommand-options>]") 672 { 673 LoadSubCommand (interpreter, "read", CommandObjectSP (new CommandObjectMemoryRead ())); 674 LoadSubCommand (interpreter, "write", CommandObjectSP (new CommandObjectMemoryWrite ())); 675 } 676 677 CommandObjectMemory::~CommandObjectMemory () 678 { 679 } 680