summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdwfl/ChangeLog7
-rw-r--r--libdwfl/elf-from-memory.c17
2 files changed, 19 insertions, 5 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 85307875..b6a9161e 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,10 @@
+2014-03-03 Mark Wielaard <[email protected]>
+
+ * elf-from-memory.c (elf_from_remote_memory): Keep track of
+ segments_end_mem. Pass memsz to first handle_segment pass. Only
+ extend contents_size and use shdrs if only file bits are in
+ segment.
+
2014-03-11 Josh Stone <[email protected]>
* dwfl_module_getdwarf.c (open_elf): Only explicitly set
diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c
index 602614b8..df9fbe69 100644
--- a/libdwfl/elf-from-memory.c
+++ b/libdwfl/elf-from-memory.c
@@ -196,6 +196,7 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
/* Scan for PT_LOAD segments to find the total size of the file image. */
size_t contents_size = 0;
GElf_Off segments_end = 0;
+ GElf_Off segments_end_mem = 0;
GElf_Addr loadbase = ehdr_vma;
bool found_base = false;
switch (ehdr.e32.e_ident[EI_CLASS])
@@ -205,7 +206,8 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
found_base yet). Returns true if sanity checking failed,
false otherwise. */
inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
- GElf_Xword filesz, GElf_Xword palign)
+ GElf_Xword filesz, GElf_Xword memsz,
+ GElf_Xword palign)
{
/* Sanity check the alignment requirements. */
if ((palign & (pagesize - 1)) != 0
@@ -225,6 +227,7 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
}
segments_end = offset + filesz;
+ segments_end_mem = offset + memsz;
return false;
}
@@ -235,7 +238,8 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
for (uint_fast16_t i = 0; i < phnum; ++i)
if (phdrs.p32[i].p_type == PT_LOAD)
if (handle_segment (phdrs.p32[i].p_vaddr, phdrs.p32[i].p_offset,
- phdrs.p32[i].p_filesz, phdrs.p32[i].p_align))
+ phdrs.p32[i].p_filesz, phdrs.p32[i].p_memsz,
+ phdrs.p32[i].p_align))
goto bad_elf;
break;
@@ -246,7 +250,8 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
for (uint_fast16_t i = 0; i < phnum; ++i)
if (phdrs.p64[i].p_type == PT_LOAD)
if (handle_segment (phdrs.p64[i].p_vaddr, phdrs.p64[i].p_offset,
- phdrs.p64[i].p_filesz, phdrs.p64[i].p_align))
+ phdrs.p64[i].p_filesz, phdrs.p64[i].p_memsz,
+ phdrs.p64[i].p_align))
goto bad_elf;
break;
@@ -257,9 +262,11 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
/* Trim the last segment so we don't bother with zeros in the last page
that are off the end of the file. However, if the extra bit in that
- page includes the section headers, keep them. */
+ page includes the section headers and the memory isn't extended (which
+ might indicate it will have been reused otherwise), keep them. */
if ((GElf_Off) contents_size > segments_end
- && (GElf_Off) contents_size >= shdrs_end)
+ && (GElf_Off) contents_size >= shdrs_end
+ && segments_end == segments_end_mem)
{
contents_size = segments_end;
if ((GElf_Off) contents_size < shdrs_end)