diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2014-01-19 15:39:52 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2014-01-19 15:39:52 +0000 |
commit | 877c22ffc05ecbe77ee2e304809226bf521a375e (patch) | |
tree | e4b5fcc61883977f9e8b0c895dcb7a883ec6435d /sys/arch | |
parent | 3db93edc1023c662a1faf7f37e498c685d6831a3 (diff) |
Cope with an arbitrary number of ELF program headers, and only copy the
contents of PT_LOAD headers to the output.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/aviion/stand/a2coff/a2coff.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/sys/arch/aviion/stand/a2coff/a2coff.c b/sys/arch/aviion/stand/a2coff/a2coff.c index c123baf9f23..96758a8efc2 100644 --- a/sys/arch/aviion/stand/a2coff/a2coff.c +++ b/sys/arch/aviion/stand/a2coff/a2coff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a2coff.c,v 1.9 2013/11/09 20:17:55 miod Exp $ */ +/* $OpenBSD: a2coff.c,v 1.10 2014/01/19 15:39:51 miod Exp $ */ /* * Copyright (c) 2006, 2013, Miodrag Vallat * @@ -205,28 +205,38 @@ convert_elf(const char *infile, int infd, int outfd, Elf_Ehdr *ehdr) { struct ecoff_exechdr ehead; struct ecoff_scnhdr escn[2]; - Elf_Phdr phdr[3]; + Elf_Phdr *phdr; off_t outpos; - uint delta; + uint delta, ptload; Elf_Addr minaddr, maxaddr; - int n; + int n, last; - if (ehdr->e_phnum > 3) - errx(1, "%s: too many program headers", infile); + phdr = (Elf_Phdr *)malloc(ehdr->e_phnum * sizeof(Elf_Phdr)); + if (phdr == NULL) + err(1, "malloc"); memset(phdr, 0, sizeof phdr); for (n = 0; n < ehdr->e_phnum; n++) { if (lseek(infd, ehdr->e_phoff + n * ehdr->e_phentsize, SEEK_SET) == (off_t) -1) err(1, "seek"); - if (read(infd, phdr + n, sizeof phdr[0]) != sizeof(phdr[0])) + if (read(infd, phdr + n, sizeof *phdr) != sizeof(*phdr)) err(1, "read"); } + ptload = 0; + for (n = 0; n < ehdr->e_phnum; n++) + if (phdr[n].p_type == PT_LOAD) + ptload++; + if (ptload > 3) + errx(1, "%s: too many PT_LOAD program headers", infile); + maxaddr = 0; minaddr = (Elf_Addr)-1; for (n = 0; n < ehdr->e_phnum; n++) { + if (phdr[n].p_type != PT_LOAD) + continue; if (phdr[n].p_paddr < minaddr) minaddr = phdr[n].p_paddr; if (phdr[n].p_paddr + phdr[n].p_memsz > maxaddr) @@ -284,16 +294,18 @@ convert_elf(const char *infile, int infd, int outfd, Elf_Ehdr *ehdr) err(1, "write"); /* - * Copy ``text'' section (all program headers). + * Copy ``text'' section (all PT_LOAD program headers). */ outpos = escn[0].s_scnptr; if (lseek(outfd, outpos, SEEK_SET) == (off_t) -1) err(1, "seek"); - for (n = 0; n < ehdr->e_phnum; n++) { - if (n != 0) { - delta = (phdr[n].p_paddr - phdr[n - 1].p_paddr) - - phdr[n - 1].p_memsz; + for (n = 0, last = -1; n < ehdr->e_phnum; n++) { + if (phdr[n].p_type != PT_LOAD) + continue; + if (last >= 0) { + delta = (phdr[n].p_paddr - phdr[last].p_paddr) - + phdr[last].p_memsz; if (delta != 0) { zerobits(outfd, delta); outpos += delta; @@ -310,8 +322,11 @@ convert_elf(const char *infile, int infd, int outfd, Elf_Ehdr *ehdr) if (delta != 0) zerobits(outfd, delta); outpos += phdr[n].p_memsz; + last = n; } + free(phdr); + /* * Fill ``data'' section. */ |