summaryrefslogtreecommitdiff
path: root/sys/lib/libsa
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1998-07-14 03:29:09 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1998-07-14 03:29:09 +0000
commitc7d428b9c27b1c37a3e753ffb21eef8904b64118 (patch)
treebbd274d80bdf2b5e55f416141875a50b860ea048 /sys/lib/libsa
parent72af685d8aa0b209634a3567f06d3514e6e6fac6 (diff)
multiformat exec framework
Diffstat (limited to 'sys/lib/libsa')
-rw-r--r--sys/lib/libsa/exec.h98
-rw-r--r--sys/lib/libsa/exec.new.c153
-rw-r--r--sys/lib/libsa/exec_aout.c83
-rw-r--r--sys/lib/libsa/exec_elf.c109
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 (&param, sizeof(param));
+ param.xp_execsw = sw;
+ param.xp_hdr = &hdr;
+
+ if (!sw->probe || sw->load(fd, &param)) {
+ 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(&param, 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;
+}
+