diff options
author | Timm Bäder <tbaeder@redhat.com> | 2021-01-08 09:09:56 +0100 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2021-01-28 23:57:06 +0100 |
commit | 9c15e1e06eb088d6b632403a41a9e47b91f58b5f (patch) | |
tree | f49301a9e43762b14a6e1ae817549fc5ac1fdb9b /libdwfl | |
parent | elf-from-memory: Restructure code to get rid of nested handle_segment() (diff) | |
download | elfutils-9c15e1e06eb088d6b632403a41a9e47b91f58b5f.tar.gz elfutils-9c15e1e06eb088d6b632403a41a9e47b91f58b5f.tar.bz2 elfutils-9c15e1e06eb088d6b632403a41a9e47b91f58b5f.tar.xz |
elf-from-memory: Refactor to get rid of nested function
Try to unify the 32/64 bit code paths and get rid of the nested
handle_segment() this way.
Signed-off-by: Timm Bäder <tbaeder@redhat.com>
Diffstat (limited to 'libdwfl')
-rw-r--r-- | libdwfl/ChangeLog | 6 | ||||
-rw-r--r-- | libdwfl/elf-from-memory.c | 115 |
2 files changed, 56 insertions, 65 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index f17eafe7..5058f5f8 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog | |||
@@ -1,5 +1,11 @@ | |||
1 | 2021-01-08 Timm Bäder <tbaeder@redhat.com> | 1 | 2021-01-08 Timm Bäder <tbaeder@redhat.com> |
2 | 2 | ||
3 | * elf-from-memory.c (elf_from_remote_memory): Add for loop over | ||
4 | switch. inline handle_segment call, set vaddr, offset and filesz | ||
5 | directly based on class. | ||
6 | |||
7 | 2021-01-08 Timm Bäder <tbaeder@redhat.com> | ||
8 | |||
3 | * elf-from-memory.c (elf_from_remote_memory): Use if instead of | 9 | * elf-from-memory.c (elf_from_remote_memory): Use if instead of |
4 | switch on class. Set new vaddr, memsz, offset and filesz | 10 | switch on class. Set new vaddr, memsz, offset and filesz |
5 | variables. Inline handle_segment function check and set loadbase, | 11 | variables. Inline handle_segment function check and set loadbase, |
diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c index 933ab864..a0ef0014 100644 --- a/libdwfl/elf-from-memory.c +++ b/libdwfl/elf-from-memory.c | |||
@@ -292,80 +292,65 @@ elf_from_remote_memory (GElf_Addr ehdr_vma, | |||
292 | goto no_memory; | 292 | goto no_memory; |
293 | } | 293 | } |
294 | 294 | ||
295 | switch (ehdr.e32.e_ident[EI_CLASS]) | 295 | for (uint_fast16_t i = 0; i < phnum; ++i) |
296 | { | 296 | { |
297 | /* Reads the given segment. Returns true if reading fails, | 297 | GElf_Word type = class32 ? (*p32)[i].p_type : (*p64)[i].p_type; |
298 | false otherwise. */ | ||
299 | inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset, | ||
300 | GElf_Xword filesz) | ||
301 | { | ||
302 | GElf_Off start = offset & -pagesize; | ||
303 | GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize; | ||
304 | if (end > (GElf_Off) contents_size) | ||
305 | end = contents_size; | ||
306 | nread = (*read_memory) (arg, buffer + start, | ||
307 | (loadbase + vaddr) & -pagesize, | ||
308 | end - start, end - start); | ||
309 | return nread <= 0; | ||
310 | } | ||
311 | 298 | ||
312 | case ELFCLASS32: | 299 | if (type != PT_LOAD) |
313 | for (uint_fast16_t i = 0; i < phnum; ++i) | 300 | continue; |
314 | if ((*p32)[i].p_type == PT_LOAD) | 301 | |
315 | if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset, | 302 | GElf_Addr vaddr = class32 ? (*p32)[i].p_vaddr : (*p64)[i].p_vaddr; |
316 | (*p32)[i].p_filesz)) | 303 | GElf_Off offset = class32 ? (*p32)[i].p_offset : (*p64)[i].p_offset; |
317 | goto read_error; | 304 | GElf_Xword filesz = class32 ? (*p32)[i].p_filesz : (*p64)[i].p_filesz; |
318 | 305 | ||
319 | /* If the segments visible in memory didn't include the section | 306 | GElf_Off start = offset & -pagesize; |
320 | headers, then clear them from the file header. */ | 307 | GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize; |
321 | if (contents_size < shdrs_end) | 308 | if (end > (GElf_Off) contents_size) |
322 | { | 309 | end = contents_size; |
323 | ehdr.e32.e_shoff = 0; | 310 | nread = (*read_memory) (arg, buffer + start, |
324 | ehdr.e32.e_shnum = 0; | 311 | (loadbase + vaddr) & -pagesize, |
325 | ehdr.e32.e_shstrndx = 0; | 312 | end - start, end - start); |
326 | } | 313 | if (nread <= 0) |
314 | goto read_error; | ||
315 | } | ||
316 | |||
317 | /* If the segments visible in memory didn't include the section | ||
318 | headers, then clear them from the file header. */ | ||
319 | if (contents_size < shdrs_end) | ||
320 | { | ||
321 | if (class32) | ||
322 | { | ||
323 | ehdr.e32.e_shoff = 0; | ||
324 | ehdr.e32.e_shnum = 0; | ||
325 | ehdr.e32.e_shstrndx = 0; | ||
326 | } | ||
327 | else | ||
328 | { | ||
329 | ehdr.e64.e_shoff = 0; | ||
330 | ehdr.e64.e_shnum = 0; | ||
331 | ehdr.e64.e_shstrndx = 0; | ||
332 | } | ||
333 | } | ||
327 | 334 | ||
328 | /* This will normally have been in the first PT_LOAD segment. But it | 335 | /* This will normally have been in the first PT_LOAD segment. But it |
329 | conceivably could be missing, and we might have just changed it. */ | 336 | conceivably could be missing, and we might have just changed it. */ |
330 | xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR; | 337 | xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR; |
338 | xlateto.d_buf = buffer; | ||
339 | if (class32) | ||
340 | { | ||
331 | xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32; | 341 | xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32; |
332 | xlatefrom.d_buf = &ehdr.e32; | 342 | xlatefrom.d_buf = &ehdr.e32; |
333 | xlateto.d_buf = buffer; | ||
334 | if (elf32_xlatetof (&xlateto, &xlatefrom, | 343 | if (elf32_xlatetof (&xlateto, &xlatefrom, |
335 | ehdr.e32.e_ident[EI_DATA]) == NULL) | 344 | ehdr.e32.e_ident[EI_DATA]) == NULL) |
336 | goto libelf_error; | 345 | goto libelf_error; |
337 | break; | 346 | } |
338 | 347 | else | |
339 | case ELFCLASS64: | 348 | { |
340 | for (uint_fast16_t i = 0; i < phnum; ++i) | ||
341 | if ((*p64)[i].p_type == PT_LOAD) | ||
342 | if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset, | ||
343 | (*p64)[i].p_filesz)) | ||
344 | goto read_error; | ||
345 | |||
346 | /* If the segments visible in memory didn't include the section | ||
347 | headers, then clear them from the file header. */ | ||
348 | if (contents_size < shdrs_end) | ||
349 | { | ||
350 | ehdr.e64.e_shoff = 0; | ||
351 | ehdr.e64.e_shnum = 0; | ||
352 | ehdr.e64.e_shstrndx = 0; | ||
353 | } | ||
354 | |||
355 | /* This will normally have been in the first PT_LOAD segment. But it | ||
356 | conceivably could be missing, and we might have just changed it. */ | ||
357 | xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR; | ||
358 | xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64; | 349 | xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64; |
359 | xlatefrom.d_buf = &ehdr.e64; | 350 | xlatefrom.d_buf = &ehdr.e64; |
360 | xlateto.d_buf = buffer; | ||
361 | if (elf64_xlatetof (&xlateto, &xlatefrom, | 351 | if (elf64_xlatetof (&xlateto, &xlatefrom, |
362 | ehdr.e64.e_ident[EI_DATA]) == NULL) | 352 | ehdr.e64.e_ident[EI_DATA]) == NULL) |
363 | goto libelf_error; | 353 | goto libelf_error; |
364 | break; | ||
365 | |||
366 | default: | ||
367 | abort (); | ||
368 | break; | ||
369 | } | 354 | } |
370 | 355 | ||
371 | free (phdrsp); | 356 | free (phdrsp); |