diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 1998-07-14 03:29:09 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 1998-07-14 03:29:09 +0000 |
commit | c7d428b9c27b1c37a3e753ffb21eef8904b64118 (patch) | |
tree | bbd274d80bdf2b5e55f416141875a50b860ea048 /sys/lib/libsa | |
parent | 72af685d8aa0b209634a3567f06d3514e6e6fac6 (diff) |
multiformat exec framework
Diffstat (limited to 'sys/lib/libsa')
-rw-r--r-- | sys/lib/libsa/exec.h | 98 | ||||
-rw-r--r-- | sys/lib/libsa/exec.new.c | 153 | ||||
-rw-r--r-- | sys/lib/libsa/exec_aout.c | 83 | ||||
-rw-r--r-- | sys/lib/libsa/exec_elf.c | 109 |
4 files changed, 443 insertions, 0 deletions
diff --git a/sys/lib/libsa/exec.h b/sys/lib/libsa/exec.h new file mode 100644 index 00000000000..36abf1611e0 --- /dev/null +++ b/sys/lib/libsa/exec.h @@ -0,0 +1,98 @@ +/* $OpenBSD: exec.h,v 1.1 1998/07/14 03:29:08 mickey Exp $ */ + +/* + * Copyright (c) 1998 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Michael Shalayeff. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SA_EXEC_H_ +#define _SA_EXEC_H_ + +#define MAX_EXEC_NAME 8 + +#ifdef EXEC_AOUT +#include <sys/exec_aout.h> +#endif +#ifdef EXEC_ECOFF +#include <sys/exec_ecoff.h> +#endif +#ifdef EXEC_ELF +#include <sys/exec_elf.h> +#endif +#ifdef EXEC_SOM +#include <sys/exec_som.h> +#endif + +union x_header { +#ifdef EXEC_AOUT + struct exec x_aout; +#endif +#ifdef EXEC_ECOFF + struct ecoff_filehdr x_ecoff; +#endif +#ifdef EXEC_ELF + struct elfhdr x_elf; +#endif +#ifdef EXEC_SOM + struct som_filehdr x_som; +#endif +}; + +struct x_param; +struct x_sw { + char name[MAX_EXEC_NAME]; + /* returns file position to lseek to */ + int (*probe) __P((int, union x_header *)); + /* zero on success */ + int (*load) __P((int, struct x_param *)); +}; + +struct x_param { + union x_header *xp_hdr; + const struct x_sw *xp_execsw; + u_int xp_entry, xp_end; + + struct { u_int addr, size, foff; } text, data, bss, sym, str; +}; + +extern const struct x_sw execsw[]; +void machdep_exec __P((struct x_param *, int, void *)); + +int aout_probe __P((int, union x_header *)); +int aout_load __P((int, struct x_param *)); + +int elf_probe __P((int, union x_header *)); +int elf_load __P((int, struct x_param *)); + +int ecoff_probe __P((int, union x_header *)); +int ecoff_load __P((int, struct x_param *)); + +int som_probe __P((int, union x_header *)); +int som_load __P((int, struct x_param *)); + +#endif /* _SA_EXEC_H_ */ diff --git a/sys/lib/libsa/exec.new.c b/sys/lib/libsa/exec.new.c new file mode 100644 index 00000000000..2cf5eed76a0 --- /dev/null +++ b/sys/lib/libsa/exec.new.c @@ -0,0 +1,153 @@ +/* $OpenBSD: exec.new.c,v 1.1 1998/07/14 03:29:08 mickey Exp $ */ + +/* + * Copyright (c) 1998 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Michael Shalayeff. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/reboot.h> +#ifndef INSECURE +#include <sys/stat.h> +#endif +#include "libsa.h" +#include <lib/libsa/exec.h> + +void +exec(path, loadaddr, howto) + char *path; + void *loadaddr; + int howto; +{ + int fd; + struct stat sb; + const struct x_sw *sw; + struct x_param param; + union x_header hdr; + register u_char *pa; + register int save_err; + u_int sz; + + if ((fd = open(path, 0)) < 0 || fstat(fd, &sb)) + return; + + if (sb.st_mode & 2) + printf("non-secure file, check permissions!\n"); + + if (read(fd, (char *)&hdr, sizeof(hdr)) != sizeof(hdr)) + return; + + errno = 0; /* XXX */ + /* probe obj format */ + for (sw = execsw; sw->probe; sw++) + if (sw->probe(fd, &hdr)) + break; + + bzero (¶m, sizeof(param)); + param.xp_execsw = sw; + param.xp_hdr = &hdr; + + if (!sw->probe || sw->load(fd, ¶m)) { + errno = errno? errno : EFTYPE; + goto err; + } +#ifdef EXEC_DEBUG + printf("ep=%x, end=%x\n.text=%x,%u,%u\n.data=%x,%u,%u\n" + ".bss=%x,%u,%u\n.sym=%x,%u,%u\n.str=%x,%u,%u\n", + param.xp_entry, param.xp_end, + param.text.addr, param.text.size, param.text.foff, + param.data.addr, param.data.size, param.data.foff, + param.bss.addr, param.bss.size, param.bss.foff, + param.sym.addr, param.sym.size, param.sym.foff, + param.str.addr, param.str.size, param.str.foff); +#endif + pa = loadaddr; + + printf("%u", param.text.size); + /* read .text + .data + .sym */ + if (lseek(fd, param.text.foff, SEEK_SET) < 0 || + read(fd, pa+param.text.addr, param.text.size) != param.text.size) + goto err; + + if (param.data.size) { + printf("+%u", param.data.size); + if (lseek(fd, param.data.foff, SEEK_SET) <= 0 || + read(fd,pa+param.data.addr,param.data.size) != param.data.size) + goto err; + } + + /* .bss */ + printf("+%u", param.bss.size); + bzero (pa + param.bss.addr, param.bss.size); + + sz = 0; + if (param.sym.size) { + printf("+[%u", param.sym.size); + if (lseek(fd, param.sym.foff, SEEK_SET) <= 0 || + read(fd,pa+param.sym.addr,param.sym.size) != param.sym.size) + goto err; + + /* .str */ + if (lseek(fd, param.str.foff, SEEK_SET) <= 0) + goto err; + + pa += param.str.addr; + sz = param.str.size; + + /* special hack for a.out, where .str size is it's first int */ + if (param.str.foff && sz == 0) { + if (read(fd, pa, sizeof(u_int)) != sizeof(u_int)) + goto err; + else { + sz = param.sym.size = *(u_int*)pa; + pa += sizeof(u_int); + sz -= sizeof(u_int); + } + } + if (sz) { + if (sz && read(fd, pa, sz) != sz) + goto err; + } + printf("+%u]", sz); + } + + param.xp_end = (u_int)(pa + sz); + + printf(" total=0x%x start=0x%x\n", param.xp_end, param.xp_entry); + + /* call the joker */ + machdep_exec(¶m, howto, loadaddr); + + /* exec failed */ + errno = ENOEXEC; + return; +err: + save_err = errno? errno: EIO; + close(fd); + errno = save_err; +} diff --git a/sys/lib/libsa/exec_aout.c b/sys/lib/libsa/exec_aout.c new file mode 100644 index 00000000000..a44c7c0b0ca --- /dev/null +++ b/sys/lib/libsa/exec_aout.c @@ -0,0 +1,83 @@ +/* $OpenBSD: exec_aout.c,v 1.1 1998/07/14 03:29:08 mickey Exp $ */ + +/* + * Copyright (c) 1998 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Michael Shalayeff. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "libsa.h" +#include <machine/exec.h> +#include <lib/libsa/exec.h> + +int +aout_probe(fd, hdr) + int fd; + union x_header *hdr; +{ + return !N_BADMAG(hdr->x_aout); +} + + +int +aout_load(fd, xp) + int fd; + register struct x_param *xp; +{ + register struct exec *x = &xp->xp_hdr->x_aout; + +#ifdef EXEC_DEBUG + printf("\nstruct exec {%x, %x, %x, %x, %x, %x, %x, %x}\n", + x->a_midmag, x->a_text, x->a_data, x->a_bss, x->a_syms, + x->a_entry, x->a_trsize, x->a_drsize); +#endif + xp->xp_entry = x->a_entry; + + xp->text.foff = N_GETMAGIC(*x) == ZMAGIC? 0: sizeof(*x); + xp->data.foff = xp->text.foff + x->a_text; + xp->bss.foff = 0; + if (x->a_syms) { + xp->sym.foff = xp->data.foff + x->a_data; + xp->str.foff = xp->sym.foff + x->a_syms; + } + + xp->text.addr = 0; + xp->data.addr = xp->text.addr + x->a_text; + if (N_GETMAGIC(*x) == NMAGIC) + xp->data.addr += N_PAGSIZ(x)- (xp->data.addr & (N_PAGSIZ(x)-1)); + xp->bss.addr = xp->data.addr + x->a_data; + xp->sym.addr = xp->bss.addr + x->a_bss; + xp->str.addr = xp->sym.addr + x->a_syms; + + xp->text.size = x->a_text; + xp->data.size = x->a_data; + xp->bss.size = x->a_bss; + xp->sym.size = x->a_syms; + xp->str.size = 0; /* will be hacked later in exec() */ + + return 0; +} diff --git a/sys/lib/libsa/exec_elf.c b/sys/lib/libsa/exec_elf.c new file mode 100644 index 00000000000..7bb15cce4df --- /dev/null +++ b/sys/lib/libsa/exec_elf.c @@ -0,0 +1,109 @@ +/* $OpenBSD: exec_elf.c,v 1.1 1998/07/14 03:29:08 mickey Exp $ */ + +/* + * Copyright (c) 1998 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Michael Shalayeff. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "libsa.h" +#include <machine/exec.h> +#include <lib/libsa/exec.h> +#include <sys/exec_elf.h> + +int +elf_probe(fd, hdr) + int fd; + union x_header *hdr; +{ + return IS_ELF(hdr->x_elf); +} + +int +elf_load(fd, xp) + int fd; + struct x_param *xp; +{ + register Elf32_Ehdr *ehdr = (Elf32_Ehdr *)xp->xp_hdr; + register Elf32_Phdr *phdr, *ph; + register Elf32_Shdr *shdr, *sh; + size_t phsize, shsize; + u_int pa; + + xp->xp_entry = ehdr->e_entry; + + if (lseek(fd, ehdr->e_phoff, SEEK_SET) <= 0) + return -1; + + phsize = ehdr->e_phnum * ehdr->e_phentsize; + phdr = alloca(phsize); + + if (read(fd, phdr, phsize) != phsize) + return -1; + + pa = 0; + for (ph = phdr; ph < &phdr[ehdr->e_phnum]; ph++) { + if (ntohl(ph->p_filesz) && ntohl(ph->p_flags) & PF_X) { + pa = ph->p_vaddr; + xp->text.addr = 0; + xp->text.size = ph->p_filesz; + xp->text.foff = ph->p_offset; + } else if (ntohl(ph->p_filesz) && ntohl(ph->p_flags) & PF_W) { + xp->data.addr = ph->p_vaddr - pa; + xp->data.size = ph->p_filesz; + xp->data.foff = ph->p_offset; + } else if (!ntohl(ph->p_filesz)) { + xp->bss.addr = ph->p_vaddr - pa; + xp->bss.size = ph->p_memsz; + xp->bss.foff = 0; + } + } + + if (lseek(fd, ehdr->e_shoff, SEEK_SET)) + return -1; + + shsize = ehdr->e_shnum * ehdr->e_shentsize; + shdr = (Elf32_Shdr *) alloca(shsize); + + if (read(fd, shdr, shsize) != shsize) + return -1; + + for (sh = shdr; sh < &shdr[ehdr->e_shnum]; sh++) { + switch (sh->sh_type) { + case SHT_SYMTAB: + xp->sym.foff = sh->sh_offset; + xp->sym.size = sh->sh_size; + case SHT_STRTAB: + xp->str.foff = sh->sh_offset; + xp->str.size = sh->sh_size; + } + break; + } + + return 0; +} + |