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