summaryrefslogtreecommitdiffstats
path: root/libdwfl/elf-from-memory.c
diff options
context:
space:
mode:
authorChih-Hung Hsieh <[email protected]>2015-10-06 15:53:15 -0700
committerMark Wielaard <[email protected]>2015-10-07 22:44:41 +0200
commit7eff36d5daa6ebca5e6399638a7643af105ae5b0 (patch)
tree7bfd9c4a93f88135b9f42337d827948aa6b63cdb /libdwfl/elf-from-memory.c
parentdaee4714ee3761e2d92f764a724e83875a79a3f0 (diff)
Do without union of variable length arrays.
Prepare to compile with clang. A union like { T32 a32[n]; T64 a64[n]; } u; is expanded to size_t nbytes = n * MAX(sizeof(T32), sizeof(T64)); void *data = malloc(nbytes); T32 (*a32)[n] = data; T64 (*a64)[n] = data; Signed-off-by: Chih-Hung Hsieh <[email protected]>
Diffstat (limited to 'libdwfl/elf-from-memory.c')
-rw-r--r--libdwfl/elf-from-memory.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c
index ed8f6e92..5be21bb0 100644
--- a/libdwfl/elf-from-memory.c
+++ b/libdwfl/elf-from-memory.c
@@ -38,6 +38,10 @@
#include <stdlib.h>
#include <string.h>
+#ifndef MAX
+# define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
/* Reconstruct an ELF file by reading the segments out of remote memory
based on the ELF file header at EHDR_VMA and the ELF program headers it
points to. If not null, *LOADBASEP is filled in with the difference
@@ -191,22 +195,25 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
xlatefrom.d_buf = buffer;
}
- typedef union
- {
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } phdrsn;
-
- phdrsp = malloc (sizeof (phdrsn));
+ if (unlikely (phnum >
+ SIZE_MAX / MAX (sizeof (Elf32_Phdr), sizeof (Elf64_Phdr))))
+ {
+ free (buffer);
+ goto no_memory;
+ }
+ const size_t phdrsp_bytes =
+ phnum * MAX (sizeof (Elf32_Phdr), sizeof (Elf64_Phdr));
+ phdrsp = malloc (phdrsp_bytes);
+ Elf32_Phdr (*p32)[phnum] = phdrsp;
+ Elf64_Phdr (*p64)[phnum] = phdrsp;
if (unlikely (phdrsp == NULL))
{
free (buffer);
goto no_memory;
}
- phdrsn *phdrs = (phdrsn *) phdrsp;
- xlateto.d_buf = phdrs;
- xlateto.d_size = sizeof (phdrsn);
+ xlateto.d_buf = phdrsp;
+ xlateto.d_size = phdrsp_bytes;
/* Scan for PT_LOAD segments to find the total size of the file image. */
size_t contents_size = 0;
@@ -249,9 +256,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
ehdr.e32.e_ident[EI_DATA]) == NULL)
goto libelf_error;
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_memsz))
+ if ((*p32)[i].p_type == PT_LOAD)
+ if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
+ (*p32)[i].p_filesz, (*p32)[i].p_memsz))
goto bad_elf;
break;
@@ -260,9 +267,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
ehdr.e64.e_ident[EI_DATA]) == NULL)
goto libelf_error;
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_memsz))
+ if ((*p64)[i].p_type == PT_LOAD)
+ if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset,
+ (*p64)[i].p_filesz, (*p64)[i].p_memsz))
goto bad_elf;
break;
@@ -315,9 +322,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
case ELFCLASS32:
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))
+ if ((*p32)[i].p_type == PT_LOAD)
+ if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
+ (*p32)[i].p_filesz))
goto read_error;
/* If the segments visible in memory didn't include the section
@@ -342,9 +349,9 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
case ELFCLASS64:
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))
+ if ((*p64)[i].p_type == PT_LOAD)
+ if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset,
+ (*p64)[i].p_filesz))
goto read_error;
/* If the segments visible in memory didn't include the section
@@ -373,7 +380,7 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
}
free (phdrsp);
- phdrs = phdrsp = NULL;
+ phdrsp = NULL;
/* Now we have the image. Open libelf on it. */