diff options
author | Timm Bäder <tbaeder@redhat.com> | 2021-01-08 09:09:55 +0100 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2021-01-28 22:03:40 +0100 |
commit | 67a912f0b81047d42881be3c40c8404c2711711c (patch) | |
tree | 561d7be0fb08c169fdc337e6b4d0db4f51a9890e | |
parent | strip: Remove no_symtab_updates() function (diff) | |
download | elfutils-67a912f0b81047d42881be3c40c8404c2711711c.tar.gz elfutils-67a912f0b81047d42881be3c40c8404c2711711c.tar.bz2 elfutils-67a912f0b81047d42881be3c40c8404c2711711c.tar.xz |
elf-from-memory: Restructure code to get rid of nested handle_segment()
Use one loop for both 32 and 64 bit case. This allows for only one call
site of the old handle_segment(), which we can then inline into the for
loop.
Signed-off-by: Timm Bäder <tbaeder@redhat.com>
-rw-r--r-- | libdwfl/ChangeLog | 7 | ||||
-rw-r--r-- | libdwfl/elf-from-memory.c | 81 |
2 files changed, 41 insertions, 47 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index f9f6f01f..f17eafe7 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog | |||
@@ -1,3 +1,10 @@ | |||
1 | 2021-01-08 Timm Bäder <tbaeder@redhat.com> | ||
2 | |||
3 | * elf-from-memory.c (elf_from_remote_memory): Use if instead of | ||
4 | switch on class. Set new vaddr, memsz, offset and filesz | ||
5 | variables. Inline handle_segment function check and set loadbase, | ||
6 | found_base, segments_end and segments_end_mem directly. | ||
7 | |||
1 | 2020-12-16 Dmitry V. Levin <ldv@altlinux.org> | 8 | 2020-12-16 Dmitry V. Levin <ldv@altlinux.org> |
2 | 9 | ||
3 | * argp-std.c (_): Remove. | 10 | * argp-std.c (_): Remove. |
diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c index c54c1b99..933ab864 100644 --- a/libdwfl/elf-from-memory.c +++ b/libdwfl/elf-from-memory.c | |||
@@ -223,61 +223,48 @@ elf_from_remote_memory (GElf_Addr ehdr_vma, | |||
223 | bool found_base = false; | 223 | bool found_base = false; |
224 | Elf32_Phdr (*p32)[phnum] = phdrsp; | 224 | Elf32_Phdr (*p32)[phnum] = phdrsp; |
225 | Elf64_Phdr (*p64)[phnum] = phdrsp; | 225 | Elf64_Phdr (*p64)[phnum] = phdrsp; |
226 | switch (ehdr.e32.e_ident[EI_CLASS]) | 226 | |
227 | if (class32) | ||
227 | { | 228 | { |
228 | /* Sanity checks segments and calculates segment_end, | 229 | if (! elf32_xlatetom (&xlateto, &xlatefrom, ehdr.e32.e_ident[EI_DATA])) |
229 | segments_end, segments_end_mem and loadbase (if not | 230 | goto libelf_error; |
230 | found_base yet). Returns true if sanity checking failed, | 231 | } |
231 | false otherwise. */ | 232 | else |
232 | inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset, | 233 | { |
233 | GElf_Xword filesz, GElf_Xword memsz) | 234 | if (! elf64_xlatetom (&xlateto, &xlatefrom, ehdr.e64.e_ident[EI_DATA])) |
234 | { | 235 | goto libelf_error; |
235 | /* Sanity check the segment load aligns with the pagesize. */ | 236 | } |
236 | if (((vaddr - offset) & (pagesize - 1)) != 0) | ||
237 | return true; | ||
238 | 237 | ||
239 | GElf_Off segment_end = ((offset + filesz + pagesize - 1) | 238 | for (uint_fast16_t i = 0; i < phnum; ++i) |
240 | & -pagesize); | 239 | { |
240 | GElf_Word type = class32 ? (*p32)[i].p_type : (*p64)[i].p_type; | ||
241 | 241 | ||
242 | if (segment_end > (GElf_Off) contents_size) | 242 | if (type != PT_LOAD) |
243 | contents_size = segment_end; | 243 | continue; |
244 | 244 | ||
245 | if (!found_base && (offset & -pagesize) == 0) | 245 | GElf_Addr vaddr = class32 ? (*p32)[i].p_vaddr : (*p64)[i].p_vaddr; |
246 | { | 246 | GElf_Xword memsz = class32 ? (*p32)[i].p_memsz : (*p64)[i].p_memsz; |
247 | loadbase = ehdr_vma - (vaddr & -pagesize); | 247 | GElf_Off offset = class32 ? (*p32)[i].p_offset : (*p64)[i].p_offset; |
248 | found_base = true; | 248 | GElf_Xword filesz = class32 ? (*p32)[i].p_filesz : (*p64)[i].p_filesz; |
249 | } | ||
250 | 249 | ||
251 | segments_end = offset + filesz; | 250 | /* Sanity check the segment load aligns with the pagesize. */ |
252 | segments_end_mem = offset + memsz; | 251 | if (((vaddr - offset) & (pagesize - 1)) != 0) |
253 | return false; | 252 | goto bad_elf; |
254 | } | ||
255 | 253 | ||
256 | case ELFCLASS32: | 254 | GElf_Off segment_end = ((offset + filesz + pagesize - 1) |
257 | if (elf32_xlatetom (&xlateto, &xlatefrom, | 255 | & -pagesize); |
258 | ehdr.e32.e_ident[EI_DATA]) == NULL) | ||
259 | goto libelf_error; | ||
260 | for (uint_fast16_t i = 0; i < phnum; ++i) | ||
261 | if ((*p32)[i].p_type == PT_LOAD) | ||
262 | if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset, | ||
263 | (*p32)[i].p_filesz, (*p32)[i].p_memsz)) | ||
264 | goto bad_elf; | ||
265 | break; | ||
266 | 256 | ||
267 | case ELFCLASS64: | 257 | if (segment_end > (GElf_Off) contents_size) |
268 | if (elf64_xlatetom (&xlateto, &xlatefrom, | 258 | contents_size = segment_end; |
269 | ehdr.e64.e_ident[EI_DATA]) == NULL) | ||
270 | goto libelf_error; | ||
271 | for (uint_fast16_t i = 0; i < phnum; ++i) | ||
272 | if ((*p64)[i].p_type == PT_LOAD) | ||
273 | if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset, | ||
274 | (*p64)[i].p_filesz, (*p64)[i].p_memsz)) | ||
275 | goto bad_elf; | ||
276 | break; | ||
277 | 259 | ||
278 | default: | 260 | if (!found_base && (offset & -pagesize) == 0) |
279 | abort (); | 261 | { |
280 | break; | 262 | loadbase = ehdr_vma - (vaddr & -pagesize); |
263 | found_base = true; | ||
264 | } | ||
265 | |||
266 | segments_end = offset + filesz; | ||
267 | segments_end_mem = offset + memsz; | ||
281 | } | 268 | } |
282 | 269 | ||
283 | /* Trim the last segment so we don't bother with zeros in the last page | 270 | /* Trim the last segment so we don't bother with zeros in the last page |