1 /* $OpenBSD: exec_elf.c,v 1.10 2004/01/04 18:30:05 deraadt Exp $ */
2
3 /*
4 * Copyright (c) 1999 Mats O Jansson. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include <err.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <nlist.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <sys/exec.h>
35 #include <sys/exec_elf.h>
36 #include <sys/types.h>
37
38 #include "ukc.h"
39 #include "config.h"
40
41 __RCSID("$MirOS: src/usr.sbin/config/exec_elf.c,v 1.4 2010/07/25 16:31:08 tg Exp $");
42
43 caddr_t ptr, rest, pre;
44 Elf_Ehdr elf_ex;
45 Elf_Phdr *elf_phdr;
46 Elf_Shdr *elf_shdr;
47 char *elf_total;
48 char *elf_shstrtab;
49 off_t elf_size;
50
51 caddr_t elf_adjust(caddr_t);
52 caddr_t elf_readjust(caddr_t);
53 int elf_check(const char *);
54 void elf_loadkernel(const char *);
55 void elf_savekernel(const char *);
56
57 caddr_t
elf_adjust(caddr_t x)58 elf_adjust(caddr_t x)
59 {
60 int i;
61 Elf_Shdr *s;
62 unsigned long y = 0;
63
64 s = elf_shdr;
65
66 for (i = 0; i < elf_ex.e_shnum; i++) {
67 if (s[i].sh_addr == 0)
68 continue;
69 if (((unsigned long)x >= s[i].sh_addr) &&
70 ((unsigned long)x < (s[i].sh_addr+s[i].sh_size))) {
71 y = (unsigned long)&elf_total[(unsigned long)x -
72 s[i].sh_addr + s[i].sh_offset];
73 break;
74 }
75 }
76
77 return((caddr_t)y);
78 }
79
80 caddr_t
elf_readjust(caddr_t x)81 elf_readjust(caddr_t x)
82 {
83 int i;
84 Elf_Shdr *s;
85 unsigned long y = 0;
86
87 s = elf_shdr;
88
89 for (i = 0; i < elf_ex.e_shnum; i++) {
90 if (s[i].sh_addr == 0)
91 continue;
92 if (((Elf_Off)(x - elf_total) >= s[i].sh_offset) &&
93 ((Elf_Off)(x - elf_total) <= (s[i].sh_offset + s[i].sh_size)))
94 y = (unsigned long)x - (unsigned long)elf_total +
95 (unsigned long)s[i].sh_addr - s[i].sh_offset;
96 }
97
98 return((caddr_t)y);
99 }
100
101 int
elf_check(const char * file)102 elf_check(const char *file)
103 {
104 int fd, ret = 1;
105
106 if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0)
107 return (0);
108
109 if (read(fd, (char *)&elf_ex, sizeof(elf_ex)) != sizeof(elf_ex))
110 ret = 0;
111
112 if (ret) {
113 if (!IS_ELF(elf_ex))
114 ret = 0;
115 }
116
117 close(fd);
118 return (ret);
119 }
120
121 void
elf_loadkernel(const char * file)122 elf_loadkernel(const char *file)
123 {
124 int fd;
125
126 if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0)
127 err(1, "%s", file);
128
129 if (read(fd, (char *)&elf_ex, sizeof(elf_ex)) != sizeof(elf_ex))
130 errx(1, "can't read elf header");
131
132 if (!IS_ELF(elf_ex))
133 errx(1, "bad elf magic");
134
135 elf_size = lseek(fd, (off_t)0, SEEK_END);
136 (void)lseek(fd, (off_t)0, SEEK_SET);
137 elf_total = emalloc((size_t)elf_size);
138
139 if (read(fd, elf_total, (size_t)elf_size) != elf_size)
140 errx(1, "can't read elf kernel");
141
142 elf_phdr = (Elf_Phdr *)&elf_total[elf_ex.e_phoff];
143 elf_shdr = (Elf_Shdr *)&elf_total[elf_ex.e_shoff];
144
145 elf_shstrtab = &elf_total[elf_shdr[elf_ex.e_shstrndx].sh_offset];
146
147 close(fd);
148 }
149
150 void
elf_savekernel(const char * outfile)151 elf_savekernel(const char *outfile)
152 {
153 int fd;
154
155 if ((fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0755)) < 0)
156 err(1, "%s", outfile);
157
158 if (write(fd, elf_total, (size_t)elf_size) != elf_size)
159 errx(1, "can't write file %s", outfile);
160
161 close(fd);
162 }
163