diff options
| -rw-r--r-- | libdwfl/ChangeLog | 7 | ||||
| -rw-r--r-- | libdwfl/elf-from-memory.c | 17 |
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) |
