diff options
Diffstat (limited to 'usr.sbin/config/exec_elf.c')
-rw-r--r-- | usr.sbin/config/exec_elf.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/usr.sbin/config/exec_elf.c b/usr.sbin/config/exec_elf.c new file mode 100644 index 00000000000..1446fa27012 --- /dev/null +++ b/usr.sbin/config/exec_elf.c @@ -0,0 +1,173 @@ +/* $OpenBSD: exec_elf.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $ */ + +/* + * Copyright (c) 1999 Mats O Jansson. 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 Mats O Jansson. + * 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 LINT +static char rcsid[] = "$OpenBSD: exec_elf.c,v 1.1 1999/10/04 20:00:51 deraadt Exp $"; +#endif + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <nlist.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/exec.h> +#include <sys/exec_elf.h> +#include <sys/types.h> + +#include "ukc.h" + +caddr_t ptr,rest,pre; +Elf32_Ehdr elf_ex; +Elf32_Phdr *elf_phdr; +Elf32_Shdr *elf_shdr; +char *elf_total; +char *elf_shstrtab; +off_t elf_size; + +caddr_t +elf_adjust(x) + caddr_t x; +{ + int i; + Elf32_Shdr *s; + unsigned long y = 0; + + s = elf_shdr; + + for (i = 0; i < elf_ex.e_shnum; i++) { + if (s[i].sh_addr == 0) + continue; + if (((unsigned long)x >= s[i].sh_addr) && + ((unsigned long)x < (s[i].sh_addr+s[i].sh_size))) { + y = (unsigned long)&elf_total[(unsigned long)x - + s[i].sh_addr + + s[i].sh_offset]; + break; + } + } + + return((caddr_t)y); +} + +caddr_t +elf_readjust(x) + caddr_t x; +{ + int i; + Elf32_Shdr *s; + unsigned long y = 0; + + s = elf_shdr; + + for (i = 0; i < elf_ex.e_shnum; i++) { + if (s[i].sh_addr == 0) + continue; + if (((x - elf_total) >= s[i].sh_offset) && + ((x - elf_total) <= (s[i].sh_offset + s[i].sh_size))) + y = x - elf_total + s[i].sh_addr; + } + + return((caddr_t)y); +} + +int +elf_check(file) + char *file; +{ + int fd,ret = 1; + + if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0) + return (0); + + if (read(fd, (char *)&elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) + ret = 0; + + if (ret) { + if (!IS_ELF(elf_ex)) + ret = 0; + } + + close(fd); + return (ret); +} + +void +elf_loadkernel(file) + char *file; +{ + int fd; + Elf32_Phdr *p; + Elf32_Shdr *s; + + if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0) + err(1, file, errno); + + if (read(fd, (char *)&elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) + errx(1, "can't read elf header"); + + if (!IS_ELF(elf_ex)) + errx(1, "bad elf magic\n"); + + elf_size = lseek(fd, 0L, SEEK_END); + (void)lseek(fd, 0L, SEEK_SET); + elf_total = malloc(elf_size); + + if (read(fd, elf_total, elf_size) != elf_size) + errx(1, "can't read elf kernel"); + + elf_phdr = (Elf32_Phdr *)&elf_total[elf_ex.e_phoff]; + elf_shdr = (Elf32_Shdr *)&elf_total[elf_ex.e_shoff]; + + p = elf_phdr; + s = elf_shdr; + + elf_shstrtab = &elf_total[elf_shdr[elf_ex.e_shstrndx].sh_offset]; + + close(fd); +} + +void +elf_savekernel(outfile) + + char *outfile; +{ + int fd; + + if ((fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0755)) < 0) + err(1, outfile, errno); + + if (write(fd, elf_total, elf_size) != elf_size) + errx(1, "can't write file %s", outfile); + + close(fd); +} |