summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2003-08-11 06:37:40 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2003-08-11 06:37:40 +0000
commit733dbb9d1f3d6b4a8b971e63c97c447af112f57d (patch)
tree8d607fa22d898f7e7c72b57905c66679e595178a /sys
parentc5ad97eefa2759171b1b56bc27178406f85e8771 (diff)
load file in one pass avoiding seeking the headers back and forth; miod@ testing & ok (two months ago and then i forgot ;)
Diffstat (limited to 'sys')
-rw-r--r--sys/lib/libsa/loadfile.c67
1 files changed, 38 insertions, 29 deletions
diff --git a/sys/lib/libsa/loadfile.c b/sys/lib/libsa/loadfile.c
index 3000583965a..c9b8ee1a7d9 100644
--- a/sys/lib/libsa/loadfile.c
+++ b/sys/lib/libsa/loadfile.c
@@ -1,5 +1,5 @@
/* $NetBSD: loadfile.c,v 1.10 2000/12/03 02:53:04 tsutsui Exp $ */
-/* $OpenBSD: loadfile.c,v 1.7 2003/08/11 06:23:09 deraadt Exp $ */
+/* $OpenBSD: loadfile.c,v 1.8 2003/08/11 06:37:39 mickey Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -259,6 +259,7 @@ static int
elf_exec(int fd, Elf_Ehdr *elf, u_long *marks, int flags)
{
Elf_Shdr *shp;
+ Elf_Phdr *phdr;
Elf_Off off;
int i;
size_t sz;
@@ -267,19 +268,24 @@ elf_exec(int fd, Elf_Ehdr *elf, u_long *marks, int flags)
paddr_t minp = ~0, maxp = 0, pos = 0;
paddr_t offset = marks[MARK_START], shpp, elfp;
+ sz = elf->e_phnum * sizeof(Elf_Phdr);
+ phdr = ALLOC(sz);
+
+ if (lseek(fd, elf->e_phoff, SEEK_SET) == -1) {
+ WARN(("lseek phdr"));
+ FREE(phdr, sz);
+ return 1;
+ }
+ if (read(fd, phdr, sz) != sz) {
+ WARN(("read program headers"));
+ FREE(phdr, sz);
+ return 1;
+ }
+
for (first = 1, i = 0; i < elf->e_phnum; i++) {
- Elf_Phdr phdr;
- if (lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET)
- == -1) {
- WARN(("lseek phdr"));
- return 1;
- }
- if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
- WARN(("read phdr"));
- return 1;
- }
- if (phdr.p_type != PT_LOAD ||
- (phdr.p_flags & (PF_W|PF_X)) == 0)
+
+ if (phdr[i].p_type != PT_LOAD ||
+ (phdr[i].p_flags & (PF_W|PF_X)) == 0)
continue;
#define IS_TEXT(p) (p.p_flags & PF_X)
@@ -288,48 +294,51 @@ elf_exec(int fd, Elf_Ehdr *elf, u_long *marks, int flags)
/*
* XXX: Assume first address is lowest
*/
- if ((IS_TEXT(phdr) && (flags & LOAD_TEXT)) ||
- (IS_DATA(phdr) && (flags & LOAD_DATA))) {
+ if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) ||
+ (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) {
/* Read in segment. */
PROGRESS(("%s%lu", first ? "" : "+",
- (u_long)phdr.p_filesz));
+ (u_long)phdr[i].p_filesz));
- if (lseek(fd, phdr.p_offset, SEEK_SET) == -1) {
+ if (lseek(fd, phdr[i].p_offset, SEEK_SET) == -1) {
WARN(("lseek text"));
+ FREE(phdr, sz);
return 1;
}
- if (READ(fd, phdr.p_vaddr, phdr.p_filesz) !=
- phdr.p_filesz) {
+ if (READ(fd, phdr[i].p_vaddr, phdr[i].p_filesz) !=
+ phdr[i].p_filesz) {
WARN(("read text"));
+ FREE(phdr, sz);
return 1;
}
first = 0;
}
- if ((IS_TEXT(phdr) && (flags & (LOAD_TEXT|COUNT_TEXT))) ||
- (IS_DATA(phdr) && (flags & (LOAD_DATA|COUNT_TEXT)))) {
- pos = phdr.p_vaddr;
+ if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT|COUNT_TEXT))) ||
+ (IS_DATA(phdr[i]) && (flags & (LOAD_DATA|COUNT_TEXT)))) {
+ pos = phdr[i].p_vaddr;
if (minp > pos)
minp = pos;
- pos += phdr.p_filesz;
+ pos += phdr[i].p_filesz;
if (maxp < pos)
maxp = pos;
}
/* Zero out bss. */
- if (IS_BSS(phdr) && (flags & LOAD_BSS)) {
+ if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) {
PROGRESS(("+%lu",
- (u_long)(phdr.p_memsz - phdr.p_filesz)));
- BZERO((phdr.p_vaddr + phdr.p_filesz),
- phdr.p_memsz - phdr.p_filesz);
+ (u_long)(phdr[i].p_memsz - phdr[i].p_filesz)));
+ BZERO((phdr[i].p_vaddr + phdr[i].p_filesz),
+ phdr[i].p_memsz - phdr[i].p_filesz);
}
- if (IS_BSS(phdr) && (flags & (LOAD_BSS|COUNT_BSS))) {
- pos += phdr.p_memsz - phdr.p_filesz;
+ if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) {
+ pos += phdr[i].p_memsz - phdr[i].p_filesz;
if (maxp < pos)
maxp = pos;
}
}
+ FREE(phdr, sz);
/*
* Copy the ELF and section headers.