summaryrefslogtreecommitdiffstats
path: root/usr.sbin/mkuboot
diff options
context:
space:
mode:
authorsyl <syl@openbsd.org>2013-11-01 14:47:47 +0000
committersyl <syl@openbsd.org>2013-11-01 14:47:47 +0000
commit75e5de18dccfd6f054cdafaebd76bf873f68dc4e (patch)
tree204ffcef0e7ae2091e994f5f79991272fd91205c /usr.sbin/mkuboot
parentSend pflow(4) packets in the correct rdomain. (diff)
downloadwireguard-openbsd-75e5de18dccfd6f054cdafaebd76bf873f68dc4e.tar.xz
wireguard-openbsd-75e5de18dccfd6f054cdafaebd76bf873f68dc4e.zip
Fix endianess for big endian architecture.
Works with macppc. ok miod@
Diffstat (limited to 'usr.sbin/mkuboot')
-rw-r--r--usr.sbin/mkuboot/copy_elf.c156
1 files changed, 89 insertions, 67 deletions
diff --git a/usr.sbin/mkuboot/copy_elf.c b/usr.sbin/mkuboot/copy_elf.c
index 1b7c603d49e..abf19612a75 100644
--- a/usr.sbin/mkuboot/copy_elf.c
+++ b/usr.sbin/mkuboot/copy_elf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: copy_elf.c,v 1.1 2013/10/28 09:00:06 patrick Exp $ */
+/* $OpenBSD: copy_elf.c,v 1.2 2013/11/01 14:47:47 syl Exp $ */
/*
* Copyright (c) 2013 Miodrag Vallat.
@@ -24,6 +24,16 @@
#include <sys/exec_elf.h>
+#if defined(ELFSIZE) && (ELFSIZE == 32)
+#define elfoff2h(x) letoh32(x)
+#define h2elfoff(x) htole32(x)
+#elif defined(ELFSIZE) && (ELFSIZE == 64)
+#define elfoff2h(x) letoh64(x)
+#define h2elfoff(x) htole64(x)
+#else
+#error "unknown elf size"
+#endif
+
struct image_header;
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
@@ -32,11 +42,12 @@ extern u_long copy_data(int, const char *, int, const char *, u_long,
struct image_header *, Elf_Word);
u_long copy_mem(void *, int, const char *, u_long, struct image_header *,
Elf_Word);
-extern u_long fill_zeroes(int, const char *, u_long, struct image_header *, Elf_Word);
+extern u_long fill_zeroes(int, const char *, u_long, struct image_header *,
+ Elf_Word);
u_long
-ELFNAME(copy_elf)(int ifd, const char *iname, int ofd, const char *oname, u_long crc,
- struct image_header *ih)
+ELFNAME(copy_elf)(int ifd, const char *iname, int ofd, const char *oname,
+ u_long crc, struct image_header *ih)
{
ssize_t nbytes;
Elf_Ehdr ehdr, elf;
@@ -54,32 +65,31 @@ ELFNAME(copy_elf)(int ifd, const char *iname, int ofd, const char *oname, u_long
elf = ehdr;
- if (lseek(ifd, (off_t)elf.e_shoff, SEEK_SET) == -1) {
+ if (lseek(ifd, (off_t)elfoff2h(elf.e_shoff), SEEK_SET) == -1)
err(1, "%s unable to seek to section header", iname);
- }
- sz = elf.e_shnum * sizeof(Elf_Shdr);
+ sz = letoh16(elf.e_shnum) * sizeof(Elf_Shdr);
shp = calloc(sz, 1);
- if (read(ifd, shp, sz) != sz) {
+ if (read(ifd, shp, sz) != sz)
err(1, "%s: read section headers", iname);
- }
+
wshp = calloc(sz, 1);
memcpy(wshp, shp, sz);
-
/* first walk the load sections to find the kernel addresses */
/* next we walk the sections to find the
* location of esym (first address of data space
*/
- for (i = 0; i < ehdr.e_phnum; i++) {
- if (lseek(ifd, ehdr.e_phoff + i * ehdr.e_phentsize, SEEK_SET) ==
- (off_t)-1)
+ for (i = 0; i < letoh16(ehdr.e_phnum); i++) {
+ if (lseek(ifd, elfoff2h(ehdr.e_phoff) + i *
+ letoh16(ehdr.e_phentsize), SEEK_SET) == (off_t)-1)
err(1, "%s", iname);
if (read(ifd, &phdr, sizeof phdr) != sizeof(phdr))
err(1, "%s", iname);
/* assumes it loads in incrementing address order */
- if (phdr.p_type == PT_LOAD)
- vaddr = phdr.p_vaddr + phdr.p_memsz;
+ if (letoh32(phdr.p_type) == PT_LOAD)
+ vaddr = elfoff2h(phdr.p_vaddr) +
+ elfoff2h(phdr.p_memsz);
}
/* ok, we need to write the elf header and section header
@@ -91,68 +101,75 @@ ELFNAME(copy_elf)(int ifd, const char *iname, int ofd, const char *oname, u_long
ssym = vaddr;
vaddr += roundup((sizeof(Elf_Ehdr) + sz), sizeof(Elf_Addr));
off = roundup((sizeof(Elf_Ehdr) + sz), sizeof(Elf_Addr));
- for (i = 0; i < elf.e_shnum; i++) {
- if (esym == 0 && shp[i].sh_flags & SHF_WRITE) {
- esym = shp[i].sh_addr;
- }
- if (shp[i].sh_type == SHT_SYMTAB ||
- shp[i].sh_type == SHT_STRTAB) {
+ for (i = 0; i < letoh16(elf.e_shnum); i++) {
+ if (esym == 0 && elfoff2h(shp[i].sh_flags) & SHF_WRITE)
+ esym = elfoff2h(shp[i].sh_addr);
+
+ if (letoh32(shp[i].sh_type) == SHT_SYMTAB ||
+ letoh32(shp[i].sh_type) == SHT_STRTAB) {
#ifdef DEBUG
- fprintf(stderr, "shdr %d %d/%d off %lx\n", i, shp[i].sh_type,
- roundup(shp[i].sh_size, sizeof(Elf_Addr)), off);
+ fprintf(stderr, "shdr %d %d/%d off %lx\n", i,
+ letoh32(shp[i].sh_type), roundup(elfoff2h(shp[i].sh_size),
+ sizeof(Elf_Addr)), off);
#endif
/* data is at shp[i].sh_offset of len shp[i].sh_size */
- wshp[i].sh_offset = off;
- off += roundup(shp[i].sh_size, sizeof(Elf_Addr));
- vaddr += roundup(shp[i].sh_size, sizeof(Elf_Addr));
+ wshp[i].sh_offset = h2elfoff(off);
+ off += roundup(elfoff2h(shp[i].sh_size),
+ sizeof(Elf_Addr));
+ vaddr += roundup(elfoff2h(shp[i].sh_size),
+ sizeof(Elf_Addr));
}
}
esymval = vaddr;
#ifdef DEBUG
- fprintf(stderr, "esymval %lx size %ld\n", esymval, esymval - ssym);
+ fprintf(stderr, "esymval %lx size %ld\n", esymval, esymval - ssym);
#endif
- for (i = 0; i < ehdr.e_phnum; i++) {
+ for (i = 0; i < letoh16(ehdr.e_phnum); i++) {
#ifdef DEBUG
- fprintf(stderr, "phdr %d/%d\n", i, ehdr.e_phnum);
+ fprintf(stderr, "phdr %d/%d\n", i, letoh16(ehdr.e_phnum));
#endif
- if (lseek(ifd, ehdr.e_phoff + i * ehdr.e_phentsize, SEEK_SET) ==
- (off_t)-1)
+ if (lseek(ifd, elfoff2h(ehdr.e_phoff) + i *
+ letoh16(ehdr.e_phentsize), SEEK_SET) == (off_t)-1)
err(1, "%s", iname);
if (read(ifd, &phdr, sizeof phdr) != sizeof(phdr))
err(1, "%s", iname);
#ifdef DEBUG
fprintf(stderr, "vaddr %p offset %p filesz %p memsz %p\n",
- phdr.p_vaddr, phdr.p_offset, phdr.p_filesz, phdr.p_memsz);
+ elfoff2h(phdr.p_vaddr), elfoff2h(phdr.p_offset),
+ elfoff2h(phdr.p_filesz), elfoff2h(phdr.p_memsz));
#endif
if (i == 0)
- vaddr = phdr.p_vaddr;
- else if (vaddr != phdr.p_vaddr) {
+ vaddr = elfoff2h(phdr.p_vaddr);
+ else if (vaddr != elfoff2h(phdr.p_vaddr)) {
#ifdef DEBUG
- fprintf(stderr, "gap %p->%p\n", vaddr, phdr.p_vaddr);
+ fprintf(stderr, "gap %p->%p\n", vaddr,
+ elfoff2h(phdr.p_vaddr));
#endif
/* fill the gap between the previous phdr if any */
crc = fill_zeroes(ofd, oname, crc, ih,
- phdr.p_vaddr - vaddr);
- vaddr = phdr.p_vaddr;
+ elfoff2h(phdr.p_vaddr) - vaddr);
+ vaddr = elfoff2h(phdr.p_vaddr);
}
- if (phdr.p_filesz != 0) {
+ if (elfoff2h(phdr.p_filesz) != 0) {
#ifdef DEBUG
fprintf(stderr, "copying %p from infile %p\n",
- phdr.p_filesz, phdr.p_offset);
+ elfoff2h(hphdr.p_filesz), elfoff2h(phdr.p_offset));
#endif
/* esym will be in the data portion of a region */
- if (esym >= phdr.p_vaddr &&
- esym < phdr.p_vaddr + phdr.p_filesz) {
+ if (esym >= elfoff2h(phdr.p_vaddr) &&
+ esym < elfoff2h(phdr.p_vaddr) +
+ elfoff2h(phdr.p_filesz)) {
/* load the region up to the esym
* (may be empty)
*/
- Elf_Addr loadlen = esym - phdr.p_vaddr;
+ Elf_Addr loadlen = esym -
+ elfoff2h(phdr.p_vaddr);
- if (lseek(ifd, phdr.p_offset, SEEK_SET) ==
- (off_t)-1)
+ if (lseek(ifd, elfoff2h(phdr.p_offset),
+ SEEK_SET) == (off_t)-1)
err(1, "%s", iname);
crc = copy_data(ifd, iname, ofd, oname, crc,
ih, loadlen);
@@ -160,29 +177,33 @@ ELFNAME(copy_elf)(int ifd, const char *iname, int ofd, const char *oname, u_long
crc = copy_mem(&esymval, ofd, oname, crc, ih,
sizeof(esymval));
- if (lseek(ifd, phdr.p_offset + loadlen +
- sizeof(esymval), SEEK_SET) == (off_t)-1)
+ if (lseek(ifd, elfoff2h(phdr.p_offset) +
+ loadlen + sizeof(esymval), SEEK_SET) ==
+ (off_t)-1)
err(1, "%s", iname);
crc = copy_data(ifd, iname, ofd, oname, crc,
- ih, phdr.p_filesz - loadlen -
+ ih, elfoff2h(phdr.p_filesz) - loadlen -
sizeof(esymval));
} else {
- if (lseek(ifd, phdr.p_offset, SEEK_SET) ==
- (off_t)-1)
+ if (lseek(ifd, elfoff2h(phdr.p_offset),
+ SEEK_SET) == (off_t)-1)
err(1, "%s", iname);
crc = copy_data(ifd, iname, ofd, oname, crc,
- ih, phdr.p_filesz);
+ ih, elfoff2h(phdr.p_filesz));
}
- if (phdr.p_memsz - phdr.p_filesz != 0) {
+ if (elfoff2h(phdr.p_memsz) - elfoff2h(phdr.p_filesz)
+ != 0) {
#ifdef DEBUG
fprintf(stderr, "zeroing %p\n",
- phdr.p_memsz - phdr.p_filesz);
+ elfoff2h(phdr.p_memsz) -
+ elfoff2h(phdr.p_filesz));
#endif
crc = fill_zeroes(ofd, oname, crc, ih,
- phdr.p_memsz - phdr.p_filesz);
+ elfoff2h(phdr.p_memsz) -
+ elfoff2h(phdr.p_filesz));
}
- ovaddr = vaddr + phdr.p_memsz;
+ ovaddr = vaddr + elfoff2h(phdr.p_memsz);
} else {
ovaddr = vaddr;
}
@@ -191,27 +212,27 @@ ELFNAME(copy_elf)(int ifd, const char *iname, int ofd, const char *oname, u_long
* need to provide. If it's not the last phdr, the gap
* filling code will output the necessary zeroes anyway.
*/
- vaddr += phdr.p_memsz;
+ vaddr += elfoff2h(phdr.p_memsz);
}
vaddr = roundup(vaddr, sizeof(Elf_Addr));
if (vaddr != ovaddr) {
#ifdef DEBUG
- fprintf(stderr, "gap %p->%p\n", vaddr, phdr.p_vaddr);
+ fprintf(stderr, "gap %p->%p\n", vaddr, elfoff2h(phdr.p_vaddr));
#endif
/* fill the gap between the previous phdr if not aligned */
crc = fill_zeroes(ofd, oname, crc, ih, vaddr - ovaddr);
}
- for (havesyms = i = 0; i < elf.e_shnum; i++)
- if (shp[i].sh_type == SHT_SYMTAB)
- havesyms = 1;
+ for (havesyms = i = 0; i < letoh16(elf.e_shnum); i++)
+ if (letoh32(shp[i].sh_type) == SHT_SYMTAB)
+ havesyms = 1;
if (havesyms == 0)
return crc;
elf.e_phoff = 0;
- elf.e_shoff = sizeof(Elf_Ehdr);
+ elf.e_shoff = h2elfoff(sizeof(Elf_Ehdr));
elf.e_phentsize = 0;
elf.e_phnum = 0;
crc = copy_mem(&elf, ofd, oname, crc, ih, sizeof(elf));
@@ -219,16 +240,17 @@ ELFNAME(copy_elf)(int ifd, const char *iname, int ofd, const char *oname, u_long
off = sizeof(elf) + sz;
off = roundup((sizeof(Elf_Ehdr) + sz), sizeof(Elf_Addr));
- for (i = 0; i < elf.e_shnum; i++) {
- if (shp[i].sh_type == SHT_SYMTAB ||
- shp[i].sh_type == SHT_STRTAB) {
+ for (i = 0; i < letoh16(elf.e_shnum); i++) {
+ if (letoh32(shp[i].sh_type) == SHT_SYMTAB ||
+ letoh32(shp[i].sh_type) == SHT_STRTAB) {
/* data is at shp[i].sh_offset of len shp[i].sh_size */
- if (lseek(ifd, shp[i].sh_offset, SEEK_SET) == -1) {
+ if (lseek(ifd, elfoff2h(shp[i].sh_offset), SEEK_SET)
+ == -1)
err(1, "%s", iname);
- }
- off += shp[i].sh_size;
+
+ off += elfoff2h(shp[i].sh_size);
crc = copy_data(ifd, iname, ofd, oname, crc, ih,
- shp[i].sh_size);
+ elfoff2h(shp[i].sh_size));
}
}