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/Host/StringConvert.h" 28 #include "lldb/Interpreter/Args.h" 29 #include "lldb/Interpreter/CommandReturnObject.h" 30 #include "lldb/Interpreter/CommandInterpreter.h" 31 #include "lldb/Interpreter/Options.h" 32 #include "lldb/Interpreter/OptionGroupFormat.h" 33 #include "lldb/Interpreter/OptionGroupOutputFile.h" 34 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" 35 #include "lldb/Interpreter/OptionValueString.h" 36 #include "lldb/Symbol/TypeList.h" 37 #include "lldb/Target/MemoryHistory.h" 38 #include "lldb/Target/Process.h" 39 #include "lldb/Target/StackFrame.h" 40 #include "lldb/Target/Thread.h" 41 42 using namespace lldb; 43 using namespace lldb_private; 44 45 static OptionDefinition 46 g_option_table[] = 47 { 48 { LLDB_OPT_SET_1, false, "num-per-line" ,'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNumberPerLine ,"The number of items per line to display."}, 49 { LLDB_OPT_SET_2, false, "binary" ,'b', OptionParser::eNoArgument , NULL, 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."}, 50 { LLDB_OPT_SET_3, true , "type" ,'t', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone ,"The name of a type to view memory as."}, 51 { LLDB_OPT_SET_1| 52 LLDB_OPT_SET_2| 53 LLDB_OPT_SET_3, false, "force" ,'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone ,"Necessary if reading over target.max-memory-read-size bytes."}, 54 }; 55 56 57 58 class OptionGroupReadMemory : public OptionGroup 59 { 60 public: 61 62 OptionGroupReadMemory () : 63 m_num_per_line (1,1), 64 m_output_as_binary (false), 65 m_view_as_type() 66 { 67 } 68 69 virtual 70 ~OptionGroupReadMemory () 71 { 72 } 73 74 75 virtual uint32_t 76 GetNumDefinitions () 77 { 78 return sizeof (g_option_table) / sizeof (OptionDefinition); 79 } 80 81 virtual const OptionDefinition* 82 GetDefinitions () 83 { 84 return g_option_table; 85 } 86 87 virtual Error 88 SetOptionValue (CommandInterpreter &interpreter, 89 uint32_t option_idx, 90 const char *option_arg) 91 { 92 Error error; 93 const int short_option = g_option_table[option_idx].short_option; 94 95 switch (short_option) 96 { 97 case 'l': 98 error = m_num_per_line.SetValueFromString (option_arg); 99 if (m_num_per_line.GetCurrentValue() == 0) 100 error.SetErrorStringWithFormat("invalid value for --num-per-line option '%s'", option_arg); 101 break; 102 103 case 'b': 104 m_output_as_binary = true; 105 break; 106 107 case 't': 108 error = m_view_as_type.SetValueFromString (option_arg); 109 break; 110 111 case 'r': 112 m_force = true; 113 break; 114 115 default: 116 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 117 break; 118 } 119 return error; 120 } 121 122 virtual void 123 OptionParsingStarting (CommandInterpreter &interpreter) 124 { 125 m_num_per_line.Clear(); 126 m_output_as_binary = false; 127 m_view_as_type.Clear(); 128 m_force = false; 129 } 130 131 Error 132 FinalizeSettings (Target *target, OptionGroupFormat& format_options) 133 { 134 Error error; 135 OptionValueUInt64 &byte_size_value = format_options.GetByteSizeValue(); 136 OptionValueUInt64 &count_value = format_options.GetCountValue(); 137 const bool byte_size_option_set = byte_size_value.OptionWasSet(); 138 const bool num_per_line_option_set = m_num_per_line.OptionWasSet(); 139 const bool count_option_set = format_options.GetCountValue().OptionWasSet(); 140 141 switch (format_options.GetFormat()) 142 { 143 default: 144 break; 145 146 case eFormatBoolean: 147 if (!byte_size_option_set) 148 byte_size_value = 1; 149 if (!num_per_line_option_set) 150 m_num_per_line = 1; 151 if (!count_option_set) 152 format_options.GetCountValue() = 8; 153 break; 154 155 case eFormatCString: 156 break; 157 158 case eFormatInstruction: 159 if (count_option_set) 160 byte_size_value = target->GetArchitecture().GetMaximumOpcodeByteSize(); 161 m_num_per_line = 1; 162 break; 163 164 case eFormatAddressInfo: 165 if (!byte_size_option_set) 166 byte_size_value = target->GetArchitecture().GetAddressByteSize(); 167 m_num_per_line = 1; 168 if (!count_option_set) 169 format_options.GetCountValue() = 8; 170 break; 171 172 case eFormatPointer: 173 byte_size_value = target->GetArchitecture().GetAddressByteSize(); 174 if (!num_per_line_option_set) 175 m_num_per_line = 4; 176 if (!count_option_set) 177 format_options.GetCountValue() = 8; 178 break; 179 180 case eFormatBinary: 181 case eFormatFloat: 182 case eFormatOctal: 183 case eFormatDecimal: 184 case eFormatEnum: 185 case eFormatUnicode16: 186 case eFormatUnicode32: 187 case eFormatUnsigned: 188 case eFormatHexFloat: 189 if (!byte_size_option_set) 190 byte_size_value = 4; 191 if (!num_per_line_option_set) 192 m_num_per_line = 1; 193 if (!count_option_set) 194 format_options.GetCountValue() = 8; 195 break; 196 197 case eFormatBytes: 198 case eFormatBytesWithASCII: 199 if (byte_size_option_set) 200 { 201 if (byte_size_value > 1) 202 error.SetErrorStringWithFormat ("display format (bytes/bytes with ascii) conflicts with the specified byte size %" PRIu64 "\n" 203 "\tconsider using a different display format or don't specify the byte size", 204 byte_size_value.GetCurrentValue()); 205 } 206 else 207 byte_size_value = 1; 208 if (!num_per_line_option_set) 209 m_num_per_line = 16; 210 if (!count_option_set) 211 format_options.GetCountValue() = 32; 212 break; 213 case eFormatCharArray: 214 case eFormatChar: 215 case eFormatCharPrintable: 216 if (!byte_size_option_set) 217 byte_size_value = 1; 218 if (!num_per_line_option_set) 219 m_num_per_line = 32; 220 if (!count_option_set) 221 format_options.GetCountValue() = 64; 222 break; 223 case eFormatComplex: 224 if (!byte_size_option_set) 225 byte_size_value = 8; 226 if (!num_per_line_option_set) 227 m_num_per_line = 1; 228 if (!count_option_set) 229 format_options.GetCountValue() = 8; 230 break; 231 case eFormatComplexInteger: 232 if (!byte_size_option_set) 233 byte_size_value = 8; 234 if (!num_per_line_option_set) 235 m_num_per_line = 1; 236 if (!count_option_set) 237 format_options.GetCountValue() = 8; 238 break; 239 case eFormatHex: 240 if (!byte_size_option_set) 241 byte_size_value = 4; 242 if (!num_per_line_option_set) 243 { 244 switch (byte_size_value) 245 { 246 case 1: 247 case 2: 248 m_num_per_line = 8; 249 break; 250 case 4: 251 m_num_per_line = 4; 252 break; 253 case 8: 254 m_num_per_line = 2; 255 break; 256 default: 257 m_num_per_line = 1; 258 break; 259 } 260 } 261 if (!count_option_set) 262 count_value = 8; 263 break; 264 265 case eFormatVectorOfChar: 266 case eFormatVectorOfSInt8: 267 case eFormatVectorOfUInt8: 268 case eFormatVectorOfSInt16: 269 case eFormatVectorOfUInt16: 270 case eFormatVectorOfSInt32: 271 case eFormatVectorOfUInt32: 272 case eFormatVectorOfSInt64: 273 case eFormatVectorOfUInt64: 274 case eFormatVectorOfFloat32: 275 case eFormatVectorOfFloat64: 276 case eFormatVectorOfUInt128: 277 if (!byte_size_option_set) 278 byte_size_value = 128; 279 if (!num_per_line_option_set) 280 m_num_per_line = 1; 281 if (!count_option_set) 282 count_value = 4; 283 break; 284 } 285 return error; 286 } 287 288 bool 289 AnyOptionWasSet () const 290 { 291 return m_num_per_line.OptionWasSet() || 292 m_output_as_binary || 293 m_view_as_type.OptionWasSet(); 294 } 295 296 OptionValueUInt64 m_num_per_line; 297 bool m_output_as_binary; 298 OptionValueString m_view_as_type; 299 bool m_force; 300 }; 301 302 303 304 //---------------------------------------------------------------------- 305 // Read memory from the inferior process 306 //---------------------------------------------------------------------- 307 class CommandObjectMemoryRead : public CommandObjectParsed 308 { 309 public: 310 311 CommandObjectMemoryRead (CommandInterpreter &interpreter) : 312 CommandObjectParsed (interpreter, 313 "memory read", 314 "Read from the memory of the process being debugged.", 315 NULL, 316 eFlagRequiresTarget | eFlagProcessMustBePaused), 317 m_option_group (interpreter), 318 m_format_options (eFormatBytesWithASCII, 1, 8), 319 m_memory_options (), 320 m_outfile_options (), 321 m_varobj_options(), 322 m_next_addr(LLDB_INVALID_ADDRESS), 323 m_prev_byte_size(0), 324 m_prev_format_options (eFormatBytesWithASCII, 1, 8), 325 m_prev_memory_options (), 326 m_prev_outfile_options (), 327 m_prev_varobj_options() 328 { 329 CommandArgumentEntry arg1; 330 CommandArgumentEntry arg2; 331 CommandArgumentData start_addr_arg; 332 CommandArgumentData end_addr_arg; 333 334 // Define the first (and only) variant of this arg. 335 start_addr_arg.arg_type = eArgTypeAddressOrExpression; 336 start_addr_arg.arg_repetition = eArgRepeatPlain; 337 338 // There is only one variant this argument could be; put it into the argument entry. 339 arg1.push_back (start_addr_arg); 340 341 // Define the first (and only) variant of this arg. 342 end_addr_arg.arg_type = eArgTypeAddressOrExpression; 343 end_addr_arg.arg_repetition = eArgRepeatOptional; 344 345 // There is only one variant this argument could be; put it into the argument entry. 346 arg2.push_back (end_addr_arg); 347 348 // Push the data for the first argument into the m_arguments vector. 349 m_arguments.push_back (arg1); 350 m_arguments.push_back (arg2); 351 352 // Add the "--format" and "--count" options to group 1 and 3 353 m_option_group.Append (&m_format_options, 354 OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_COUNT, 355 LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3); 356 m_option_group.Append (&m_format_options, 357 OptionGroupFormat::OPTION_GROUP_GDB_FMT, 358 LLDB_OPT_SET_1 | LLDB_OPT_SET_3); 359 // Add the "--size" option to group 1 and 2 360 m_option_group.Append (&m_format_options, 361 OptionGroupFormat::OPTION_GROUP_SIZE, 362 LLDB_OPT_SET_1 | LLDB_OPT_SET_2); 363 m_option_group.Append (&m_memory_options); 364 m_option_group.Append (&m_outfile_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3); 365 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3); 366 m_option_group.Finalize(); 367 } 368 369 virtual 370 ~CommandObjectMemoryRead () 371 { 372 } 373 374 Options * 375 GetOptions () 376 { 377 return &m_option_group; 378 } 379 380 virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 381 { 382 return m_cmd_name.c_str(); 383 } 384 385 protected: 386 virtual bool 387 DoExecute (Args& command, CommandReturnObject &result) 388 { 389 // No need to check "target" for validity as eFlagRequiresTarget ensures it is valid 390 Target *target = m_exe_ctx.GetTargetPtr(); 391 392 const size_t argc = command.GetArgumentCount(); 393 394 if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2) 395 { 396 result.AppendErrorWithFormat ("%s takes a start address expression with an optional end address expression.\n", m_cmd_name.c_str()); 397 result.AppendRawWarning("Expressions should be quoted if they contain spaces or other special characters.\n"); 398 result.SetStatus(eReturnStatusFailed); 399 return false; 400 } 401 402 ClangASTType clang_ast_type; 403 Error error; 404 405 const char *view_as_type_cstr = m_memory_options.m_view_as_type.GetCurrentValue(); 406 if (view_as_type_cstr && view_as_type_cstr[0]) 407 { 408 // We are viewing memory as a type 409 410 SymbolContext sc; 411 const bool exact_match = false; 412 TypeList type_list; 413 uint32_t reference_count = 0; 414 uint32_t pointer_count = 0; 415 size_t idx; 416 417 #define ALL_KEYWORDS \ 418 KEYWORD("const") \ 419 KEYWORD("volatile") \ 420 KEYWORD("restrict") \ 421 KEYWORD("struct") \ 422 KEYWORD("class") \ 423 KEYWORD("union") 424 425 #define KEYWORD(s) s, 426 static const char *g_keywords[] = 427 { 428 ALL_KEYWORDS 429 }; 430 #undef KEYWORD 431 432 #define KEYWORD(s) (sizeof(s) - 1), 433 static const int g_keyword_lengths[] = 434 { 435 ALL_KEYWORDS 436 }; 437 #undef KEYWORD 438 439 #undef ALL_KEYWORDS 440 441 static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *); 442 std::string type_str(view_as_type_cstr); 443 444 // Remove all instances of g_keywords that are followed by spaces 445 for (size_t i = 0; i < g_num_keywords; ++i) 446 { 447 const char *keyword = g_keywords[i]; 448 int keyword_len = g_keyword_lengths[i]; 449 450 idx = 0; 451 while ((idx = type_str.find (keyword, idx)) != std::string::npos) 452 { 453 if (type_str[idx + keyword_len] == ' ' || type_str[idx + keyword_len] == '\t') 454 { 455 type_str.erase(idx, keyword_len+1); 456 idx = 0; 457 } 458 else 459 { 460 idx += keyword_len; 461 } 462 } 463 } 464 bool done = type_str.empty(); 465 // 466 idx = type_str.find_first_not_of (" \t"); 467 if (idx > 0 && idx != std::string::npos) 468 type_str.erase (0, idx); 469 while (!done) 470 { 471 // Strip trailing spaces 472 if (type_str.empty()) 473 done = true; 474 else 475 { 476 switch (type_str[type_str.size()-1]) 477 { 478 case '*': 479 ++pointer_count; 480 // fall through... 481 case ' ': 482 case '\t': 483 type_str.erase(type_str.size()-1); 484 break; 485 486 case '&': 487 if (reference_count == 0) 488 { 489 reference_count = 1; 490 type_str.erase(type_str.size()-1); 491 } 492 else 493 { 494 result.AppendErrorWithFormat ("invalid type string: '%s'\n", view_as_type_cstr); 495 result.SetStatus(eReturnStatusFailed); 496 return false; 497 } 498 break; 499 500 default: 501 done = true; 502 break; 503 } 504 } 505 } 506 507 ConstString lookup_type_name(type_str.c_str()); 508 StackFrame *frame = m_exe_ctx.GetFramePtr(); 509 if (frame) 510 { 511 sc = frame->GetSymbolContext (eSymbolContextModule); 512 if (sc.module_sp) 513 { 514 sc.module_sp->FindTypes (sc, 515 lookup_type_name, 516 exact_match, 517 1, 518 type_list); 519 } 520 } 521 if (type_list.GetSize() == 0) 522 { 523 target->GetImages().FindTypes (sc, 524 lookup_type_name, 525 exact_match, 526 1, 527 type_list); 528 } 529 530 if (type_list.GetSize() == 0 && lookup_type_name.GetCString() && *lookup_type_name.GetCString() == '$') 531 { 532 clang::TypeDecl *tdecl = target->GetPersistentVariables().GetPersistentType(ConstString(lookup_type_name)); 533 if (tdecl) 534 { 535 clang_ast_type.SetClangType(&tdecl->getASTContext(),(lldb::clang_type_t)tdecl->getTypeForDecl()); 536 } 537 } 538 539 if (clang_ast_type.IsValid() == false) 540 { 541 if (type_list.GetSize() == 0) 542 { 543 result.AppendErrorWithFormat ("unable to find any types that match the raw type '%s' for full type '%s'\n", 544 lookup_type_name.GetCString(), 545 view_as_type_cstr); 546 result.SetStatus(eReturnStatusFailed); 547 return false; 548 } 549 else 550 { 551 TypeSP type_sp (type_list.GetTypeAtIndex(0)); 552 clang_ast_type = type_sp->GetClangFullType(); 553 } 554 } 555 556 while (pointer_count > 0) 557 { 558 ClangASTType pointer_type = clang_ast_type.GetPointerType(); 559 if (pointer_type.IsValid()) 560 clang_ast_type = pointer_type; 561 else 562 { 563 result.AppendError ("unable make a pointer type\n"); 564 result.SetStatus(eReturnStatusFailed); 565 return false; 566 } 567 --pointer_count; 568 } 569 570 m_format_options.GetByteSizeValue() = clang_ast_type.GetByteSize(nullptr); 571 572 if (m_format_options.GetByteSizeValue() == 0) 573 { 574 result.AppendErrorWithFormat ("unable to get the byte size of the type '%s'\n", 575 view_as_type_cstr); 576 result.SetStatus(eReturnStatusFailed); 577 return false; 578 } 579 580 if (!m_format_options.GetCountValue().OptionWasSet()) 581 m_format_options.GetCountValue() = 1; 582 } 583 else 584 { 585 error = m_memory_options.FinalizeSettings (target, m_format_options); 586 } 587 588 // Look for invalid combinations of settings 589 if (error.Fail()) 590 { 591 result.AppendError(error.AsCString()); 592 result.SetStatus(eReturnStatusFailed); 593 return false; 594 } 595 596 lldb::addr_t addr; 597 size_t total_byte_size = 0; 598 if (argc == 0) 599 { 600 // Use the last address and byte size and all options as they were 601 // if no options have been set 602 addr = m_next_addr; 603 total_byte_size = m_prev_byte_size; 604 clang_ast_type = m_prev_clang_ast_type; 605 if (!m_format_options.AnyOptionWasSet() && 606 !m_memory_options.AnyOptionWasSet() && 607 !m_outfile_options.AnyOptionWasSet() && 608 !m_varobj_options.AnyOptionWasSet()) 609 { 610 m_format_options = m_prev_format_options; 611 m_memory_options = m_prev_memory_options; 612 m_outfile_options = m_prev_outfile_options; 613 m_varobj_options = m_prev_varobj_options; 614 } 615 } 616 617 size_t item_count = m_format_options.GetCountValue().GetCurrentValue(); 618 619 // TODO For non-8-bit byte addressable architectures this needs to be 620 // revisited to fully support all lldb's range of formatting options. 621 // Furthermore code memory reads (for those architectures) will not 622 // be correctly formatted even w/o formatting options. 623 size_t item_byte_size = 624 target->GetArchitecture().GetDataByteSize() > 1 ? 625 target->GetArchitecture().GetDataByteSize() : 626 m_format_options.GetByteSizeValue().GetCurrentValue(); 627 628 const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue(); 629 630 if (total_byte_size == 0) 631 { 632 total_byte_size = item_count * item_byte_size; 633 if (total_byte_size == 0) 634 total_byte_size = 32; 635 } 636 637 if (argc > 0) 638 addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error); 639 640 if (addr == LLDB_INVALID_ADDRESS) 641 { 642 result.AppendError("invalid start address expression."); 643 result.AppendError(error.AsCString()); 644 result.SetStatus(eReturnStatusFailed); 645 return false; 646 } 647 648 if (argc == 2) 649 { 650 lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0); 651 if (end_addr == LLDB_INVALID_ADDRESS) 652 { 653 result.AppendError("invalid end address expression."); 654 result.AppendError(error.AsCString()); 655 result.SetStatus(eReturnStatusFailed); 656 return false; 657 } 658 else if (end_addr <= addr) 659 { 660 result.AppendErrorWithFormat("end address (0x%" PRIx64 ") must be greater that the start address (0x%" PRIx64 ").\n", end_addr, addr); 661 result.SetStatus(eReturnStatusFailed); 662 return false; 663 } 664 else if (m_format_options.GetCountValue().OptionWasSet()) 665 { 666 result.AppendErrorWithFormat("specify either the end address (0x%" PRIx64 ") or the count (--count %" PRIu64 "), not both.\n", end_addr, (uint64_t)item_count); 667 result.SetStatus(eReturnStatusFailed); 668 return false; 669 } 670 671 total_byte_size = end_addr - addr; 672 item_count = total_byte_size / item_byte_size; 673 } 674 675 uint32_t max_unforced_size = target->GetMaximumMemReadSize(); 676 677 if (total_byte_size > max_unforced_size && !m_memory_options.m_force) 678 { 679 result.AppendErrorWithFormat("Normally, \'memory read\' will not read over %" PRIu32 " bytes of data.\n",max_unforced_size); 680 result.AppendErrorWithFormat("Please use --force to override this restriction just once.\n"); 681 result.AppendErrorWithFormat("or set target.max-memory-read-size if you will often need a larger limit.\n"); 682 return false; 683 } 684 685 DataBufferSP data_sp; 686 size_t bytes_read = 0; 687 if (clang_ast_type.GetOpaqueQualType()) 688 { 689 // Make sure we don't display our type as ASCII bytes like the default memory read 690 if (m_format_options.GetFormatValue().OptionWasSet() == false) 691 m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault); 692 693 bytes_read = clang_ast_type.GetByteSize(nullptr) * m_format_options.GetCountValue().GetCurrentValue(); 694 } 695 else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString) 696 { 697 data_sp.reset (new DataBufferHeap (total_byte_size, '\0')); 698 if (data_sp->GetBytes() == NULL) 699 { 700 result.AppendErrorWithFormat ("can't allocate 0x%" PRIx32 " bytes for the memory read buffer, specify a smaller size to read", (uint32_t)total_byte_size); 701 result.SetStatus(eReturnStatusFailed); 702 return false; 703 } 704 705 Address address(addr, NULL); 706 bytes_read = target->ReadMemory(address, false, data_sp->GetBytes (), data_sp->GetByteSize(), error); 707 if (bytes_read == 0) 708 { 709 const char *error_cstr = error.AsCString(); 710 if (error_cstr && error_cstr[0]) 711 { 712 result.AppendError(error_cstr); 713 } 714 else 715 { 716 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr); 717 } 718 result.SetStatus(eReturnStatusFailed); 719 return false; 720 } 721 722 if (bytes_read < total_byte_size) 723 result.AppendWarningWithFormat("Not all bytes (%" PRIu64 "/%" PRIu64 ") were able to be read from 0x%" PRIx64 ".\n", (uint64_t)bytes_read, (uint64_t)total_byte_size, addr); 724 } 725 else 726 { 727 // we treat c-strings as a special case because they do not have a fixed size 728 if (m_format_options.GetByteSizeValue().OptionWasSet() && !m_format_options.HasGDBFormat()) 729 item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue(); 730 else 731 item_byte_size = target->GetMaximumSizeOfStringSummary(); 732 if (!m_format_options.GetCountValue().OptionWasSet()) 733 item_count = 1; 734 data_sp.reset (new DataBufferHeap ((item_byte_size+1) * item_count, '\0')); // account for NULLs as necessary 735 if (data_sp->GetBytes() == NULL) 736 { 737 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)); 738 result.SetStatus(eReturnStatusFailed); 739 return false; 740 } 741 uint8_t *data_ptr = data_sp->GetBytes(); 742 auto data_addr = addr; 743 auto count = item_count; 744 item_count = 0; 745 while (item_count < count) 746 { 747 std::string buffer; 748 buffer.resize(item_byte_size+1,0); 749 Error error; 750 size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0], item_byte_size+1, error); 751 if (error.Fail()) 752 { 753 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr); 754 result.SetStatus(eReturnStatusFailed); 755 return false; 756 } 757 if (item_byte_size == read) 758 { 759 result.AppendWarningWithFormat("unable to find a NULL terminated string at 0x%" PRIx64 ".Consider increasing the maximum read length.\n", data_addr); 760 break; 761 } 762 read+=1; // account for final NULL byte 763 memcpy(data_ptr, &buffer[0], read); 764 data_ptr += read; 765 data_addr += read; 766 bytes_read += read; 767 item_count++; // if we break early we know we only read item_count strings 768 } 769 data_sp.reset(new DataBufferHeap(data_sp->GetBytes(),bytes_read+1)); 770 } 771 772 m_next_addr = addr + bytes_read; 773 m_prev_byte_size = bytes_read; 774 m_prev_format_options = m_format_options; 775 m_prev_memory_options = m_memory_options; 776 m_prev_outfile_options = m_outfile_options; 777 m_prev_varobj_options = m_varobj_options; 778 m_prev_clang_ast_type = clang_ast_type; 779 780 StreamFile outfile_stream; 781 Stream *output_stream = NULL; 782 const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue(); 783 if (outfile_spec) 784 { 785 char path[PATH_MAX]; 786 outfile_spec.GetPath (path, sizeof(path)); 787 788 uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; 789 const bool append = m_outfile_options.GetAppend().GetCurrentValue(); 790 if (append) 791 open_options |= File::eOpenOptionAppend; 792 793 if (outfile_stream.GetFile ().Open (path, open_options).Success()) 794 { 795 if (m_memory_options.m_output_as_binary) 796 { 797 const size_t bytes_written = outfile_stream.Write (data_sp->GetBytes(), bytes_read); 798 if (bytes_written > 0) 799 { 800 result.GetOutputStream().Printf ("%zi bytes %s to '%s'\n", 801 bytes_written, 802 append ? "appended" : "written", 803 path); 804 return true; 805 } 806 else 807 { 808 result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", (uint64_t)bytes_read, path); 809 result.SetStatus(eReturnStatusFailed); 810 return false; 811 } 812 } 813 else 814 { 815 // We are going to write ASCII to the file just point the 816 // output_stream to our outfile_stream... 817 output_stream = &outfile_stream; 818 } 819 } 820 else 821 { 822 result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", path, append ? "append" : "write"); 823 result.SetStatus(eReturnStatusFailed); 824 return false; 825 } 826 } 827 else 828 { 829 output_stream = &result.GetOutputStream(); 830 } 831 832 833 ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope(); 834 if (clang_ast_type.GetOpaqueQualType()) 835 { 836 for (uint32_t i = 0; i<item_count; ++i) 837 { 838 addr_t item_addr = addr + (i * item_byte_size); 839 Address address (item_addr); 840 StreamString name_strm; 841 name_strm.Printf ("0x%" PRIx64, item_addr); 842 ValueObjectSP valobj_sp (ValueObjectMemory::Create (exe_scope, 843 name_strm.GetString().c_str(), 844 address, 845 clang_ast_type)); 846 if (valobj_sp) 847 { 848 Format format = m_format_options.GetFormat(); 849 if (format != eFormatDefault) 850 valobj_sp->SetFormat (format); 851 852 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(eLanguageRuntimeDescriptionDisplayVerbosityFull,format)); 853 854 valobj_sp->Dump(*output_stream,options); 855 } 856 else 857 { 858 result.AppendErrorWithFormat ("failed to create a value object for: (%s) %s\n", 859 view_as_type_cstr, 860 name_strm.GetString().c_str()); 861 result.SetStatus(eReturnStatusFailed); 862 return false; 863 } 864 } 865 return true; 866 } 867 868 result.SetStatus(eReturnStatusSuccessFinishResult); 869 DataExtractor data (data_sp, 870 target->GetArchitecture().GetByteOrder(), 871 target->GetArchitecture().GetAddressByteSize(), 872 target->GetArchitecture().GetDataByteSize()); 873 874 Format format = m_format_options.GetFormat(); 875 if ( ( (format == eFormatChar) || (format == eFormatCharPrintable) ) 876 && (item_byte_size != 1)) 877 { 878 // if a count was not passed, or it is 1 879 if (m_format_options.GetCountValue().OptionWasSet() == false || item_count == 1) 880 { 881 // this turns requests such as 882 // memory read -fc -s10 -c1 *charPtrPtr 883 // which make no sense (what is a char of size 10?) 884 // into a request for fetching 10 chars of size 1 from the same memory location 885 format = eFormatCharArray; 886 item_count = item_byte_size; 887 item_byte_size = 1; 888 } 889 else 890 { 891 // here we passed a count, and it was not 1 892 // so we have a byte_size and a count 893 // we could well multiply those, but instead let's just fail 894 result.AppendErrorWithFormat("reading memory as characters of size %" PRIu64 " is not supported", (uint64_t)item_byte_size); 895 result.SetStatus(eReturnStatusFailed); 896 return false; 897 } 898 } 899 900 assert (output_stream); 901 size_t bytes_dumped = data.Dump (output_stream, 902 0, 903 format, 904 item_byte_size, 905 item_count, 906 num_per_line / target->GetArchitecture().GetDataByteSize(), 907 addr, 908 0, 909 0, 910 exe_scope); 911 m_next_addr = addr + bytes_dumped; 912 output_stream->EOL(); 913 return true; 914 } 915 916 OptionGroupOptions m_option_group; 917 OptionGroupFormat m_format_options; 918 OptionGroupReadMemory m_memory_options; 919 OptionGroupOutputFile m_outfile_options; 920 OptionGroupValueObjectDisplay m_varobj_options; 921 lldb::addr_t m_next_addr; 922 lldb::addr_t m_prev_byte_size; 923 OptionGroupFormat m_prev_format_options; 924 OptionGroupReadMemory m_prev_memory_options; 925 OptionGroupOutputFile m_prev_outfile_options; 926 OptionGroupValueObjectDisplay m_prev_varobj_options; 927 ClangASTType m_prev_clang_ast_type; 928 }; 929 930 OptionDefinition 931 g_memory_find_option_table[] = 932 { 933 { LLDB_OPT_SET_1, false, "expression", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."}, 934 { LLDB_OPT_SET_2, false, "string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Use text to find a byte pattern."}, 935 { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many times to perform the search."}, 936 { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "dump-offset", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."}, 937 }; 938 939 //---------------------------------------------------------------------- 940 // Find the specified data in memory 941 //---------------------------------------------------------------------- 942 class CommandObjectMemoryFind : public CommandObjectParsed 943 { 944 public: 945 946 class OptionGroupFindMemory : public OptionGroup 947 { 948 public: 949 OptionGroupFindMemory () : 950 OptionGroup(), 951 m_count(1), 952 m_offset(0) 953 { 954 } 955 956 virtual 957 ~OptionGroupFindMemory () 958 { 959 } 960 961 virtual uint32_t 962 GetNumDefinitions () 963 { 964 return sizeof (g_memory_find_option_table) / sizeof (OptionDefinition); 965 } 966 967 virtual const OptionDefinition* 968 GetDefinitions () 969 { 970 return g_memory_find_option_table; 971 } 972 973 virtual Error 974 SetOptionValue (CommandInterpreter &interpreter, 975 uint32_t option_idx, 976 const char *option_arg) 977 { 978 Error error; 979 const int short_option = g_memory_find_option_table[option_idx].short_option; 980 981 switch (short_option) 982 { 983 case 'e': 984 m_expr.SetValueFromString(option_arg); 985 break; 986 987 case 's': 988 m_string.SetValueFromString(option_arg); 989 break; 990 991 case 'c': 992 if (m_count.SetValueFromString(option_arg).Fail()) 993 error.SetErrorString("unrecognized value for count"); 994 break; 995 996 case 'o': 997 if (m_offset.SetValueFromString(option_arg).Fail()) 998 error.SetErrorString("unrecognized value for dump-offset"); 999 break; 1000 1001 default: 1002 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 1003 break; 1004 } 1005 return error; 1006 } 1007 1008 virtual void 1009 OptionParsingStarting (CommandInterpreter &interpreter) 1010 { 1011 m_expr.Clear(); 1012 m_string.Clear(); 1013 m_count.Clear(); 1014 } 1015 1016 OptionValueString m_expr; 1017 OptionValueString m_string; 1018 OptionValueUInt64 m_count; 1019 OptionValueUInt64 m_offset; 1020 }; 1021 1022 CommandObjectMemoryFind (CommandInterpreter &interpreter) : 1023 CommandObjectParsed (interpreter, 1024 "memory find", 1025 "Find a value in the memory of the process being debugged.", 1026 NULL, 1027 eFlagRequiresProcess | eFlagProcessMustBeLaunched), 1028 m_option_group (interpreter), 1029 m_memory_options () 1030 { 1031 CommandArgumentEntry arg1; 1032 CommandArgumentEntry arg2; 1033 CommandArgumentData addr_arg; 1034 CommandArgumentData value_arg; 1035 1036 // Define the first (and only) variant of this arg. 1037 addr_arg.arg_type = eArgTypeAddress; 1038 addr_arg.arg_repetition = eArgRepeatPlain; 1039 1040 // There is only one variant this argument could be; put it into the argument entry. 1041 arg1.push_back (addr_arg); 1042 1043 // Define the first (and only) variant of this arg. 1044 value_arg.arg_type = eArgTypeValue; 1045 value_arg.arg_repetition = eArgRepeatPlus; 1046 1047 // There is only one variant this argument could be; put it into the argument entry. 1048 arg2.push_back (value_arg); 1049 1050 // Push the data for the first argument into the m_arguments vector. 1051 m_arguments.push_back (arg1); 1052 m_arguments.push_back (arg2); 1053 1054 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2); 1055 m_option_group.Finalize(); 1056 } 1057 1058 virtual 1059 ~CommandObjectMemoryFind () 1060 { 1061 } 1062 1063 Options * 1064 GetOptions () 1065 { 1066 return &m_option_group; 1067 } 1068 1069 protected: 1070 virtual bool 1071 DoExecute (Args& command, CommandReturnObject &result) 1072 { 1073 // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid 1074 Process *process = m_exe_ctx.GetProcessPtr(); 1075 1076 const size_t argc = command.GetArgumentCount(); 1077 1078 if (argc != 2) 1079 { 1080 result.AppendError("two addresses needed for memory find"); 1081 return false; 1082 } 1083 1084 Error error; 1085 lldb::addr_t low_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0),LLDB_INVALID_ADDRESS,&error); 1086 if (low_addr == LLDB_INVALID_ADDRESS || error.Fail()) 1087 { 1088 result.AppendError("invalid low address"); 1089 return false; 1090 } 1091 lldb::addr_t high_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1),LLDB_INVALID_ADDRESS,&error); 1092 if (high_addr == LLDB_INVALID_ADDRESS || error.Fail()) 1093 { 1094 result.AppendError("invalid high address"); 1095 return false; 1096 } 1097 1098 if (high_addr <= low_addr) 1099 { 1100 result.AppendError("starting address must be smaller than ending address"); 1101 return false; 1102 } 1103 1104 lldb::addr_t found_location = LLDB_INVALID_ADDRESS; 1105 1106 DataBufferHeap buffer; 1107 1108 if (m_memory_options.m_string.OptionWasSet()) 1109 buffer.CopyData(m_memory_options.m_string.GetStringValue(), strlen(m_memory_options.m_string.GetStringValue())); 1110 else if (m_memory_options.m_expr.OptionWasSet()) 1111 { 1112 StackFrame* frame = m_exe_ctx.GetFramePtr(); 1113 ValueObjectSP result_sp; 1114 if (process->GetTarget().EvaluateExpression(m_memory_options.m_expr.GetStringValue(), frame, result_sp) && result_sp.get()) 1115 { 1116 uint64_t value = result_sp->GetValueAsUnsigned(0); 1117 switch (result_sp->GetClangType().GetByteSize(nullptr)) 1118 { 1119 case 1: { 1120 uint8_t byte = (uint8_t)value; 1121 buffer.CopyData(&byte,1); 1122 } 1123 break; 1124 case 2: { 1125 uint16_t word = (uint16_t)value; 1126 buffer.CopyData(&word,2); 1127 } 1128 break; 1129 case 4: { 1130 uint32_t lword = (uint32_t)value; 1131 buffer.CopyData(&lword,4); 1132 } 1133 break; 1134 case 8: { 1135 buffer.CopyData(&value, 8); 1136 } 1137 break; 1138 case 3: 1139 case 5: 1140 case 6: 1141 case 7: 1142 result.AppendError("unknown type. pass a string instead"); 1143 return false; 1144 default: 1145 result.AppendError("do not know how to deal with larger than 8 byte result types. pass a string instead"); 1146 return false; 1147 } 1148 } 1149 else 1150 { 1151 result.AppendError("expression evaluation failed. pass a string instead?"); 1152 return false; 1153 } 1154 } 1155 else 1156 { 1157 result.AppendError("please pass either a block of text, or an expression to evaluate."); 1158 return false; 1159 } 1160 1161 size_t count = m_memory_options.m_count.GetCurrentValue(); 1162 found_location = low_addr; 1163 bool ever_found = false; 1164 while (count) 1165 { 1166 found_location = Search(found_location, high_addr, buffer.GetBytes(), buffer.GetByteSize()); 1167 if (found_location == LLDB_INVALID_ADDRESS) 1168 { 1169 if (!ever_found) 1170 { 1171 result.AppendMessage("Your data was not found within the range.\n"); 1172 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult); 1173 } 1174 else 1175 result.AppendMessage("No more matches found within the range.\n"); 1176 break; 1177 } 1178 result.AppendMessageWithFormat("Your data was found at location: 0x%" PRIx64 "\n", found_location); 1179 1180 DataBufferHeap dumpbuffer(32,0); 1181 process->ReadMemory(found_location+m_memory_options.m_offset.GetCurrentValue(), dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), error); 1182 if (!error.Fail()) 1183 { 1184 DataExtractor data(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), process->GetByteOrder(), process->GetAddressByteSize()); 1185 data.Dump(&result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1, dumpbuffer.GetByteSize(), 16, found_location+m_memory_options.m_offset.GetCurrentValue(), 0, 0); 1186 result.GetOutputStream().EOL(); 1187 } 1188 1189 --count; 1190 found_location++; 1191 ever_found = true; 1192 } 1193 1194 result.SetStatus(lldb::eReturnStatusSuccessFinishResult); 1195 return true; 1196 } 1197 1198 lldb::addr_t 1199 Search (lldb::addr_t low, 1200 lldb::addr_t high, 1201 uint8_t* buffer, 1202 size_t buffer_size) 1203 { 1204 Process *process = m_exe_ctx.GetProcessPtr(); 1205 DataBufferHeap heap(buffer_size, 0); 1206 lldb::addr_t fictional_ptr = low; 1207 for (auto ptr = low; 1208 low < high; 1209 fictional_ptr++) 1210 { 1211 Error error; 1212 if (ptr == low || buffer_size == 1) 1213 process->ReadMemory(ptr, heap.GetBytes(), buffer_size, error); 1214 else 1215 { 1216 memmove(heap.GetBytes(), heap.GetBytes()+1, buffer_size-1); 1217 process->ReadMemory(ptr, heap.GetBytes()+buffer_size-1, 1, error); 1218 } 1219 if (error.Fail()) 1220 return LLDB_INVALID_ADDRESS; 1221 if (memcmp(heap.GetBytes(), buffer, buffer_size) == 0) 1222 return fictional_ptr; 1223 if (ptr == low) 1224 ptr += buffer_size; 1225 else 1226 ptr += 1; 1227 } 1228 return LLDB_INVALID_ADDRESS; 1229 } 1230 1231 OptionGroupOptions m_option_group; 1232 OptionGroupFindMemory m_memory_options; 1233 }; 1234 1235 1236 OptionDefinition 1237 g_memory_write_option_table[] = 1238 { 1239 { LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Write memory using the contents of a file."}, 1240 { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."}, 1241 }; 1242 1243 //---------------------------------------------------------------------- 1244 // Write memory to the inferior process 1245 //---------------------------------------------------------------------- 1246 class CommandObjectMemoryWrite : public CommandObjectParsed 1247 { 1248 public: 1249 1250 class OptionGroupWriteMemory : public OptionGroup 1251 { 1252 public: 1253 OptionGroupWriteMemory () : 1254 OptionGroup() 1255 { 1256 } 1257 1258 virtual 1259 ~OptionGroupWriteMemory () 1260 { 1261 } 1262 1263 virtual uint32_t 1264 GetNumDefinitions () 1265 { 1266 return sizeof (g_memory_write_option_table) / sizeof (OptionDefinition); 1267 } 1268 1269 virtual const OptionDefinition* 1270 GetDefinitions () 1271 { 1272 return g_memory_write_option_table; 1273 } 1274 1275 virtual Error 1276 SetOptionValue (CommandInterpreter &interpreter, 1277 uint32_t option_idx, 1278 const char *option_arg) 1279 { 1280 Error error; 1281 const int short_option = g_memory_write_option_table[option_idx].short_option; 1282 1283 switch (short_option) 1284 { 1285 case 'i': 1286 m_infile.SetFile (option_arg, true); 1287 if (!m_infile.Exists()) 1288 { 1289 m_infile.Clear(); 1290 error.SetErrorStringWithFormat("input file does not exist: '%s'", option_arg); 1291 } 1292 break; 1293 1294 case 'o': 1295 { 1296 bool success; 1297 m_infile_offset = StringConvert::ToUInt64(option_arg, 0, 0, &success); 1298 if (!success) 1299 { 1300 error.SetErrorStringWithFormat("invalid offset string '%s'", option_arg); 1301 } 1302 } 1303 break; 1304 1305 default: 1306 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 1307 break; 1308 } 1309 return error; 1310 } 1311 1312 virtual void 1313 OptionParsingStarting (CommandInterpreter &interpreter) 1314 { 1315 m_infile.Clear(); 1316 m_infile_offset = 0; 1317 } 1318 1319 FileSpec m_infile; 1320 off_t m_infile_offset; 1321 }; 1322 1323 CommandObjectMemoryWrite (CommandInterpreter &interpreter) : 1324 CommandObjectParsed (interpreter, 1325 "memory write", 1326 "Write to the memory of the process being debugged.", 1327 NULL, 1328 eFlagRequiresProcess | eFlagProcessMustBeLaunched), 1329 m_option_group (interpreter), 1330 m_format_options (eFormatBytes, 1, UINT64_MAX), 1331 m_memory_options () 1332 { 1333 CommandArgumentEntry arg1; 1334 CommandArgumentEntry arg2; 1335 CommandArgumentData addr_arg; 1336 CommandArgumentData value_arg; 1337 1338 // Define the first (and only) variant of this arg. 1339 addr_arg.arg_type = eArgTypeAddress; 1340 addr_arg.arg_repetition = eArgRepeatPlain; 1341 1342 // There is only one variant this argument could be; put it into the argument entry. 1343 arg1.push_back (addr_arg); 1344 1345 // Define the first (and only) variant of this arg. 1346 value_arg.arg_type = eArgTypeValue; 1347 value_arg.arg_repetition = eArgRepeatPlus; 1348 1349 // There is only one variant this argument could be; put it into the argument entry. 1350 arg2.push_back (value_arg); 1351 1352 // Push the data for the first argument into the m_arguments vector. 1353 m_arguments.push_back (arg1); 1354 m_arguments.push_back (arg2); 1355 1356 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1); 1357 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_SIZE , LLDB_OPT_SET_1|LLDB_OPT_SET_2); 1358 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2); 1359 m_option_group.Finalize(); 1360 1361 } 1362 1363 virtual 1364 ~CommandObjectMemoryWrite () 1365 { 1366 } 1367 1368 Options * 1369 GetOptions () 1370 { 1371 return &m_option_group; 1372 } 1373 1374 bool 1375 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size) 1376 { 1377 if (total_byte_size > 8) 1378 return false; 1379 1380 if (total_byte_size == 8) 1381 return true; 1382 1383 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1; 1384 return uval64 <= max; 1385 } 1386 1387 bool 1388 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size) 1389 { 1390 if (total_byte_size > 8) 1391 return false; 1392 1393 if (total_byte_size == 8) 1394 return true; 1395 1396 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1; 1397 const int64_t min = ~(max); 1398 return min <= sval64 && sval64 <= max; 1399 } 1400 1401 protected: 1402 virtual bool 1403 DoExecute (Args& command, CommandReturnObject &result) 1404 { 1405 // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid 1406 Process *process = m_exe_ctx.GetProcessPtr(); 1407 1408 const size_t argc = command.GetArgumentCount(); 1409 1410 if (m_memory_options.m_infile) 1411 { 1412 if (argc < 1) 1413 { 1414 result.AppendErrorWithFormat ("%s takes a destination address when writing file contents.\n", m_cmd_name.c_str()); 1415 result.SetStatus(eReturnStatusFailed); 1416 return false; 1417 } 1418 } 1419 else if (argc < 2) 1420 { 1421 result.AppendErrorWithFormat ("%s takes a destination address and at least one value.\n", m_cmd_name.c_str()); 1422 result.SetStatus(eReturnStatusFailed); 1423 return false; 1424 } 1425 1426 StreamString buffer (Stream::eBinary, 1427 process->GetTarget().GetArchitecture().GetAddressByteSize(), 1428 process->GetTarget().GetArchitecture().GetByteOrder()); 1429 1430 OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue(); 1431 size_t item_byte_size = byte_size_value.GetCurrentValue(); 1432 1433 Error error; 1434 lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx, 1435 command.GetArgumentAtIndex(0), 1436 LLDB_INVALID_ADDRESS, 1437 &error); 1438 1439 if (addr == LLDB_INVALID_ADDRESS) 1440 { 1441 result.AppendError("invalid address expression\n"); 1442 result.AppendError(error.AsCString()); 1443 result.SetStatus(eReturnStatusFailed); 1444 return false; 1445 } 1446 1447 if (m_memory_options.m_infile) 1448 { 1449 size_t length = SIZE_MAX; 1450 if (item_byte_size > 1) 1451 length = item_byte_size; 1452 lldb::DataBufferSP data_sp (m_memory_options.m_infile.ReadFileContents (m_memory_options.m_infile_offset, length)); 1453 if (data_sp) 1454 { 1455 length = data_sp->GetByteSize(); 1456 if (length > 0) 1457 { 1458 Error error; 1459 size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error); 1460 1461 if (bytes_written == length) 1462 { 1463 // All bytes written 1464 result.GetOutputStream().Printf("%" PRIu64 " bytes were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, addr); 1465 result.SetStatus(eReturnStatusSuccessFinishResult); 1466 } 1467 else if (bytes_written > 0) 1468 { 1469 // Some byte written 1470 result.GetOutputStream().Printf("%" PRIu64 " bytes of %" PRIu64 " requested were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, (uint64_t)length, addr); 1471 result.SetStatus(eReturnStatusSuccessFinishResult); 1472 } 1473 else 1474 { 1475 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); 1476 result.SetStatus(eReturnStatusFailed); 1477 } 1478 } 1479 } 1480 else 1481 { 1482 result.AppendErrorWithFormat ("Unable to read contents of file.\n"); 1483 result.SetStatus(eReturnStatusFailed); 1484 } 1485 return result.Succeeded(); 1486 } 1487 else if (item_byte_size == 0) 1488 { 1489 if (m_format_options.GetFormat() == eFormatPointer) 1490 item_byte_size = buffer.GetAddressByteSize(); 1491 else 1492 item_byte_size = 1; 1493 } 1494 1495 command.Shift(); // shift off the address argument 1496 uint64_t uval64; 1497 int64_t sval64; 1498 bool success = false; 1499 const size_t num_value_args = command.GetArgumentCount(); 1500 for (size_t i=0; i<num_value_args; ++i) 1501 { 1502 const char *value_str = command.GetArgumentAtIndex(i); 1503 1504 switch (m_format_options.GetFormat()) 1505 { 1506 case kNumFormats: 1507 case eFormatFloat: // TODO: add support for floats soon 1508 case eFormatCharPrintable: 1509 case eFormatBytesWithASCII: 1510 case eFormatComplex: 1511 case eFormatEnum: 1512 case eFormatUnicode16: 1513 case eFormatUnicode32: 1514 case eFormatVectorOfChar: 1515 case eFormatVectorOfSInt8: 1516 case eFormatVectorOfUInt8: 1517 case eFormatVectorOfSInt16: 1518 case eFormatVectorOfUInt16: 1519 case eFormatVectorOfSInt32: 1520 case eFormatVectorOfUInt32: 1521 case eFormatVectorOfSInt64: 1522 case eFormatVectorOfUInt64: 1523 case eFormatVectorOfFloat32: 1524 case eFormatVectorOfFloat64: 1525 case eFormatVectorOfUInt128: 1526 case eFormatOSType: 1527 case eFormatComplexInteger: 1528 case eFormatAddressInfo: 1529 case eFormatHexFloat: 1530 case eFormatInstruction: 1531 case eFormatVoid: 1532 result.AppendError("unsupported format for writing memory"); 1533 result.SetStatus(eReturnStatusFailed); 1534 return false; 1535 1536 case eFormatDefault: 1537 case eFormatBytes: 1538 case eFormatHex: 1539 case eFormatHexUppercase: 1540 case eFormatPointer: 1541 1542 // Decode hex bytes 1543 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 16, &success); 1544 if (!success) 1545 { 1546 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str); 1547 result.SetStatus(eReturnStatusFailed); 1548 return false; 1549 } 1550 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1551 { 1552 result.AppendErrorWithFormat("Value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); 1553 result.SetStatus(eReturnStatusFailed); 1554 return false; 1555 } 1556 buffer.PutMaxHex64 (uval64, item_byte_size); 1557 break; 1558 1559 case eFormatBoolean: 1560 uval64 = Args::StringToBoolean(value_str, false, &success); 1561 if (!success) 1562 { 1563 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str); 1564 result.SetStatus(eReturnStatusFailed); 1565 return false; 1566 } 1567 buffer.PutMaxHex64 (uval64, item_byte_size); 1568 break; 1569 1570 case eFormatBinary: 1571 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 2, &success); 1572 if (!success) 1573 { 1574 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str); 1575 result.SetStatus(eReturnStatusFailed); 1576 return false; 1577 } 1578 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1579 { 1580 result.AppendErrorWithFormat("Value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); 1581 result.SetStatus(eReturnStatusFailed); 1582 return false; 1583 } 1584 buffer.PutMaxHex64 (uval64, item_byte_size); 1585 break; 1586 1587 case eFormatCharArray: 1588 case eFormatChar: 1589 case eFormatCString: 1590 if (value_str[0]) 1591 { 1592 size_t len = strlen (value_str); 1593 // Include the NULL for C strings... 1594 if (m_format_options.GetFormat() == eFormatCString) 1595 ++len; 1596 Error error; 1597 if (process->WriteMemory (addr, value_str, len, error) == len) 1598 { 1599 addr += len; 1600 } 1601 else 1602 { 1603 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); 1604 result.SetStatus(eReturnStatusFailed); 1605 return false; 1606 } 1607 } 1608 break; 1609 1610 case eFormatDecimal: 1611 sval64 = StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success); 1612 if (!success) 1613 { 1614 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str); 1615 result.SetStatus(eReturnStatusFailed); 1616 return false; 1617 } 1618 else if (!SIntValueIsValidForSize (sval64, item_byte_size)) 1619 { 1620 result.AppendErrorWithFormat ("Value %" PRIi64 " is too large or small to fit in a %" PRIu64 " byte signed integer value.\n", sval64, (uint64_t)item_byte_size); 1621 result.SetStatus(eReturnStatusFailed); 1622 return false; 1623 } 1624 buffer.PutMaxHex64 (sval64, item_byte_size); 1625 break; 1626 1627 case eFormatUnsigned: 1628 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success); 1629 if (!success) 1630 { 1631 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str); 1632 result.SetStatus(eReturnStatusFailed); 1633 return false; 1634 } 1635 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1636 { 1637 result.AppendErrorWithFormat ("Value %" PRIu64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); 1638 result.SetStatus(eReturnStatusFailed); 1639 return false; 1640 } 1641 buffer.PutMaxHex64 (uval64, item_byte_size); 1642 break; 1643 1644 case eFormatOctal: 1645 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 8, &success); 1646 if (!success) 1647 { 1648 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str); 1649 result.SetStatus(eReturnStatusFailed); 1650 return false; 1651 } 1652 else if (!UIntValueIsValidForSize (uval64, item_byte_size)) 1653 { 1654 result.AppendErrorWithFormat ("Value %" PRIo64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); 1655 result.SetStatus(eReturnStatusFailed); 1656 return false; 1657 } 1658 buffer.PutMaxHex64 (uval64, item_byte_size); 1659 break; 1660 } 1661 } 1662 1663 if (!buffer.GetString().empty()) 1664 { 1665 Error error; 1666 if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size()) 1667 return true; 1668 else 1669 { 1670 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString()); 1671 result.SetStatus(eReturnStatusFailed); 1672 return false; 1673 } 1674 } 1675 return true; 1676 } 1677 1678 OptionGroupOptions m_option_group; 1679 OptionGroupFormat m_format_options; 1680 OptionGroupWriteMemory m_memory_options; 1681 }; 1682 1683 //---------------------------------------------------------------------- 1684 // Get malloc/free history of a memory address. 1685 //---------------------------------------------------------------------- 1686 class CommandObjectMemoryHistory : public CommandObjectParsed 1687 { 1688 public: 1689 1690 CommandObjectMemoryHistory (CommandInterpreter &interpreter) : 1691 CommandObjectParsed (interpreter, 1692 "memory history", 1693 "Prints out the recorded stack traces for allocation/deallocation of a memory address.", 1694 NULL, 1695 eFlagRequiresTarget | eFlagRequiresProcess | eFlagProcessMustBePaused | eFlagProcessMustBeLaunched) 1696 { 1697 CommandArgumentEntry arg1; 1698 CommandArgumentData addr_arg; 1699 1700 // Define the first (and only) variant of this arg. 1701 addr_arg.arg_type = eArgTypeAddress; 1702 addr_arg.arg_repetition = eArgRepeatPlain; 1703 1704 // There is only one variant this argument could be; put it into the argument entry. 1705 arg1.push_back (addr_arg); 1706 1707 // Push the data for the first argument into the m_arguments vector. 1708 m_arguments.push_back (arg1); 1709 } 1710 1711 virtual 1712 ~CommandObjectMemoryHistory () 1713 { 1714 } 1715 1716 virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 1717 { 1718 return m_cmd_name.c_str(); 1719 } 1720 1721 protected: 1722 virtual bool 1723 DoExecute (Args& command, CommandReturnObject &result) 1724 { 1725 const size_t argc = command.GetArgumentCount(); 1726 1727 if (argc == 0 || argc > 1) 1728 { 1729 result.AppendErrorWithFormat ("%s takes an address expression", m_cmd_name.c_str()); 1730 result.SetStatus(eReturnStatusFailed); 1731 return false; 1732 } 1733 1734 Error error; 1735 lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx, 1736 command.GetArgumentAtIndex(0), 1737 LLDB_INVALID_ADDRESS, 1738 &error); 1739 1740 if (addr == LLDB_INVALID_ADDRESS) 1741 { 1742 result.AppendError("invalid address expression"); 1743 result.AppendError(error.AsCString()); 1744 result.SetStatus(eReturnStatusFailed); 1745 return false; 1746 } 1747 1748 Stream *output_stream = &result.GetOutputStream(); 1749 1750 const ProcessSP &process_sp = m_exe_ctx.GetProcessSP(); 1751 const MemoryHistorySP &memory_history = MemoryHistory::FindPlugin(process_sp); 1752 1753 if (! memory_history.get()) 1754 { 1755 result.AppendError("no available memory history provider"); 1756 result.SetStatus(eReturnStatusFailed); 1757 return false; 1758 } 1759 1760 HistoryThreads thread_list = memory_history->GetHistoryThreads(addr); 1761 1762 for (auto thread : thread_list) { 1763 thread->GetStatus(*output_stream, 0, UINT32_MAX, 0); 1764 } 1765 1766 result.SetStatus(eReturnStatusSuccessFinishResult); 1767 1768 return true; 1769 } 1770 1771 }; 1772 1773 1774 //------------------------------------------------------------------------- 1775 // CommandObjectMemory 1776 //------------------------------------------------------------------------- 1777 1778 CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) : 1779 CommandObjectMultiword (interpreter, 1780 "memory", 1781 "A set of commands for operating on memory.", 1782 "memory <subcommand> [<subcommand-options>]") 1783 { 1784 LoadSubCommand ("find", CommandObjectSP (new CommandObjectMemoryFind (interpreter))); 1785 LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter))); 1786 LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter))); 1787 LoadSubCommand ("history", CommandObjectSP (new CommandObjectMemoryHistory (interpreter))); 1788 } 1789 1790 CommandObjectMemory::~CommandObjectMemory () 1791 { 1792 } 1793