forked from OSchip/llvm-project
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:
parent
11707435cc
commit
e9fe788d32
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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]) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 §ion_load_list = GetSectionLoadList();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue