37 #include "llvm/Support/MathExtras.h"
44 #define LLDB_OPTIONS_memory_read
45 #include "CommandOptions.inc"
50 : m_num_per_line(1, 1), m_offset(0, 0),
56 return llvm::makeArrayRef(g_memory_read_options);
62 const int short_option = g_memory_read_options[option_idx].short_option;
64 switch (short_option) {
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());
74 m_output_as_binary =
true;
78 error = m_view_as_type.SetValueFromString(option_value);
86 error = m_language_for_type.SetValueFromString(option_value);
90 error = m_offset.SetValueFromString(option_value);
98 llvm_unreachable(
"Unimplemented option");
104 m_num_per_line.Clear();
105 m_output_as_binary =
false;
106 m_view_as_type.Clear();
109 m_language_for_type.Clear();
117 const bool byte_size_option_set = byte_size_value.
OptionWasSet();
118 const bool num_per_line_option_set = m_num_per_line.OptionWasSet();
126 if (!byte_size_option_set)
128 if (!num_per_line_option_set)
130 if (!count_option_set)
138 if (count_option_set)
144 if (!byte_size_option_set)
147 if (!count_option_set)
153 if (!num_per_line_option_set)
155 if (!count_option_set)
169 if (!byte_size_option_set)
171 if (!num_per_line_option_set)
173 if (!count_option_set)
179 if (byte_size_option_set) {
180 if (byte_size_value > 1)
181 error.SetErrorStringWithFormat(
182 "display format (bytes/bytes with ASCII) conflicts with the "
183 "specified byte size %" PRIu64
"\n"
184 "\tconsider using a different display format or don't specify "
189 if (!num_per_line_option_set)
191 if (!count_option_set)
198 if (!byte_size_option_set)
200 if (!num_per_line_option_set)
202 if (!count_option_set)
207 if (!byte_size_option_set)
209 if (!num_per_line_option_set)
211 if (!count_option_set)
216 if (!byte_size_option_set)
218 if (!num_per_line_option_set)
220 if (!count_option_set)
225 if (!byte_size_option_set)
227 if (!num_per_line_option_set) {
228 switch (byte_size_value) {
244 if (!count_option_set)
261 if (!byte_size_option_set)
262 byte_size_value = 128;
263 if (!num_per_line_option_set)
265 if (!count_option_set)
273 return m_num_per_line.OptionWasSet() || m_output_as_binary ||
274 m_view_as_type.OptionWasSet() || m_offset.OptionWasSet() ||
275 m_language_for_type.OptionWasSet();
279 bool m_output_as_binary =
false;
284 bool m_show_tags =
false;
292 interpreter,
"memory read",
293 "Read from the memory of the current target process.", nullptr,
294 eCommandRequiresTarget | eCommandProcessMustBePaused),
309 arg1.push_back(start_addr_arg);
317 arg2.push_back(end_addr_arg);
320 m_arguments.push_back(arg1);
321 m_arguments.push_back(arg2);
324 m_option_group.Append(&m_format_options,
325 OptionGroupFormat::OPTION_GROUP_FORMAT |
326 OptionGroupFormat::OPTION_GROUP_COUNT,
328 m_option_group.Append(&m_format_options,
329 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
332 m_option_group.Append(&m_format_options,
333 OptionGroupFormat::OPTION_GROUP_SIZE,
335 m_option_group.Append(&m_memory_options);
339 m_option_group.Finalize();
355 Target *target = m_exe_ctx.GetTargetPtr();
361 "an optional end address expression.\n",
363 result.
AppendWarning(
"Expressions should be quoted if they contain "
364 "spaces or other special characters.");
371 const char *view_as_type_cstr =
372 m_memory_options.m_view_as_type.GetCurrentValue();
373 if (view_as_type_cstr && view_as_type_cstr[0]) {
376 const bool exact_match =
false;
382 #define ALL_KEYWORDS \
384 KEYWORD("volatile") \
385 KEYWORD("restrict") \
390 #define KEYWORD(s) s,
394 #define KEYWORD(s) (sizeof(s) - 1),
400 static size_t g_num_keywords =
sizeof(g_keywords) /
sizeof(
const char *);
404 for (
size_t i = 0; i < g_num_keywords; ++i) {
405 const char *keyword = g_keywords[i];
406 int keyword_len = g_keyword_lengths[i];
409 while ((idx = type_str.find(keyword, idx)) != std::string::npos) {
410 if (type_str[idx + keyword_len] ==
' ' ||
411 type_str[idx + keyword_len] ==
'\t') {
412 type_str.erase(idx, keyword_len + 1);
419 bool done = type_str.empty();
421 idx = type_str.find_first_not_of(
" \t");
422 if (idx > 0 && idx != std::string::npos)
423 type_str.erase(0, idx);
426 if (type_str.empty())
429 switch (type_str[type_str.size() - 1]) {
435 type_str.erase(type_str.size() - 1);
439 if (reference_count == 0) {
441 type_str.erase(type_str.size() - 1);
456 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
459 ModuleSP search_first;
464 exact_match, 1, searched_symbol_files,
469 m_memory_options.m_language_for_type.GetCurrentValue();
470 std::set<LanguageType> languages_to_check;
472 languages_to_check.insert(language_for_type);
474 languages_to_check = Language::GetSupportedLanguages();
477 std::set<CompilerType> user_defined_types;
478 for (
auto lang : languages_to_check) {
479 if (
auto *persistent_vars =
481 if (llvm::Optional<CompilerType> type =
482 persistent_vars->GetCompilerTypeFromPersistentDecl(
484 user_defined_types.emplace(*type);
489 if (user_defined_types.size() > 1) {
491 "Mutiple types found matching raw type '%s', please disambiguate "
492 "by specifying the language with -x",
497 if (user_defined_types.size() == 1) {
498 compiler_type = *user_defined_types.begin();
502 if (!compiler_type.
IsValid()) {
503 if (type_list.
GetSize() == 0) {
505 "the raw type '%s' for full type '%s'\n",
511 compiler_type = type_sp->GetFullCompilerType();
515 while (pointer_count > 0) {
518 compiler_type = pointer_type;
520 result.
AppendError(
"unable make a pointer type\n");
526 llvm::Optional<uint64_t> size = compiler_type.
GetByteSize(
nullptr);
529 "unable to get the byte size of the type '%s'\n",
533 m_format_options.GetByteSizeValue() = *size;
535 if (!m_format_options.GetCountValue().OptionWasSet())
536 m_format_options.GetCountValue() = 1;
538 error = m_memory_options.FinalizeSettings(target, m_format_options);
548 size_t total_byte_size = 0;
553 total_byte_size = m_prev_byte_size;
554 compiler_type = m_prev_compiler_type;
555 if (!m_format_options.AnyOptionWasSet() &&
556 !m_memory_options.AnyOptionWasSet() &&
557 !m_outfile_options.AnyOptionWasSet() &&
558 !m_varobj_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;
566 size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
572 size_t item_byte_size =
575 : m_format_options.GetByteSizeValue().GetCurrentValue();
577 const size_t num_per_line =
578 m_memory_options.m_num_per_line.GetCurrentValue();
580 if (total_byte_size == 0) {
581 total_byte_size = item_count * item_byte_size;
582 if (total_byte_size == 0)
583 total_byte_size = 32;
587 addr = OptionArgParser::ToAddress(&m_exe_ctx, command[0].ref(),
591 result.
AppendError(
"invalid start address expression.");
596 ABISP abi = m_exe_ctx.GetProcessPtr()->GetABI();
598 addr = abi->FixDataAddress(addr);
604 end_addr = abi->FixDataAddress(end_addr);
607 result.
AppendError(
"invalid end address expression.");
610 }
else if (end_addr <= addr) {
612 "end address (0x%" PRIx64
613 ") must be greater than the start address (0x%" PRIx64
").\n",
616 }
else if (m_format_options.GetCountValue().OptionWasSet()) {
618 "specify either the end address (0x%" PRIx64
619 ") or the count (--count %" PRIu64
"), not both.\n",
620 end_addr, (uint64_t)item_count);
624 total_byte_size = end_addr - addr;
625 item_count = total_byte_size / item_byte_size;
630 if (total_byte_size > max_unforced_size && !m_memory_options.m_force) {
632 "Normally, \'memory read\' will not read over %" PRIu32
636 "Please use --force to override this restriction just once.\n");
638 "will often need a larger limit.\n");
642 WritableDataBufferSP data_sp;
643 size_t bytes_read = 0;
647 if (!m_format_options.GetFormatValue().OptionWasSet())
648 m_format_options.GetFormatValue().SetCurrentValue(
eFormatDefault);
650 llvm::Optional<uint64_t> size = compiler_type.
GetByteSize(
nullptr);
655 bytes_read = *size * m_format_options.GetCountValue().GetCurrentValue();
658 addr = addr + (*size * m_memory_options.m_offset.GetCurrentValue());
659 }
else if (m_format_options.GetFormatValue().GetCurrentValue() !=
661 data_sp = std::make_shared<DataBufferHeap>(total_byte_size,
'\0');
662 if (data_sp->GetBytes() ==
nullptr) {
664 "can't allocate 0x%" PRIx32
665 " bytes for the memory read buffer, specify a smaller size to read",
670 Address address(addr,
nullptr);
671 bytes_read = target->
ReadMemory(address, data_sp->GetBytes(),
672 data_sp->GetByteSize(),
error,
true);
673 if (bytes_read == 0) {
674 const char *error_cstr =
error.AsCString();
675 if (error_cstr && error_cstr[0]) {
679 "failed to read memory from 0x%" PRIx64
".\n", addr);
684 if (bytes_read < total_byte_size)
686 "Not all bytes (%" PRIu64
"/%" PRIu64
687 ") were able to be read from 0x%" PRIx64
".\n",
688 (uint64_t)bytes_read, (uint64_t)total_byte_size, addr);
692 if (m_format_options.GetByteSizeValue().OptionWasSet() &&
693 !m_format_options.HasGDBFormat())
694 item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
697 if (!m_format_options.GetCountValue().OptionWasSet())
699 data_sp = std::make_shared<DataBufferHeap>(
700 (item_byte_size + 1) * item_count,
702 if (data_sp->GetBytes() ==
nullptr) {
704 "can't allocate 0x%" PRIx64
705 " bytes for the memory read buffer, specify a smaller size to read",
706 (uint64_t)((item_byte_size + 1) * item_count));
709 uint8_t *data_ptr = data_sp->GetBytes();
710 auto data_addr = addr;
711 auto count = item_count;
713 bool break_on_no_NULL =
false;
714 while (item_count < count) {
716 buffer.resize(item_byte_size + 1, 0);
719 item_byte_size + 1,
error);
722 "failed to read memory from 0x%" PRIx64
".\n", addr);
726 if (item_byte_size == read) {
728 "unable to find a NULL terminated string at 0x%" PRIx64
729 ". Consider increasing the maximum read length.\n",
732 break_on_no_NULL =
true;
736 memcpy(data_ptr, &buffer[0], read);
743 if (break_on_no_NULL)
747 std::make_shared<DataBufferHeap>(data_sp->GetBytes(), bytes_read + 1);
750 m_next_addr = addr + bytes_read;
751 m_prev_byte_size = bytes_read;
752 m_prev_format_options = m_format_options;
753 m_prev_memory_options = m_memory_options;
754 m_prev_outfile_options = m_outfile_options;
755 m_prev_varobj_options = m_varobj_options;
756 m_prev_compiler_type = compiler_type;
758 std::unique_ptr<Stream> output_stream_storage;
759 Stream *output_stream_p =
nullptr;
761 m_outfile_options.GetFile().GetCurrentValue();
767 File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate;
768 const bool append = m_outfile_options.GetAppend().GetCurrentValue();
770 append ? File::eOpenOptionAppend : File::eOpenOptionTruncate;
772 auto outfile = FileSystem::Instance().Open(outfile_spec, open_options);
775 auto outfile_stream_up =
776 std::make_unique<StreamFile>(std::move(outfile.get()));
777 if (m_memory_options.m_output_as_binary) {
778 const size_t bytes_written =
779 outfile_stream_up->Write(data_sp->GetBytes(), bytes_read);
780 if (bytes_written > 0) {
782 "%zi bytes %s to '%s'\n", bytes_written,
783 append ?
"appended" :
"written", path.c_str());
788 (uint64_t)bytes_read, path.c_str());
794 output_stream_storage = std::move(outfile_stream_up);
795 output_stream_p = output_stream_storage.get();
799 path.c_str(), append ?
"append" :
"write");
810 for (
uint32_t i = 0; i < item_count; ++i) {
811 addr_t item_addr = addr + (i * item_byte_size);
814 name_strm.
Printf(
"0x%" PRIx64, item_addr);
815 ValueObjectSP valobj_sp(ValueObjectMemory::Create(
816 exe_scope, name_strm.
GetString(), address, compiler_type));
818 Format format = m_format_options.GetFormat();
820 valobj_sp->SetFormat(format);
825 valobj_sp->Dump(*output_stream_p, options);
828 "failed to create a value object for: (%s) %s\n",
829 view_as_type_cstr, name_strm.
GetData());
841 Format format = m_format_options.GetFormat();
843 (item_byte_size != 1)) {
845 if (!m_format_options.GetCountValue().OptionWasSet() || item_count == 1) {
851 item_count = item_byte_size;
857 "reading memory as characters of size %" PRIu64
" is not supported",
858 (uint64_t)item_byte_size);
863 assert(output_stream_p);
865 data, output_stream_p, 0, format, item_byte_size, item_count,
867 exe_scope, m_memory_options.m_show_tags);
868 m_next_addr = addr + bytes_dumped;
869 output_stream_p->
EOL();
887 #define LLDB_OPTIONS_memory_find
888 #include "CommandOptions.inc"
900 return llvm::makeArrayRef(g_memory_find_options);
906 const int short_option = g_memory_find_options[option_idx].short_option;
908 switch (short_option) {
910 m_expr.SetValueFromString(option_value);
914 m_string.SetValueFromString(option_value);
918 if (m_count.SetValueFromString(option_value).Fail())
919 error.SetErrorString(
"unrecognized value for count");
923 if (m_offset.SetValueFromString(option_value).Fail())
924 error.SetErrorString(
"unrecognized value for dump-offset");
928 llvm_unreachable(
"Unimplemented option");
947 interpreter,
"memory find",
948 "Find a value in the memory of the current target process.",
949 nullptr, eCommandRequiresProcess | eCommandProcessMustBeLaunched) {
961 arg1.push_back(addr_arg);
969 arg2.push_back(value_arg);
972 m_arguments.push_back(arg1);
973 m_arguments.push_back(arg2);
975 m_option_group.Append(&m_memory_options);
976 m_option_group.Finalize();
987 : m_process_sp(process_sp), m_base_addr(base) {
1000 m_process_sp->ReadMemory(m_base_addr + offset, &retval, 1,
error)) {
1011 bool m_is_valid =
true;
1016 Process *process = m_exe_ctx.GetProcessPtr();
1021 result.
AppendError(
"two addresses needed for memory find");
1039 ABISP abi = m_exe_ctx.GetProcessPtr()->GetABI();
1041 low_addr = abi->FixDataAddress(low_addr);
1042 high_addr = abi->FixDataAddress(high_addr);
1045 if (high_addr <= low_addr) {
1047 "starting address must be smaller than ending address");
1055 if (m_memory_options.m_string.OptionWasSet()) {
1056 llvm::StringRef str = m_memory_options.m_string.GetStringValue();
1058 result.
AppendError(
"search string must have non-zero length.");
1062 }
else if (m_memory_options.m_expr.OptionWasSet()) {
1064 ValueObjectSP result_sp;
1067 m_memory_options.m_expr.GetStringValue(), frame, result_sp)) &&
1069 uint64_t value = result_sp->GetValueAsUnsigned(0);
1070 llvm::Optional<uint64_t> size =
1071 result_sp->GetCompilerType().GetByteSize(
nullptr);
1076 uint8_t
byte = (uint8_t)value;
1094 result.
AppendError(
"unknown type. pass a string instead");
1098 "result size larger than 8 bytes. pass a string instead");
1103 "expression evaluation failed. pass a string instead");
1108 "please pass either a block of text, or an expression to evaluate.");
1112 size_t count = m_memory_options.m_count.GetCurrentValue();
1113 found_location = low_addr;
1114 bool ever_found =
false;
1116 found_location = FastSearch(found_location, high_addr, buffer.GetBytes(),
1123 result.
AppendMessage(
"no more matches within the range.\n");
1131 found_location + m_memory_options.m_offset.GetCurrentValue(),
1133 if (!
error.Fail()) {
1140 found_location + m_memory_options.m_offset.GetCurrentValue(), 0, 0);
1154 size_t buffer_size) {
1155 const size_t region_size = high - low;
1157 if (region_size < buffer_size)
1160 std::vector<size_t> bad_char_heuristic(256, buffer_size);
1161 ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1164 for (
size_t idx = 0; idx < buffer_size - 1; idx++) {
1165 decltype(bad_char_heuristic)::size_type bcu_idx = buffer[idx];
1166 bad_char_heuristic[bcu_idx] = buffer_size - idx - 1;
1168 for (
size_t s = 0; s <= (region_size - buffer_size);) {
1169 int64_t j = buffer_size - 1;
1170 while (j >= 0 && buffer[j] == iterator[s + j])
1175 s += bad_char_heuristic[iterator[s + buffer_size - 1]];
1185 #define LLDB_OPTIONS_memory_write
1186 #include "CommandOptions.inc"
1198 return llvm::makeArrayRef(g_memory_write_options);
1204 const int short_option = g_memory_write_options[option_idx].short_option;
1206 switch (short_option) {
1208 m_infile.SetFile(option_value, FileSpec::Style::native);
1209 FileSystem::Instance().Resolve(m_infile);
1210 if (!FileSystem::Instance().Exists(m_infile)) {
1212 error.SetErrorStringWithFormat(
"input file does not exist: '%s'",
1213 option_value.str().c_str());
1218 if (option_value.getAsInteger(0, m_infile_offset)) {
1219 m_infile_offset = 0;
1220 error.SetErrorStringWithFormat(
"invalid offset string '%s'",
1221 option_value.str().c_str());
1226 llvm_unreachable(
"Unimplemented option");
1233 m_infile_offset = 0;
1242 interpreter,
"memory write",
1243 "Write to the memory of the current target process.", nullptr,
1244 eCommandRequiresProcess | eCommandProcessMustBeLaunched),
1249 "The format to use for each of the value to be written."),
1251 "The size in bytes to write from input file or "
1253 CommandArgumentEntry arg1;
1254 CommandArgumentEntry arg2;
1255 CommandArgumentData addr_arg;
1256 CommandArgumentData value_arg;
1264 arg1.push_back(addr_arg);
1273 arg2.push_back(value_arg);
1276 m_arguments.push_back(arg1);
1277 m_arguments.push_back(arg2);
1279 m_option_group.Append(&m_format_options,
1280 OptionGroupFormat::OPTION_GROUP_FORMAT,
1282 m_option_group.Append(&m_format_options,
1283 OptionGroupFormat::OPTION_GROUP_SIZE,
1286 m_option_group.Finalize();
1297 Process *process = m_exe_ctx.GetProcessPtr();
1301 if (m_memory_options.m_infile) {
1304 "%s takes a destination address when writing file contents.\n",
1305 m_cmd_name.c_str());
1310 "%s takes only a destination address when writing file contents.\n",
1311 m_cmd_name.c_str());
1314 }
else if (argc < 2) {
1316 "%s takes a destination address and at least one value.\n",
1317 m_cmd_name.c_str());
1334 result.
AppendError(
"invalid address expression\n");
1339 if (m_memory_options.m_infile) {
1340 size_t length = SIZE_MAX;
1341 if (item_byte_size > 1)
1342 length = item_byte_size;
1343 auto data_sp = FileSystem::Instance().CreateDataBuffer(
1344 m_memory_options.m_infile.GetPath(), length,
1345 m_memory_options.m_infile_offset);
1347 length = data_sp->GetByteSize();
1350 size_t bytes_written =
1353 if (bytes_written == length) {
1356 "%" PRIu64
" bytes were written to 0x%" PRIx64
"\n",
1357 (uint64_t)bytes_written, addr);
1359 }
else if (bytes_written > 0) {
1362 "%" PRIu64
" bytes of %" PRIu64
1363 " requested were written to 0x%" PRIx64
"\n",
1364 (uint64_t)bytes_written, (uint64_t)length, addr);
1369 addr,
error.AsCString());
1376 }
else if (item_byte_size == 0) {
1386 bool success =
false;
1387 for (
auto &entry : command) {
1388 switch (m_format_options.GetFormat()) {
1417 result.
AppendError(
"unsupported format for writing memory");
1428 bool success =
false;
1429 if (entry.ref().startswith(
"0x"))
1430 success = !entry.ref().getAsInteger(0, uval64);
1432 success = !entry.ref().getAsInteger(16, uval64);
1435 "'%s' is not a valid hex string value.\n", entry.c_str());
1437 }
else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1439 " is too large to fit in a %" PRIu64
1440 " byte unsigned integer value.\n",
1441 uval64, (uint64_t)item_byte_size);
1448 uval64 = OptionArgParser::ToBoolean(entry.ref(),
false, &success);
1451 "'%s' is not a valid boolean string value.\n", entry.c_str());
1458 if (entry.ref().getAsInteger(2, uval64)) {
1460 "'%s' is not a valid binary string value.\n", entry.c_str());
1462 }
else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1464 " is too large to fit in a %" PRIu64
1465 " byte unsigned integer value.\n",
1466 uval64, (uint64_t)item_byte_size);
1475 if (entry.ref().empty())
1478 size_t len = entry.ref().size();
1488 addr,
error.AsCString());
1494 if (entry.ref().getAsInteger(0, sval64)) {
1496 "'%s' is not a valid signed decimal value.\n", entry.c_str());
1498 }
else if (!llvm::isIntN(item_byte_size * 8, sval64)) {
1500 "Value %" PRIi64
" is too large or small to fit in a %" PRIu64
1501 " byte signed integer value.\n",
1502 sval64, (uint64_t)item_byte_size);
1510 if (entry.ref().getAsInteger(0, uval64)) {
1512 "'%s' is not a valid unsigned decimal string value.\n",
1515 }
else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1517 " is too large to fit in a %" PRIu64
1518 " byte unsigned integer value.\n",
1519 uval64, (uint64_t)item_byte_size);
1526 if (entry.ref().getAsInteger(8, uval64)) {
1528 "'%s' is not a valid octal string value.\n", entry.c_str());
1530 }
else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1532 " is too large to fit in a %" PRIu64
1533 " byte unsigned integer value.\n",
1534 uval64, (uint64_t)item_byte_size);
1551 addr,
error.AsCString());
1568 "Print recorded stack traces for "
1569 "allocation/deallocation events "
1570 "associated with an address.",
1572 eCommandRequiresTarget | eCommandRequiresProcess |
1573 eCommandProcessMustBePaused |
1574 eCommandProcessMustBeLaunched) {
1584 arg1.push_back(addr_arg);
1587 m_arguments.push_back(arg1);
1601 if (argc == 0 || argc > 1) {
1603 m_cmd_name.c_str());
1619 const ProcessSP &process_sp = m_exe_ctx.GetProcessSP();
1620 const MemoryHistorySP &memory_history =
1621 MemoryHistory::FindPlugin(process_sp);
1623 if (!memory_history) {
1624 result.
AppendError(
"no available memory history provider");
1628 HistoryThreads thread_list = memory_history->GetHistoryThreads(addr);
1630 const bool stop_format =
false;
1631 for (
auto thread : thread_list) {
1632 thread->GetStatus(*output_stream, 0,
UINT32_MAX, 0, stop_format);
1642 #pragma mark CommandObjectMemoryRegion
1648 "Get information on the memory region containing "
1649 "an address in the current target process.",
1650 "memory region ADDR",
1651 eCommandRequiresProcess | eCommandTryTargetAPILock |
1652 eCommandProcessMustBeLaunched) {}
1658 ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1670 const lldb::ABISP &abi = process_sp->GetABI();
1673 auto load_addr_str = command[0].ref();
1675 load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str,
1679 command[0].c_str(),
error.AsCString());
1682 }
else if (argc > 1 ||
1691 (abi && (abi->FixAnyAddress(load_addr) != load_addr))) {
1693 m_cmd_name.c_str(), m_cmd_syntax.c_str());
1698 error = process_sp->GetMemoryRegionInfo(load_addr, range_info);
1699 if (
error.Success()) {
1703 if (process_sp->GetTarget().ResolveLoadAddress(load_addr, addr)) {
1707 while (section_sp->GetParent())
1708 section_sp = section_sp->GetParent();
1709 section_name = section_sp->GetName();
1714 "[{0:x16}-{1:x16}) {2:r}{3:w}{4:x}{5}{6}{7}{8}",
1718 name, section_name ?
" " :
"", section_name);
1721 if (memory_tagged == MemoryRegionInfo::OptionalBool::eYes)
1724 const llvm::Optional<std::vector<addr_t>> &dirty_page_list =
1726 if (dirty_page_list.hasValue()) {
1727 const size_t page_count = dirty_page_list.getValue().size();
1729 "Modified memory (dirty) page list provided, %zu entries.\n",
1731 if (page_count > 0) {
1732 bool print_comma =
false;
1734 for (
size_t i = 0; i < page_count; i++) {
1740 dirty_page_list.getValue()[i]);
1769 interpreter,
"memory",
1770 "Commands for operating on memory in the current target process.",
1771 "memory <subcommand> [<subcommand-options>]") {