summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Target/Target.h19
-rw-r--r--lldb/source/Core/Address.cpp3
-rw-r--r--lldb/source/Core/Disassembler.cpp3
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp14
-rw-r--r--lldb/source/Target/Target.cpp54
5 files changed, 74 insertions, 19 deletions
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 4bb3e3f02d6..a01bed40f0d 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -401,12 +401,27 @@ public:
GetTargetTriple (ConstString &target_triple);
size_t
+ ReadMemoryFromFileCache (const Address& addr,
+ void *dst,
+ size_t dst_len,
+ Error &error);
+
+ // Reading memory through the target allows us to skip going to the process
+ // for reading memory if possible and it allows us to try and read from
+ // any constant sections in our object files on disk. If you always want
+ // live program memory, read straight from the process. If you possibly
+ // want to 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,
Error &error);
-
-
SectionLoadList&
GetSectionLoadList()
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp
index a038dd83edc..c87814fa1f6 100644
--- a/lldb/source/Core/Address.cpp
+++ b/lldb/source/Core/Address.cpp
@@ -68,7 +68,8 @@ ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst,
if (target)
{
Error error;
- return target->ReadMemory (address, dst, dst_len, error);
+ bool prefer_file_cache = false;
+ return target->ReadMemory (address, prefer_file_cache, dst, dst_len, error);
}
return 0;
}
diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index 65380493082..e6fe1b018a5 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -422,7 +422,8 @@ Disassembler::ParseInstructions
DataBufferSP data_sp(heap_buffer);
Error error;
- const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), heap_buffer->GetBytes(), heap_buffer->GetByteSize(), error);
+ bool prefer_file_cache = true;
+ const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), prefer_file_cache, heap_buffer->GetBytes(), heap_buffer->GetByteSize(), error);
if (bytes_read > 0)
{
diff --git a/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp b/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp
index d6463e22474..fd42948d5db 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp
@@ -470,7 +470,8 @@ read_byte_for_edis (uint8_t *buf, uint64_t offset_address, void *arg)
uint8_t onebyte_buf[1];
Error error;
- if (target->ReadMemory (read_addr, onebyte_buf, 1, error) != -1)
+ const bool prefer_file_cache = true;
+ if (target->ReadMemory (read_addr, prefer_file_cache, onebyte_buf, 1, error) != -1)
{
*buf = onebyte_buf[0];
return 0;
@@ -550,6 +551,7 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
row.SetRegisterInfo (m_lldb_ip_regnum, initial_regloc);
unwind_plan.AppendRow (row);
+ const bool prefer_file_cache = true;
while (m_func_bounds.ContainsFileAddress (m_cur_insn) && non_prologue_insn_count < 10)
{
@@ -562,7 +564,7 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
// An unrecognized/junk instruction
break;
}
- if (m_target.ReadMemory (m_cur_insn, m_cur_insn_bytes, insn_len, error) == -1)
+ if (m_target.ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
{
// Error reading the instruction out of the file, stop scanning
break;
@@ -672,7 +674,7 @@ loopnext:
Address last_insn (m_func_bounds.GetBaseAddress());
last_insn.SetOffset (last_insn.GetOffset() + m_func_bounds.GetByteSize() - 1);
uint8_t bytebuf[1];
- if (m_target.ReadMemory (last_insn, bytebuf, 1, error) != -1)
+ if (m_target.ReadMemory (last_insn, prefer_file_cache, bytebuf, 1, error) != -1)
{
if (bytebuf[0] == 0xc3) // ret aka retq
{
@@ -723,7 +725,8 @@ AssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_
uint8_t bytebuf[4];
Error error;
- if (m_target.ReadMemory (func.GetBaseAddress(), bytebuf, sizeof (bytebuf), error) == -1)
+ const bool prefer_file_cache = true;
+ if (m_target.ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf, sizeof (bytebuf), error) == -1)
return false;
uint8_t i386_prologue[] = {0x55, 0x89, 0xe5};
@@ -781,6 +784,7 @@ AssemblyParse_x86::find_first_non_prologue_insn (Address &address)
return false;
}
+ const bool prefer_file_cache = true;
while (m_func_bounds.ContainsFileAddress (m_cur_insn))
{
Error error;
@@ -790,7 +794,7 @@ AssemblyParse_x86::find_first_non_prologue_insn (Address &address)
// An error parsing the instruction, i.e. probably data/garbage - stop scanning
break;
}
- if (m_target.ReadMemory (m_cur_insn, m_cur_insn_bytes, insn_len, error) == -1)
+ if (m_target.ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
{
// Error reading the instruction out of the file, stop scanning
break;
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 36058e9cc5f..6f5858a8acc 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -589,12 +589,43 @@ Target::ModulesDidUnload (ModuleList &module_list)
}
size_t
-Target::ReadMemory (const Address& addr, void *dst, size_t dst_len, Error &error)
+Target::ReadMemoryFromFileCache (const Address& addr, void *dst, size_t dst_len, Error &error)
{
- error.Clear();
+ const Section *section = addr.GetSection();
+ if (section && section->GetModule())
+ {
+ ObjectFile *objfile = section->GetModule()->GetObjectFile();
+ if (objfile)
+ {
+ size_t bytes_read = section->ReadSectionDataFromObjectFile (objfile,
+ addr.GetOffset(),
+ dst,
+ dst_len);
+ if (bytes_read > 0)
+ return bytes_read;
+ else
+ error.SetErrorStringWithFormat("error reading data from section %s", section->GetName().GetCString());
+ }
+ else
+ {
+ error.SetErrorString("address isn't from a object file");
+ }
+ }
+ else
+ {
+ error.SetErrorString("address doesn't contain a section that points to a section in a object file");
+ }
+ return 0;
+}
+size_t
+Target::ReadMemory (const Address& addr, bool prefer_file_cache, void *dst, size_t dst_len, Error &error)
+{
+ error.Clear();
+
bool process_is_valid = m_process_sp && m_process_sp->IsAlive();
+ size_t bytes_read = 0;
Address resolved_addr(addr);
if (!resolved_addr.IsSectionOffset())
{
@@ -608,6 +639,12 @@ Target::ReadMemory (const Address& addr, void *dst, size_t dst_len, Error &error
}
}
+ if (prefer_file_cache)
+ {
+ bytes_read = ReadMemoryFromFileCache (resolved_addr, dst, dst_len, error);
+ if (bytes_read > 0)
+ return bytes_read;
+ }
if (process_is_valid)
{
@@ -623,7 +660,7 @@ Target::ReadMemory (const Address& addr, void *dst, size_t dst_len, Error &error
}
else
{
- size_t bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);
+ bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);
if (bytes_read != dst_len)
{
if (error.Success())
@@ -646,14 +683,11 @@ Target::ReadMemory (const Address& addr, void *dst, size_t dst_len, Error &error
}
}
- const Section *section = resolved_addr.GetSection();
- if (section && section->GetModule())
+ if (!prefer_file_cache)
{
- ObjectFile *objfile = section->GetModule()->GetObjectFile();
- return section->ReadSectionDataFromObjectFile (objfile,
- resolved_addr.GetOffset(),
- dst,
- dst_len);
+ // 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);
}
return 0;
}
OpenPOWER on IntegriCloud