summaryrefslogtreecommitdiffstats
path: root/libdwfl
diff options
context:
space:
mode:
authorTimm Bäder <tbaeder@redhat.com>2021-01-08 09:09:56 +0100
committerMark Wielaard <mark@klomp.org>2021-01-28 23:57:06 +0100
commit9c15e1e06eb088d6b632403a41a9e47b91f58b5f (patch)
treef49301a9e43762b14a6e1ae817549fc5ac1fdb9b /libdwfl
parentelf-from-memory: Restructure code to get rid of nested handle_segment() (diff)
downloadelfutils-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/ChangeLog6
-rw-r--r--libdwfl/elf-from-memory.c115
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 @@
12021-01-08 Timm Bäder <tbaeder@redhat.com> 12021-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
72021-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);