2 a84cbb2a 2004-04-19 devnull * Parse 32-bit ELF files.
3 a84cbb2a 2004-04-19 devnull * Copyright (c) 2004 Russ Cox. See LICENSE.
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"
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;
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;
21 a84cbb2a 2004-04-19 devnull struct ElfHdrBytes
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];
39 443d6288 2012-02-19 rsc struct ElfHdrBytes64
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];
57 a84cbb2a 2004-04-19 devnull struct ElfSectBytes
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];
71 443d6288 2012-02-19 rsc struct ElfSectBytes64
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];
85 a84cbb2a 2004-04-19 devnull struct ElfSymBytes
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];
95 443d6288 2012-02-19 rsc struct ElfSymBytes64
97 443d6288 2012-02-19 rsc uchar name[4];
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];
105 a84cbb2a 2004-04-19 devnull struct ElfProgBytes
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];
117 443d6288 2012-02-19 rsc struct ElfProgBytes64
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];
129 a84cbb2a 2004-04-19 devnull uchar ElfMagic[4] = { 0x7F, 'E', 'L', 'F' };
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*);
135 a84cbb2a 2004-04-19 devnull static char *elftypes[] = {
137 a84cbb2a 2004-04-19 devnull "relocatable",
138 a84cbb2a 2004-04-19 devnull "executable",
139 a84cbb2a 2004-04-19 devnull "shared object",
144 a84cbb2a 2004-04-19 devnull elftype(int t)
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];
151 a84cbb2a 2004-04-19 devnull static char *elfmachs[] = {
153 a84cbb2a 2004-04-19 devnull "32100",
154 a84cbb2a 2004-04-19 devnull "sparc",
156 a84cbb2a 2004-04-19 devnull "68000",
157 a84cbb2a 2004-04-19 devnull "88000",
164 a84cbb2a 2004-04-19 devnull elfmachine(int t)
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];
172 a84cbb2a 2004-04-19 devnull elfopen(char *name)
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;
185 a84cbb2a 2004-04-19 devnull elfinit(int fd)
189 a84cbb2a 2004-04-19 devnull ElfHdr *h;
191 443d6288 2012-02-19 rsc ElfHdrBytes h32;
192 443d6288 2012-02-19 rsc ElfHdrBytes64 h64;
195 a84cbb2a 2004-04-19 devnull ElfSect *s;
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;
203 a84cbb2a 2004-04-19 devnull * parse header
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;
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;
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;
225 a84cbb2a 2004-04-19 devnull * the prog+section info is almost always small - just load it into memory.
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);
238 a84cbb2a 2004-04-19 devnull e->nsect = h->shnum;
239 a84cbb2a 2004-04-19 devnull if(e->nsect == 0)
240 a84cbb2a 2004-04-19 devnull goto nosects;
241 a84cbb2a 2004-04-19 devnull e->sect = mallocz(sizeof(ElfSect)*e->nsect, 1);
242 443d6288 2012-02-19 rsc p = mallocz(h->shentsize, 1);
243 a84cbb2a 2004-04-19 devnull for(i=0; i<e->nsect; i++){
244 a84cbb2a 2004-04-19 devnull if(seek(fd, h->shoff+i*h->shentsize, 0) < 0
245 443d6288 2012-02-19 rsc || readn(fd, p, h->shentsize) != h->shentsize)
246 a84cbb2a 2004-04-19 devnull goto err;
247 443d6288 2012-02-19 rsc unpacksect(h, &e->sect[i], p);
251 a84cbb2a 2004-04-19 devnull if(h->shstrndx >= e->nsect){
252 a84cbb2a 2004-04-19 devnull fprint(2, "warning: bad string section index %d >= %d", h->shstrndx, e->nsect);
253 a84cbb2a 2004-04-19 devnull h->shnum = 0;
254 a84cbb2a 2004-04-19 devnull e->nsect = 0;
255 a84cbb2a 2004-04-19 devnull goto nosects;
257 a84cbb2a 2004-04-19 devnull s = &e->sect[h->shstrndx];
258 a84cbb2a 2004-04-19 devnull if(elfmap(e, s) < 0)
259 a84cbb2a 2004-04-19 devnull goto err;
261 a84cbb2a 2004-04-19 devnull for(i=0; i<e->nsect; i++)
262 a84cbb2a 2004-04-19 devnull if(e->sect[i].name)
263 929ba9b9 2004-04-20 devnull e->sect[i].name = (char*)s->base + (ulong)e->sect[i].name;
265 a84cbb2a 2004-04-19 devnull e->symtab = elfsection(e, ".symtab");
266 a84cbb2a 2004-04-19 devnull if(e->symtab){
267 a84cbb2a 2004-04-19 devnull if(e->symtab->link >= e->nsect)
268 a84cbb2a 2004-04-19 devnull e->symtab = nil;
270 a84cbb2a 2004-04-19 devnull e->symstr = &e->sect[e->symtab->link];
271 a84cbb2a 2004-04-19 devnull e->nsymtab = e->symtab->size / sizeof(ElfSymBytes);
274 a84cbb2a 2004-04-19 devnull e->dynsym = elfsection(e, ".dynsym");
275 a84cbb2a 2004-04-19 devnull if(e->dynsym){
276 a84cbb2a 2004-04-19 devnull if(e->dynsym->link >= e->nsect)
277 a84cbb2a 2004-04-19 devnull e->dynsym = nil;
279 a84cbb2a 2004-04-19 devnull e->dynstr = &e->sect[e->dynsym->link];
280 a84cbb2a 2004-04-19 devnull e->ndynsym = e->dynsym->size / sizeof(ElfSymBytes);
284 a84cbb2a 2004-04-19 devnull e->bss = elfsection(e, ".bss");
286 a84cbb2a 2004-04-19 devnull nosects:
287 a84cbb2a 2004-04-19 devnull return e;
290 a84cbb2a 2004-04-19 devnull free(e->sect);
291 a84cbb2a 2004-04-19 devnull free(e->prog);
292 a84cbb2a 2004-04-19 devnull free(e->shstrtab);
293 a84cbb2a 2004-04-19 devnull free(e);
294 a84cbb2a 2004-04-19 devnull return nil;
298 a84cbb2a 2004-04-19 devnull elfclose(Elf *elf)
302 a84cbb2a 2004-04-19 devnull for(i=0; i<elf->nsect; i++)
303 a84cbb2a 2004-04-19 devnull free(elf->sect[i].base);
304 a84cbb2a 2004-04-19 devnull free(elf->sect);
305 a84cbb2a 2004-04-19 devnull free(elf->prog);
306 a84cbb2a 2004-04-19 devnull free(elf->shstrtab);
307 a84cbb2a 2004-04-19 devnull free(elf);
310 a84cbb2a 2004-04-19 devnull static void
311 443d6288 2012-02-19 rsc unpackhdr(ElfHdr *h, void *v)
313 a84cbb2a 2004-04-19 devnull u16int (*e2)(uchar*);
314 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
315 a84cbb2a 2004-04-19 devnull u64int (*e8)(uchar*);
316 443d6288 2012-02-19 rsc ElfHdrBytes *b;
317 443d6288 2012-02-19 rsc ElfHdrBytes64 *b64;
320 a84cbb2a 2004-04-19 devnull memmove(h->magic, b->ident, 4);
321 a84cbb2a 2004-04-19 devnull h->class = b->ident[4];
322 a84cbb2a 2004-04-19 devnull h->encoding = b->ident[5];
323 a84cbb2a 2004-04-19 devnull switch(h->encoding){
324 a84cbb2a 2004-04-19 devnull case ElfDataLsb:
325 a84cbb2a 2004-04-19 devnull e2 = leload2;
326 a84cbb2a 2004-04-19 devnull e4 = leload4;
327 a84cbb2a 2004-04-19 devnull e8 = leload8;
329 a84cbb2a 2004-04-19 devnull case ElfDataMsb:
330 a84cbb2a 2004-04-19 devnull e2 = beload2;
331 a84cbb2a 2004-04-19 devnull e4 = beload4;
332 a84cbb2a 2004-04-19 devnull e8 = beload8;
334 a84cbb2a 2004-04-19 devnull default:
337 a84cbb2a 2004-04-19 devnull h->abi = b->ident[7];
338 a84cbb2a 2004-04-19 devnull h->abiversion = b->ident[8];
340 a84cbb2a 2004-04-19 devnull h->e2 = e2;
341 a84cbb2a 2004-04-19 devnull h->e4 = e4;
342 a84cbb2a 2004-04-19 devnull h->e8 = e8;
344 443d6288 2012-02-19 rsc if(h->class == ElfClass64)
347 a84cbb2a 2004-04-19 devnull h->type = e2(b->type);
348 a84cbb2a 2004-04-19 devnull h->machine = e2(b->machine);
349 a84cbb2a 2004-04-19 devnull h->version = e4(b->version);
350 a84cbb2a 2004-04-19 devnull h->entry = e4(b->entry);
351 a84cbb2a 2004-04-19 devnull h->phoff = e4(b->phoff);
352 a84cbb2a 2004-04-19 devnull h->shoff = e4(b->shoff);
353 a84cbb2a 2004-04-19 devnull h->flags = e4(b->flags);
354 a84cbb2a 2004-04-19 devnull h->ehsize = e2(b->ehsize);
355 a84cbb2a 2004-04-19 devnull h->phentsize = e2(b->phentsize);
356 a84cbb2a 2004-04-19 devnull h->phnum = e2(b->phnum);
357 a84cbb2a 2004-04-19 devnull h->shentsize = e2(b->shentsize);
358 a84cbb2a 2004-04-19 devnull h->shnum = e2(b->shnum);
359 a84cbb2a 2004-04-19 devnull h->shstrndx = e2(b->shstrndx);
364 443d6288 2012-02-19 rsc h->type = e2(b64->type);
365 443d6288 2012-02-19 rsc h->machine = e2(b64->machine);
366 443d6288 2012-02-19 rsc h->version = e4(b64->version);
367 443d6288 2012-02-19 rsc h->entry = e8(b64->entry);
368 443d6288 2012-02-19 rsc h->phoff = e8(b64->phoff);
369 443d6288 2012-02-19 rsc h->shoff = e8(b64->shoff);
370 443d6288 2012-02-19 rsc h->flags = e4(b64->flags);
371 443d6288 2012-02-19 rsc h->ehsize = e2(b64->ehsize);
372 443d6288 2012-02-19 rsc h->phentsize = e2(b64->phentsize);
373 443d6288 2012-02-19 rsc h->phnum = e2(b64->phnum);
374 443d6288 2012-02-19 rsc h->shentsize = e2(b64->shentsize);
375 443d6288 2012-02-19 rsc h->shnum = e2(b64->shnum);
376 443d6288 2012-02-19 rsc h->shstrndx = e2(b64->shstrndx);
380 a84cbb2a 2004-04-19 devnull static void
381 443d6288 2012-02-19 rsc unpackprog(ElfHdr *h, ElfProg *p, void *v)
383 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
384 443d6288 2012-02-19 rsc u64int (*e8)(uchar*);
386 443d6288 2012-02-19 rsc if(h->class == ElfClass32) {
387 443d6288 2012-02-19 rsc ElfProgBytes *b;
391 443d6288 2012-02-19 rsc p->type = e4(b->type);
392 443d6288 2012-02-19 rsc p->offset = e4(b->offset);
393 443d6288 2012-02-19 rsc p->vaddr = e4(b->vaddr);
394 443d6288 2012-02-19 rsc p->paddr = e4(b->paddr);
395 443d6288 2012-02-19 rsc p->filesz = e4(b->filesz);
396 443d6288 2012-02-19 rsc p->memsz = e4(b->memsz);
397 443d6288 2012-02-19 rsc p->flags = e4(b->flags);
398 443d6288 2012-02-19 rsc p->align = e4(b->align);
400 443d6288 2012-02-19 rsc ElfProgBytes64 *b;
405 443d6288 2012-02-19 rsc p->type = e4(b->type);
406 443d6288 2012-02-19 rsc p->offset = e8(b->offset);
407 443d6288 2012-02-19 rsc p->vaddr = e8(b->vaddr);
408 443d6288 2012-02-19 rsc p->paddr = e8(b->paddr);
409 443d6288 2012-02-19 rsc p->filesz = e8(b->filesz);
410 443d6288 2012-02-19 rsc p->memsz = e8(b->memsz);
411 443d6288 2012-02-19 rsc p->flags = e4(b->flags);
412 443d6288 2012-02-19 rsc p->align = e8(b->align);
416 a84cbb2a 2004-04-19 devnull static void
417 443d6288 2012-02-19 rsc unpacksect(ElfHdr *h, ElfSect *s, void *v)
419 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
420 443d6288 2012-02-19 rsc u64int (*e8)(uchar*);
422 443d6288 2012-02-19 rsc if(h->class == ElfClass32) {
423 443d6288 2012-02-19 rsc ElfSectBytes *b;
427 443d6288 2012-02-19 rsc s->name = (char*)(uintptr)e4(b->name);
428 443d6288 2012-02-19 rsc s->type = e4(b->type);
429 443d6288 2012-02-19 rsc s->flags = e4(b->flags);
430 443d6288 2012-02-19 rsc s->addr = e4(b->addr);
431 443d6288 2012-02-19 rsc s->offset = e4(b->offset);
432 443d6288 2012-02-19 rsc s->size = e4(b->size);
433 443d6288 2012-02-19 rsc s->link = e4(b->link);
434 443d6288 2012-02-19 rsc s->info = e4(b->info);
435 443d6288 2012-02-19 rsc s->align = e4(b->align);
436 443d6288 2012-02-19 rsc s->entsize = e4(b->entsize);
438 443d6288 2012-02-19 rsc ElfSectBytes64 *b;
443 443d6288 2012-02-19 rsc s->name = (char*)(uintptr)e4(b->name);
444 443d6288 2012-02-19 rsc s->type = e4(b->type);
445 443d6288 2012-02-19 rsc s->flags = e8(b->flags);
446 443d6288 2012-02-19 rsc s->addr = e8(b->addr);
447 443d6288 2012-02-19 rsc s->offset = e8(b->offset);
448 443d6288 2012-02-19 rsc s->size = e8(b->size);
449 443d6288 2012-02-19 rsc s->link = e4(b->link);
450 443d6288 2012-02-19 rsc s->info = e4(b->info);
451 443d6288 2012-02-19 rsc s->align = e8(b->align);
452 443d6288 2012-02-19 rsc s->entsize = e8(b->entsize);
456 a84cbb2a 2004-04-19 devnull ElfSect*
457 a84cbb2a 2004-04-19 devnull elfsection(Elf *elf, char *name)
461 a84cbb2a 2004-04-19 devnull for(i=0; i<elf->nsect; i++){
462 a84cbb2a 2004-04-19 devnull if(elf->sect[i].name == name)
463 a84cbb2a 2004-04-19 devnull return &elf->sect[i];
464 a84cbb2a 2004-04-19 devnull if(elf->sect[i].name && name
465 a84cbb2a 2004-04-19 devnull && strcmp(elf->sect[i].name, name) == 0)
466 a84cbb2a 2004-04-19 devnull return &elf->sect[i];
468 a84cbb2a 2004-04-19 devnull werrstr("elf section '%s' not found", name);
469 a84cbb2a 2004-04-19 devnull return nil;
473 a84cbb2a 2004-04-19 devnull elfmap(Elf *elf, ElfSect *sect)
475 a84cbb2a 2004-04-19 devnull if(sect->base)
476 a84cbb2a 2004-04-19 devnull return 0;
477 a84cbb2a 2004-04-19 devnull if((sect->base = malloc(sect->size)) == nil)
478 a84cbb2a 2004-04-19 devnull return -1;
479 a84cbb2a 2004-04-19 devnull werrstr("short read");
480 a84cbb2a 2004-04-19 devnull if(seek(elf->fd, sect->offset, 0) < 0
481 a84cbb2a 2004-04-19 devnull || readn(elf->fd, sect->base, sect->size) != sect->size){
482 a84cbb2a 2004-04-19 devnull free(sect->base);
483 a84cbb2a 2004-04-19 devnull sect->base = nil;
484 a84cbb2a 2004-04-19 devnull return -1;
486 a84cbb2a 2004-04-19 devnull return 0;
490 a84cbb2a 2004-04-19 devnull elfsym(Elf *elf, int i, ElfSym *sym)
492 a84cbb2a 2004-04-19 devnull ElfSect *symtab, *strtab;
493 a84cbb2a 2004-04-19 devnull uchar *p;
494 a84cbb2a 2004-04-19 devnull char *s;
495 a84cbb2a 2004-04-19 devnull ulong x;
497 a84cbb2a 2004-04-19 devnull if(i < 0){
498 a84cbb2a 2004-04-19 devnull werrstr("bad index %d in elfsym", i);
499 a84cbb2a 2004-04-19 devnull return -1;
502 a84cbb2a 2004-04-19 devnull if(i < elf->nsymtab){
503 a84cbb2a 2004-04-19 devnull symtab = elf->symtab;
504 a84cbb2a 2004-04-19 devnull strtab = elf->symstr;
505 a84cbb2a 2004-04-19 devnull extract:
506 a84cbb2a 2004-04-19 devnull if(elfmap(elf, symtab) < 0 || elfmap(elf, strtab) < 0)
507 a84cbb2a 2004-04-19 devnull return -1;
508 443d6288 2012-02-19 rsc if(elf->hdr.class == ElfClass32) {
509 443d6288 2012-02-19 rsc p = symtab->base + i * sizeof(ElfSymBytes);
510 443d6288 2012-02-19 rsc s = (char*)strtab->base;
511 443d6288 2012-02-19 rsc x = elf->hdr.e4(p);
512 443d6288 2012-02-19 rsc if(x >= strtab->size){
513 443d6288 2012-02-19 rsc werrstr("bad symbol name offset 0x%lux", x);
516 443d6288 2012-02-19 rsc sym->name = s + x;
517 443d6288 2012-02-19 rsc sym->value = elf->hdr.e4(p+4);
518 443d6288 2012-02-19 rsc sym->size = elf->hdr.e4(p+8);
520 443d6288 2012-02-19 rsc sym->bind = x>>4;
521 443d6288 2012-02-19 rsc sym->type = x & 0xF;
522 443d6288 2012-02-19 rsc sym->other = p[13];
523 443d6288 2012-02-19 rsc sym->shndx = elf->hdr.e2(p+14);
525 443d6288 2012-02-19 rsc p = symtab->base + i * sizeof(ElfSymBytes64);
526 443d6288 2012-02-19 rsc s = (char*)strtab->base;
527 443d6288 2012-02-19 rsc x = elf->hdr.e4(p);
528 443d6288 2012-02-19 rsc if(x >= strtab->size){
529 443d6288 2012-02-19 rsc werrstr("bad symbol name offset 0x%lux", x);
532 443d6288 2012-02-19 rsc sym->name = s + x;
534 443d6288 2012-02-19 rsc sym->bind = x>>4;
535 443d6288 2012-02-19 rsc sym->type = x & 0xF;
536 443d6288 2012-02-19 rsc sym->other = p[5];
537 443d6288 2012-02-19 rsc sym->shndx = elf->hdr.e2(p+6);
538 443d6288 2012-02-19 rsc sym->value = elf->hdr.e8(p+8);
539 443d6288 2012-02-19 rsc sym->size = elf->hdr.e8(p+16);
541 a84cbb2a 2004-04-19 devnull return 0;
543 a84cbb2a 2004-04-19 devnull i -= elf->nsymtab;
544 a84cbb2a 2004-04-19 devnull if(i < elf->ndynsym){
545 a84cbb2a 2004-04-19 devnull symtab = elf->dynsym;
546 a84cbb2a 2004-04-19 devnull strtab = elf->dynstr;
547 a84cbb2a 2004-04-19 devnull goto extract;
549 a84cbb2a 2004-04-19 devnull /* i -= elf->ndynsym */
551 a84cbb2a 2004-04-19 devnull werrstr("symbol index out of range");
552 a84cbb2a 2004-04-19 devnull return -1;