Blame


1 a84cbb2a 2004-04-19 devnull /*
2 a84cbb2a 2004-04-19 devnull * Parse 32-bit ELF files.
3 a84cbb2a 2004-04-19 devnull * Copyright (c) 2004 Russ Cox. See LICENSE.
4 a84cbb2a 2004-04-19 devnull */
5 a84cbb2a 2004-04-19 devnull
6 a84cbb2a 2004-04-19 devnull #include <u.h>
7 a84cbb2a 2004-04-19 devnull #include <libc.h>
8 a84cbb2a 2004-04-19 devnull #include <mach.h>
9 a84cbb2a 2004-04-19 devnull #include "elf.h"
10 a84cbb2a 2004-04-19 devnull
11 a84cbb2a 2004-04-19 devnull typedef struct ElfHdrBytes ElfHdrBytes;
12 a84cbb2a 2004-04-19 devnull typedef struct ElfSectBytes ElfSectBytes;
13 a84cbb2a 2004-04-19 devnull typedef struct ElfProgBytes ElfProgBytes;
14 a84cbb2a 2004-04-19 devnull typedef struct ElfSymBytes ElfSymBytes;
15 a84cbb2a 2004-04-19 devnull
16 443d6288 2012-02-19 rsc typedef struct ElfHdrBytes64 ElfHdrBytes64;
17 443d6288 2012-02-19 rsc typedef struct ElfSectBytes64 ElfSectBytes64;
18 443d6288 2012-02-19 rsc typedef struct ElfProgBytes64 ElfProgBytes64;
19 443d6288 2012-02-19 rsc typedef struct ElfSymBytes64 ElfSymBytes64;
20 443d6288 2012-02-19 rsc
21 a84cbb2a 2004-04-19 devnull struct ElfHdrBytes
22 a84cbb2a 2004-04-19 devnull {
23 a84cbb2a 2004-04-19 devnull uchar ident[16];
24 a84cbb2a 2004-04-19 devnull uchar type[2];
25 a84cbb2a 2004-04-19 devnull uchar machine[2];
26 a84cbb2a 2004-04-19 devnull uchar version[4];
27 a84cbb2a 2004-04-19 devnull uchar entry[4];
28 a84cbb2a 2004-04-19 devnull uchar phoff[4];
29 a84cbb2a 2004-04-19 devnull uchar shoff[4];
30 a84cbb2a 2004-04-19 devnull uchar flags[4];
31 a84cbb2a 2004-04-19 devnull uchar ehsize[2];
32 a84cbb2a 2004-04-19 devnull uchar phentsize[2];
33 a84cbb2a 2004-04-19 devnull uchar phnum[2];
34 a84cbb2a 2004-04-19 devnull uchar shentsize[2];
35 a84cbb2a 2004-04-19 devnull uchar shnum[2];
36 a84cbb2a 2004-04-19 devnull uchar shstrndx[2];
37 a84cbb2a 2004-04-19 devnull };
38 a84cbb2a 2004-04-19 devnull
39 443d6288 2012-02-19 rsc struct ElfHdrBytes64
40 443d6288 2012-02-19 rsc {
41 443d6288 2012-02-19 rsc uchar ident[16];
42 443d6288 2012-02-19 rsc uchar type[2];
43 443d6288 2012-02-19 rsc uchar machine[2];
44 443d6288 2012-02-19 rsc uchar version[4];
45 443d6288 2012-02-19 rsc uchar entry[8];
46 443d6288 2012-02-19 rsc uchar phoff[8];
47 443d6288 2012-02-19 rsc uchar shoff[8];
48 443d6288 2012-02-19 rsc uchar flags[4];
49 443d6288 2012-02-19 rsc uchar ehsize[2];
50 443d6288 2012-02-19 rsc uchar phentsize[2];
51 443d6288 2012-02-19 rsc uchar phnum[2];
52 443d6288 2012-02-19 rsc uchar shentsize[2];
53 443d6288 2012-02-19 rsc uchar shnum[2];
54 443d6288 2012-02-19 rsc uchar shstrndx[2];
55 443d6288 2012-02-19 rsc };
56 443d6288 2012-02-19 rsc
57 a84cbb2a 2004-04-19 devnull struct ElfSectBytes
58 a84cbb2a 2004-04-19 devnull {
59 a84cbb2a 2004-04-19 devnull uchar name[4];
60 a84cbb2a 2004-04-19 devnull uchar type[4];
61 a84cbb2a 2004-04-19 devnull uchar flags[4];
62 a84cbb2a 2004-04-19 devnull uchar addr[4];
63 a84cbb2a 2004-04-19 devnull uchar offset[4];
64 a84cbb2a 2004-04-19 devnull uchar size[4];
65 a84cbb2a 2004-04-19 devnull uchar link[4];
66 a84cbb2a 2004-04-19 devnull uchar info[4];
67 a84cbb2a 2004-04-19 devnull uchar align[4];
68 a84cbb2a 2004-04-19 devnull uchar entsize[4];
69 a84cbb2a 2004-04-19 devnull };
70 a84cbb2a 2004-04-19 devnull
71 443d6288 2012-02-19 rsc struct ElfSectBytes64
72 443d6288 2012-02-19 rsc {
73 443d6288 2012-02-19 rsc uchar name[4];
74 443d6288 2012-02-19 rsc uchar type[4];
75 443d6288 2012-02-19 rsc uchar flags[8];
76 443d6288 2012-02-19 rsc uchar addr[8];
77 443d6288 2012-02-19 rsc uchar offset[8];
78 443d6288 2012-02-19 rsc uchar size[8];
79 443d6288 2012-02-19 rsc uchar link[4];
80 443d6288 2012-02-19 rsc uchar info[4];
81 443d6288 2012-02-19 rsc uchar align[8];
82 443d6288 2012-02-19 rsc uchar entsize[8];
83 443d6288 2012-02-19 rsc };
84 443d6288 2012-02-19 rsc
85 a84cbb2a 2004-04-19 devnull struct ElfSymBytes
86 a84cbb2a 2004-04-19 devnull {
87 a84cbb2a 2004-04-19 devnull uchar name[4];
88 a84cbb2a 2004-04-19 devnull uchar value[4];
89 a84cbb2a 2004-04-19 devnull uchar size[4];
90 a84cbb2a 2004-04-19 devnull uchar info; /* top4: bind, bottom4: type */
91 a84cbb2a 2004-04-19 devnull uchar other;
92 a84cbb2a 2004-04-19 devnull uchar shndx[2];
93 a84cbb2a 2004-04-19 devnull };
94 a84cbb2a 2004-04-19 devnull
95 443d6288 2012-02-19 rsc struct ElfSymBytes64
96 443d6288 2012-02-19 rsc {
97 443d6288 2012-02-19 rsc uchar name[4];
98 443d6288 2012-02-19 rsc uchar info;
99 443d6288 2012-02-19 rsc uchar other;
100 443d6288 2012-02-19 rsc uchar shndx[2];
101 443d6288 2012-02-19 rsc uchar value[8];
102 443d6288 2012-02-19 rsc uchar size[8];
103 443d6288 2012-02-19 rsc };
104 443d6288 2012-02-19 rsc
105 a84cbb2a 2004-04-19 devnull struct ElfProgBytes
106 a84cbb2a 2004-04-19 devnull {
107 a84cbb2a 2004-04-19 devnull uchar type[4];
108 a84cbb2a 2004-04-19 devnull uchar offset[4];
109 a84cbb2a 2004-04-19 devnull uchar vaddr[4];
110 a84cbb2a 2004-04-19 devnull uchar paddr[4];
111 a84cbb2a 2004-04-19 devnull uchar filesz[4];
112 a84cbb2a 2004-04-19 devnull uchar memsz[4];
113 a84cbb2a 2004-04-19 devnull uchar flags[4];
114 a84cbb2a 2004-04-19 devnull uchar align[4];
115 a84cbb2a 2004-04-19 devnull };
116 a84cbb2a 2004-04-19 devnull
117 443d6288 2012-02-19 rsc struct ElfProgBytes64
118 443d6288 2012-02-19 rsc {
119 443d6288 2012-02-19 rsc uchar type[4];
120 443d6288 2012-02-19 rsc uchar flags[4];
121 443d6288 2012-02-19 rsc uchar offset[8];
122 443d6288 2012-02-19 rsc uchar vaddr[8];
123 443d6288 2012-02-19 rsc uchar paddr[8];
124 443d6288 2012-02-19 rsc uchar filesz[8];
125 443d6288 2012-02-19 rsc uchar memsz[8];
126 443d6288 2012-02-19 rsc uchar align[8];
127 443d6288 2012-02-19 rsc };
128 443d6288 2012-02-19 rsc
129 a84cbb2a 2004-04-19 devnull uchar ElfMagic[4] = { 0x7F, 'E', 'L', 'F' };
130 a84cbb2a 2004-04-19 devnull
131 443d6288 2012-02-19 rsc static void unpackhdr(ElfHdr*, void*);
132 443d6288 2012-02-19 rsc static void unpackprog(ElfHdr*, ElfProg*, void*);
133 443d6288 2012-02-19 rsc static void unpacksect(ElfHdr*, ElfSect*, void*);
134 a84cbb2a 2004-04-19 devnull
135 a84cbb2a 2004-04-19 devnull static char *elftypes[] = {
136 a84cbb2a 2004-04-19 devnull "none",
137 a84cbb2a 2004-04-19 devnull "relocatable",
138 a84cbb2a 2004-04-19 devnull "executable",
139 a84cbb2a 2004-04-19 devnull "shared object",
140 a84cbb2a 2004-04-19 devnull "core",
141 a84cbb2a 2004-04-19 devnull };
142 a84cbb2a 2004-04-19 devnull
143 a84cbb2a 2004-04-19 devnull char*
144 a84cbb2a 2004-04-19 devnull elftype(int t)
145 a84cbb2a 2004-04-19 devnull {
146 a84cbb2a 2004-04-19 devnull if(t < 0 || t >= nelem(elftypes))
147 a84cbb2a 2004-04-19 devnull return "unknown";
148 a84cbb2a 2004-04-19 devnull return elftypes[t];
149 a84cbb2a 2004-04-19 devnull }
150 a84cbb2a 2004-04-19 devnull
151 a84cbb2a 2004-04-19 devnull static char *elfmachs[] = {
152 a84cbb2a 2004-04-19 devnull "none",
153 a84cbb2a 2004-04-19 devnull "32100",
154 a84cbb2a 2004-04-19 devnull "sparc",
155 a84cbb2a 2004-04-19 devnull "386",
156 a84cbb2a 2004-04-19 devnull "68000",
157 a84cbb2a 2004-04-19 devnull "88000",
158 a84cbb2a 2004-04-19 devnull "486",
159 a84cbb2a 2004-04-19 devnull "860",
160 a84cbb2a 2004-04-19 devnull "MIPS",
161 a84cbb2a 2004-04-19 devnull };
162 a84cbb2a 2004-04-19 devnull
163 a84cbb2a 2004-04-19 devnull char*
164 a84cbb2a 2004-04-19 devnull elfmachine(int t)
165 a84cbb2a 2004-04-19 devnull {
166 a84cbb2a 2004-04-19 devnull if(t < 0 || t >= nelem(elfmachs))
167 a84cbb2a 2004-04-19 devnull return "unknown";
168 a84cbb2a 2004-04-19 devnull return elfmachs[t];
169 a84cbb2a 2004-04-19 devnull }
170 a84cbb2a 2004-04-19 devnull
171 a84cbb2a 2004-04-19 devnull Elf*
172 a84cbb2a 2004-04-19 devnull elfopen(char *name)
173 a84cbb2a 2004-04-19 devnull {
174 a84cbb2a 2004-04-19 devnull int fd;
175 a84cbb2a 2004-04-19 devnull Elf *e;
176 a84cbb2a 2004-04-19 devnull
177 a84cbb2a 2004-04-19 devnull if((fd = open(name, OREAD)) < 0)
178 a84cbb2a 2004-04-19 devnull return nil;
179 a84cbb2a 2004-04-19 devnull if((e = elfinit(fd)) == nil)
180 a84cbb2a 2004-04-19 devnull close(fd);
181 a84cbb2a 2004-04-19 devnull return e;
182 a84cbb2a 2004-04-19 devnull }
183 a84cbb2a 2004-04-19 devnull
184 a84cbb2a 2004-04-19 devnull Elf*
185 a84cbb2a 2004-04-19 devnull elfinit(int fd)
186 a84cbb2a 2004-04-19 devnull {
187 a84cbb2a 2004-04-19 devnull int i;
188 a84cbb2a 2004-04-19 devnull Elf *e;
189 a84cbb2a 2004-04-19 devnull ElfHdr *h;
190 443d6288 2012-02-19 rsc union {
191 443d6288 2012-02-19 rsc ElfHdrBytes h32;
192 443d6288 2012-02-19 rsc ElfHdrBytes64 h64;
193 443d6288 2012-02-19 rsc } hdrb;
194 2c97de1a 2020-01-07 crossd void *p = nil;
195 a84cbb2a 2004-04-19 devnull ElfSect *s;
196 a84cbb2a 2004-04-19 devnull
197 a84cbb2a 2004-04-19 devnull e = mallocz(sizeof(Elf), 1);
198 a84cbb2a 2004-04-19 devnull if(e == nil)
199 a84cbb2a 2004-04-19 devnull return nil;
200 a84cbb2a 2004-04-19 devnull e->fd = fd;
201 a84cbb2a 2004-04-19 devnull
202 a84cbb2a 2004-04-19 devnull /*
203 a84cbb2a 2004-04-19 devnull * parse header
204 a84cbb2a 2004-04-19 devnull */
205 a84cbb2a 2004-04-19 devnull seek(fd, 0, 0);
206 a84cbb2a 2004-04-19 devnull if(readn(fd, &hdrb, sizeof hdrb) != sizeof hdrb)
207 a84cbb2a 2004-04-19 devnull goto err;
208 a84cbb2a 2004-04-19 devnull h = &e->hdr;
209 a84cbb2a 2004-04-19 devnull unpackhdr(h, &hdrb);
210 443d6288 2012-02-19 rsc if(h->class != ElfClass32 && h->class != ElfClass64){
211 443d6288 2012-02-19 rsc werrstr("bad ELF class - not 32-bit, 64-bit");
212 a84cbb2a 2004-04-19 devnull goto err;
213 a84cbb2a 2004-04-19 devnull }
214 a84cbb2a 2004-04-19 devnull if(h->encoding != ElfDataLsb && h->encoding != ElfDataMsb){
215 a84cbb2a 2004-04-19 devnull werrstr("bad ELF encoding - not LSB, MSB");
216 a84cbb2a 2004-04-19 devnull goto err;
217 a84cbb2a 2004-04-19 devnull }
218 443d6288 2012-02-19 rsc if(hdrb.h32.ident[6] != h->version){
219 a84cbb2a 2004-04-19 devnull werrstr("bad ELF encoding - version mismatch %02ux and %08ux",
220 443d6288 2012-02-19 rsc (uint)hdrb.h32.ident[6], (uint)h->version);
221 a84cbb2a 2004-04-19 devnull goto err;
222 a84cbb2a 2004-04-19 devnull }
223 a84cbb2a 2004-04-19 devnull
224 a84cbb2a 2004-04-19 devnull /*
225 a84cbb2a 2004-04-19 devnull * the prog+section info is almost always small - just load it into memory.
226 a84cbb2a 2004-04-19 devnull */
227 a84cbb2a 2004-04-19 devnull e->nprog = h->phnum;
228 a84cbb2a 2004-04-19 devnull e->prog = mallocz(sizeof(ElfProg)*e->nprog, 1);
229 443d6288 2012-02-19 rsc p = mallocz(h->phentsize, 1);
230 a84cbb2a 2004-04-19 devnull for(i=0; i<e->nprog; i++){
231 a84cbb2a 2004-04-19 devnull if(seek(fd, h->phoff+i*h->phentsize, 0) < 0
232 443d6288 2012-02-19 rsc || readn(fd, p, h->phentsize) != h->phentsize)
233 a84cbb2a 2004-04-19 devnull goto err;
234 443d6288 2012-02-19 rsc unpackprog(h, &e->prog[i], p);
235 a84cbb2a 2004-04-19 devnull }
236 443d6288 2012-02-19 rsc free(p);
237 2c97de1a 2020-01-07 crossd p = nil;
238 a84cbb2a 2004-04-19 devnull
239 a84cbb2a 2004-04-19 devnull e->nsect = h->shnum;
240 a84cbb2a 2004-04-19 devnull if(e->nsect == 0)
241 a84cbb2a 2004-04-19 devnull goto nosects;
242 a84cbb2a 2004-04-19 devnull e->sect = mallocz(sizeof(ElfSect)*e->nsect, 1);
243 443d6288 2012-02-19 rsc p = mallocz(h->shentsize, 1);
244 a84cbb2a 2004-04-19 devnull for(i=0; i<e->nsect; i++){
245 a84cbb2a 2004-04-19 devnull if(seek(fd, h->shoff+i*h->shentsize, 0) < 0
246 443d6288 2012-02-19 rsc || readn(fd, p, h->shentsize) != h->shentsize)
247 a84cbb2a 2004-04-19 devnull goto err;
248 443d6288 2012-02-19 rsc unpacksect(h, &e->sect[i], p);
249 a84cbb2a 2004-04-19 devnull }
250 443d6288 2012-02-19 rsc free(p);
251 2c97de1a 2020-01-07 crossd p = nil;
252 a84cbb2a 2004-04-19 devnull
253 a84cbb2a 2004-04-19 devnull if(h->shstrndx >= e->nsect){
254 a84cbb2a 2004-04-19 devnull fprint(2, "warning: bad string section index %d >= %d", h->shstrndx, e->nsect);
255 a84cbb2a 2004-04-19 devnull h->shnum = 0;
256 a84cbb2a 2004-04-19 devnull e->nsect = 0;
257 a84cbb2a 2004-04-19 devnull goto nosects;
258 a84cbb2a 2004-04-19 devnull }
259 a84cbb2a 2004-04-19 devnull s = &e->sect[h->shstrndx];
260 a84cbb2a 2004-04-19 devnull if(elfmap(e, s) < 0)
261 a84cbb2a 2004-04-19 devnull goto err;
262 a84cbb2a 2004-04-19 devnull
263 a84cbb2a 2004-04-19 devnull for(i=0; i<e->nsect; i++)
264 a84cbb2a 2004-04-19 devnull if(e->sect[i].name)
265 929ba9b9 2004-04-20 devnull e->sect[i].name = (char*)s->base + (ulong)e->sect[i].name;
266 a84cbb2a 2004-04-19 devnull
267 a84cbb2a 2004-04-19 devnull e->symtab = elfsection(e, ".symtab");
268 a84cbb2a 2004-04-19 devnull if(e->symtab){
269 a84cbb2a 2004-04-19 devnull if(e->symtab->link >= e->nsect)
270 a84cbb2a 2004-04-19 devnull e->symtab = nil;
271 a84cbb2a 2004-04-19 devnull else{
272 a84cbb2a 2004-04-19 devnull e->symstr = &e->sect[e->symtab->link];
273 a84cbb2a 2004-04-19 devnull e->nsymtab = e->symtab->size / sizeof(ElfSymBytes);
274 a84cbb2a 2004-04-19 devnull }
275 a84cbb2a 2004-04-19 devnull }
276 a84cbb2a 2004-04-19 devnull e->dynsym = elfsection(e, ".dynsym");
277 a84cbb2a 2004-04-19 devnull if(e->dynsym){
278 a84cbb2a 2004-04-19 devnull if(e->dynsym->link >= e->nsect)
279 a84cbb2a 2004-04-19 devnull e->dynsym = nil;
280 a84cbb2a 2004-04-19 devnull else{
281 a84cbb2a 2004-04-19 devnull e->dynstr = &e->sect[e->dynsym->link];
282 a84cbb2a 2004-04-19 devnull e->ndynsym = e->dynsym->size / sizeof(ElfSymBytes);
283 a84cbb2a 2004-04-19 devnull }
284 a84cbb2a 2004-04-19 devnull }
285 a84cbb2a 2004-04-19 devnull
286 a84cbb2a 2004-04-19 devnull e->bss = elfsection(e, ".bss");
287 a84cbb2a 2004-04-19 devnull
288 a84cbb2a 2004-04-19 devnull nosects:
289 a84cbb2a 2004-04-19 devnull return e;
290 a84cbb2a 2004-04-19 devnull
291 a84cbb2a 2004-04-19 devnull err:
292 2c97de1a 2020-01-07 crossd free(p);
293 a84cbb2a 2004-04-19 devnull free(e->sect);
294 a84cbb2a 2004-04-19 devnull free(e->prog);
295 a84cbb2a 2004-04-19 devnull free(e->shstrtab);
296 a84cbb2a 2004-04-19 devnull free(e);
297 a84cbb2a 2004-04-19 devnull return nil;
298 a84cbb2a 2004-04-19 devnull }
299 a84cbb2a 2004-04-19 devnull
300 a84cbb2a 2004-04-19 devnull void
301 a84cbb2a 2004-04-19 devnull elfclose(Elf *elf)
302 a84cbb2a 2004-04-19 devnull {
303 a84cbb2a 2004-04-19 devnull int i;
304 a84cbb2a 2004-04-19 devnull
305 a84cbb2a 2004-04-19 devnull for(i=0; i<elf->nsect; i++)
306 a84cbb2a 2004-04-19 devnull free(elf->sect[i].base);
307 a84cbb2a 2004-04-19 devnull free(elf->sect);
308 a84cbb2a 2004-04-19 devnull free(elf->prog);
309 a84cbb2a 2004-04-19 devnull free(elf->shstrtab);
310 a84cbb2a 2004-04-19 devnull free(elf);
311 a84cbb2a 2004-04-19 devnull }
312 a84cbb2a 2004-04-19 devnull
313 a84cbb2a 2004-04-19 devnull static void
314 443d6288 2012-02-19 rsc unpackhdr(ElfHdr *h, void *v)
315 a84cbb2a 2004-04-19 devnull {
316 a84cbb2a 2004-04-19 devnull u16int (*e2)(uchar*);
317 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
318 a84cbb2a 2004-04-19 devnull u64int (*e8)(uchar*);
319 443d6288 2012-02-19 rsc ElfHdrBytes *b;
320 443d6288 2012-02-19 rsc ElfHdrBytes64 *b64;
321 a84cbb2a 2004-04-19 devnull
322 443d6288 2012-02-19 rsc b = v;
323 a84cbb2a 2004-04-19 devnull memmove(h->magic, b->ident, 4);
324 a84cbb2a 2004-04-19 devnull h->class = b->ident[4];
325 a84cbb2a 2004-04-19 devnull h->encoding = b->ident[5];
326 a84cbb2a 2004-04-19 devnull switch(h->encoding){
327 a84cbb2a 2004-04-19 devnull case ElfDataLsb:
328 a84cbb2a 2004-04-19 devnull e2 = leload2;
329 a84cbb2a 2004-04-19 devnull e4 = leload4;
330 a84cbb2a 2004-04-19 devnull e8 = leload8;
331 a84cbb2a 2004-04-19 devnull break;
332 a84cbb2a 2004-04-19 devnull case ElfDataMsb:
333 a84cbb2a 2004-04-19 devnull e2 = beload2;
334 a84cbb2a 2004-04-19 devnull e4 = beload4;
335 a84cbb2a 2004-04-19 devnull e8 = beload8;
336 a84cbb2a 2004-04-19 devnull break;
337 a84cbb2a 2004-04-19 devnull default:
338 a84cbb2a 2004-04-19 devnull return;
339 a84cbb2a 2004-04-19 devnull }
340 a84cbb2a 2004-04-19 devnull h->abi = b->ident[7];
341 a84cbb2a 2004-04-19 devnull h->abiversion = b->ident[8];
342 a84cbb2a 2004-04-19 devnull
343 a84cbb2a 2004-04-19 devnull h->e2 = e2;
344 a84cbb2a 2004-04-19 devnull h->e4 = e4;
345 a84cbb2a 2004-04-19 devnull h->e8 = e8;
346 fa325e9b 2020-01-10 cross
347 443d6288 2012-02-19 rsc if(h->class == ElfClass64)
348 443d6288 2012-02-19 rsc goto b64;
349 443d6288 2012-02-19 rsc
350 a84cbb2a 2004-04-19 devnull h->type = e2(b->type);
351 a84cbb2a 2004-04-19 devnull h->machine = e2(b->machine);
352 a84cbb2a 2004-04-19 devnull h->version = e4(b->version);
353 a84cbb2a 2004-04-19 devnull h->entry = e4(b->entry);
354 a84cbb2a 2004-04-19 devnull h->phoff = e4(b->phoff);
355 a84cbb2a 2004-04-19 devnull h->shoff = e4(b->shoff);
356 a84cbb2a 2004-04-19 devnull h->flags = e4(b->flags);
357 a84cbb2a 2004-04-19 devnull h->ehsize = e2(b->ehsize);
358 a84cbb2a 2004-04-19 devnull h->phentsize = e2(b->phentsize);
359 a84cbb2a 2004-04-19 devnull h->phnum = e2(b->phnum);
360 a84cbb2a 2004-04-19 devnull h->shentsize = e2(b->shentsize);
361 a84cbb2a 2004-04-19 devnull h->shnum = e2(b->shnum);
362 a84cbb2a 2004-04-19 devnull h->shstrndx = e2(b->shstrndx);
363 443d6288 2012-02-19 rsc return;
364 443d6288 2012-02-19 rsc
365 443d6288 2012-02-19 rsc b64:
366 443d6288 2012-02-19 rsc b64 = v;
367 443d6288 2012-02-19 rsc h->type = e2(b64->type);
368 443d6288 2012-02-19 rsc h->machine = e2(b64->machine);
369 443d6288 2012-02-19 rsc h->version = e4(b64->version);
370 443d6288 2012-02-19 rsc h->entry = e8(b64->entry);
371 443d6288 2012-02-19 rsc h->phoff = e8(b64->phoff);
372 443d6288 2012-02-19 rsc h->shoff = e8(b64->shoff);
373 443d6288 2012-02-19 rsc h->flags = e4(b64->flags);
374 443d6288 2012-02-19 rsc h->ehsize = e2(b64->ehsize);
375 443d6288 2012-02-19 rsc h->phentsize = e2(b64->phentsize);
376 443d6288 2012-02-19 rsc h->phnum = e2(b64->phnum);
377 443d6288 2012-02-19 rsc h->shentsize = e2(b64->shentsize);
378 443d6288 2012-02-19 rsc h->shnum = e2(b64->shnum);
379 443d6288 2012-02-19 rsc h->shstrndx = e2(b64->shstrndx);
380 443d6288 2012-02-19 rsc return;
381 a84cbb2a 2004-04-19 devnull }
382 a84cbb2a 2004-04-19 devnull
383 a84cbb2a 2004-04-19 devnull static void
384 443d6288 2012-02-19 rsc unpackprog(ElfHdr *h, ElfProg *p, void *v)
385 a84cbb2a 2004-04-19 devnull {
386 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
387 443d6288 2012-02-19 rsc u64int (*e8)(uchar*);
388 a84cbb2a 2004-04-19 devnull
389 443d6288 2012-02-19 rsc if(h->class == ElfClass32) {
390 443d6288 2012-02-19 rsc ElfProgBytes *b;
391 fa325e9b 2020-01-10 cross
392 443d6288 2012-02-19 rsc b = v;
393 443d6288 2012-02-19 rsc e4 = h->e4;
394 443d6288 2012-02-19 rsc p->type = e4(b->type);
395 443d6288 2012-02-19 rsc p->offset = e4(b->offset);
396 443d6288 2012-02-19 rsc p->vaddr = e4(b->vaddr);
397 443d6288 2012-02-19 rsc p->paddr = e4(b->paddr);
398 443d6288 2012-02-19 rsc p->filesz = e4(b->filesz);
399 443d6288 2012-02-19 rsc p->memsz = e4(b->memsz);
400 443d6288 2012-02-19 rsc p->flags = e4(b->flags);
401 443d6288 2012-02-19 rsc p->align = e4(b->align);
402 443d6288 2012-02-19 rsc } else {
403 443d6288 2012-02-19 rsc ElfProgBytes64 *b;
404 fa325e9b 2020-01-10 cross
405 443d6288 2012-02-19 rsc b = v;
406 443d6288 2012-02-19 rsc e4 = h->e4;
407 443d6288 2012-02-19 rsc e8 = h->e8;
408 443d6288 2012-02-19 rsc p->type = e4(b->type);
409 443d6288 2012-02-19 rsc p->offset = e8(b->offset);
410 443d6288 2012-02-19 rsc p->vaddr = e8(b->vaddr);
411 443d6288 2012-02-19 rsc p->paddr = e8(b->paddr);
412 443d6288 2012-02-19 rsc p->filesz = e8(b->filesz);
413 443d6288 2012-02-19 rsc p->memsz = e8(b->memsz);
414 443d6288 2012-02-19 rsc p->flags = e4(b->flags);
415 443d6288 2012-02-19 rsc p->align = e8(b->align);
416 443d6288 2012-02-19 rsc }
417 a84cbb2a 2004-04-19 devnull }
418 a84cbb2a 2004-04-19 devnull
419 a84cbb2a 2004-04-19 devnull static void
420 443d6288 2012-02-19 rsc unpacksect(ElfHdr *h, ElfSect *s, void *v)
421 a84cbb2a 2004-04-19 devnull {
422 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
423 443d6288 2012-02-19 rsc u64int (*e8)(uchar*);
424 a84cbb2a 2004-04-19 devnull
425 443d6288 2012-02-19 rsc if(h->class == ElfClass32) {
426 443d6288 2012-02-19 rsc ElfSectBytes *b;
427 fa325e9b 2020-01-10 cross
428 443d6288 2012-02-19 rsc b = v;
429 443d6288 2012-02-19 rsc e4 = h->e4;
430 443d6288 2012-02-19 rsc s->name = (char*)(uintptr)e4(b->name);
431 443d6288 2012-02-19 rsc s->type = e4(b->type);
432 443d6288 2012-02-19 rsc s->flags = e4(b->flags);
433 443d6288 2012-02-19 rsc s->addr = e4(b->addr);
434 443d6288 2012-02-19 rsc s->offset = e4(b->offset);
435 443d6288 2012-02-19 rsc s->size = e4(b->size);
436 443d6288 2012-02-19 rsc s->link = e4(b->link);
437 443d6288 2012-02-19 rsc s->info = e4(b->info);
438 443d6288 2012-02-19 rsc s->align = e4(b->align);
439 443d6288 2012-02-19 rsc s->entsize = e4(b->entsize);
440 443d6288 2012-02-19 rsc } else {
441 443d6288 2012-02-19 rsc ElfSectBytes64 *b;
442 fa325e9b 2020-01-10 cross
443 443d6288 2012-02-19 rsc b = v;
444 443d6288 2012-02-19 rsc e4 = h->e4;
445 443d6288 2012-02-19 rsc e8 = h->e8;
446 443d6288 2012-02-19 rsc s->name = (char*)(uintptr)e4(b->name);
447 443d6288 2012-02-19 rsc s->type = e4(b->type);
448 443d6288 2012-02-19 rsc s->flags = e8(b->flags);
449 443d6288 2012-02-19 rsc s->addr = e8(b->addr);
450 443d6288 2012-02-19 rsc s->offset = e8(b->offset);
451 443d6288 2012-02-19 rsc s->size = e8(b->size);
452 443d6288 2012-02-19 rsc s->link = e4(b->link);
453 443d6288 2012-02-19 rsc s->info = e4(b->info);
454 443d6288 2012-02-19 rsc s->align = e8(b->align);
455 443d6288 2012-02-19 rsc s->entsize = e8(b->entsize);
456 443d6288 2012-02-19 rsc }
457 a84cbb2a 2004-04-19 devnull }
458 a84cbb2a 2004-04-19 devnull
459 a84cbb2a 2004-04-19 devnull ElfSect*
460 a84cbb2a 2004-04-19 devnull elfsection(Elf *elf, char *name)
461 a84cbb2a 2004-04-19 devnull {
462 a84cbb2a 2004-04-19 devnull int i;
463 a84cbb2a 2004-04-19 devnull
464 a84cbb2a 2004-04-19 devnull for(i=0; i<elf->nsect; i++){
465 a84cbb2a 2004-04-19 devnull if(elf->sect[i].name == name)
466 a84cbb2a 2004-04-19 devnull return &elf->sect[i];
467 a84cbb2a 2004-04-19 devnull if(elf->sect[i].name && name
468 a84cbb2a 2004-04-19 devnull && strcmp(elf->sect[i].name, name) == 0)
469 a84cbb2a 2004-04-19 devnull return &elf->sect[i];
470 a84cbb2a 2004-04-19 devnull }
471 a84cbb2a 2004-04-19 devnull werrstr("elf section '%s' not found", name);
472 a84cbb2a 2004-04-19 devnull return nil;
473 a84cbb2a 2004-04-19 devnull }
474 a84cbb2a 2004-04-19 devnull
475 a84cbb2a 2004-04-19 devnull int
476 a84cbb2a 2004-04-19 devnull elfmap(Elf *elf, ElfSect *sect)
477 a84cbb2a 2004-04-19 devnull {
478 a84cbb2a 2004-04-19 devnull if(sect->base)
479 a84cbb2a 2004-04-19 devnull return 0;
480 a84cbb2a 2004-04-19 devnull if((sect->base = malloc(sect->size)) == nil)
481 a84cbb2a 2004-04-19 devnull return -1;
482 a84cbb2a 2004-04-19 devnull werrstr("short read");
483 a84cbb2a 2004-04-19 devnull if(seek(elf->fd, sect->offset, 0) < 0
484 a84cbb2a 2004-04-19 devnull || readn(elf->fd, sect->base, sect->size) != sect->size){
485 a84cbb2a 2004-04-19 devnull free(sect->base);
486 a84cbb2a 2004-04-19 devnull sect->base = nil;
487 a84cbb2a 2004-04-19 devnull return -1;
488 a84cbb2a 2004-04-19 devnull }
489 a84cbb2a 2004-04-19 devnull return 0;
490 a84cbb2a 2004-04-19 devnull }
491 a84cbb2a 2004-04-19 devnull
492 a84cbb2a 2004-04-19 devnull int
493 a84cbb2a 2004-04-19 devnull elfsym(Elf *elf, int i, ElfSym *sym)
494 a84cbb2a 2004-04-19 devnull {
495 a84cbb2a 2004-04-19 devnull ElfSect *symtab, *strtab;
496 a84cbb2a 2004-04-19 devnull uchar *p;
497 a84cbb2a 2004-04-19 devnull char *s;
498 a84cbb2a 2004-04-19 devnull ulong x;
499 a84cbb2a 2004-04-19 devnull
500 a84cbb2a 2004-04-19 devnull if(i < 0){
501 a84cbb2a 2004-04-19 devnull werrstr("bad index %d in elfsym", i);
502 a84cbb2a 2004-04-19 devnull return -1;
503 a84cbb2a 2004-04-19 devnull }
504 a84cbb2a 2004-04-19 devnull
505 a84cbb2a 2004-04-19 devnull if(i < elf->nsymtab){
506 a84cbb2a 2004-04-19 devnull symtab = elf->symtab;
507 a84cbb2a 2004-04-19 devnull strtab = elf->symstr;
508 a84cbb2a 2004-04-19 devnull extract:
509 a84cbb2a 2004-04-19 devnull if(elfmap(elf, symtab) < 0 || elfmap(elf, strtab) < 0)
510 a84cbb2a 2004-04-19 devnull return -1;
511 443d6288 2012-02-19 rsc if(elf->hdr.class == ElfClass32) {
512 443d6288 2012-02-19 rsc p = symtab->base + i * sizeof(ElfSymBytes);
513 443d6288 2012-02-19 rsc s = (char*)strtab->base;
514 443d6288 2012-02-19 rsc x = elf->hdr.e4(p);
515 443d6288 2012-02-19 rsc if(x >= strtab->size){
516 443d6288 2012-02-19 rsc werrstr("bad symbol name offset 0x%lux", x);
517 443d6288 2012-02-19 rsc return -1;
518 443d6288 2012-02-19 rsc }
519 443d6288 2012-02-19 rsc sym->name = s + x;
520 443d6288 2012-02-19 rsc sym->value = elf->hdr.e4(p+4);
521 443d6288 2012-02-19 rsc sym->size = elf->hdr.e4(p+8);
522 443d6288 2012-02-19 rsc x = p[12];
523 443d6288 2012-02-19 rsc sym->bind = x>>4;
524 443d6288 2012-02-19 rsc sym->type = x & 0xF;
525 443d6288 2012-02-19 rsc sym->other = p[13];
526 443d6288 2012-02-19 rsc sym->shndx = elf->hdr.e2(p+14);
527 443d6288 2012-02-19 rsc } else {
528 443d6288 2012-02-19 rsc p = symtab->base + i * sizeof(ElfSymBytes64);
529 443d6288 2012-02-19 rsc s = (char*)strtab->base;
530 443d6288 2012-02-19 rsc x = elf->hdr.e4(p);
531 443d6288 2012-02-19 rsc if(x >= strtab->size){
532 443d6288 2012-02-19 rsc werrstr("bad symbol name offset 0x%lux", x);
533 443d6288 2012-02-19 rsc return -1;
534 443d6288 2012-02-19 rsc }
535 443d6288 2012-02-19 rsc sym->name = s + x;
536 443d6288 2012-02-19 rsc x = p[4];
537 443d6288 2012-02-19 rsc sym->bind = x>>4;
538 443d6288 2012-02-19 rsc sym->type = x & 0xF;
539 443d6288 2012-02-19 rsc sym->other = p[5];
540 443d6288 2012-02-19 rsc sym->shndx = elf->hdr.e2(p+6);
541 443d6288 2012-02-19 rsc sym->value = elf->hdr.e8(p+8);
542 443d6288 2012-02-19 rsc sym->size = elf->hdr.e8(p+16);
543 a84cbb2a 2004-04-19 devnull }
544 a84cbb2a 2004-04-19 devnull return 0;
545 a84cbb2a 2004-04-19 devnull }
546 a84cbb2a 2004-04-19 devnull i -= elf->nsymtab;
547 a84cbb2a 2004-04-19 devnull if(i < elf->ndynsym){
548 a84cbb2a 2004-04-19 devnull symtab = elf->dynsym;
549 a84cbb2a 2004-04-19 devnull strtab = elf->dynstr;
550 a84cbb2a 2004-04-19 devnull goto extract;
551 a84cbb2a 2004-04-19 devnull }
552 a84cbb2a 2004-04-19 devnull /* i -= elf->ndynsym */
553 a84cbb2a 2004-04-19 devnull
554 a84cbb2a 2004-04-19 devnull werrstr("symbol index out of range");
555 a84cbb2a 2004-04-19 devnull return -1;
556 a84cbb2a 2004-04-19 devnull }