[elf-core] Improve reading memory from core file

This patch tries to improve memory-read from core files
(in order to improve disassembly functionality).

I am using RHEL 7.7 (linux kernel 3.10) and for a lot of cases,
I was not able to disassemble some functions from backtrace when
debugging crashes from core files. It outputs some dummy code.

The cause of the problem was the fact we are returning all the zeros
from ProcessElfCore::ReadMemory() that is being called within
Disassembler::ParseInstructions() and it disassembles some dummy
opcodes from the buffer returned. Therefore, we are removing zero
bytes filling (padding) completely.

Differential Revision: https://reviews.llvm.org/D93939
This commit is contained in:
Djordje Todorovic 2020-12-30 00:38:20 -08:00 committed by Djordje Todorovic
parent 035abe30c9
commit 9abd8c1a4c
2 changed files with 20 additions and 12 deletions

View File

@ -353,7 +353,6 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
const lldb::addr_t file_end = address_range->data.GetRangeEnd();
size_t bytes_to_read = size; // Number of bytes to read from the core file
size_t bytes_copied = 0; // Number of bytes actually read from the core file
size_t zero_fill_size = 0; // Padding
lldb::addr_t bytes_left =
0; // Number of bytes available in the core file from the given address
@ -367,24 +366,15 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
if (file_end > file_start + offset)
bytes_left = file_end - (file_start + offset);
// Figure out how many bytes we need to zero-fill if we are reading more
// bytes than available in the on-disk segment
if (bytes_to_read > bytes_left) {
zero_fill_size = bytes_to_read - bytes_left;
if (bytes_to_read > bytes_left)
bytes_to_read = bytes_left;
}
// If there is data available on the core file read it
if (bytes_to_read)
bytes_copied =
core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
assert(zero_fill_size <= size);
// Pad remaining bytes
if (zero_fill_size)
memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
return bytes_copied + zero_fill_size;
return bytes_copied;
}
void ProcessElfCore::Clear() {

View File

@ -155,6 +155,24 @@ class LinuxCoreTestCase(TestBase):
self.do_test("linux-x86_64", self._x86_64_pid, self._x86_64_regions,
"a.out")
@skipIf(triple='^mips')
@skipIfLLVMTargetMissing("X86")
@skipIfWindows
@skipIfReproducer
def test_read_memory(self):
"""Test that we are able to read as many bytes as available"""
target = self.dbg.CreateTarget("linux-x86_64.out")
process = target.LoadCore("linux-x86_64.core")
self.assertTrue(process, PROCESS_IS_VALID)
error = lldb.SBError()
bytesread = process.ReadMemory(0x400ff0, 20, error)
# read only 16 bytes without zero bytes filling
self.assertEqual(len(bytesread), 16)
self.dbg.DeleteTarget(target)
@skipIf(triple='^mips')
@skipIfLLVMTargetMissing("X86")
def test_FPR_SSE(self):