Target::ReadMemory read from read-only binary file Section, not memory

Commiting this patch for Augusto Noronha who is getting set
up still.

This patch changes Target::ReadMemory so the default behavior
when a read is in a Section that is read-only is to fetch the
data from the local binary image, instead of reading it from
memory.  Update all callers to use their old preferences
(the old prefer_file_cache bool) using the new API; we should
revisit these calls and see if they really intend to read
live memory, or if reading from a read-only Section would be
equivalent and important for performance-sensitive cases.

rdar://30634422

Differential revision: https://reviews.llvm.org/D100338
This commit is contained in:
Jason Molenda 2021-04-16 16:10:16 -07:00
parent 11707435cc
commit e9fe788d32
28 changed files with 122 additions and 133 deletions

View File

@ -394,10 +394,12 @@ public:
lldb::addr_t value;
};
static lldb::DisassemblerSP
DisassembleRange(const ArchSpec &arch, const char *plugin_name,
const char *flavor, Target &target,
const AddressRange &disasm_range, bool prefer_file_cache);
static lldb::DisassemblerSP DisassembleRange(const ArchSpec &arch,
const char *plugin_name,
const char *flavor,
Target &target,
const AddressRange &disasm_range,
bool force_live_memory = false);
static lldb::DisassemblerSP
DisassembleBytes(const ArchSpec &arch, const char *plugin_name,
@ -426,7 +428,8 @@ public:
Stream &strm);
size_t ParseInstructions(Target &target, Address address, Limit limit,
Stream *error_strm_ptr, bool prefer_file_cache);
Stream *error_strm_ptr,
bool force_live_memory = false);
virtual size_t DecodeInstructions(const Address &base_addr,
const DataExtractor &data,

View File

@ -631,10 +631,10 @@ public:
lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx,
const char *flavor,
bool prefer_file_cache);
bool force_live_memory = false);
bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
bool prefer_file_cache, Stream &strm);
Stream &strm, bool force_live_memory = false);
protected:
enum {

View File

@ -1005,11 +1005,12 @@ public:
// read from const sections in object files, read from the target. This
// version of ReadMemory will try and read memory from the process if the
// process is alive. The order is:
// 1 - if (prefer_file_cache == true) then read from object file cache
// 2 - if there is a valid process, try and read from its memory
// 3 - if (prefer_file_cache == false) then read from object file cache
size_t ReadMemory(const Address &addr, bool prefer_file_cache, void *dst,
size_t dst_len, Status &error,
// 1 - if (force_live_memory == false) and the address falls in a read-only
// section, then read from the file cache
// 2 - if there is a process, then read from memory
// 3 - if there is no process, then read from the file cache
size_t ReadMemory(const Address &addr, void *dst, size_t dst_len,
Status &error, bool force_live_memory = false,
lldb::addr_t *load_addr_ptr = nullptr);
size_t ReadCStringFromMemory(const Address &addr, std::string &out_str,
@ -1018,18 +1019,19 @@ public:
size_t ReadCStringFromMemory(const Address &addr, char *dst,
size_t dst_max_len, Status &result_error);
size_t ReadScalarIntegerFromMemory(const Address &addr,
bool prefer_file_cache, uint32_t byte_size,
size_t ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_size,
bool is_signed, Scalar &scalar,
Status &error);
Status &error,
bool force_live_memory = false);
uint64_t ReadUnsignedIntegerFromMemory(const Address &addr,
bool prefer_file_cache,
size_t integer_byte_size,
uint64_t fail_value, Status &error);
uint64_t fail_value, Status &error,
bool force_live_memory = false);
bool ReadPointerFromMemory(const Address &addr, bool prefer_file_cache,
Status &error, Address &pointer_addr);
bool ReadPointerFromMemory(const Address &addr, Status &error,
Address &pointer_addr,
bool force_live_memory = false);
SectionLoadList &GetSectionLoadList() {
return m_section_load_history.GetCurrentSectionLoadList();

View File

@ -132,10 +132,10 @@ SBInstructionList SBFunction::GetInstructions(SBTarget target,
m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule());
if (target_sp && module_sp) {
lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
const bool prefer_file_cache = false;
const bool force_live_memory = true;
sb_instructions.SetDisassembler(Disassembler::DisassembleRange(
module_sp->GetArchitecture(), nullptr, flavor, *target_sp,
m_opaque_ptr->GetAddressRange(), prefer_file_cache));
m_opaque_ptr->GetAddressRange(), force_live_memory));
}
}
return LLDB_RECORD_RESULT(sb_instructions);

