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 { 865 // if a count was not passed, or it is 1 866 if (m_format_options.GetCountValue().OptionWasSet() == false || item_count == 1) 867 { 868 // this turns requests such as 869 // memory read -fc -s10 -c1 *charPtrPtr 870 // which make no sense (what is a char of size 10?) 871 // into a request for fetching 10 chars of size 1 from the same memory location 872 format = eFormatCharArray; 873 item_count = item_byte_size; 874 item_byte_size = 1; 875 } 876 else 877 { 878 // here we passed a count, and it was not 1 879 // so we have a byte_size and a count 880 // we could well multiply those, but instead let's just fail 881 result.AppendErrorWithFormat("reading memory as characters of size %zu is not supported", item_byte_size); 882 result.SetStatus(eReturnStatusFailed); 883 return false; 884 } 885 } 886 887 assert (output_stream); 888 size_t bytes_dumped = data.Dump (output_stream, 889 0, 890 format, 891 item_byte_size, 892 item_count, 893 num_per_line, 894 addr, 895 0, 896 0, 897 exe_scope); 898 m_next_addr = addr + bytes_dumped; 899 output_stream->EOL(); 900 return true; 901 } 902 903 OptionGroupOptions m_option_group; 904 OptionGroupFormat m_format_options; 905 OptionGroupReadMemory m_memory_options; 906 OptionGroupOutputFile m_outfile_options; 907 OptionGroupValueObjectDisplay m_varobj_options; 908 lldb::addr_t m_next_addr; 909 lldb::addr_t m_prev_byte_size; 910 OptionGroupFormat m_prev_format_options; 911 OptionGroupReadMemory m_prev_memory_options; 912 OptionGroupOutputFile m_prev_outfile_options; 913 OptionGroupValueObjectDisplay m_prev_varobj_options; 914 ClangASTType m_prev_clang_ast_type; 915 }; 916 917 918 OptionDefinition 919 g_memory_write_option_table[] = 920 { 921 { LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFilename, "Write memory using the contents of a file."}, 922 { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset, "Start writng bytes from an offset within the input file."}, 923 }; 924 925 926 //---------------------------------------------------------------------- 927 // Write memory to the inferior process 928 //---------------------------------------------------------------------- 929 class CommandObjectMemoryWrite : public CommandObjectParsed 930 { 931 public: 932 933 class OptionGroupWriteMemory : public OptionGroup 934 { 935 public: 936 OptionGroupWriteMemory () : 937 OptionGroup() 938 { 939 } 940 941 virtual 942 ~OptionGroupWriteMemory () 943 { 944 } 945 946 virtual uint32_t 947 GetNumDefinitions () 948 { 949 return sizeof (g_memory_write_option_table) / sizeof (OptionDefinition); 950 } 951 952 virtual const OptionDefinition* 953 GetDefinitions () 954 { 955 return g_memory_write_option_table; 956 } 957 958 virtual Error 959 SetOptionValue (CommandInterpreter &interpreter, 960 uint32_t option_idx, 961 const char *option_arg) 962 { 963 Error error; 964 const int short_option = g_memory_write_option_table[option_idx].short_option; 965 966 switch (short_option) 967 { 968 case 'i': 969 m_infile.SetFile (option_arg, true); 970 if (!m_infile.Exists()) 971 { 972 m_infile.Clear(); 973 error.SetErrorStringWithFormat("input file does not exist: '%s'", option_arg); 974 } 975 break; 976 977 case 'o': 978 { 979 bool success; 980 m_infile_offset = Args::StringToUInt64(option_arg, 0, 0, &success); 981 if (!success) 982 { 983 error.SetErrorStringWithFormat("invalid offset string '%s'", option_arg); 984 } 985 } 986 break; 987 988 default: 989 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 990 break; 991 } 992 return error; 993 } 994 995 virtual void 996 OptionParsingStarting (CommandInterpreter &interpreter) 997 { 998 m_infile.Clear(); 999 m_infile_offset = 0; 1000 } 1001 1002 FileSpec m_infile; 1003 off_t m_infile_offset; 1004 }; 1005 1006 CommandObjectMemoryWrite (CommandInterpreter &interpreter) : 1007 CommandObjectParsed (interpreter, 1008 "memory write", 1009 "Write to the memory of the process being debugged.", 1010 NULL, 1011 eFlagRequiresProcess | eFlagProcessMustBeLaunched), 1012 m_option_group (interpreter), 1013 m_format_options (eFormatBytes, 1, UINT64_MAX), 1014 m_memory_options () 1015 { 1016 CommandArgumentEntry arg1; 1017 CommandArgumentEntry arg2; 1018 CommandArgumentData addr_arg; 1019 CommandArgumentData value_arg; 1020 1021 // Define the first (and only) variant of this arg. 1022 addr_arg.arg_type = eArgTypeAddress; 1023 addr_arg.arg_repetition = eArgRepeatPlain; 1024 1025 // There is only one variant this argument could be; put it into the argument entry. 1026 arg1.push_back (addr_arg); 1027 1028 // Define the first (and only) variant of this arg. 1029 value_arg.arg_type = eArgTypeValue; 1030 value_arg.arg_repetition = eArgRepeatPlus; 1031 1032 // There is only one variant this argument could be; put it into the argument entry. 1033 arg2.push_back (value_arg); 1034 1035 // Push the data for the first argument into the m_arguments vector. 1036 m_arguments.push_back (arg1); 1037 m_arguments.push_back (arg2); 1038 1039 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1); 1040 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_SIZE , LLDB_OPT_SET_1|LLDB_OPT_SET_2); 1041 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2); 1042 m_option_group.Finalize(); 1043 1044 } 1045 1046 virtual 1047 ~CommandObjectMemoryWrite () 1048 { 1049 } 1050 1051 Options * 1052 GetOptions () 1053 { 1054 return &m_option_group; 1055 } 1056 1057 bool 1058 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size) 1059 { 1060 if (total_byte_size > 8) 1061 return false; 1062 1063 if (total_byte_size == 8) 1064 return true; 1065 1066 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1; 1067 return uval64 <= max; 1068 } 1069 1070 bool 1071 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size) 1072 { 1073 if (total_byte_size > 8) 1074 return false; 1075 1076 if (total_byte_size == 8) 1077 return true; 1078 1079 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1; 1080 const int64_t min = ~(max); 1081 return min <= sval64 && sval64 <= max; 1082 } 1083 1084 protected: 1085 virtual bool 1086 DoExecute (Args& command, CommandReturnObject &result) 1087 { 1088 // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid 1089 Process *process = m_exe_ctx.GetProcessPtr(); 1090 1091 const size_t argc = command.GetArgumentCount(); 1092 1093 if (m_memory_options.m_infile) 1094 { 1095 if (argc < 1) 1096 { 1097 result.AppendErrorWithFormat ("%s takes a destination address when writing file contents.\n", m_cmd_name.c_str()); 1098 result.SetStatus(eReturnStatusFailed); 1099 return false; 1100 } 1101 } 1102 else if (argc < 2) 1103 { 1104 result.AppendErrorWithFormat ("%s takes a destination address and at least one value.\n", m_cmd_name.c_str()); 1105 result.SetStatus(eReturnStatusFailed); 1106 return false; 1107 } 1108 1109 StreamString buffer (Stream::eBinary, 1110 process->GetTarget().GetArchitecture().GetAddressByteSize(), 1111 process->GetTarget().GetArchitecture().GetByteOrder()); 1112 1113 OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue(); 1114 size_t item_byte_size = byte_size_value.GetCurrentValue(); 1115 1116 Error error; 1117 lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx, 1118 command.GetArgumentAtIndex(0), 1119 LLDB_INVALID_ADDRESS, 1120 &error); 1121 1122 if (addr == LLDB_INVALID_ADDRESS) 1123 { 1124 result.AppendError("invalid address expression\n"); 1125 result.AppendError(error.AsCString()); 1126 result.SetStatus(eReturnStatusFailed); 1127 return false; 1128 } 1129 1130 if (m_memory_options.m_infile) 1131 { 1132 size_t length = SIZE_MAX; 1133 if (item_byte_size > 0) 1134 length = item_byte_size; 1135 lldb::DataBufferSP data_sp (m_memory_options.m_infile.ReadFileContents (m_memory_options.m_infile_offset, length)); 1136 if (data_sp) 1137 { 1138 length = data_sp->GetByteSize(); 1139 if (length > 0) 1140 { 1141 Error error; 1142 size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error); 1143 1144 if (bytes_written == length) 1145 { 1146 // All bytes written 1147 result.GetOutputStream().Printf("%" PRIu64 " bytes were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, addr); 1148 result.SetStatus(eReturnStatusSuccessFinishResult); 1149 } 1150 else if (bytes_written > 0) 1151 { 1152 // Some byte written 1153 result.GetOutputStream().Printf("%" PRIu64 " bytes of %" PRIu64 " requested were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, (uint64_t)length, addr); 1154 result.SetStatus(eReturnStatusSuccessFinishResult); 1155 } 1156 else 1157 { 1158 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); 1159 result.SetStatus(eReturnStatusFailed); 1160 } 1161 } 1162 } 1163 else 1164 { 1165 result.AppendErrorWithFormat ("Unable to read contents of file.\n"); 1166 result.SetStatus(eReturnStatusFailed); 1167 } 1168 return result.Succeeded(); 1169 } 1170 else if (item_byte_size == 0) 1171 { 1172 if (m_format_options.GetFormat() == eFormatPointer) 1173 item_byte_size = buffer.GetAddressByteSize(); 1174 else 1175 item_byte_size = 1; 1176 } 1177 1178 command.Shift(); // shift off the address argument 1179 uint64_t uval64; 1180 int64_t sval64; 1181 bool success = false; 1182 const size_t num_value_args = command.GetArgumentCount(); 1183 for (size_t i=0; i<num_value_args; ++i) 1184 { 1185 const char *value_str = command.GetArgumentAtIndex(i); 1186 1187 switch (m_format_options.GetFormat()) 1188 { 1189 case kNumFormats: 1190 case eFormatFloat: // TODO: add support for floats soon 1191 case eFormatCharPrintable: 1192 case eFormatBytesWithASCII: 1193 case eFormatComplex: 1194 case eFormatEnum: 1195 case eFormatUnicode16: 1196 case eFormatUnicode32: 1197 case eFormatVectorOfChar: 1198 case eFormatVectorOfSInt8: 1199 case eFormatVectorOfUInt8: 1200 case eFormatVectorOfSInt16: 1201 case eFormatVectorOfUInt16: 1202 case eFormatVectorOfSInt32: 1203 case eFormatVectorOfUInt32: 1204 case eFormatVectorOfSInt64: 1205 case eFormatVectorOfUInt64: 1206 case eFormatVectorOfFloat32: 1207 case eFormatVectorOfFloat64: 1208 case eFormatVectorOfUInt128: 1209 case eFormatOSType: 1210 case eFormatComplexInteger: 1211 case eFormatAddressInfo: 1212 case eFormatHexFloat: 1213 case eFormatInstruction: 1214 case eFormatVoid: 1215 result.AppendError("unsupported format for writing memory"); 1216 result.SetStatus(eReturnStatusFailed); 1217 return false; 1218 1219 case eFormatDefault: 1220 case eFormatBytes: 1221 case eFormatHex: 1222 case eFormatHexUppercase: 1223 case eFormatPointer: 1224 1225 // Decode hex bytes 1226 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success); 1227 if (!success) 1228 { 1229 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str); 1230 result.SetStatus(eReturnStatusFailed); 1231 return false; 1232 } 1233 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1234 { 1235 result.AppendErrorWithFormat ("Value 0x%" PRIx64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size); 1236 result.SetStatus(eReturnStatusFailed); 1237 return false; 1238 } 1239 buffer.PutMaxHex64 (uval64, item_byte_size); 1240 break; 1241 1242 case eFormatBoolean: 1243 uval64 = Args::StringToBoolean(value_str, false, &success); 1244 if (!success) 1245 { 1246 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str); 1247 result.SetStatus(eReturnStatusFailed); 1248 return false; 1249 } 1250 buffer.PutMaxHex64 (uval64, item_byte_size); 1251 break; 1252 1253 case eFormatBinary: 1254 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success); 1255 if (!success) 1256 { 1257 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str); 1258 result.SetStatus(eReturnStatusFailed); 1259 return false; 1260 } 1261 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1262 { 1263 result.AppendErrorWithFormat ("Value 0x%" PRIx64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size); 1264 result.SetStatus(eReturnStatusFailed); 1265 return false; 1266 } 1267 buffer.PutMaxHex64 (uval64, item_byte_size); 1268 break; 1269 1270 case eFormatCharArray: 1271 case eFormatChar: 1272 case eFormatCString: 1273 if (value_str[0]) 1274 { 1275 size_t len = strlen (value_str); 1276 // Include the NULL for C strings... 1277 if (m_format_options.GetFormat() == eFormatCString) 1278 ++len; 1279 Error error; 1280 if (process->WriteMemory (addr, value_str, len, error) == len) 1281 { 1282 addr += len; 1283 } 1284 else 1285 { 1286 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); 1287 result.SetStatus(eReturnStatusFailed); 1288 return false; 1289 } 1290 } 1291 break; 1292 1293 case eFormatDecimal: 1294 sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success); 1295 if (!success) 1296 { 1297 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str); 1298 result.SetStatus(eReturnStatusFailed); 1299 return false; 1300 } 1301 else if (!SIntValueIsValidForSize (sval64, item_byte_size)) 1302 { 1303 result.AppendErrorWithFormat ("Value %" PRIi64 " is too large or small to fit in a %lu byte signed integer value.\n", sval64, item_byte_size); 1304 result.SetStatus(eReturnStatusFailed); 1305 return false; 1306 } 1307 buffer.PutMaxHex64 (sval64, item_byte_size); 1308 break; 1309 1310 case eFormatUnsigned: 1311 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success); 1312 if (!success) 1313 { 1314 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str); 1315 result.SetStatus(eReturnStatusFailed); 1316 return false; 1317 } 1318 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1319 { 1320 result.AppendErrorWithFormat ("Value %" PRIu64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size); 1321 result.SetStatus(eReturnStatusFailed); 1322 return false; 1323 } 1324 buffer.PutMaxHex64 (uval64, item_byte_size); 1325 break; 1326 1327 case eFormatOctal: 1328 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success); 1329 if (!success) 1330 { 1331 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str); 1332 result.SetStatus(eReturnStatusFailed); 1333 return false; 1334 } 1335 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1336 { 1337 result.AppendErrorWithFormat ("Value %" PRIo64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size); 1338 result.SetStatus(eReturnStatusFailed); 1339 return false; 1340 } 1341 buffer.PutMaxHex64 (uval64, item_byte_size); 1342 break; 1343 } 1344 } 1345 1346 if (!buffer.GetString().empty()) 1347 { 1348 Error error; 1349 if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size()) 1350 return true; 1351 else 1352 { 1353 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); 1354 result.SetStatus(eReturnStatusFailed); 1355 return false; 1356 } 1357 } 1358 return true; 1359 } 1360 1361 OptionGroupOptions m_option_group; 1362 OptionGroupFormat m_format_options; 1363 OptionGroupWriteMemory m_memory_options; 1364 }; 1365 1366 1367 //------------------------------------------------------------------------- 1368 // CommandObjectMemory 1369 //------------------------------------------------------------------------- 1370 1371 CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) : 1372 CommandObjectMultiword (interpreter, 1373 "memory", 1374 "A set of commands for operating on memory.", 1375 "memory <subcommand> [<subcommand-options>]") 1376 { 1377 LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter))); 1378 LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter))); 1379 } 1380 1381 CommandObjectMemory::~CommandObjectMemory () 1382 { 1383 } 1384