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