39 #include "llvm/Support/MathExtras.h"
47 #define LLDB_OPTIONS_memory_read
48 #include "CommandOptions.inc"
53 : m_num_per_line(1, 1), m_offset(0, 0),
59 return llvm::ArrayRef(g_memory_read_options);
65 const int short_option = g_memory_read_options[option_idx].short_option;
67 switch (short_option) {
69 error = m_num_per_line.SetValueFromString(option_value);
70 if (m_num_per_line.GetCurrentValue() == 0)
71 error.SetErrorStringWithFormat(
72 "invalid value for --num-per-line option '%s'",
73 option_value.str().c_str());
77 m_output_as_binary =
true;
81 error = m_view_as_type.SetValueFromString(option_value);
89 error = m_language_for_type.SetValueFromString(option_value);
93 error = m_offset.SetValueFromString(option_value);
97 llvm_unreachable(
"Unimplemented option");
103 m_num_per_line.Clear();
104 m_output_as_binary =
false;
105 m_view_as_type.Clear();
108 m_language_for_type.Clear();
115 const bool byte_size_option_set = byte_size_value.
OptionWasSet();
116 const bool num_per_line_option_set = m_num_per_line.OptionWasSet();
124 if (!byte_size_option_set)
126 if (!num_per_line_option_set)
128 if (!count_option_set)
136 if (count_option_set)
142 if (!byte_size_option_set)
145 if (!count_option_set)
151 if (!num_per_line_option_set)
153 if (!count_option_set)
167 if (!byte_size_option_set)
169 if (!num_per_line_option_set)
171 if (!count_option_set)
177 if (byte_size_option_set) {
178 if (byte_size_value > 1)
179 error.SetErrorStringWithFormat(
180 "display format (bytes/bytes with ASCII) conflicts with the "
181 "specified byte size %" PRIu64
"\n"
182 "\tconsider using a different display format or don't specify "
187 if (!num_per_line_option_set)
189 if (!count_option_set)
196 if (!byte_size_option_set)
198 if (!num_per_line_option_set)
200 if (!count_option_set)
205 if (!byte_size_option_set)
207 if (!num_per_line_option_set)
209 if (!count_option_set)
214 if (!byte_size_option_set)
216 if (!num_per_line_option_set)
218 if (!count_option_set)
223 if (!byte_size_option_set)
225 if (!num_per_line_option_set) {
226 switch (byte_size_value) {
242 if (!count_option_set)
259 if (!byte_size_option_set)
260 byte_size_value = 128;
261 if (!num_per_line_option_set)
263 if (!count_option_set)
271 return m_num_per_line.OptionWasSet() || m_output_as_binary ||
272 m_view_as_type.OptionWasSet() || m_offset.OptionWasSet() ||
273 m_language_for_type.OptionWasSet();
277 bool m_output_as_binary =
false;
279 bool m_force =
false;
289 interpreter,
"memory read",
290 "Read from the memory of the current target process.", nullptr,
291 eCommandRequiresTarget | eCommandProcessMustBePaused),
293 m_memory_tag_options(true),
306 arg1.push_back(start_addr_arg);
314 arg2.push_back(end_addr_arg);
317 m_arguments.push_back(arg1);
318 m_arguments.push_back(arg2);
321 m_option_group.Append(&m_format_options,
322 OptionGroupFormat::OPTION_GROUP_FORMAT |
323 OptionGroupFormat::OPTION_GROUP_COUNT,
325 m_option_group.Append(&m_format_options,
326 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
329 m_option_group.Append(&m_format_options,
330 OptionGroupFormat::OPTION_GROUP_SIZE,
332 m_option_group.Append(&m_memory_options);
338 m_option_group.Finalize();
354 Target *target = m_exe_ctx.GetTargetPtr();
360 "an optional end address expression.\n",
362 result.
AppendWarning(
"Expressions should be quoted if they contain "
363 "spaces or other special characters.");
370 const char *view_as_type_cstr =
371 m_memory_options.m_view_as_type.GetCurrentValue();
372 if (view_as_type_cstr && view_as_type_cstr[0]) {
375 const bool exact_match =
false;
381 #define ALL_KEYWORDS \
383 KEYWORD("volatile") \
384 KEYWORD("restrict") \
389 #define KEYWORD(s) s,
393 #define KEYWORD(s) (sizeof(s) - 1),
399 static size_t g_num_keywords =
sizeof(g_keywords) /
sizeof(
const char *);
403 for (
size_t i = 0; i < g_num_keywords; ++i) {
404 const char *keyword = g_keywords[i];
405 int keyword_len = g_keyword_lengths[i];
408 while ((idx = type_str.find(keyword, idx)) != std::string::npos) {
409 if (type_str[idx + keyword_len] ==
' ' ||
410 type_str[idx + keyword_len] ==
'\t') {
411 type_str.erase(idx, keyword_len + 1);
418 bool done = type_str.empty();
420 idx = type_str.find_first_not_of(
" \t");
421 if (idx > 0 && idx != std::string::npos)
422 type_str.erase(0, idx);
425 if (type_str.empty())
428 switch (type_str[type_str.size() - 1]) {
434 type_str.erase(type_str.size() - 1);
438 if (reference_count == 0) {
440 type_str.erase(type_str.size() - 1);
455 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
458 ModuleSP search_first;
463 exact_match, 1, searched_symbol_files,
468 m_memory_options.m_language_for_type.GetCurrentValue();
469 std::set<LanguageType> languages_to_check;
471 languages_to_check.insert(language_for_type);
473 languages_to_check = Language::GetSupportedLanguages();
476 std::set<CompilerType> user_defined_types;
477 for (
auto lang : languages_to_check) {
478 if (
auto *persistent_vars =
480 if (std::optional<CompilerType> type =
481 persistent_vars->GetCompilerTypeFromPersistentDecl(
483 user_defined_types.emplace(*type);
488 if (user_defined_types.size() > 1) {
490 "Mutiple types found matching raw type '%s', please disambiguate "
491 "by specifying the language with -x",
496 if (user_defined_types.size() == 1) {
497 compiler_type = *user_defined_types.begin();
501 if (!compiler_type.
IsValid()) {
502 if (type_list.
GetSize() == 0) {
504 "the raw type '%s' for full type '%s'\n",
510 compiler_type = type_sp->GetFullCompilerType();
514 while (pointer_count > 0) {
517 compiler_type = pointer_type;
519 result.
AppendError(
"unable make a pointer type\n");
525 std::optional<uint64_t> size = compiler_type.
GetByteSize(
nullptr);
528 "unable to get the byte size of the type '%s'\n",
532 m_format_options.GetByteSizeValue() = *size;
534 if (!m_format_options.GetCountValue().OptionWasSet())
535 m_format_options.GetCountValue() = 1;
537 error = m_memory_options.FinalizeSettings(target, m_format_options);
547 size_t total_byte_size = 0;
552 total_byte_size = m_prev_byte_size;
553 compiler_type = m_prev_compiler_type;
554 if (!m_format_options.AnyOptionWasSet() &&
555 !m_memory_options.AnyOptionWasSet() &&
556 !m_outfile_options.AnyOptionWasSet() &&
557 !m_varobj_options.AnyOptionWasSet() &&
558 !m_memory_tag_options.AnyOptionWasSet()) {
559 m_format_options = m_prev_format_options;
560 m_memory_options = m_prev_memory_options;
561 m_outfile_options = m_prev_outfile_options;
562 m_varobj_options = m_prev_varobj_options;
563 m_memory_tag_options = m_prev_memory_tag_options;
567 size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
573 size_t item_byte_size =
576 : m_format_options.GetByteSizeValue().GetCurrentValue();
578 const size_t num_per_line =
579 m_memory_options.m_num_per_line.GetCurrentValue();
581 if (total_byte_size == 0) {
582 total_byte_size = item_count * item_byte_size;
583 if (total_byte_size == 0)
584 total_byte_size = 32;
588 addr = OptionArgParser::ToAddress(&m_exe_ctx, command[0].ref(),
592 result.
AppendError(
"invalid start address expression.");
598 if (
Process *proc = m_exe_ctx.GetProcessPtr())
599 abi = proc->GetABI();
602 addr = abi->FixDataAddress(addr);
608 end_addr = abi->FixDataAddress(end_addr);
611 result.
AppendError(
"invalid end address expression.");
614 }
else if (end_addr <= addr) {
616 "end address (0x%" PRIx64
617 ") must be greater than the start address (0x%" PRIx64
").\n",
620 }
else if (m_format_options.GetCountValue().OptionWasSet()) {
622 "specify either the end address (0x%" PRIx64
623 ") or the count (--count %" PRIu64
"), not both.\n",
624 end_addr, (uint64_t)item_count);
628 total_byte_size = end_addr - addr;
629 item_count = total_byte_size / item_byte_size;
634 if (total_byte_size > max_unforced_size && !m_memory_options.m_force) {
636 "Normally, \'memory read\' will not read over %" PRIu32
640 "Please use --force to override this restriction just once.\n");
642 "will often need a larger limit.\n");
646 WritableDataBufferSP data_sp;
647 size_t bytes_read = 0;
651 if (!m_format_options.GetFormatValue().OptionWasSet())
652 m_format_options.GetFormatValue().SetCurrentValue(
eFormatDefault);
654 std::optional<uint64_t> size = compiler_type.
GetByteSize(
nullptr);
659 bytes_read = *size * m_format_options.GetCountValue().GetCurrentValue();
662 addr = addr + (*size * m_memory_options.m_offset.GetCurrentValue());
663 }
else if (m_format_options.GetFormatValue().GetCurrentValue() !=
665 data_sp = std::make_shared<DataBufferHeap>(total_byte_size,
'\0');
666 if (data_sp->GetBytes() ==
nullptr) {
668 "can't allocate 0x%" PRIx32
669 " bytes for the memory read buffer, specify a smaller size to read",
674 Address address(addr,
nullptr);
675 bytes_read = target->
ReadMemory(address, data_sp->GetBytes(),
676 data_sp->GetByteSize(),
error,
true);
677 if (bytes_read == 0) {
678 const char *error_cstr =
error.AsCString();
679 if (error_cstr && error_cstr[0]) {
683 "failed to read memory from 0x%" PRIx64
".\n", addr);
688 if (bytes_read < total_byte_size)
690 "Not all bytes (%" PRIu64
"/%" PRIu64
691 ") were able to be read from 0x%" PRIx64
".\n",
692 (uint64_t)bytes_read, (uint64_t)total_byte_size, addr);
696 if (m_format_options.GetByteSizeValue().OptionWasSet() &&
697 !m_format_options.HasGDBFormat())
698 item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
701 if (!m_format_options.GetCountValue().OptionWasSet())
703 data_sp = std::make_shared<DataBufferHeap>(
704 (item_byte_size + 1) * item_count,
706 if (data_sp->GetBytes() ==
nullptr) {
708 "can't allocate 0x%" PRIx64
709 " bytes for the memory read buffer, specify a smaller size to read",
710 (uint64_t)((item_byte_size + 1) * item_count));
713 uint8_t *data_ptr = data_sp->GetBytes();
714 auto data_addr = addr;
715 auto count = item_count;
717 bool break_on_no_NULL =
false;
718 while (item_count < count) {
720 buffer.resize(item_byte_size + 1, 0);
723 item_byte_size + 1,
error);
726 "failed to read memory from 0x%" PRIx64
".\n", addr);
730 if (item_byte_size == read) {
732 "unable to find a NULL terminated string at 0x%" PRIx64
733 ". Consider increasing the maximum read length.\n",
736 break_on_no_NULL =
true;
740 memcpy(data_ptr, &buffer[0], read);
747 if (break_on_no_NULL)
751 std::make_shared<DataBufferHeap>(data_sp->GetBytes(), bytes_read + 1);
754 m_next_addr = addr + bytes_read;
755 m_prev_byte_size = bytes_read;
756 m_prev_format_options = m_format_options;
757 m_prev_memory_options = m_memory_options;
758 m_prev_outfile_options = m_outfile_options;
759 m_prev_varobj_options = m_varobj_options;
760 m_prev_memory_tag_options = m_memory_tag_options;
761 m_prev_compiler_type = compiler_type;
763 std::unique_ptr<Stream> output_stream_storage;
764 Stream *output_stream_p =
nullptr;
766 m_outfile_options.GetFile().GetCurrentValue();
772 File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate;
773 const bool append = m_outfile_options.GetAppend().GetCurrentValue();
775 append ? File::eOpenOptionAppend : File::eOpenOptionTruncate;
777 auto outfile = FileSystem::Instance().Open(outfile_spec, open_options);
780 auto outfile_stream_up =
781 std::make_unique<StreamFile>(std::move(outfile.get()));
782 if (m_memory_options.m_output_as_binary) {
783 const size_t bytes_written =
784 outfile_stream_up->Write(data_sp->GetBytes(), bytes_read);
785 if (bytes_written > 0) {
787 "%zi bytes %s to '%s'\n", bytes_written,
788 append ?
"appended" :
"written", path.c_str());
793 (uint64_t)bytes_read, path.c_str());
799 output_stream_storage = std::move(outfile_stream_up);
800 output_stream_p = output_stream_storage.get();
804 path.c_str(), append ?
"append" :
"write");
815 for (
uint32_t i = 0; i < item_count; ++i) {
816 addr_t item_addr = addr + (i * item_byte_size);
819 name_strm.
Printf(
"0x%" PRIx64, item_addr);
820 ValueObjectSP valobj_sp(ValueObjectMemory::Create(
821 exe_scope, name_strm.
GetString(), address, compiler_type));
823 Format format = m_format_options.GetFormat();
825 valobj_sp->SetFormat(format);
830 valobj_sp->Dump(*output_stream_p, options);
833 "failed to create a value object for: (%s) %s\n",
834 view_as_type_cstr, name_strm.
GetData());
846 Format format = m_format_options.GetFormat();
848 (item_byte_size != 1)) {
850 if (!m_format_options.GetCountValue().OptionWasSet() || item_count == 1) {
856 item_count = item_byte_size;
862 "reading memory as characters of size %" PRIu64
" is not supported",
863 (uint64_t)item_byte_size);
868 assert(output_stream_p);
870 data, output_stream_p, 0, format, item_byte_size, item_count,
872 exe_scope, m_memory_tag_options.GetShowTags().GetCurrentValue());
873 m_next_addr = addr + bytes_dumped;
874 output_stream_p->
EOL();
894 #define LLDB_OPTIONS_memory_find
895 #include "CommandOptions.inc"
907 return llvm::ArrayRef(g_memory_find_options);
913 const int short_option = g_memory_find_options[option_idx].short_option;
915 switch (short_option) {
917 m_expr.SetValueFromString(option_value);
921 m_string.SetValueFromString(option_value);
925 if (m_count.SetValueFromString(option_value).Fail())
926 error.SetErrorString(
"unrecognized value for count");
930 if (m_offset.SetValueFromString(option_value).Fail())
931 error.SetErrorString(
"unrecognized value for dump-offset");
935 llvm_unreachable(
"Unimplemented option");
954 interpreter,
"memory find",
955 "Find a value in the memory of the current target process.",
956 nullptr, eCommandRequiresProcess | eCommandProcessMustBeLaunched) {
968 arg1.push_back(addr_arg);
976 arg2.push_back(value_arg);
979 m_arguments.push_back(arg1);
980 m_arguments.push_back(arg2);
982 m_option_group.Append(&m_memory_options);
985 m_option_group.Finalize();
996 : m_process_sp(process_sp), m_base_addr(base) {
1009 m_process_sp->ReadMemory(m_base_addr + offset, &retval, 1,
error)) {
1020 bool m_is_valid =
true;
1025 Process *process = m_exe_ctx.GetProcessPtr();
1030 result.
AppendError(
"two addresses needed for memory find");
1048 ABISP abi = m_exe_ctx.GetProcessPtr()->GetABI();
1050 low_addr = abi->FixDataAddress(low_addr);
1051 high_addr = abi->FixDataAddress(high_addr);
1054 if (high_addr <= low_addr) {
1056 "starting address must be smaller than ending address");
1064 if (m_memory_options.m_string.OptionWasSet()) {
1065 llvm::StringRef str = m_memory_options.m_string.GetStringValue();
1067 result.
AppendError(
"search string must have non-zero length.");
1071 }
else if (m_memory_options.m_expr.OptionWasSet()) {
1073 ValueObjectSP result_sp;
1076 m_memory_options.m_expr.GetStringValue(), frame, result_sp)) &&
1078 uint64_t value = result_sp->GetValueAsUnsigned(0);
1079 std::optional<uint64_t> size =
1080 result_sp->GetCompilerType().GetByteSize(
nullptr);
1085 uint8_t
byte = (uint8_t)value;
1103 result.
AppendError(
"unknown type. pass a string instead");
1107 "result size larger than 8 bytes. pass a string instead");
1112 "expression evaluation failed. pass a string instead");
1117 "please pass either a block of text, or an expression to evaluate.");
1121 size_t count = m_memory_options.m_count.GetCurrentValue();
1122 found_location = low_addr;
1123 bool ever_found =
false;
1125 found_location = FastSearch(found_location, high_addr, buffer.GetBytes(),
1132 result.
AppendMessage(
"no more matches within the range.\n");
1140 found_location + m_memory_options.m_offset.GetCurrentValue(),
1142 if (!
error.Fail()) {
1149 found_location + m_memory_options.m_offset.GetCurrentValue(), 0, 0,
1150 m_exe_ctx.GetBestExecutionContextScope(),
1151 m_memory_tag_options.GetShowTags().GetCurrentValue());
1165 size_t buffer_size) {
1166 const size_t region_size = high - low;
1168 if (region_size < buffer_size)
1171 std::vector<size_t> bad_char_heuristic(256, buffer_size);
1172 ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1175 for (
size_t idx = 0; idx < buffer_size - 1; idx++) {
1176 decltype(bad_char_heuristic)::size_type bcu_idx = buffer[idx];
1177 bad_char_heuristic[bcu_idx] = buffer_size - idx - 1;
1179 for (
size_t s = 0; s <= (region_size - buffer_size);) {
1180 int64_t j = buffer_size - 1;
1181 while (j >= 0 && buffer[j] == iterator[s + j])
1186 s += bad_char_heuristic[iterator[s + buffer_size - 1]];
1197 #define LLDB_OPTIONS_memory_write
1198 #include "CommandOptions.inc"
1210 return llvm::ArrayRef(g_memory_write_options);
1216 const int short_option = g_memory_write_options[option_idx].short_option;
1218 switch (short_option) {
1220 m_infile.SetFile(option_value, FileSpec::Style::native);
1221 FileSystem::Instance().Resolve(m_infile);
1222 if (!FileSystem::Instance().Exists(m_infile)) {
1224 error.SetErrorStringWithFormat(
"input file does not exist: '%s'",
1225 option_value.str().c_str());
1230 if (option_value.getAsInteger(0, m_infile_offset)) {
1231 m_infile_offset = 0;
1232 error.SetErrorStringWithFormat(
"invalid offset string '%s'",
1233 option_value.str().c_str());
1238 llvm_unreachable(
"Unimplemented option");
1245 m_infile_offset = 0;
1254 interpreter,
"memory write",
1255 "Write to the memory of the current target process.", nullptr,
1256 eCommandRequiresProcess | eCommandProcessMustBeLaunched),
1261 "The format to use for each of the value to be written."),
1263 "The size in bytes to write from input file or "
1265 CommandArgumentEntry arg1;
1266 CommandArgumentEntry arg2;
1267 CommandArgumentData addr_arg;
1268 CommandArgumentData value_arg;
1276 arg1.push_back(addr_arg);
1285 arg2.push_back(value_arg);
1288 m_arguments.push_back(arg1);
1289 m_arguments.push_back(arg2);
1291 m_option_group.Append(&m_format_options,
1292 OptionGroupFormat::OPTION_GROUP_FORMAT,
1294 m_option_group.Append(&m_format_options,
1295 OptionGroupFormat::OPTION_GROUP_SIZE,
1298 m_option_group.Finalize();
1309 Process *process = m_exe_ctx.GetProcessPtr();
1313 if (m_memory_options.m_infile) {
1316 "%s takes a destination address when writing file contents.\n",
1317 m_cmd_name.c_str());
1322 "%s takes only a destination address when writing file contents.\n",
1323 m_cmd_name.c_str());
1326 }
else if (argc < 2) {
1328 "%s takes a destination address and at least one value.\n",
1329 m_cmd_name.c_str());
1346 result.
AppendError(
"invalid address expression\n");
1351 if (m_memory_options.m_infile) {
1352 size_t length = SIZE_MAX;
1353 if (item_byte_size > 1)
1354 length = item_byte_size;
1355 auto data_sp = FileSystem::Instance().CreateDataBuffer(
1356 m_memory_options.m_infile.GetPath(), length,
1357 m_memory_options.m_infile_offset);
1359 length = data_sp->GetByteSize();
1362 size_t bytes_written =
1365 if (bytes_written == length) {
1368 "%" PRIu64
" bytes were written to 0x%" PRIx64
"\n",
1369 (uint64_t)bytes_written, addr);
1371 }
else if (bytes_written > 0) {
1374 "%" PRIu64
" bytes of %" PRIu64
1375 " requested were written to 0x%" PRIx64
"\n",
1376 (uint64_t)bytes_written, (uint64_t)length, addr);
1381 addr,
error.AsCString());
1388 }
else if (item_byte_size == 0) {
1398 bool success =
false;
1399 for (
auto &entry : command) {
1400 switch (m_format_options.GetFormat()) {
1429 result.
AppendError(
"unsupported format for writing memory");
1440 bool success =
false;
1441 if (entry.ref().startswith(
"0x"))
1442 success = !entry.ref().getAsInteger(0, uval64);
1444 success = !entry.ref().getAsInteger(16, uval64);
1447 "'%s' is not a valid hex string value.\n", entry.c_str());
1449 }
else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1451 " is too large to fit in a %" PRIu64
1452 " byte unsigned integer value.\n",
1453 uval64, (uint64_t)item_byte_size);
1460 uval64 = OptionArgParser::ToBoolean(entry.ref(),
false, &success);
1463 "'%s' is not a valid boolean string value.\n", entry.c_str());
1470 if (entry.ref().getAsInteger(2, uval64)) {
1472 "'%s' is not a valid binary string value.\n", entry.c_str());
1474 }
else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1476 " is too large to fit in a %" PRIu64
1477 " byte unsigned integer value.\n",
1478 uval64, (uint64_t)item_byte_size);
1487 if (entry.ref().empty())
1490 size_t len = entry.ref().size();
1500 addr,
error.AsCString());
1506 if (entry.ref().getAsInteger(0, sval64)) {
1508 "'%s' is not a valid signed decimal value.\n", entry.c_str());
1510 }
else if (!llvm::isIntN(item_byte_size * 8, sval64)) {
1512 "Value %" PRIi64
" is too large or small to fit in a %" PRIu64
1513 " byte signed integer value.\n",
1514 sval64, (uint64_t)item_byte_size);
1522 if (entry.ref().getAsInteger(0, uval64)) {
1524 "'%s' is not a valid unsigned decimal string value.\n",
1527 }
else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1529 " is too large to fit in a %" PRIu64
1530 " byte unsigned integer value.\n",
1531 uval64, (uint64_t)item_byte_size);
1538 if (entry.ref().getAsInteger(8, uval64)) {
1540 "'%s' is not a valid octal string value.\n", entry.c_str());
1542 }
else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1544 " is too large to fit in a %" PRIu64
1545 " byte unsigned integer value.\n",
1546 uval64, (uint64_t)item_byte_size);
1563 addr,
error.AsCString());
1580 "Print recorded stack traces for "
1581 "allocation/deallocation events "
1582 "associated with an address.",
1584 eCommandRequiresTarget | eCommandRequiresProcess |
1585 eCommandProcessMustBePaused |
1586 eCommandProcessMustBeLaunched) {
1596 arg1.push_back(addr_arg);
1599 m_arguments.push_back(arg1);
1613 if (argc == 0 || argc > 1) {
1615 m_cmd_name.c_str());
1631 const ProcessSP &process_sp = m_exe_ctx.GetProcessSP();
1632 const MemoryHistorySP &memory_history =
1633 MemoryHistory::FindPlugin(process_sp);
1635 if (!memory_history) {
1636 result.
AppendError(
"no available memory history provider");
1640 HistoryThreads thread_list = memory_history->GetHistoryThreads(addr);
1642 const bool stop_format =
false;
1643 for (
auto thread : thread_list) {
1644 thread->GetStatus(*output_stream, 0,
UINT32_MAX, 0, stop_format);
1654 #pragma mark CommandObjectMemoryRegion
1656 #define LLDB_OPTIONS_memory_region
1657 #include "CommandOptions.inc"
1668 return llvm::ArrayRef(g_memory_region_options);
1674 const int short_option = g_memory_region_options[option_idx].short_option;
1676 switch (short_option) {
1678 m_all.SetCurrentValue(
true);
1679 m_all.SetOptionWasSet();
1682 llvm_unreachable(
"Unimplemented option");
1697 "Get information on the memory region containing "
1698 "an address in the current target process.",
1699 "memory region <address-expression> (or --all)",
1700 eCommandRequiresProcess | eCommandTryTargetAPILock |
1701 eCommandProcessMustBeLaunched) {
1706 m_option_group.Append(&m_memory_region_options);
1707 m_option_group.Finalize();
1723 while (section_sp->GetParent())
1724 section_sp = section_sp->GetParent();
1725 section_name = section_sp->GetName();
1731 "[{0:x16}-{1:x16}) {2:r}{3:w}{4:x}{5}{6}{7}{8}",
1735 name, section_name ?
" " :
"", section_name);
1737 if (memory_tagged == MemoryRegionInfo::OptionalBool::eYes)
1740 const std::optional<std::vector<addr_t>> &dirty_page_list =
1742 if (dirty_page_list) {
1743 const size_t page_count = dirty_page_list->size();
1745 "Modified memory (dirty) page list provided, %zu entries.\n",
1747 if (page_count > 0) {
1748 bool print_comma =
false;
1750 for (
size_t i = 0; i < page_count; i++) {
1763 ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1775 const lldb::ABISP &abi = process_sp->GetABI();
1778 if (m_memory_region_options.m_all) {
1780 "The \"--all\" option cannot be used when an address "
1781 "argument is given");
1785 auto load_addr_str = command[0].ref();
1787 load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str,
1791 command[0].c_str(),
error.AsCString());
1794 }
else if (argc > 1 ||
1798 (argc == 0 && !m_memory_region_options.m_all &&
1804 (abi && (abi->FixAnyAddress(load_addr) != load_addr))) {
1806 "'%s' takes one argument or \"--all\" option:\nUsage: %s\n",
1807 m_cmd_name.c_str(), m_cmd_syntax.c_str());
1815 std::vector<std::pair<lldb_private::MemoryRegionInfo, lldb::addr_t>>
1817 if (m_memory_region_options.m_all) {
1825 (!abi || (abi->FixAnyAddress(addr) == addr))) {
1827 error = process_sp->GetMemoryRegionInfo(addr, region_info);
1829 if (
error.Success()) {
1830 region_list.push_back({region_info, addr});
1836 error = process_sp->GetMemoryRegionInfo(load_addr, region_info);
1837 if (
error.Success())
1838 region_list.push_back({region_info, load_addr});
1841 if (
error.Success()) {
1842 for (std::pair<MemoryRegionInfo, addr_t> &range : region_list) {
1843 DumpRegion(result, process_sp->GetTarget(), range.first, range.second);
1844 m_prev_end_addr = range.first.GetRange().GetRangeEnd();
1872 interpreter,
"memory",
1873 "Commands for operating on memory in the current target process.",
1874 "memory <subcommand> [<subcommand-options>]") {