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/Args.h" 17 #include "lldb/Core/DataBufferHeap.h" 18 #include "lldb/Core/DataExtractor.h" 19 #include "lldb/Core/Options.h" 20 #include "lldb/Core/StreamString.h" 21 #include "lldb/Interpreter/CommandReturnObject.h" 22 #include "lldb/Interpreter/CommandContext.h" 23 #include "lldb/Target/Process.h" 24 25 using namespace lldb; 26 using namespace lldb_private; 27 28 //---------------------------------------------------------------------- 29 // Read memory from the inferior process 30 //---------------------------------------------------------------------- 31 class CommandObjectMemoryRead : public CommandObject 32 { 33 public: 34 35 class CommandOptions : public Options 36 { 37 public: 38 CommandOptions () : 39 Options() 40 { 41 ResetOptionValues(); 42 } 43 44 virtual 45 ~CommandOptions () 46 { 47 } 48 49 virtual Error 50 SetOptionValue (int option_idx, const char *option_arg) 51 { 52 Error error; 53 char short_option = (char) m_getopt_table[option_idx].val; 54 55 switch (short_option) 56 { 57 case 'f': 58 error = Args::StringToFormat (option_arg, m_format); 59 60 switch (m_format) 61 { 62 default: 63 break; 64 65 case eFormatBoolean: 66 if (m_byte_size == 0) 67 m_byte_size = 1; 68 if (m_num_per_line == 0) 69 m_num_per_line = 1; 70 break; 71 72 case eFormatCString: 73 if (m_num_per_line == 0) 74 m_num_per_line = 1; 75 break; 76 77 case eFormatPointer: 78 break; 79 80 case eFormatBinary: 81 case eFormatFloat: 82 case eFormatOctal: 83 case eFormatDecimal: 84 case eFormatEnum: 85 case eFormatUnicode16: 86 case eFormatUnicode32: 87 case eFormatUnsigned: 88 if (m_byte_size == 0) 89 m_byte_size = 4; 90 if (m_num_per_line == 0) 91 m_num_per_line = 1; 92 break; 93 94 case eFormatBytes: 95 case eFormatBytesWithASCII: 96 case eFormatChar: 97 case eFormatCharPrintable: 98 if (m_byte_size == 0) 99 m_byte_size = 1; 100 break; 101 case eFormatComplex: 102 if (m_byte_size == 0) 103 m_byte_size = 8; 104 break; 105 case eFormatHex: 106 if (m_byte_size == 0) 107 m_byte_size = 4; 108 break; 109 110 case eFormatVectorOfChar: 111 case eFormatVectorOfSInt8: 112 case eFormatVectorOfUInt8: 113 case eFormatVectorOfSInt16: 114 case eFormatVectorOfUInt16: 115 case eFormatVectorOfSInt32: 116 case eFormatVectorOfUInt32: 117 case eFormatVectorOfSInt64: 118 case eFormatVectorOfUInt64: 119 case eFormatVectorOfFloat32: 120 case eFormatVectorOfFloat64: 121 case eFormatVectorOfUInt128: 122 break; 123 } 124 break; 125 126 case 'l': 127 m_num_per_line = Args::StringToUInt32 (option_arg, 0); 128 if (m_num_per_line == 0) 129 error.SetErrorStringWithFormat("Invalid value for --num-per-line option '%s'. Must be positive integer value.\n", option_arg); 130 break; 131 132 case 'c': 133 m_count = Args::StringToUInt32 (option_arg, 0); 134 if (m_count == 0) 135 error.SetErrorStringWithFormat("Invalid value for --count option '%s'. Must be positive integer value.\n", option_arg); 136 break; 137 138 case 's': 139 m_byte_size = Args::StringToUInt32 (option_arg, 0); 140 if (m_byte_size == 0) 141 error.SetErrorStringWithFormat("Invalid value for --size option '%s'. Must be positive integer value.\n", option_arg); 142 break; 143 144 default: 145 error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option); 146 break; 147 } 148 return error; 149 } 150 151 void 152 ResetOptionValues () 153 { 154 Options::ResetOptionValues(); 155 m_format = eFormatBytesWithASCII; 156 m_byte_size = 0; 157 m_count = 0; 158 m_num_per_line = 0; 159 } 160 161 const lldb::OptionDefinition* 162 GetDefinitions () 163 { 164 return g_option_table; 165 } 166 167 // Options table: Required for subclasses of Options. 168 169 static lldb::OptionDefinition g_option_table[]; 170 171 // Instance variables to hold the values for command options. 172 lldb::Format m_format; 173 uint32_t m_byte_size; 174 uint32_t m_count; 175 uint32_t m_num_per_line; 176 }; 177 178 CommandObjectMemoryRead () : 179 CommandObject ("memory read", 180 "Read memory from the process being debugged.", 181 "memory read [<cmd-options>] <start-addr> [<end-addr>]", 182 eFlagProcessMustBeLaunched) 183 { 184 } 185 186 virtual 187 ~CommandObjectMemoryRead () 188 { 189 } 190 191 Options * 192 GetOptions () 193 { 194 return &m_options; 195 } 196 197 virtual bool 198 Execute (Args& command, 199 CommandContext *context, 200 CommandInterpreter *interpreter, 201 CommandReturnObject &result) 202 { 203 Process *process = context->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 { 0, 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 { 0, false, "size", 's', required_argument, NULL, 0, "<byte-size>","The size in bytes to use when displaying with the selected format."}, 322 { 0, false, "num-per-line", 'l', required_argument, NULL, 0, "<N>", "The number of items per line to display."}, 323 { 0, 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 (Args& command, 445 CommandContext *context, 446 CommandInterpreter *interpreter, 447 CommandReturnObject &result) 448 { 449 Process *process = context->GetExecutionContext().process; 450 if (process == NULL) 451 { 452 result.AppendError("need a process to read memory"); 453 result.SetStatus(eReturnStatusFailed); 454 return false; 455 } 456 457 const size_t argc = command.GetArgumentCount(); 458 459 if (argc < 2) 460 { 461 result.AppendErrorWithFormat ("%s takes an address and at least one value.\n", m_cmd_name.c_str()); 462 result.SetStatus(eReturnStatusFailed); 463 return false; 464 } 465 466 size_t item_byte_size = m_options.m_byte_size ? m_options.m_byte_size : 1; 467 StreamString buffer (Stream::eBinary, 468 process->GetAddressByteSize(), 469 process->GetByteOrder()); 470 471 lldb::addr_t addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0); 472 473 if (addr == LLDB_INVALID_ADDRESS) 474 { 475 result.AppendErrorWithFormat("Invalid address string '%s'.\n", command.GetArgumentAtIndex(0)); 476 result.SetStatus(eReturnStatusFailed); 477 return false; 478 } 479 command.Shift(); // shift off the address argument 480 uint64_t uval64; 481 int64_t sval64; 482 bool success = false; 483 const uint32_t num_value_args = command.GetArgumentCount(); 484 uint32_t i; 485 for (i=0; i<num_value_args; ++i) 486 { 487 const char *value_str = command.GetArgumentAtIndex(i); 488 489 switch (m_options.m_format) 490 { 491 case eFormatFloat: // TODO: add support for floats soon 492 case eFormatCharPrintable: 493 case eFormatBytesWithASCII: 494 case eFormatComplex: 495 case eFormatEnum: 496 case eFormatUnicode16: 497 case eFormatUnicode32: 498 case eFormatVectorOfChar: 499 case eFormatVectorOfSInt8: 500 case eFormatVectorOfUInt8: 501 case eFormatVectorOfSInt16: 502 case eFormatVectorOfUInt16: 503 case eFormatVectorOfSInt32: 504 case eFormatVectorOfUInt32: 505 case eFormatVectorOfSInt64: 506 case eFormatVectorOfUInt64: 507 case eFormatVectorOfFloat32: 508 case eFormatVectorOfFloat64: 509 case eFormatVectorOfUInt128: 510 result.AppendError("unsupported format for writing memory"); 511 result.SetStatus(eReturnStatusFailed); 512 return false; 513 514 case eFormatDefault: 515 case eFormatBytes: 516 case eFormatHex: 517 // Decode hex bytes 518 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success); 519 if (!success) 520 { 521 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str); 522 result.SetStatus(eReturnStatusFailed); 523 return false; 524 } 525 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 526 { 527 result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); 528 result.SetStatus(eReturnStatusFailed); 529 return false; 530 } 531 buffer.PutMaxHex64 (uval64, item_byte_size); 532 break; 533 534 case eFormatBoolean: 535 uval64 = Args::StringToBoolean(value_str, false, &success); 536 if (!success) 537 { 538 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str); 539 result.SetStatus(eReturnStatusFailed); 540 return false; 541 } 542 buffer.PutMaxHex64 (uval64, item_byte_size); 543 break; 544 545 case eFormatBinary: 546 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success); 547 if (!success) 548 { 549 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str); 550 result.SetStatus(eReturnStatusFailed); 551 return false; 552 } 553 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 554 { 555 result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); 556 result.SetStatus(eReturnStatusFailed); 557 return false; 558 } 559 buffer.PutMaxHex64 (uval64, item_byte_size); 560 break; 561 562 case eFormatChar: 563 case eFormatCString: 564 if (value_str[0]) 565 { 566 size_t len = strlen (value_str); 567 // Include the NULL for C strings... 568 if (m_options.m_format == eFormatCString) 569 ++len; 570 Error error; 571 if (process->WriteMemory (addr, value_str, len, error) == len) 572 { 573 addr += len; 574 } 575 else 576 { 577 result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString()); 578 result.SetStatus(eReturnStatusFailed); 579 return false; 580 } 581 } 582 break; 583 584 case eFormatDecimal: 585 sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success); 586 if (!success) 587 { 588 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str); 589 result.SetStatus(eReturnStatusFailed); 590 return false; 591 } 592 else if (!SIntValueIsValidForSize (sval64, item_byte_size)) 593 { 594 result.AppendErrorWithFormat ("Value %lli is too large or small to fit in a %u byte signed integer value.\n", sval64, item_byte_size); 595 result.SetStatus(eReturnStatusFailed); 596 return false; 597 } 598 buffer.PutMaxHex64 (sval64, item_byte_size); 599 break; 600 601 case eFormatUnsigned: 602 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success); 603 if (!success) 604 { 605 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str); 606 result.SetStatus(eReturnStatusFailed); 607 return false; 608 } 609 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 610 { 611 result.AppendErrorWithFormat ("Value %llu is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); 612 result.SetStatus(eReturnStatusFailed); 613 return false; 614 } 615 buffer.PutMaxHex64 (uval64, item_byte_size); 616 break; 617 618 case eFormatOctal: 619 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success); 620 if (!success) 621 { 622 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str); 623 result.SetStatus(eReturnStatusFailed); 624 return false; 625 } 626 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 627 { 628 result.AppendErrorWithFormat ("Value %llo is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); 629 result.SetStatus(eReturnStatusFailed); 630 return false; 631 } 632 buffer.PutMaxHex64 (uval64, item_byte_size); 633 break; 634 } 635 } 636 637 if (!buffer.GetString().empty()) 638 { 639 Error error; 640 if (process->WriteMemory (addr, buffer.GetString().data(), buffer.GetString().size(), error) == buffer.GetString().size()) 641 return true; 642 else 643 { 644 result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString()); 645 result.SetStatus(eReturnStatusFailed); 646 return false; 647 } 648 } 649 return true; 650 } 651 652 protected: 653 CommandOptions m_options; 654 }; 655 656 lldb::OptionDefinition 657 CommandObjectMemoryWrite::CommandOptions::g_option_table[] = 658 { 659 { 0, false, "format", 'f', required_argument, NULL, 0, "<format>", "The format value types that will be decoded and written to memory."}, 660 { 0, false, "size", 's', required_argument, NULL, 0, "<byte-size>","The size in bytes of the values to write to memory."}, 661 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } 662 }; 663 664 665 //------------------------------------------------------------------------- 666 // CommandObjectMemory 667 //------------------------------------------------------------------------- 668 669 CommandObjectMemory::CommandObjectMemory (CommandInterpreter *interpreter) : 670 CommandObjectMultiword ("memory", 671 "A set of commands for operating on a memory.", 672 "memory <subcommand> [<subcommand-options>]") 673 { 674 LoadSubCommand (CommandObjectSP (new CommandObjectMemoryRead ()), "read", interpreter); 675 LoadSubCommand (CommandObjectSP (new CommandObjectMemoryWrite ()), "write", interpreter); 676 } 677 678 CommandObjectMemory::~CommandObjectMemory () 679 { 680 } 681