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 "lldb/lldb-python.h" 11 12 #include "CommandObjectMemory.h" 13 14 // C Includes 15 #include <inttypes.h> 16 17 // C++ Includes 18 // Other libraries and framework includes 19 // Project includes 20 #include "lldb/Core/DataBufferHeap.h" 21 #include "lldb/Core/DataExtractor.h" 22 #include "lldb/Core/Debugger.h" 23 #include "lldb/Core/Module.h" 24 #include "lldb/Core/StreamString.h" 25 #include "lldb/Core/ValueObjectMemory.h" 26 #include "lldb/DataFormatters/ValueObjectPrinter.h" 27 #include "lldb/Interpreter/Args.h" 28 #include "lldb/Interpreter/CommandReturnObject.h" 29 #include "lldb/Interpreter/CommandInterpreter.h" 30 #include "lldb/Interpreter/Options.h" 31 #include "lldb/Interpreter/OptionGroupFormat.h" 32 #include "lldb/Interpreter/OptionGroupOutputFile.h" 33 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" 34 #include "lldb/Interpreter/OptionValueString.h" 35 #include "lldb/Symbol/TypeList.h" 36 #include "lldb/Target/Process.h" 37 #include "lldb/Target/StackFrame.h" 38 39 using namespace lldb; 40 using namespace lldb_private; 41 42 static OptionDefinition 43 g_option_table[] = 44 { 45 { LLDB_OPT_SET_1, false, "num-per-line" ,'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeNumberPerLine ,"The number of items per line to display."}, 46 { LLDB_OPT_SET_2, false, "binary" ,'b', OptionParser::eNoArgument , NULL, 0, eArgTypeNone ,"If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that uses the format, size, count and number per line settings."}, 47 { LLDB_OPT_SET_3, true , "type" ,'t', OptionParser::eRequiredArgument, NULL, 0, eArgTypeNone ,"The name of a type to view memory as."}, 48 { LLDB_OPT_SET_1| 49 LLDB_OPT_SET_2| 50 LLDB_OPT_SET_3, false, "force" ,'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone ,"Necessary if reading over target.max-memory-read-size bytes."}, 51 }; 52 53 54 55 class OptionGroupReadMemory : public OptionGroup 56 { 57 public: 58 59 OptionGroupReadMemory () : 60 m_num_per_line (1,1), 61 m_output_as_binary (false), 62 m_view_as_type() 63 { 64 } 65 66 virtual 67 ~OptionGroupReadMemory () 68 { 69 } 70 71 72 virtual uint32_t 73 GetNumDefinitions () 74 { 75 return sizeof (g_option_table) / sizeof (OptionDefinition); 76 } 77 78 virtual const OptionDefinition* 79 GetDefinitions () 80 { 81 return g_option_table; 82 } 83 84 virtual Error 85 SetOptionValue (CommandInterpreter &interpreter, 86 uint32_t option_idx, 87 const char *option_arg) 88 { 89 Error error; 90 const int short_option = g_option_table[option_idx].short_option; 91 92 switch (short_option) 93 { 94 case 'l': 95 error = m_num_per_line.SetValueFromCString (option_arg); 96 if (m_num_per_line.GetCurrentValue() == 0) 97 error.SetErrorStringWithFormat("invalid value for --num-per-line option '%s'", option_arg); 98 break; 99 100 case 'b': 101 m_output_as_binary = true; 102 break; 103 104 case 't': 105 error = m_view_as_type.SetValueFromCString (option_arg); 106 break; 107 108 case 'r': 109 m_force = true; 110 break; 111 112 default: 113 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 114 break; 115 } 116 return error; 117 } 118 119 virtual void 120 OptionParsingStarting (CommandInterpreter &interpreter) 121 { 122 m_num_per_line.Clear(); 123 m_output_as_binary = false; 124 m_view_as_type.Clear(); 125 m_force = false; 126 } 127 128 Error 129 FinalizeSettings (Target *target, OptionGroupFormat& format_options) 130 { 131 Error error; 132 OptionValueUInt64 &byte_size_value = format_options.GetByteSizeValue(); 133 OptionValueUInt64 &count_value = format_options.GetCountValue(); 134 const bool byte_size_option_set = byte_size_value.OptionWasSet(); 135 const bool num_per_line_option_set = m_num_per_line.OptionWasSet(); 136 const bool count_option_set = format_options.GetCountValue().OptionWasSet(); 137 138 switch (format_options.GetFormat()) 139 { 140 default: 141 break; 142 143 case eFormatBoolean: 144 if (!byte_size_option_set) 145 byte_size_value = 1; 146 if (!num_per_line_option_set) 147 m_num_per_line = 1; 148 if (!count_option_set) 149 format_options.GetCountValue() = 8; 150 break; 151 152 case eFormatCString: 153 break; 154 155 case eFormatInstruction: 156 if (count_option_set) 157 byte_size_value = target->GetArchitecture().GetMaximumOpcodeByteSize(); 158 m_num_per_line = 1; 159 break; 160 161 case eFormatAddressInfo: 162 if (!byte_size_option_set) 163 byte_size_value = target->GetArchitecture().GetAddressByteSize(); 164 m_num_per_line = 1; 165 if (!count_option_set) 166 format_options.GetCountValue() = 8; 167 break; 168 169 case eFormatPointer: 170 byte_size_value = target->GetArchitecture().GetAddressByteSize(); 171 if (!num_per_line_option_set) 172 m_num_per_line = 4; 173 if (!count_option_set) 174 format_options.GetCountValue() = 8; 175 break; 176 177 case eFormatBinary: 178 case eFormatFloat: 179 case eFormatOctal: 180 case eFormatDecimal: 181 case eFormatEnum: 182 case eFormatUnicode16: 183 case eFormatUnicode32: 184 case eFormatUnsigned: 185 case eFormatHexFloat: 186 if (!byte_size_option_set) 187 byte_size_value = 4; 188 if (!num_per_line_option_set) 189 m_num_per_line = 1; 190 if (!count_option_set) 191 format_options.GetCountValue() = 8; 192 break; 193 194 case eFormatBytes: 195 case eFormatBytesWithASCII: 196 if (byte_size_option_set) 197 { 198 if (byte_size_value > 1) 199 error.SetErrorStringWithFormat ("display format (bytes/bytes with ascii) conflicts with the specified byte size %" PRIu64 "\n" 200 "\tconsider using a different display format or don't specify the byte size", 201 byte_size_value.GetCurrentValue()); 202 } 203 else 204 byte_size_value = 1; 205 if (!num_per_line_option_set) 206 m_num_per_line = 16; 207 if (!count_option_set) 208 format_options.GetCountValue() = 32; 209 break; 210 case eFormatCharArray: 211 case eFormatChar: 212 case eFormatCharPrintable: 213 if (!byte_size_option_set) 214 byte_size_value = 1; 215 if (!num_per_line_option_set) 216 m_num_per_line = 32; 217 if (!count_option_set) 218 format_options.GetCountValue() = 64; 219 break; 220 case eFormatComplex: 221 if (!byte_size_option_set) 222 byte_size_value = 8; 223 if (!num_per_line_option_set) 224 m_num_per_line = 1; 225 if (!count_option_set) 226 format_options.GetCountValue() = 8; 227 break; 228 case eFormatComplexInteger: 229 if (!byte_size_option_set) 230 byte_size_value = 8; 231 if (!num_per_line_option_set) 232 m_num_per_line = 1; 233 if (!count_option_set) 234 format_options.GetCountValue() = 8; 235 break; 236 case eFormatHex: 237 if (!byte_size_option_set) 238 byte_size_value = 4; 239 if (!num_per_line_option_set) 240 { 241 switch (byte_size_value) 242 { 243 case 1: 244 case 2: 245 m_num_per_line = 8; 246 break; 247 case 4: 248 m_num_per_line = 4; 249 break; 250 case 8: 251 m_num_per_line = 2; 252 break; 253 default: 254 m_num_per_line = 1; 255 break; 256 } 257 } 258 if (!count_option_set) 259 count_value = 8; 260 break; 261 262 case eFormatVectorOfChar: 263 case eFormatVectorOfSInt8: 264 case eFormatVectorOfUInt8: 265 case eFormatVectorOfSInt16: 266 case eFormatVectorOfUInt16: 267 case eFormatVectorOfSInt32: 268 case eFormatVectorOfUInt32: 269 case eFormatVectorOfSInt64: 270 case eFormatVectorOfUInt64: 271 case eFormatVectorOfFloat32: 272 case eFormatVectorOfFloat64: 273 case eFormatVectorOfUInt128: 274 if (!byte_size_option_set) 275 byte_size_value = 128; 276 if (!num_per_line_option_set) 277 m_num_per_line = 1; 278 if (!count_option_set) 279 count_value = 4; 280 break; 281 } 282 return error; 283 } 284 285 bool 286 AnyOptionWasSet () const 287 { 288 return m_num_per_line.OptionWasSet() || 289 m_output_as_binary || 290 m_view_as_type.OptionWasSet(); 291 } 292 293 OptionValueUInt64 m_num_per_line; 294 bool m_output_as_binary; 295 OptionValueString m_view_as_type; 296 bool m_force; 297 }; 298 299 300 301 //---------------------------------------------------------------------- 302 // Read memory from the inferior process 303 //---------------------------------------------------------------------- 304 class CommandObjectMemoryRead : public CommandObjectParsed 305 { 306 public: 307 308 CommandObjectMemoryRead (CommandInterpreter &interpreter) : 309 CommandObjectParsed (interpreter, 310 "memory read", 311 "Read from the memory of the process being debugged.", 312 NULL, 313 eFlagRequiresTarget | eFlagProcessMustBePaused), 314 m_option_group (interpreter), 315 m_format_options (eFormatBytesWithASCII, 1, 8), 316 m_memory_options (), 317 m_outfile_options (), 318 m_varobj_options(), 319 m_next_addr(LLDB_INVALID_ADDRESS), 320 m_prev_byte_size(0), 321 m_prev_format_options (eFormatBytesWithASCII, 1, 8), 322 m_prev_memory_options (), 323 m_prev_outfile_options (), 324 m_prev_varobj_options() 325 { 326 CommandArgumentEntry arg1; 327 CommandArgumentEntry arg2; 328 CommandArgumentData start_addr_arg; 329 CommandArgumentData end_addr_arg; 330 331 // Define the first (and only) variant of this arg. 332 start_addr_arg.arg_type = eArgTypeAddressOrExpression; 333 start_addr_arg.arg_repetition = eArgRepeatPlain; 334 335 // There is only one variant this argument could be; put it into the argument entry. 336 arg1.push_back (start_addr_arg); 337 338 // Define the first (and only) variant of this arg. 339 end_addr_arg.arg_type = eArgTypeAddressOrExpression; 340 end_addr_arg.arg_repetition = eArgRepeatOptional; 341 342 // There is only one variant this argument could be; put it into the argument entry. 343 arg2.push_back (end_addr_arg); 344 345 // Push the data for the first argument into the m_arguments vector. 346 m_arguments.push_back (arg1); 347 m_arguments.push_back (arg2); 348 349 // Add the "--format" and "--count" options to group 1 and 3 350 m_option_group.Append (&m_format_options, 351 OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_COUNT, 352 LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3); 353 m_option_group.Append (&m_format_options, 354 OptionGroupFormat::OPTION_GROUP_GDB_FMT, 355 LLDB_OPT_SET_1 | LLDB_OPT_SET_3); 356 // Add the "--size" option to group 1 and 2 357 m_option_group.Append (&m_format_options, 358 OptionGroupFormat::OPTION_GROUP_SIZE, 359 LLDB_OPT_SET_1 | LLDB_OPT_SET_2); 360 m_option_group.Append (&m_memory_options); 361 m_option_group.Append (&m_outfile_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3); 362 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3); 363 m_option_group.Finalize(); 364 } 365 366 virtual 367 ~CommandObjectMemoryRead () 368 { 369 } 370 371 Options * 372 GetOptions () 373 { 374 return &m_option_group; 375 } 376 377 virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 378 { 379 return m_cmd_name.c_str(); 380 } 381 382 protected: 383 virtual bool 384 DoExecute (Args& command, CommandReturnObject &result) 385 { 386 // No need to check "target" for validity as eFlagRequiresTarget ensures it is valid 387 Target *target = m_exe_ctx.GetTargetPtr(); 388 389 const size_t argc = command.GetArgumentCount(); 390 391 if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2) 392 { 393 result.AppendErrorWithFormat ("%s takes a start address expression with an optional end address expression.\n", m_cmd_name.c_str()); 394 result.AppendRawWarning("Expressions should be quoted if they contain spaces or other special characters.\n"); 395 result.SetStatus(eReturnStatusFailed); 396 return false; 397 } 398 399 ClangASTType clang_ast_type; 400 Error error; 401 402 const char *view_as_type_cstr = m_memory_options.m_view_as_type.GetCurrentValue(); 403 if (view_as_type_cstr && view_as_type_cstr[0]) 404 { 405 // We are viewing memory as a type 406 407 SymbolContext sc; 408 const bool exact_match = false; 409 TypeList type_list; 410 uint32_t reference_count = 0; 411 uint32_t pointer_count = 0; 412 size_t idx; 413 414 #define ALL_KEYWORDS \ 415 KEYWORD("const") \ 416 KEYWORD("volatile") \ 417 KEYWORD("restrict") \ 418 KEYWORD("struct") \ 419 KEYWORD("class") \ 420 KEYWORD("union") 421 422 #define KEYWORD(s) s, 423 static const char *g_keywords[] = 424 { 425 ALL_KEYWORDS 426 }; 427 #undef KEYWORD 428 429 #define KEYWORD(s) (sizeof(s) - 1), 430 static const int g_keyword_lengths[] = 431 { 432 ALL_KEYWORDS 433 }; 434 #undef KEYWORD 435 436 #undef ALL_KEYWORDS 437 438 static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *); 439 std::string type_str(view_as_type_cstr); 440 441 // Remove all instances of g_keywords that are followed by spaces 442 for (size_t i = 0; i < g_num_keywords; ++i) 443 { 444 const char *keyword = g_keywords[i]; 445 int keyword_len = g_keyword_lengths[i]; 446 447 idx = 0; 448 while ((idx = type_str.find (keyword, idx)) != std::string::npos) 449 { 450 if (type_str[idx + keyword_len] == ' ' || type_str[idx + keyword_len] == '\t') 451 { 452 type_str.erase(idx, keyword_len+1); 453 idx = 0; 454 } 455 else 456 { 457 idx += keyword_len; 458 } 459 } 460 } 461 bool done = type_str.empty(); 462 // 463 idx = type_str.find_first_not_of (" \t"); 464 if (idx > 0 && idx != std::string::npos) 465 type_str.erase (0, idx); 466 while (!done) 467 { 468 // Strip trailing spaces 469 if (type_str.empty()) 470 done = true; 471 else 472 { 473 switch (type_str[type_str.size()-1]) 474 { 475 case '*': 476 ++pointer_count; 477 // fall through... 478 case ' ': 479 case '\t': 480 type_str.erase(type_str.size()-1); 481 break; 482 483 case '&': 484 if (reference_count == 0) 485 { 486 reference_count = 1; 487 type_str.erase(type_str.size()-1); 488 } 489 else 490 { 491 result.AppendErrorWithFormat ("invalid type string: '%s'\n", view_as_type_cstr); 492 result.SetStatus(eReturnStatusFailed); 493 return false; 494 } 495 break; 496 497 default: 498 done = true; 499 break; 500 } 501 } 502 } 503 504 ConstString lookup_type_name(type_str.c_str()); 505 StackFrame *frame = m_exe_ctx.GetFramePtr(); 506 if (frame) 507 { 508 sc = frame->GetSymbolContext (eSymbolContextModule); 509 if (sc.module_sp) 510 { 511 sc.module_sp->FindTypes (sc, 512 lookup_type_name, 513 exact_match, 514 1, 515 type_list); 516 } 517 } 518 if (type_list.GetSize() == 0) 519 { 520 target->GetImages().FindTypes (sc, 521 lookup_type_name, 522 exact_match, 523 1, 524 type_list); 525 } 526 527 if (type_list.GetSize() == 0 && lookup_type_name.GetCString() && *lookup_type_name.GetCString() == '$') 528 { 529 clang::TypeDecl *tdecl = target->GetPersistentVariables().GetPersistentType(ConstString(lookup_type_name)); 530 if (tdecl) 531 { 532 clang_ast_type.SetClangType(&tdecl->getASTContext(),(lldb::clang_type_t)tdecl->getTypeForDecl()); 533 } 534 } 535 536 if (clang_ast_type.IsValid() == false) 537 { 538 if (type_list.GetSize() == 0) 539 { 540 result.AppendErrorWithFormat ("unable to find any types that match the raw type '%s' for full type '%s'\n", 541 lookup_type_name.GetCString(), 542 view_as_type_cstr); 543 result.SetStatus(eReturnStatusFailed); 544 return false; 545 } 546 else 547 { 548 TypeSP type_sp (type_list.GetTypeAtIndex(0)); 549 clang_ast_type = type_sp->GetClangFullType(); 550 } 551 } 552 553 while (pointer_count > 0) 554 { 555 ClangASTType pointer_type = clang_ast_type.GetPointerType(); 556 if (pointer_type.IsValid()) 557 clang_ast_type = pointer_type; 558 else 559 { 560 result.AppendError ("unable make a pointer type\n"); 561 result.SetStatus(eReturnStatusFailed); 562 return false; 563 } 564 --pointer_count; 565 } 566 567 m_format_options.GetByteSizeValue() = clang_ast_type.GetByteSize(); 568 569 if (m_format_options.GetByteSizeValue() == 0) 570 { 571 result.AppendErrorWithFormat ("unable to get the byte size of the type '%s'\n", 572 view_as_type_cstr); 573 result.SetStatus(eReturnStatusFailed); 574 return false; 575 } 576 577 if (!m_format_options.GetCountValue().OptionWasSet()) 578 m_format_options.GetCountValue() = 1; 579 } 580 else 581 { 582 error = m_memory_options.FinalizeSettings (target, m_format_options); 583 } 584 585 // Look for invalid combinations of settings 586 if (error.Fail()) 587 { 588 result.AppendError(error.AsCString()); 589 result.SetStatus(eReturnStatusFailed); 590 return false; 591 } 592 593 lldb::addr_t addr; 594 size_t total_byte_size = 0; 595 if (argc == 0) 596 { 597 // Use the last address and byte size and all options as they were 598 // if no options have been set 599 addr = m_next_addr; 600 total_byte_size = m_prev_byte_size; 601 clang_ast_type = m_prev_clang_ast_type; 602 if (!m_format_options.AnyOptionWasSet() && 603 !m_memory_options.AnyOptionWasSet() && 604 !m_outfile_options.AnyOptionWasSet() && 605 !m_varobj_options.AnyOptionWasSet()) 606 { 607 m_format_options = m_prev_format_options; 608 m_memory_options = m_prev_memory_options; 609 m_outfile_options = m_prev_outfile_options; 610 m_varobj_options = m_prev_varobj_options; 611 } 612 } 613 614 size_t item_count = m_format_options.GetCountValue().GetCurrentValue(); 615 size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue(); 616 const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue(); 617 618 if (total_byte_size == 0) 619 { 620 total_byte_size = item_count * item_byte_size; 621 if (total_byte_size == 0) 622 total_byte_size = 32; 623 } 624 625 if (argc > 0) 626 addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error); 627 628 if (addr == LLDB_INVALID_ADDRESS) 629 { 630 result.AppendError("invalid start address expression."); 631 result.AppendError(error.AsCString()); 632 result.SetStatus(eReturnStatusFailed); 633 return false; 634 } 635 636 if (argc == 2) 637 { 638 lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0); 639 if (end_addr == LLDB_INVALID_ADDRESS) 640 { 641 result.AppendError("invalid end address expression."); 642 result.AppendError(error.AsCString()); 643 result.SetStatus(eReturnStatusFailed); 644 return false; 645 } 646 else if (end_addr <= addr) 647 { 648 result.AppendErrorWithFormat("end address (0x%" PRIx64 ") must be greater that the start address (0x%" PRIx64 ").\n", end_addr, addr); 649 result.SetStatus(eReturnStatusFailed); 650 return false; 651 } 652 else if (m_format_options.GetCountValue().OptionWasSet()) 653 { 654 result.AppendErrorWithFormat("specify either the end address (0x%" PRIx64 ") or the count (--count %lu), not both.\n", end_addr, item_count); 655 result.SetStatus(eReturnStatusFailed); 656 return false; 657 } 658 659 total_byte_size = end_addr - addr; 660 item_count = total_byte_size / item_byte_size; 661 } 662 663 uint32_t max_unforced_size = target->GetMaximumMemReadSize(); 664 665 if (total_byte_size > max_unforced_size && !m_memory_options.m_force) 666 { 667 result.AppendErrorWithFormat("Normally, \'memory read\' will not read over %" PRIu32 " bytes of data.\n",max_unforced_size); 668 result.AppendErrorWithFormat("Please use --force to override this restriction just once.\n"); 669 result.AppendErrorWithFormat("or set target.max-memory-read-size if you will often need a larger limit.\n"); 670 return false; 671 } 672 673 DataBufferSP data_sp; 674 size_t bytes_read = 0; 675 if (clang_ast_type.GetOpaqueQualType()) 676 { 677 // Make sure we don't display our type as ASCII bytes like the default memory read 678 if (m_format_options.GetFormatValue().OptionWasSet() == false) 679 m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault); 680 681 bytes_read = clang_ast_type.GetByteSize() * m_format_options.GetCountValue().GetCurrentValue(); 682 } 683 else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString) 684 { 685 data_sp.reset (new DataBufferHeap (total_byte_size, '\0')); 686 if (data_sp->GetBytes() == NULL) 687 { 688 result.AppendErrorWithFormat ("can't allocate 0x%zx bytes for the memory read buffer, specify a smaller size to read", total_byte_size); 689 result.SetStatus(eReturnStatusFailed); 690 return false; 691 } 692 693 Address address(addr, NULL); 694 bytes_read = target->ReadMemory(address, false, data_sp->GetBytes (), data_sp->GetByteSize(), error); 695 if (bytes_read == 0) 696 { 697 const char *error_cstr = error.AsCString(); 698 if (error_cstr && error_cstr[0]) 699 { 700 result.AppendError(error_cstr); 701 } 702 else 703 { 704 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr); 705 } 706 result.SetStatus(eReturnStatusFailed); 707 return false; 708 } 709 710 if (bytes_read < total_byte_size) 711 result.AppendWarningWithFormat("Not all bytes (%lu/%lu) were able to be read from 0x%" PRIx64 ".\n", bytes_read, total_byte_size, addr); 712 } 713 else 714 { 715 // we treat c-strings as a special case because they do not have a fixed size 716 if (m_format_options.GetByteSizeValue().OptionWasSet() && !m_format_options.HasGDBFormat()) 717 item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue(); 718 else 719 item_byte_size = target->GetMaximumSizeOfStringSummary(); 720 if (!m_format_options.GetCountValue().OptionWasSet()) 721 item_count = 1; 722 data_sp.reset (new DataBufferHeap ((item_byte_size+1) * item_count, '\0')); // account for NULLs as necessary 723 if (data_sp->GetBytes() == NULL) 724 { 725 result.AppendErrorWithFormat ("can't allocate 0x%" PRIx64 " bytes for the memory read buffer, specify a smaller size to read", (uint64_t)((item_byte_size+1) * item_count)); 726 result.SetStatus(eReturnStatusFailed); 727 return false; 728 } 729 uint8_t *data_ptr = data_sp->GetBytes(); 730 auto data_addr = addr; 731 auto count = item_count; 732 item_count = 0; 733 while (item_count < count) 734 { 735 std::string buffer; 736 buffer.resize(item_byte_size+1,0); 737 Error error; 738 size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0], item_byte_size+1, error); 739 if (error.Fail()) 740 { 741 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr); 742 result.SetStatus(eReturnStatusFailed); 743 return false; 744 } 745 if (item_byte_size == read) 746 { 747 result.AppendWarningWithFormat("unable to find a NULL terminated string at 0x%" PRIx64 ".Consider increasing the maximum read length.\n", data_addr); 748 break; 749 } 750 read+=1; // account for final NULL byte 751 memcpy(data_ptr, &buffer[0], read); 752 data_ptr += read; 753 data_addr += read; 754 bytes_read += read; 755 item_count++; // if we break early we know we only read item_count strings 756 } 757 data_sp.reset(new DataBufferHeap(data_sp->GetBytes(),bytes_read+1)); 758 } 759 760 m_next_addr = addr + bytes_read; 761 m_prev_byte_size = bytes_read; 762 m_prev_format_options = m_format_options; 763 m_prev_memory_options = m_memory_options; 764 m_prev_outfile_options = m_outfile_options; 765 m_prev_varobj_options = m_varobj_options; 766 m_prev_clang_ast_type = clang_ast_type; 767 768 StreamFile outfile_stream; 769 Stream *output_stream = NULL; 770 const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue(); 771 if (outfile_spec) 772 { 773 char path[PATH_MAX]; 774 outfile_spec.GetPath (path, sizeof(path)); 775 776 uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; 777 const bool append = m_outfile_options.GetAppend().GetCurrentValue(); 778 if (append) 779 open_options |= File::eOpenOptionAppend; 780 781 if (outfile_stream.GetFile ().Open (path, open_options).Success()) 782 { 783 if (m_memory_options.m_output_as_binary) 784 { 785 const size_t bytes_written = outfile_stream.Write (data_sp->GetBytes(), bytes_read); 786 if (bytes_written > 0) 787 { 788 result.GetOutputStream().Printf ("%zi bytes %s to '%s'\n", 789 bytes_written, 790 append ? "appended" : "written", 791 path); 792 return true; 793 } 794 else 795 { 796 result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", (uint64_t)bytes_read, path); 797 result.SetStatus(eReturnStatusFailed); 798 return false; 799 } 800 } 801 else 802 { 803 // We are going to write ASCII to the file just point the 804 // output_stream to our outfile_stream... 805 output_stream = &outfile_stream; 806 } 807 } 808 else 809 { 810 result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", path, append ? "append" : "write"); 811 result.SetStatus(eReturnStatusFailed); 812 return false; 813 } 814 } 815 else 816 { 817 output_stream = &result.GetOutputStream(); 818 } 819 820 821 ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope(); 822 if (clang_ast_type.GetOpaqueQualType()) 823 { 824 for (uint32_t i = 0; i<item_count; ++i) 825 { 826 addr_t item_addr = addr + (i * item_byte_size); 827 Address address (item_addr); 828 StreamString name_strm; 829 name_strm.Printf ("0x%" PRIx64, item_addr); 830 ValueObjectSP valobj_sp (ValueObjectMemory::Create (exe_scope, 831 name_strm.GetString().c_str(), 832 address, 833 clang_ast_type)); 834 if (valobj_sp) 835 { 836 Format format = m_format_options.GetFormat(); 837 if (format != eFormatDefault) 838 valobj_sp->SetFormat (format); 839 840 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(eLanguageRuntimeDescriptionDisplayVerbosityFull,format)); 841 842 valobj_sp->Dump(*output_stream,options); 843 } 844 else 845 { 846 result.AppendErrorWithFormat ("failed to create a value object for: (%s) %s\n", 847 view_as_type_cstr, 848 name_strm.GetString().c_str()); 849 result.SetStatus(eReturnStatusFailed); 850 return false; 851 } 852 } 853 return true; 854 } 855 856 result.SetStatus(eReturnStatusSuccessFinishResult); 857 DataExtractor data (data_sp, 858 target->GetArchitecture().GetByteOrder(), 859 target->GetArchitecture().GetAddressByteSize()); 860 861 Format format = m_format_options.GetFormat(); 862 if ( ( (format == eFormatChar) || (format == eFormatCharPrintable) ) 863 && (item_byte_size != 1) 864 && (item_count == 1)) 865 { 866 // this turns requests such as 867 // memory read -fc -s10 -c1 *charPtrPtr 868 // which make no sense (what is a char of size 10?) 869 // into a request for fetching 10 chars of size 1 from the same memory location 870 format = eFormatCharArray; 871 item_count = item_byte_size; 872 item_byte_size = 1; 873 } 874 875 assert (output_stream); 876 size_t bytes_dumped = data.Dump (output_stream, 877 0, 878 format, 879 item_byte_size, 880 item_count, 881 num_per_line, 882 addr, 883 0, 884 0, 885 exe_scope); 886 m_next_addr = addr + bytes_dumped; 887 output_stream->EOL(); 888 return true; 889 } 890 891 OptionGroupOptions m_option_group; 892 OptionGroupFormat m_format_options; 893 OptionGroupReadMemory m_memory_options; 894 OptionGroupOutputFile m_outfile_options; 895 OptionGroupValueObjectDisplay m_varobj_options; 896 lldb::addr_t m_next_addr; 897 lldb::addr_t m_prev_byte_size; 898 OptionGroupFormat m_prev_format_options; 899 OptionGroupReadMemory m_prev_memory_options; 900 OptionGroupOutputFile m_prev_outfile_options; 901 OptionGroupValueObjectDisplay m_prev_varobj_options; 902 ClangASTType m_prev_clang_ast_type; 903 }; 904 905 906 OptionDefinition 907 g_memory_write_option_table[] = 908 { 909 { LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFilename, "Write memory using the contents of a file."}, 910 { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset, "Start writng bytes from an offset within the input file."}, 911 }; 912 913 914 //---------------------------------------------------------------------- 915 // Write memory to the inferior process 916 //---------------------------------------------------------------------- 917 class CommandObjectMemoryWrite : public CommandObjectParsed 918 { 919 public: 920 921 class OptionGroupWriteMemory : public OptionGroup 922 { 923 public: 924 OptionGroupWriteMemory () : 925 OptionGroup() 926 { 927 } 928 929 virtual 930 ~OptionGroupWriteMemory () 931 { 932 } 933 934 virtual uint32_t 935 GetNumDefinitions () 936 { 937 return sizeof (g_memory_write_option_table) / sizeof (OptionDefinition); 938 } 939 940 virtual const OptionDefinition* 941 GetDefinitions () 942 { 943 return g_memory_write_option_table; 944 } 945 946 virtual Error 947 SetOptionValue (CommandInterpreter &interpreter, 948 uint32_t option_idx, 949 const char *option_arg) 950 { 951 Error error; 952 const int short_option = g_memory_write_option_table[option_idx].short_option; 953 954 switch (short_option) 955 { 956 case 'i': 957 m_infile.SetFile (option_arg, true); 958 if (!m_infile.Exists()) 959 { 960 m_infile.Clear(); 961 error.SetErrorStringWithFormat("input file does not exist: '%s'", option_arg); 962 } 963 break; 964 965 case 'o': 966 { 967 bool success; 968 m_infile_offset = Args::StringToUInt64(option_arg, 0, 0, &success); 969 if (!success) 970 { 971 error.SetErrorStringWithFormat("invalid offset string '%s'", option_arg); 972 } 973 } 974 break; 975 976 default: 977 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 978 break; 979 } 980 return error; 981 } 982 983 virtual void 984 OptionParsingStarting (CommandInterpreter &interpreter) 985 { 986 m_infile.Clear(); 987 m_infile_offset = 0; 988 } 989 990 FileSpec m_infile; 991 off_t m_infile_offset; 992 }; 993 994 CommandObjectMemoryWrite (CommandInterpreter &interpreter) : 995 CommandObjectParsed (interpreter, 996 "memory write", 997 "Write to the memory of the process being debugged.", 998 NULL, 999 eFlagRequiresProcess | eFlagProcessMustBeLaunched), 1000 m_option_group (interpreter), 1001 m_format_options (eFormatBytes, 1, UINT64_MAX), 1002 m_memory_options () 1003 { 1004 CommandArgumentEntry arg1; 1005 CommandArgumentEntry arg2; 1006 CommandArgumentData addr_arg; 1007 CommandArgumentData value_arg; 1008 1009 // Define the first (and only) variant of this arg. 1010 addr_arg.arg_type = eArgTypeAddress; 1011 addr_arg.arg_repetition = eArgRepeatPlain; 1012 1013 // There is only one variant this argument could be; put it into the argument entry. 1014 arg1.push_back (addr_arg); 1015 1016 // Define the first (and only) variant of this arg. 1017 value_arg.arg_type = eArgTypeValue; 1018 value_arg.arg_repetition = eArgRepeatPlus; 1019 1020 // There is only one variant this argument could be; put it into the argument entry. 1021 arg2.push_back (value_arg); 1022 1023 // Push the data for the first argument into the m_arguments vector. 1024 m_arguments.push_back (arg1); 1025 m_arguments.push_back (arg2); 1026 1027 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1); 1028 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_SIZE , LLDB_OPT_SET_1|LLDB_OPT_SET_2); 1029 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2); 1030 m_option_group.Finalize(); 1031 1032 } 1033 1034 virtual 1035 ~CommandObjectMemoryWrite () 1036 { 1037 } 1038 1039 Options * 1040 GetOptions () 1041 { 1042 return &m_option_group; 1043 } 1044 1045 bool 1046 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size) 1047 { 1048 if (total_byte_size > 8) 1049 return false; 1050 1051 if (total_byte_size == 8) 1052 return true; 1053 1054 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1; 1055 return uval64 <= max; 1056 } 1057 1058 bool 1059 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size) 1060 { 1061 if (total_byte_size > 8) 1062 return false; 1063 1064 if (total_byte_size == 8) 1065 return true; 1066 1067 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1; 1068 const int64_t min = ~(max); 1069 return min <= sval64 && sval64 <= max; 1070 } 1071 1072 protected: 1073 virtual bool 1074 DoExecute (Args& command, CommandReturnObject &result) 1075 { 1076 // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid 1077 Process *process = m_exe_ctx.GetProcessPtr(); 1078 1079 const size_t argc = command.GetArgumentCount(); 1080 1081 if (m_memory_options.m_infile) 1082 { 1083 if (argc < 1) 1084 { 1085 result.AppendErrorWithFormat ("%s takes a destination address when writing file contents.\n", m_cmd_name.c_str()); 1086 result.SetStatus(eReturnStatusFailed); 1087 return false; 1088 } 1089 } 1090 else if (argc < 2) 1091 { 1092 result.AppendErrorWithFormat ("%s takes a destination address and at least one value.\n", m_cmd_name.c_str()); 1093 result.SetStatus(eReturnStatusFailed); 1094 return false; 1095 } 1096 1097 StreamString buffer (Stream::eBinary, 1098 process->GetTarget().GetArchitecture().GetAddressByteSize(), 1099 process->GetTarget().GetArchitecture().GetByteOrder()); 1100 1101 OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue(); 1102 size_t item_byte_size = byte_size_value.GetCurrentValue(); 1103 1104 Error error; 1105 lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx, 1106 command.GetArgumentAtIndex(0), 1107 LLDB_INVALID_ADDRESS, 1108 &error); 1109 1110 if (addr == LLDB_INVALID_ADDRESS) 1111 { 1112 result.AppendError("invalid address expression\n"); 1113 result.AppendError(error.AsCString()); 1114 result.SetStatus(eReturnStatusFailed); 1115 return false; 1116 } 1117 1118 if (m_memory_options.m_infile) 1119 { 1120 size_t length = SIZE_MAX; 1121 if (item_byte_size > 0) 1122 length = item_byte_size; 1123 lldb::DataBufferSP data_sp (m_memory_options.m_infile.ReadFileContents (m_memory_options.m_infile_offset, length)); 1124 if (data_sp) 1125 { 1126 length = data_sp->GetByteSize(); 1127 if (length > 0) 1128 { 1129 Error error; 1130 size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error); 1131 1132 if (bytes_written == length) 1133 { 1134 // All bytes written 1135 result.GetOutputStream().Printf("%" PRIu64 " bytes were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, addr); 1136 result.SetStatus(eReturnStatusSuccessFinishResult); 1137 } 1138 else if (bytes_written > 0) 1139 { 1140 // Some byte written 1141 result.GetOutputStream().Printf("%" PRIu64 " bytes of %" PRIu64 " requested were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, (uint64_t)length, addr); 1142 result.SetStatus(eReturnStatusSuccessFinishResult); 1143 } 1144 else 1145 { 1146 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); 1147 result.SetStatus(eReturnStatusFailed); 1148 } 1149 } 1150 } 1151 else 1152 { 1153 result.AppendErrorWithFormat ("Unable to read contents of file.\n"); 1154 result.SetStatus(eReturnStatusFailed); 1155 } 1156 return result.Succeeded(); 1157 } 1158 else if (item_byte_size == 0) 1159 { 1160 if (m_format_options.GetFormat() == eFormatPointer) 1161 item_byte_size = buffer.GetAddressByteSize(); 1162 else 1163 item_byte_size = 1; 1164 } 1165 1166 command.Shift(); // shift off the address argument 1167 uint64_t uval64; 1168 int64_t sval64; 1169 bool success = false; 1170 const size_t num_value_args = command.GetArgumentCount(); 1171 for (size_t i=0; i<num_value_args; ++i) 1172 { 1173 const char *value_str = command.GetArgumentAtIndex(i); 1174 1175 switch (m_format_options.GetFormat()) 1176 { 1177 case kNumFormats: 1178 case eFormatFloat: // TODO: add support for floats soon 1179 case eFormatCharPrintable: 1180 case eFormatBytesWithASCII: 1181 case eFormatComplex: 1182 case eFormatEnum: 1183 case eFormatUnicode16: 1184 case eFormatUnicode32: 1185 case eFormatVectorOfChar: 1186 case eFormatVectorOfSInt8: 1187 case eFormatVectorOfUInt8: 1188 case eFormatVectorOfSInt16: 1189 case eFormatVectorOfUInt16: 1190 case eFormatVectorOfSInt32: 1191 case eFormatVectorOfUInt32: 1192 case eFormatVectorOfSInt64: 1193 case eFormatVectorOfUInt64: 1194 case eFormatVectorOfFloat32: 1195 case eFormatVectorOfFloat64: 1196 case eFormatVectorOfUInt128: 1197 case eFormatOSType: 1198 case eFormatComplexInteger: 1199 case eFormatAddressInfo: 1200 case eFormatHexFloat: 1201 case eFormatInstruction: 1202 case eFormatVoid: 1203 result.AppendError("unsupported format for writing memory"); 1204 result.SetStatus(eReturnStatusFailed); 1205 return false; 1206 1207 case eFormatDefault: 1208 case eFormatBytes: 1209 case eFormatHex: 1210 case eFormatHexUppercase: 1211 case eFormatPointer: 1212 1213 // Decode hex bytes 1214 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success); 1215 if (!success) 1216 { 1217 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str); 1218 result.SetStatus(eReturnStatusFailed); 1219 return false; 1220 } 1221 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1222 { 1223 result.AppendErrorWithFormat ("Value 0x%" PRIx64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size); 1224 result.SetStatus(eReturnStatusFailed); 1225 return false; 1226 } 1227 buffer.PutMaxHex64 (uval64, item_byte_size); 1228 break; 1229 1230 case eFormatBoolean: 1231 uval64 = Args::StringToBoolean(value_str, false, &success); 1232 if (!success) 1233 { 1234 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str); 1235 result.SetStatus(eReturnStatusFailed); 1236 return false; 1237 } 1238 buffer.PutMaxHex64 (uval64, item_byte_size); 1239 break; 1240 1241 case eFormatBinary: 1242 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success); 1243 if (!success) 1244 { 1245 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str); 1246 result.SetStatus(eReturnStatusFailed); 1247 return false; 1248 } 1249 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1250 { 1251 result.AppendErrorWithFormat ("Value 0x%" PRIx64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size); 1252 result.SetStatus(eReturnStatusFailed); 1253 return false; 1254 } 1255 buffer.PutMaxHex64 (uval64, item_byte_size); 1256 break; 1257 1258 case eFormatCharArray: 1259 case eFormatChar: 1260 case eFormatCString: 1261 if (value_str[0]) 1262 { 1263 size_t len = strlen (value_str); 1264 // Include the NULL for C strings... 1265 if (m_format_options.GetFormat() == eFormatCString) 1266 ++len; 1267 Error error; 1268 if (process->WriteMemory (addr, value_str, len, error) == len) 1269 { 1270 addr += len; 1271 } 1272 else 1273 { 1274 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); 1275 result.SetStatus(eReturnStatusFailed); 1276 return false; 1277 } 1278 } 1279 break; 1280 1281 case eFormatDecimal: 1282 sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success); 1283 if (!success) 1284 { 1285 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str); 1286 result.SetStatus(eReturnStatusFailed); 1287 return false; 1288 } 1289 else if (!SIntValueIsValidForSize (sval64, item_byte_size)) 1290 { 1291 result.AppendErrorWithFormat ("Value %" PRIi64 " is too large or small to fit in a %lu byte signed integer value.\n", sval64, item_byte_size); 1292 result.SetStatus(eReturnStatusFailed); 1293 return false; 1294 } 1295 buffer.PutMaxHex64 (sval64, item_byte_size); 1296 break; 1297 1298 case eFormatUnsigned: 1299 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success); 1300 if (!success) 1301 { 1302 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str); 1303 result.SetStatus(eReturnStatusFailed); 1304 return false; 1305 } 1306 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1307 { 1308 result.AppendErrorWithFormat ("Value %" PRIu64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size); 1309 result.SetStatus(eReturnStatusFailed); 1310 return false; 1311 } 1312 buffer.PutMaxHex64 (uval64, item_byte_size); 1313 break; 1314 1315 case eFormatOctal: 1316 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success); 1317 if (!success) 1318 { 1319 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str); 1320 result.SetStatus(eReturnStatusFailed); 1321 return false; 1322 } 1323 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1324 { 1325 result.AppendErrorWithFormat ("Value %" PRIo64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size); 1326 result.SetStatus(eReturnStatusFailed); 1327 return false; 1328 } 1329 buffer.PutMaxHex64 (uval64, item_byte_size); 1330 break; 1331 } 1332 } 1333 1334 if (!buffer.GetString().empty()) 1335 { 1336 Error error; 1337 if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size()) 1338 return true; 1339 else 1340 { 1341 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); 1342 result.SetStatus(eReturnStatusFailed); 1343 return false; 1344 } 1345 } 1346 return true; 1347 } 1348 1349 OptionGroupOptions m_option_group; 1350 OptionGroupFormat m_format_options; 1351 OptionGroupWriteMemory m_memory_options; 1352 }; 1353 1354 1355 //------------------------------------------------------------------------- 1356 // CommandObjectMemory 1357 //------------------------------------------------------------------------- 1358 1359 CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) : 1360 CommandObjectMultiword (interpreter, 1361 "memory", 1362 "A set of commands for operating on memory.", 1363 "memory <subcommand> [<subcommand-options>]") 1364 { 1365 LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter))); 1366 LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter))); 1367 } 1368 1369 CommandObjectMemory::~CommandObjectMemory () 1370 { 1371 } 1372