View File

@ -132,10 +132,10 @@ SBInstructionList SBSymbol::GetInstructions(SBTarget target,
ModuleSP module_sp = symbol_addr.GetModule();
if (module_sp) {
AddressRange symbol_range(symbol_addr, m_opaque_ptr->GetByteSize());
const bool prefer_file_cache = false;
const bool force_live_memory = true;
sb_instructions.SetDisassembler(Disassembler::DisassembleRange(
module_sp->GetArchitecture(), nullptr, flavor_string, *target_sp,
symbol_range, prefer_file_cache));
symbol_range, force_live_memory));
}
}
}

View File

@ -705,7 +705,7 @@ size_t SBTarget::ReadMemory(const SBAddress addr, void *buf, size_t size,
if (target_sp) {
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
bytes_read =
target_sp->ReadMemory(addr.ref(), false, buf, size, sb_error.ref());
target_sp->ReadMemory(addr.ref(), buf, size, sb_error.ref(), true);
} else {
sb_error.SetErrorString("invalid target");
}
@ -2085,12 +2085,12 @@ lldb::SBInstructionList SBTarget::ReadInstructions(lldb::SBAddress base_addr,
if (addr_ptr) {
DataBufferHeap data(
target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0);
bool prefer_file_cache = false;
bool force_live_memory = true;
lldb_private::Status error;
lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
const size_t bytes_read =
target_sp->ReadMemory(*addr_ptr, prefer_file_cache, data.GetBytes(),
data.GetByteSize(), error, &load_addr);
target_sp->ReadMemory(*addr_ptr, data.GetBytes(), data.GetByteSize(),
error, force_live_memory, &load_addr);
const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
sb_instructions.SetDisassembler(Disassembler::DisassembleBytes(
target_sp->GetArchitecture(), nullptr, flavor_string, *addr_ptr,

View File

@ -669,8 +669,8 @@ protected:
}
Address address(addr, nullptr);
bytes_read = target->ReadMemory(address, false, data_sp->GetBytes(),
data_sp->GetByteSize(), error);
bytes_read = target->ReadMemory(address, data_sp->GetBytes(),
data_sp->GetByteSize(), error, true);
if (bytes_read == 0) {
const char *error_cstr = error.AsCString();
if (error_cstr && error_cstr[0]) {

View File

@ -65,9 +65,9 @@ static size_t ReadBytes(ExecutionContextScope *exe_scope,
TargetSP target_sp(exe_scope->CalculateTarget());
if (target_sp) {
Status error;
bool prefer_file_cache = false;
return target_sp->ReadMemory(address, prefer_file_cache, dst, dst_len,
error);
bool force_live_memory = true;
return target_sp->ReadMemory(address, dst, dst_len, error,
force_live_memory);
}
return 0;
}

View File

@ -122,7 +122,7 @@ static Address ResolveAddress(Target &target, const Address &addr) {
lldb::DisassemblerSP Disassembler::DisassembleRange(
const ArchSpec &arch, const char *plugin_name, const char *flavor,
Target &target, const AddressRange &range, bool prefer_file_cache) {
Target &target, const AddressRange &range, bool force_live_memory) {
if (range.GetByteSize() <= 0)
return {};
@ -137,7 +137,7 @@ lldb::DisassemblerSP Disassembler::DisassembleRange(
const size_t bytes_disassembled = disasm_sp->ParseInstructions(
target, range.GetBaseAddress(), {Limit::Bytes, range.GetByteSize()},
nullptr, prefer_file_cache);
nullptr, force_live_memory);
if (bytes_disassembled == 0)
return {};
@ -181,9 +181,9 @@ bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
if (!disasm_sp)
return false;
const bool prefer_file_cache = false;
const bool force_live_memory = true;
size_t bytes_disassembled = disasm_sp->ParseInstructions(
exe_ctx.GetTargetRef(), address, limit, &strm, prefer_file_cache);
exe_ctx.GetTargetRef(), address, limit, &strm, force_live_memory);
if (bytes_disassembled == 0)
return false;
@ -1036,7 +1036,7 @@ InstructionList::GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr,
size_t Disassembler::ParseInstructions(Target &target, Address start,
Limit limit, Stream *error_strm_ptr,
bool prefer_file_cache) {
bool force_live_memory) {
m_instruction_list.Clear();
if (!start.IsValid())
@ -1052,8 +1052,8 @@ size_t Disassembler::ParseInstructions(Target &target, Address start,
Status error;
lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
const size_t bytes_read =
target.ReadMemory(start, prefer_file_cache, data_sp->GetBytes(),
data_sp->GetByteSize(), error, &load_addr);
target.ReadMemory(start, data_sp->GetBytes(), data_sp->GetByteSize(),
error, force_live_memory, &load_addr);
const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
if (bytes_read == 0) {

View File

@ -3550,7 +3550,7 @@ public:
if (m_disassembly_scope != m_sc.function) {
m_disassembly_scope = m_sc.function;
m_disassembly_sp = m_sc.function->GetInstructions(
exe_ctx, nullptr, prefer_file_cache);
exe_ctx, nullptr, !prefer_file_cache);
if (m_disassembly_sp) {
set_selected_line_to_pc = true;
m_disassembly_range = m_sc.function->GetAddressRange();

View File

@ -525,15 +525,10 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
} else if ((address_type == eAddressTypeLoad) ||
(address_type == eAddressTypeFile)) {
if (file_so_addr.IsValid()) {
// We have a file address that we were able to translate into a section
// offset address so we might be able to read this from the object
// files if we don't have a live process. Lets always try and read from
// the process if we have one though since we want to read the actual
// value by setting "prefer_file_cache" to false.
const bool prefer_file_cache = false;
if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache,
dst, byte_size,
error) != byte_size) {
const bool force_live_memory = true;
if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, dst, byte_size,
error, force_live_memory) !=
byte_size) {
error.SetErrorStringWithFormat(
"read memory from 0x%" PRIx64 " failed", (uint64_t)address);
}

View File

@ -721,7 +721,7 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
if (target) {
heap_buf_ptr->SetByteSize(bytes);
size_t bytes_read = target->ReadMemory(
so_addr, false, heap_buf_ptr->GetBytes(), bytes, error);
so_addr, heap_buf_ptr->GetBytes(), bytes, error, true);
if (error.Success()) {
data.SetData(data_sp);
return bytes_read;

View File

@ -639,7 +639,7 @@ void IRMemoryMap::ReadMemory(uint8_t *bytes, lldb::addr_t process_address,
if (target_sp) {
Address absolute_address(process_address);
target_sp->ReadMemory(absolute_address, false, bytes, size, error);
target_sp->ReadMemory(absolute_address, bytes, size, error, true);
return;
}

View File

@ -160,7 +160,6 @@ Instruction *ArchitectureMips::GetInstructionAtAddress(
InstructionList instruction_list;
InstructionSP prev_insn;
bool prefer_file_cache = true; // Read from file
uint32_t inst_to_choose = 0;
Address addr = resolved_addr;
@ -171,8 +170,7 @@ Instruction *ArchitectureMips::GetInstructionAtAddress(
uint32_t insn_size = 0;
disasm_sp->ParseInstructions(target, addr,
{Disassembler::Limit::Bytes, i * 2}, nullptr,
prefer_file_cache);
{Disassembler::Limit::Bytes, i * 2}, nullptr);
uint32_t num_insns = disasm_sp->GetInstructionList().GetSize();
if (num_insns) {

View File

@ -1093,16 +1093,16 @@ bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
uint8_t buf[24];
DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
const size_t count = 4 * sizeof(uint32_t) + addr_size;
const bool prefer_file_cache = false;
const bool force_live_memory = true;
if (m_process->GetTarget().ReadPointerFromMemory(
m_kext_summary_header_ptr_addr, prefer_file_cache, error,
m_kext_summary_header_addr)) {
m_kext_summary_header_ptr_addr, error,
m_kext_summary_header_addr, force_live_memory)) {
// We got a valid address for our kext summary header and make sure it
// isn't NULL
if (m_kext_summary_header_addr.IsValid() &&
m_kext_summary_header_addr.GetFileAddress() != 0) {
const size_t bytes_read = m_process->GetTarget().ReadMemory(
m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
m_kext_summary_header_addr, buf, count, error, force_live_memory);
if (bytes_read == count) {
lldb::offset_t offset = 0;
m_kext_summary_header.version = data.GetU32(&offset);
@ -1373,10 +1373,9 @@ uint32_t DynamicLoaderDarwinKernel::ReadKextSummaries(
DataBufferHeap data(count, 0);
Status error;
const bool prefer_file_cache = false;
const bool force_live_memory = true;
const size_t bytes_read = m_process->GetTarget().ReadMemory(
kext_summary_addr, prefer_file_cache, data.GetBytes(), data.GetByteSize(),
error);
kext_summary_addr, data.GetBytes(), data.GetByteSize(), error, force_live_memory);
if (bytes_read == count) {
DataExtractor extractor(data.GetBytes(), data.GetByteSize(), endian,

View File

@ -1086,7 +1086,7 @@ DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp,
Status error;
const size_t tsl_data_size = addr_size * 3;
Target &target = m_process->GetTarget();
if (target.ReadMemory(tls_addr, false, buf, tsl_data_size, error) ==
if (target.ReadMemory(tls_addr, buf, tsl_data_size, error, true) ==
tsl_data_size) {
const ByteOrder byte_order = m_process->GetByteOrder();
DataExtractor data(buf, sizeof(buf), byte_order, addr_size);

View File

@ -193,7 +193,7 @@ DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread,
AddressRange range(pc, 2 * 15);
DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
arch, nullptr, nullptr, m_process->GetTarget(), range, true);
arch, nullptr, nullptr, m_process->GetTarget(), range);
if (!disassembler_sp) {
return ThreadPlanSP();
}

View File

@ -1018,8 +1018,9 @@ bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode,
const size_t bytes_read =
target->ReadMemory(next_addr, /* Address of next instruction */
true, /* prefer_file_cache */
buf, sizeof(uint32_t), error, &load_addr);
buf, sizeof(uint32_t), error,
false, /* force_live_memory */
&load_addr);
if (bytes_read == 0)
return true;

View File

@ -859,8 +859,7 @@ Address ObjectFileELF::GetImageInfoAddress(Target *target) {
if (symbol.d_tag == DT_MIPS_RLD_MAP) {
// DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer.
Address addr;
if (target->ReadPointerFromMemory(dyn_base + offset, false, error,
addr))
if (target->ReadPointerFromMemory(dyn_base + offset, error, addr, true))
return addr;
}
if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) {
@ -868,7 +867,7 @@ Address ObjectFileELF::GetImageInfoAddress(Target *target) {
// relative to the address of the tag.
uint64_t rel_offset;
rel_offset = target->ReadUnsignedIntegerFromMemory(
dyn_base + offset, false, GetAddressByteSize(), UINT64_MAX, error);
dyn_base + offset, GetAddressByteSize(), UINT64_MAX, error, true);
if (error.Success() && rel_offset != UINT64_MAX) {
Address addr;
addr_t debug_ptr_address =

View File

@ -38,10 +38,10 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
ProcessSP process_sp(thread.GetProcess());
if (process_sp) {
Status error;
const bool prefer_file_cache = true;
const bool force_live_memory = true;
if (process_sp->GetTarget().ReadMemory(
range.GetBaseAddress(), prefer_file_cache, function_text.data(),
range.GetByteSize(), error) != range.GetByteSize()) {
range.GetBaseAddress(), function_text.data(), range.GetByteSize(),
error, force_live_memory) != range.GetByteSize()) {
return false;
}
}

View File

@ -51,12 +51,11 @@ bool UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly(
ProcessSP process_sp(thread.GetProcess());
if (process_sp.get() == nullptr)
return false;
const bool prefer_file_cache = true;
std::vector<uint8_t> function_text(func.GetByteSize());
Status error;
if (process_sp->GetTarget().ReadMemory(
func.GetBaseAddress(), prefer_file_cache, function_text.data(),
func.GetByteSize(), error) == func.GetByteSize()) {
func.GetBaseAddress(), function_text.data(), func.GetByteSize(),
error) == func.GetByteSize()) {
RegisterContextSP reg_ctx(thread.GetRegisterContext());
m_assembly_inspection_engine->Initialize(reg_ctx);
return m_assembly_inspection_engine->GetNonCallSiteUnwindPlanFromAssembly(
@ -153,12 +152,11 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
return false;
if (m_assembly_inspection_engine == nullptr)
return false;
const bool prefer_file_cache = true;
std::vector<uint8_t> function_text(func.GetByteSize());
Status error;
if (process_sp->GetTarget().ReadMemory(
func.GetBaseAddress(), prefer_file_cache, function_text.data(),
func.GetByteSize(), error) == func.GetByteSize()) {
func.GetBaseAddress(), function_text.data(), func.GetByteSize(),
error) == func.GetByteSize()) {
RegisterContextSP reg_ctx(thread.GetRegisterContext());
m_assembly_inspection_engine->Initialize(reg_ctx);
return m_assembly_inspection_engine->AugmentUnwindPlanFromCallSite(
@ -185,10 +183,9 @@ bool UnwindAssembly_x86::GetFastUnwindPlan(AddressRange &func, Thread &thread,
ProcessSP process_sp = thread.GetProcess();
if (process_sp) {
Target &target(process_sp->GetTarget());
const bool prefer_file_cache = true;
Status error;
if (target.ReadMemory(func.GetBaseAddress(), prefer_file_cache,
opcode_data.data(), 4, error) == 4) {
if (target.ReadMemory(func.GetBaseAddress(), opcode_data.data(), 4,
error) == 4) {
uint8_t i386_push_mov[] = {0x55, 0x89, 0xe5};
uint8_t x86_64_push_mov[] = {0x55, 0x48, 0x89, 0xe5};
@ -220,12 +217,10 @@ bool UnwindAssembly_x86::FirstNonPrologueInsn(
if (m_assembly_inspection_engine == nullptr)
return false;
const bool prefer_file_cache = true;
std::vector<uint8_t> function_text(func.GetByteSize());
Status error;
if (target->ReadMemory(func.GetBaseAddress(), prefer_file_cache,
function_text.data(), func.GetByteSize(),
error) == func.GetByteSize()) {
if (target->ReadMemory(func.GetBaseAddress(), function_text.data(),
func.GetByteSize(), error) == func.GetByteSize()) {
size_t offset;
if (m_assembly_inspection_engine->FindFirstNonPrologueInstruction(
function_text.data(), func.GetByteSize(), offset)) {

View File

@ -426,17 +426,16 @@ lldb::DisassemblerSP Function::GetInstructions(const ExecutionContext &exe_ctx,
bool prefer_file_cache) {
ModuleSP module_sp(GetAddressRange().GetBaseAddress().GetModule());
if (module_sp && exe_ctx.HasTargetScope()) {
const bool prefer_file_cache = false;
return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr,
flavor, exe_ctx.GetTargetRef(),
GetAddressRange(), prefer_file_cache);
GetAddressRange(), !prefer_file_cache);
}
return lldb::DisassemblerSP();
}
bool Function::GetDisassembly(const ExecutionContext &exe_ctx,
const char *flavor, bool prefer_file_cache,
Stream &strm) {
const char *flavor, Stream &strm,
bool prefer_file_cache) {
lldb::DisassemblerSP disassembler_sp =
GetInstructions(exe_ctx, flavor, prefer_file_cache);
if (disassembler_sp) {

View File

@ -542,10 +542,9 @@ lldb::DisassemblerSP Symbol::GetInstructions(const ExecutionContext &exe_ctx,
bool prefer_file_cache) {
ModuleSP module_sp(m_addr_range.GetBaseAddress().GetModule());
if (module_sp && exe_ctx.HasTargetScope()) {
const bool prefer_file_cache = false;
return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr,
flavor, exe_ctx.GetTargetRef(),
m_addr_range, prefer_file_cache);
m_addr_range, !prefer_file_cache);
}
return lldb::DisassemblerSP();
}

View File

@ -5810,10 +5810,8 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr,
const char *plugin_name = nullptr;
const char *flavor = nullptr;
const bool prefer_file_cache = true;
disassembler_sp = Disassembler::DisassembleRange(
target.GetArchitecture(), plugin_name, flavor, GetTarget(), range_bounds,
prefer_file_cache);
target.GetArchitecture(), plugin_name, flavor, GetTarget(), range_bounds);
if (disassembler_sp)
insn_list = &disassembler_sp->GetInstructionList();

View File

@ -1294,11 +1294,11 @@ lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) {
const char *plugin_name = nullptr;
const char *flavor = nullptr;
const bool prefer_file_cache = false;
const bool force_live_memory = true;
DisassemblerSP disassembler_sp =
Disassembler::DisassembleRange(target_arch, plugin_name, flavor,
*target_sp, pc_range, prefer_file_cache);
*target_sp, pc_range, force_live_memory);
if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
return ValueObjectSP();
@ -1674,10 +1674,10 @@ lldb::ValueObjectSP StackFrame::GuessValueForRegisterAndOffset(ConstString reg,
const char *plugin_name = nullptr;
const char *flavor = nullptr;
const bool prefer_file_cache = false;
const bool force_live_memory = true;
DisassemblerSP disassembler_sp =
Disassembler::DisassembleRange(target_arch, plugin_name, flavor,
*target_sp, pc_range, prefer_file_cache);
*target_sp, pc_range, force_live_memory);
if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
return ValueObjectSP();

View File

@ -1717,8 +1717,8 @@ size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst,
return 0;
}
size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache,
void *dst, size_t dst_len, Status &error,
size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len,
Status &error, bool force_live_memory,
lldb::addr_t *load_addr_ptr) {
error.Clear();
@ -1753,10 +1753,20 @@ size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache,
if (!resolved_addr.IsValid())
resolved_addr = addr;
if (prefer_file_cache) {
bytes_read = ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
if (bytes_read > 0)
return bytes_read;
bool is_readonly = false;
// Read from file cache if read-only section.
if (!force_live_memory && resolved_addr.IsSectionOffset()) {
SectionSP section_sp(addr.GetSection());
if (section_sp) {
auto permissions = Flags(section_sp->GetPermissions());
is_readonly = !permissions.Test(ePermissionsWritable) &&
permissions.Test(ePermissionsReadable);
}
if (is_readonly) {
bytes_read = ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
if (bytes_read > 0)
return bytes_read;
}
}
if (ProcessIsValid()) {
@ -1791,17 +1801,10 @@ size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache,
*load_addr_ptr = load_addr;
return bytes_read;
}
// If the address is not section offset we have an address that doesn't
// resolve to any address in any currently loaded shared libraries and we
// failed to read memory so there isn't anything more we can do. If it is
// section offset, we might be able to read cached memory from the object
// file.
if (!resolved_addr.IsSectionOffset())
return 0;
}
}
if (!prefer_file_cache && resolved_addr.IsSectionOffset()) {
if (!is_readonly && resolved_addr.IsSectionOffset()) {
// If we didn't already try and read from the object file cache, then try
// it after failing to read from the process.
return ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
@ -1856,7 +1859,7 @@ size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,
addr_t bytes_to_read =
std::min<addr_t>(bytes_left, cache_line_bytes_left);
size_t bytes_read =
ReadMemory(address, false, curr_dst, bytes_to_read, error);
ReadMemory(address, curr_dst, bytes_to_read, error, true);
if (bytes_read == 0) {
result_error = error;
@ -1884,15 +1887,15 @@ size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,
return total_cstr_len;
}
size_t Target::ReadScalarIntegerFromMemory(const Address &addr,
bool prefer_file_cache,
uint32_t byte_size, bool is_signed,
Scalar &scalar, Status &error) {
size_t Target::ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_size,
bool is_signed, Scalar &scalar,
Status &error,
bool force_live_memory) {
uint64_t uval;
if (byte_size <= sizeof(uval)) {
size_t bytes_read =
ReadMemory(addr, prefer_file_cache, &uval, byte_size, error);
ReadMemory(addr, &uval, byte_size, error, force_live_memory);
if (bytes_read == byte_size) {
DataExtractor data(&uval, sizeof(uval), m_arch.GetSpec().GetByteOrder(),
m_arch.GetSpec().GetAddressByteSize());
@ -1914,23 +1917,22 @@ size_t Target::ReadScalarIntegerFromMemory(const Address &addr,
}
uint64_t Target::ReadUnsignedIntegerFromMemory(const Address &addr,
bool prefer_file_cache,
size_t integer_byte_size,
uint64_t fail_value,
Status &error) {
uint64_t fail_value, Status &error,
bool force_live_memory) {
Scalar scalar;
if (ReadScalarIntegerFromMemory(addr, prefer_file_cache, integer_byte_size,
false, scalar, error))
if (ReadScalarIntegerFromMemory(addr, integer_byte_size, false, scalar, error,
force_live_memory))
return scalar.ULongLong(fail_value);
return fail_value;
}
bool Target::ReadPointerFromMemory(const Address &addr, bool prefer_file_cache,
Status &error, Address &pointer_addr) {
bool Target::ReadPointerFromMemory(const Address &addr, Status &error,
Address &pointer_addr,
bool force_live_memory) {
Scalar scalar;
if (ReadScalarIntegerFromMemory(addr, prefer_file_cache,
m_arch.GetSpec().GetAddressByteSize(), false,
scalar, error)) {
if (ReadScalarIntegerFromMemory(addr, m_arch.GetSpec().GetAddressByteSize(),
false, scalar, error, force_live_memory)) {
addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
if (pointer_vm_addr != LLDB_INVALID_ADDRESS) {
SectionLoadList &section_load_list = GetSectionLoadList();

View File

@ -264,10 +264,9 @@ InstructionList *ThreadPlanStepRange::GetInstructionsForAddress(
// Disassemble the address range given:
const char *plugin_name = nullptr;
const char *flavor = nullptr;
const bool prefer_file_cache = true;
m_instruction_ranges[i] = Disassembler::DisassembleRange(
GetTarget().GetArchitecture(), plugin_name, flavor, GetTarget(),
m_address_ranges[i], prefer_file_cache);
m_address_ranges[i]);
}
if (!m_instruction_ranges[i])
return nullptr;

View File

@ -200,7 +200,7 @@ DumpInstructionInfo(Stream &s, const SymbolContext &sc,
// Now we try using the current function's disassembler
if (sc.function) {
DisassemblerSP disassembler =
sc.function->GetInstructions(exe_ctx, nullptr, true);
sc.function->GetInstructions(exe_ctx, nullptr);
if (TryDumpInstructionInfo(s, disassembler, exe_ctx, address))
return disassembler;
}
@ -209,9 +209,9 @@ DumpInstructionInfo(Stream &s, const SymbolContext &sc,
Target &target = exe_ctx.GetTargetRef();
const ArchSpec &arch = target.GetArchitecture();
AddressRange range(address, arch.GetMaximumOpcodeByteSize() * 1);
DisassemblerSP disassembler = Disassembler::DisassembleRange(
arch, /*plugin_name*/ nullptr,
/*flavor*/ nullptr, target, range, /*prefer_file_cache*/ true);
DisassemblerSP disassembler =
Disassembler::DisassembleRange(arch, /*plugin_name*/ nullptr,
/*flavor*/ nullptr, target, range);
if (TryDumpInstructionInfo(s, disassembler, exe_ctx, address))
return disassembler;
return nullptr;