diff options
| author | Chih-Hung Hsieh <[email protected]> | 2015-10-06 15:53:15 -0700 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2015-10-07 22:44:41 +0200 |
| commit | 7eff36d5daa6ebca5e6399638a7643af105ae5b0 (patch) | |
| tree | 7bfd9c4a93f88135b9f42337d827948aa6b63cdb /libdwfl/elf-from-memory.c | |
| parent | daee4714ee3761e2d92f764a724e83875a79a3f0 (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.c | 53 |
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. */ |
