Module Name: src Committed By: maxv Date: Fri Oct 13 10:39:27 UTC 2017
Modified Files: src/sys/lib/libsa: loadfile_elf32.c Log Message: Introduce two functions, and dedup code. To generate a diff of this commit: cvs rdiff -u -r1.46 -r1.47 src/sys/lib/libsa/loadfile_elf32.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/lib/libsa/loadfile_elf32.c diff -u src/sys/lib/libsa/loadfile_elf32.c:1.46 src/sys/lib/libsa/loadfile_elf32.c:1.47 --- src/sys/lib/libsa/loadfile_elf32.c:1.46 Fri Oct 13 10:04:27 2017 +++ src/sys/lib/libsa/loadfile_elf32.c Fri Oct 13 10:39:26 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: loadfile_elf32.c,v 1.46 2017/10/13 10:04:27 maxv Exp $ */ +/* $NetBSD: loadfile_elf32.c,v 1.47 2017/10/13 10:39:26 maxv Exp $ */ /* * Copyright (c) 1997, 2008, 2017 The NetBSD Foundation, Inc. @@ -268,6 +268,62 @@ externalize_shdr(Elf_Byte bo, Elf_Shdr * #define KERNALIGN 4096 /* XXX should depend on marks[] */ /* + * Read some data from a file, and put it in the bootloader memory (local). + */ +static int +ELFNAMEEND(readfile_local)(int fd, Elf_Off elfoff, void *addr, size_t size) +{ + ssize_t nr; + + if (lseek(fd, elfoff, SEEK_SET) == -1) { + WARN(("lseek section headers")); + return -1; + } + nr = read(fd, addr, size); + if (nr == -1) { + WARN(("read section headers")); + return -1; + } + if (nr != (ssize_t)size) { + errno = EIO; + WARN(("read section headers")); + return -1; + } + + return 0; +} + +/* + * Read some data from a file, and put it in wherever in memory (global). + */ +static int +ELFNAMEEND(readfile_global)(int fd, u_long offset, Elf_Off elfoff, + Elf_Addr addr, size_t size) +{ + ssize_t nr; + + /* some ports dont use the offset */ + (void)&offset; + + if (lseek(fd, elfoff, SEEK_SET) == -1) { + WARN(("lseek section")); + return -1; + } + nr = READ(fd, addr, size); + if (nr == -1) { + WARN(("read section")); + return -1; + } + if (nr != (ssize_t)size) { + errno = EIO; + WARN(("read section")); + return -1; + } + + return 0; +} + +/* * Load a dynamic ELF binary into memory. Layout of the memory: * +------------+-----------------+-----------------+------------------+ * | ELF HEADER | SECTION HEADERS | KERNEL SECTIONS | SYM+REL SECTIONS | @@ -287,32 +343,19 @@ ELFNAMEEND(loadfile_dynamic)(int fd, Elf Elf_Shdr *shdr; Elf_Addr shpp, addr; int i, j, loaded; - size_t size; - ssize_t sz, nr; + size_t size, shdrsz; Elf_Addr maxp, elfp = 0; - - /* some ports dont use the offset */ - (void)&offset; + int ret; maxp = marks[MARK_END]; internalize_ehdr(elf->e_ident[EI_DATA], elf); /* Create a local copy of the SECTION HEADERS. */ - sz = elf->e_shnum * sizeof(Elf_Shdr); - shdr = ALLOC(sz); - if (lseek(fd, elf->e_shoff, SEEK_SET) == -1) { - WARN(("lseek section headers")); - goto out; - } - nr = read(fd, shdr, sz); - if (nr == -1) { - WARN(("read section headers")); - goto out; - } - if (nr != sz) { - errno = EIO; - WARN(("read section headers")); + shdrsz = elf->e_shnum * sizeof(Elf_Shdr); + shdr = ALLOC(shdrsz); + ret = ELFNAMEEND(readfile_local)(fd, elf->e_shoff, shdr, shdrsz); + if (ret == -1) { goto out; } @@ -337,7 +380,7 @@ ELFNAMEEND(loadfile_dynamic)(int fd, Elf /* Save location of the SECTION HEADERS. */ shpp = maxp; - maxp += roundup(sz, ELFROUND); + maxp += roundup(shdrsz, ELFROUND); /* * Load the KERNEL SECTIONS. @@ -355,21 +398,11 @@ ELFNAMEEND(loadfile_dynamic)(int fd, Elf loaded = 1; break; case SHT_PROGBITS: - if (lseek(fd, shdr[i].sh_offset, SEEK_SET) == -1) { - WARN(("lseek section")); - goto out; - } - nr = READ(fd, addr, size); - if (nr == -1) { - WARN(("read section")); + ret = ELFNAMEEND(readfile_global)(fd, offset, + shdr[i].sh_offset, addr, size); + if (ret == -1) { goto out; } - if (nr != (ssize_t)size) { - errno = EIO; - WARN(("read section")); - goto out; - } - loaded = 1; break; default: @@ -409,21 +442,11 @@ ELFNAMEEND(loadfile_dynamic)(int fd, Elf case SHT_REL: case SHT_RELA: case SHT_SYMTAB: - if (lseek(fd, shdr[i].sh_offset, SEEK_SET) == -1) { - WARN(("lseek symbols")); + ret = ELFNAMEEND(readfile_global)(fd, offset, + shdr[i].sh_offset, addr, size); + if (ret == -1) { goto out; } - nr = READ(fd, addr, size); - if (nr == -1) { - WARN(("read symbols")); - goto out; - } - if (nr != (ssize_t)size) { - errno = EIO; - WARN(("read symbols")); - goto out; - } - shdr[i].sh_offset = maxp - elfp; maxp += roundup(size, ELFROUND); break; @@ -438,9 +461,9 @@ ELFNAMEEND(loadfile_dynamic)(int fd, Elf for (i = 0; i < elf->e_shnum; i++) externalize_shdr(elf->e_ident[EI_DATA], &shdr[i]); #endif - BCOPY(shdr, shpp, sz); + BCOPY(shdr, shpp, shdrsz); - DEALLOC(shdr, sz); + DEALLOC(shdr, shdrsz); /* * Just update MARK_SYM and MARK_END without touching the rest. @@ -450,7 +473,7 @@ ELFNAMEEND(loadfile_dynamic)(int fd, Elf return 0; out: - DEALLOC(shdr, sz); + DEALLOC(shdr, shdrsz); return 1; } @@ -468,7 +491,7 @@ ELFNAMEEND(loadsym)(int fd, Elf_Ehdr *el Elf_Shdr *shp; Elf_Addr shpp; char *shstr = NULL; - ssize_t nr, sz; + size_t sz; size_t i, j, shstrsz = 0; struct __packed { Elf_Nhdr nh; @@ -476,25 +499,12 @@ ELFNAMEEND(loadsym)(int fd, Elf_Ehdr *el uint8_t desc[ELF_NOTE_NETBSD_DESCSZ]; } note; int first; + int ret; - /* some ports dont use the offset */ - (void)&offset; - - if (lseek(fd, elf->e_shoff, SEEK_SET) == -1) { - WARN(("lseek section headers")); - return -1; - } sz = elf->e_shnum * sizeof(Elf_Shdr); shp = ALLOC(sz); - - nr = read(fd, shp, sz); - if (nr == -1) { - WARN(("read section headers")); - goto out; - } - if (nr != sz) { - errno = EIO; - WARN(("read section headers")); + ret = ELFNAMEEND(readfile_local)(fd, elf->e_shoff, shp, sz); + if (ret == -1) { goto out; } @@ -513,31 +523,17 @@ ELFNAMEEND(loadsym)(int fd, Elf_Ehdr *el Elf_Off shstroff = shp[elf->e_shstrndx].sh_offset; shstrsz = shp[elf->e_shstrndx].sh_size; if (flags & LOAD_SYM) { - if (lseek(fd, shstroff, SEEK_SET) == -1) { - WARN(("lseek symbols")); - goto out; - } - nr = READ(fd, maxp, shstrsz); - if (nr == -1) { - WARN(("read symbols")); - goto out; - } - if (nr != (ssize_t)shstrsz) { - errno = EIO; - WARN(("read symbols")); + ret = ELFNAMEEND(readfile_global)(fd, offset, + shstroff, maxp, shstrsz); + if (ret == -1) { goto out; } } /* Create a local copy */ shstr = ALLOC(shstrsz); - if (lseek(fd, shstroff, SEEK_SET) == -1) { - WARN(("lseek symbols")); - goto out; - } - nr = read(fd, shstr, shstrsz); - if (nr == -1) { - WARN(("read symbols")); + ret = ELFNAMEEND(readfile_local)(fd, shstroff, shstr, shstrsz); + if (ret == -1) { goto out; } shp[elf->e_shstrndx].sh_offset = maxp - elfp; @@ -585,19 +581,9 @@ havesym: if (flags & LOAD_SYM) { PROGRESS(("%s%ld", first ? " [" : "+", (u_long)shp[i].sh_size)); - if (lseek(fd, shp[i].sh_offset, - SEEK_SET) == -1) { - WARN(("lseek symbols")); - goto out; - } - nr = READ(fd, maxp, shp[i].sh_size); - if (nr == -1) { - WARN(("read symbols")); - goto out; - } - if (nr != (ssize_t)shp[i].sh_size) { - errno = EIO; - WARN(("read symbols")); + ret = ELFNAMEEND(readfile_global)(fd, offset, + shp[i].sh_offset, maxp, shp[i].sh_size); + if (ret == -1) { goto out; } } @@ -612,15 +598,13 @@ havesym: shp[i].sh_offset = 0; break; } - if (lseek(fd, shp[i].sh_offset, SEEK_SET) == -1) { - WARN(("lseek note")); - goto out; - } - nr = read(fd, ¬e, sizeof(note)); - if (nr == -1) { - WARN(("read note")); + + ret = ELFNAMEEND(readfile_local)(fd, shp[i].sh_offset, + ¬e, sizeof(note)); + if (ret == -1) { goto out; } + if (note.nh.n_namesz == ELF_NOTE_NETBSD_NAMESZ && note.nh.n_descsz == ELF_NOTE_NETBSD_DESCSZ && note.nh.n_type == ELF_NOTE_TYPE_NETBSD_TAG && @@ -682,12 +666,10 @@ ELFNAMEEND(loadfile_static)(int fd, Elf_ const u_long offset = marks[MARK_START]; Elf_Phdr *phdr; int i, first; - ssize_t sz; + size_t sz; Elf_Addr minp = ~0, maxp = 0, pos = 0, elfp = 0; - ssize_t nr; + int ret; - /* some ports dont use the offset */ - (void)&offset; /* for ports that define progress to nothing */ (void)&first; @@ -698,19 +680,8 @@ ELFNAMEEND(loadfile_static)(int fd, Elf_ sz = elf->e_phnum * sizeof(Elf_Phdr); phdr = ALLOC(sz); - - if (lseek(fd, elf->e_phoff, SEEK_SET) == -1) { - WARN(("lseek phdr")); - goto freephdr; - } - nr = read(fd, phdr, sz); - if (nr == -1) { - WARN(("read program headers")); - goto freephdr; - } - if (nr != sz) { - errno = EIO; - WARN(("read program headers")); + ret = ELFNAMEEND(readfile_local)(fd, elf->e_phoff, phdr, sz); + if (ret == -1) { goto freephdr; } @@ -736,20 +707,13 @@ ELFNAMEEND(loadfile_static)(int fd, Elf_ PROGRESS(("%s%lu", first ? "" : "+", (u_long)phdr[i].p_filesz)); - if (lseek(fd, phdr[i].p_offset, SEEK_SET) == -1) { - WARN(("lseek text")); - goto freephdr; - } - nr = READ(fd, phdr[i].p_vaddr, phdr[i].p_filesz); - if (nr == -1) { - WARN(("read text error")); - goto freephdr; - } - if (nr != (ssize_t)phdr[i].p_filesz) { - errno = EIO; - WARN(("read text")); + ret = ELFNAMEEND(readfile_global)(fd, offset, + phdr[i].p_offset, phdr[i].p_vaddr, + phdr[i].p_filesz); + if (ret == -1) { goto freephdr; } + first = 0; } if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT|COUNT_TEXT))) ||