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 a84cbb2a 2004-04-19 devnull struct ElfHdrBytes
17 a84cbb2a 2004-04-19 devnull {
18 a84cbb2a 2004-04-19 devnull uchar ident[16];
19 a84cbb2a 2004-04-19 devnull uchar type[2];
20 a84cbb2a 2004-04-19 devnull uchar machine[2];
21 a84cbb2a 2004-04-19 devnull uchar version[4];
22 a84cbb2a 2004-04-19 devnull uchar entry[4];
23 a84cbb2a 2004-04-19 devnull uchar phoff[4];
24 a84cbb2a 2004-04-19 devnull uchar shoff[4];
25 a84cbb2a 2004-04-19 devnull uchar flags[4];
26 a84cbb2a 2004-04-19 devnull uchar ehsize[2];
27 a84cbb2a 2004-04-19 devnull uchar phentsize[2];
28 a84cbb2a 2004-04-19 devnull uchar phnum[2];
29 a84cbb2a 2004-04-19 devnull uchar shentsize[2];
30 a84cbb2a 2004-04-19 devnull uchar shnum[2];
31 a84cbb2a 2004-04-19 devnull uchar shstrndx[2];
32 a84cbb2a 2004-04-19 devnull };
33 a84cbb2a 2004-04-19 devnull
34 a84cbb2a 2004-04-19 devnull struct ElfSectBytes
35 a84cbb2a 2004-04-19 devnull {
36 a84cbb2a 2004-04-19 devnull uchar name[4];
37 a84cbb2a 2004-04-19 devnull uchar type[4];
38 a84cbb2a 2004-04-19 devnull uchar flags[4];
39 a84cbb2a 2004-04-19 devnull uchar addr[4];
40 a84cbb2a 2004-04-19 devnull uchar offset[4];
41 a84cbb2a 2004-04-19 devnull uchar size[4];
42 a84cbb2a 2004-04-19 devnull uchar link[4];
43 a84cbb2a 2004-04-19 devnull uchar info[4];
44 a84cbb2a 2004-04-19 devnull uchar align[4];
45 a84cbb2a 2004-04-19 devnull uchar entsize[4];
46 a84cbb2a 2004-04-19 devnull };
47 a84cbb2a 2004-04-19 devnull
48 a84cbb2a 2004-04-19 devnull struct ElfSymBytes
49 a84cbb2a 2004-04-19 devnull {
50 a84cbb2a 2004-04-19 devnull uchar name[4];
51 a84cbb2a 2004-04-19 devnull uchar value[4];
52 a84cbb2a 2004-04-19 devnull uchar size[4];
53 a84cbb2a 2004-04-19 devnull uchar info; /* top4: bind, bottom4: type */
54 a84cbb2a 2004-04-19 devnull uchar other;
55 a84cbb2a 2004-04-19 devnull uchar shndx[2];
56 a84cbb2a 2004-04-19 devnull };
57 a84cbb2a 2004-04-19 devnull
58 a84cbb2a 2004-04-19 devnull struct ElfProgBytes
59 a84cbb2a 2004-04-19 devnull {
60 a84cbb2a 2004-04-19 devnull uchar type[4];
61 a84cbb2a 2004-04-19 devnull uchar offset[4];
62 a84cbb2a 2004-04-19 devnull uchar vaddr[4];
63 a84cbb2a 2004-04-19 devnull uchar paddr[4];
64 a84cbb2a 2004-04-19 devnull uchar filesz[4];
65 a84cbb2a 2004-04-19 devnull uchar memsz[4];
66 a84cbb2a 2004-04-19 devnull uchar flags[4];
67 a84cbb2a 2004-04-19 devnull uchar align[4];
68 a84cbb2a 2004-04-19 devnull };
69 a84cbb2a 2004-04-19 devnull
70 a84cbb2a 2004-04-19 devnull uchar ElfMagic[4] = { 0x7F, 'E', 'L', 'F' };
71 a84cbb2a 2004-04-19 devnull
72 a84cbb2a 2004-04-19 devnull static void unpackhdr(ElfHdr*, ElfHdrBytes*);
73 a84cbb2a 2004-04-19 devnull static void unpackprog(ElfHdr*, ElfProg*, ElfProgBytes*);
74 a84cbb2a 2004-04-19 devnull static void unpacksect(ElfHdr*, ElfSect*, ElfSectBytes*);
75 a84cbb2a 2004-04-19 devnull
76 a84cbb2a 2004-04-19 devnull static char *elftypes[] = {
77 a84cbb2a 2004-04-19 devnull "none",
78 a84cbb2a 2004-04-19 devnull "relocatable",
79 a84cbb2a 2004-04-19 devnull "executable",
80 a84cbb2a 2004-04-19 devnull "shared object",
81 a84cbb2a 2004-04-19 devnull "core",
82 a84cbb2a 2004-04-19 devnull };
83 a84cbb2a 2004-04-19 devnull
84 a84cbb2a 2004-04-19 devnull char*
85 a84cbb2a 2004-04-19 devnull elftype(int t)
86 a84cbb2a 2004-04-19 devnull {
87 a84cbb2a 2004-04-19 devnull if(t < 0 || t >= nelem(elftypes))
88 a84cbb2a 2004-04-19 devnull return "unknown";
89 a84cbb2a 2004-04-19 devnull return elftypes[t];
90 a84cbb2a 2004-04-19 devnull }
91 a84cbb2a 2004-04-19 devnull
92 a84cbb2a 2004-04-19 devnull static char *elfmachs[] = {
93 a84cbb2a 2004-04-19 devnull "none",
94 a84cbb2a 2004-04-19 devnull "32100",
95 a84cbb2a 2004-04-19 devnull "sparc",
96 a84cbb2a 2004-04-19 devnull "386",
97 a84cbb2a 2004-04-19 devnull "68000",
98 a84cbb2a 2004-04-19 devnull "88000",
99 a84cbb2a 2004-04-19 devnull "486",
100 a84cbb2a 2004-04-19 devnull "860",
101 a84cbb2a 2004-04-19 devnull "MIPS",
102 a84cbb2a 2004-04-19 devnull };
103 a84cbb2a 2004-04-19 devnull
104 a84cbb2a 2004-04-19 devnull char*
105 a84cbb2a 2004-04-19 devnull elfmachine(int t)
106 a84cbb2a 2004-04-19 devnull {
107 a84cbb2a 2004-04-19 devnull if(t < 0 || t >= nelem(elfmachs))
108 a84cbb2a 2004-04-19 devnull return "unknown";
109 a84cbb2a 2004-04-19 devnull return elfmachs[t];
110 a84cbb2a 2004-04-19 devnull }
111 a84cbb2a 2004-04-19 devnull
112 a84cbb2a 2004-04-19 devnull Elf*
113 a84cbb2a 2004-04-19 devnull elfopen(char *name)
114 a84cbb2a 2004-04-19 devnull {
115 a84cbb2a 2004-04-19 devnull int fd;
116 a84cbb2a 2004-04-19 devnull Elf *e;
117 a84cbb2a 2004-04-19 devnull
118 a84cbb2a 2004-04-19 devnull if((fd = open(name, OREAD)) < 0)
119 a84cbb2a 2004-04-19 devnull return nil;
120 a84cbb2a 2004-04-19 devnull if((e = elfinit(fd)) == nil)
121 a84cbb2a 2004-04-19 devnull close(fd);
122 a84cbb2a 2004-04-19 devnull return e;
123 a84cbb2a 2004-04-19 devnull }
124 a84cbb2a 2004-04-19 devnull
125 a84cbb2a 2004-04-19 devnull Elf*
126 a84cbb2a 2004-04-19 devnull elfinit(int fd)
127 a84cbb2a 2004-04-19 devnull {
128 a84cbb2a 2004-04-19 devnull int i;
129 a84cbb2a 2004-04-19 devnull Elf *e;
130 a84cbb2a 2004-04-19 devnull ElfHdr *h;
131 a84cbb2a 2004-04-19 devnull ElfHdrBytes hdrb;
132 a84cbb2a 2004-04-19 devnull ElfProgBytes progb;
133 a84cbb2a 2004-04-19 devnull ElfSectBytes sectb;
134 a84cbb2a 2004-04-19 devnull ElfSect *s;
135 a84cbb2a 2004-04-19 devnull
136 a84cbb2a 2004-04-19 devnull e = mallocz(sizeof(Elf), 1);
137 a84cbb2a 2004-04-19 devnull if(e == nil)
138 a84cbb2a 2004-04-19 devnull return nil;
139 a84cbb2a 2004-04-19 devnull e->fd = fd;
140 a84cbb2a 2004-04-19 devnull
141 a84cbb2a 2004-04-19 devnull /*
142 a84cbb2a 2004-04-19 devnull * parse header
143 a84cbb2a 2004-04-19 devnull */
144 a84cbb2a 2004-04-19 devnull seek(fd, 0, 0);
145 a84cbb2a 2004-04-19 devnull if(readn(fd, &hdrb, sizeof hdrb) != sizeof hdrb)
146 a84cbb2a 2004-04-19 devnull goto err;
147 a84cbb2a 2004-04-19 devnull h = &e->hdr;
148 a84cbb2a 2004-04-19 devnull unpackhdr(h, &hdrb);
149 a84cbb2a 2004-04-19 devnull if(h->class != ElfClass32){
150 a84cbb2a 2004-04-19 devnull werrstr("bad ELF class - not 32-bit");
151 a84cbb2a 2004-04-19 devnull goto err;
152 a84cbb2a 2004-04-19 devnull }
153 a84cbb2a 2004-04-19 devnull if(h->encoding != ElfDataLsb && h->encoding != ElfDataMsb){
154 a84cbb2a 2004-04-19 devnull werrstr("bad ELF encoding - not LSB, MSB");
155 a84cbb2a 2004-04-19 devnull goto err;
156 a84cbb2a 2004-04-19 devnull }
157 a84cbb2a 2004-04-19 devnull if(hdrb.ident[6] != h->version){
158 a84cbb2a 2004-04-19 devnull werrstr("bad ELF encoding - version mismatch %02ux and %08ux",
159 a84cbb2a 2004-04-19 devnull (uint)hdrb.ident[6], (uint)h->version);
160 a84cbb2a 2004-04-19 devnull goto err;
161 a84cbb2a 2004-04-19 devnull }
162 a84cbb2a 2004-04-19 devnull
163 a84cbb2a 2004-04-19 devnull /*
164 a84cbb2a 2004-04-19 devnull * the prog+section info is almost always small - just load it into memory.
165 a84cbb2a 2004-04-19 devnull */
166 a84cbb2a 2004-04-19 devnull e->nprog = h->phnum;
167 a84cbb2a 2004-04-19 devnull e->prog = mallocz(sizeof(ElfProg)*e->nprog, 1);
168 a84cbb2a 2004-04-19 devnull for(i=0; i<e->nprog; i++){
169 a84cbb2a 2004-04-19 devnull if(seek(fd, h->phoff+i*h->phentsize, 0) < 0
170 a84cbb2a 2004-04-19 devnull || readn(fd, &progb, sizeof progb) != sizeof progb)
171 a84cbb2a 2004-04-19 devnull goto err;
172 a84cbb2a 2004-04-19 devnull unpackprog(h, &e->prog[i], &progb);
173 a84cbb2a 2004-04-19 devnull }
174 a84cbb2a 2004-04-19 devnull
175 a84cbb2a 2004-04-19 devnull e->nsect = h->shnum;
176 a84cbb2a 2004-04-19 devnull if(e->nsect == 0)
177 a84cbb2a 2004-04-19 devnull goto nosects;
178 a84cbb2a 2004-04-19 devnull e->sect = mallocz(sizeof(ElfSect)*e->nsect, 1);
179 a84cbb2a 2004-04-19 devnull for(i=0; i<e->nsect; i++){
180 a84cbb2a 2004-04-19 devnull if(seek(fd, h->shoff+i*h->shentsize, 0) < 0
181 a84cbb2a 2004-04-19 devnull || readn(fd, &sectb, sizeof sectb) != sizeof sectb)
182 a84cbb2a 2004-04-19 devnull goto err;
183 a84cbb2a 2004-04-19 devnull unpacksect(h, &e->sect[i], &sectb);
184 a84cbb2a 2004-04-19 devnull }
185 a84cbb2a 2004-04-19 devnull
186 a84cbb2a 2004-04-19 devnull if(h->shstrndx >= e->nsect){
187 a84cbb2a 2004-04-19 devnull fprint(2, "warning: bad string section index %d >= %d", h->shstrndx, e->nsect);
188 a84cbb2a 2004-04-19 devnull h->shnum = 0;
189 a84cbb2a 2004-04-19 devnull e->nsect = 0;
190 a84cbb2a 2004-04-19 devnull goto nosects;
191 a84cbb2a 2004-04-19 devnull }
192 a84cbb2a 2004-04-19 devnull s = &e->sect[h->shstrndx];
193 a84cbb2a 2004-04-19 devnull if(elfmap(e, s) < 0)
194 a84cbb2a 2004-04-19 devnull goto err;
195 a84cbb2a 2004-04-19 devnull
196 a84cbb2a 2004-04-19 devnull for(i=0; i<e->nsect; i++)
197 a84cbb2a 2004-04-19 devnull if(e->sect[i].name)
198 929ba9b9 2004-04-20 devnull e->sect[i].name = (char*)s->base + (ulong)e->sect[i].name;
199 a84cbb2a 2004-04-19 devnull
200 a84cbb2a 2004-04-19 devnull e->symtab = elfsection(e, ".symtab");
201 a84cbb2a 2004-04-19 devnull if(e->symtab){
202 a84cbb2a 2004-04-19 devnull if(e->symtab->link >= e->nsect)
203 a84cbb2a 2004-04-19 devnull e->symtab = nil;
204 a84cbb2a 2004-04-19 devnull else{
205 a84cbb2a 2004-04-19 devnull e->symstr = &e->sect[e->symtab->link];
206 a84cbb2a 2004-04-19 devnull e->nsymtab = e->symtab->size / sizeof(ElfSymBytes);
207 a84cbb2a 2004-04-19 devnull }
208 a84cbb2a 2004-04-19 devnull }
209 a84cbb2a 2004-04-19 devnull e->dynsym = elfsection(e, ".dynsym");
210 a84cbb2a 2004-04-19 devnull if(e->dynsym){
211 a84cbb2a 2004-04-19 devnull if(e->dynsym->link >= e->nsect)
212 a84cbb2a 2004-04-19 devnull e->dynsym = nil;
213 a84cbb2a 2004-04-19 devnull else{
214 a84cbb2a 2004-04-19 devnull e->dynstr = &e->sect[e->dynsym->link];
215 a84cbb2a 2004-04-19 devnull e->ndynsym = e->dynsym->size / sizeof(ElfSymBytes);
216 a84cbb2a 2004-04-19 devnull }
217 a84cbb2a 2004-04-19 devnull }
218 a84cbb2a 2004-04-19 devnull
219 a84cbb2a 2004-04-19 devnull e->bss = elfsection(e, ".bss");
220 a84cbb2a 2004-04-19 devnull
221 a84cbb2a 2004-04-19 devnull nosects:
222 a84cbb2a 2004-04-19 devnull return e;
223 a84cbb2a 2004-04-19 devnull
224 a84cbb2a 2004-04-19 devnull err:
225 a84cbb2a 2004-04-19 devnull free(e->sect);
226 a84cbb2a 2004-04-19 devnull free(e->prog);
227 a84cbb2a 2004-04-19 devnull free(e->shstrtab);
228 a84cbb2a 2004-04-19 devnull free(e);
229 a84cbb2a 2004-04-19 devnull return nil;
230 a84cbb2a 2004-04-19 devnull }
231 a84cbb2a 2004-04-19 devnull
232 a84cbb2a 2004-04-19 devnull void
233 a84cbb2a 2004-04-19 devnull elfclose(Elf *elf)
234 a84cbb2a 2004-04-19 devnull {
235 a84cbb2a 2004-04-19 devnull int i;
236 a84cbb2a 2004-04-19 devnull
237 a84cbb2a 2004-04-19 devnull for(i=0; i<elf->nsect; i++)
238 a84cbb2a 2004-04-19 devnull free(elf->sect[i].base);
239 a84cbb2a 2004-04-19 devnull free(elf->sect);
240 a84cbb2a 2004-04-19 devnull free(elf->prog);
241 a84cbb2a 2004-04-19 devnull free(elf->shstrtab);
242 a84cbb2a 2004-04-19 devnull free(elf);
243 a84cbb2a 2004-04-19 devnull }
244 a84cbb2a 2004-04-19 devnull
245 a84cbb2a 2004-04-19 devnull static void
246 a84cbb2a 2004-04-19 devnull unpackhdr(ElfHdr *h, ElfHdrBytes *b)
247 a84cbb2a 2004-04-19 devnull {
248 a84cbb2a 2004-04-19 devnull u16int (*e2)(uchar*);
249 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
250 a84cbb2a 2004-04-19 devnull u64int (*e8)(uchar*);
251 a84cbb2a 2004-04-19 devnull
252 a84cbb2a 2004-04-19 devnull memmove(h->magic, b->ident, 4);
253 a84cbb2a 2004-04-19 devnull h->class = b->ident[4];
254 a84cbb2a 2004-04-19 devnull h->encoding = b->ident[5];
255 a84cbb2a 2004-04-19 devnull switch(h->encoding){
256 a84cbb2a 2004-04-19 devnull case ElfDataLsb:
257 a84cbb2a 2004-04-19 devnull e2 = leload2;
258 a84cbb2a 2004-04-19 devnull e4 = leload4;
259 a84cbb2a 2004-04-19 devnull e8 = leload8;
260 a84cbb2a 2004-04-19 devnull break;
261 a84cbb2a 2004-04-19 devnull case ElfDataMsb:
262 a84cbb2a 2004-04-19 devnull e2 = beload2;
263 a84cbb2a 2004-04-19 devnull e4 = beload4;
264 a84cbb2a 2004-04-19 devnull e8 = beload8;
265 a84cbb2a 2004-04-19 devnull break;
266 a84cbb2a 2004-04-19 devnull default:
267 a84cbb2a 2004-04-19 devnull return;
268 a84cbb2a 2004-04-19 devnull }
269 a84cbb2a 2004-04-19 devnull h->abi = b->ident[7];
270 a84cbb2a 2004-04-19 devnull h->abiversion = b->ident[8];
271 a84cbb2a 2004-04-19 devnull
272 a84cbb2a 2004-04-19 devnull h->e2 = e2;
273 a84cbb2a 2004-04-19 devnull h->e4 = e4;
274 a84cbb2a 2004-04-19 devnull h->e8 = e8;
275 a84cbb2a 2004-04-19 devnull
276 a84cbb2a 2004-04-19 devnull h->type = e2(b->type);
277 a84cbb2a 2004-04-19 devnull h->machine = e2(b->machine);
278 a84cbb2a 2004-04-19 devnull h->version = e4(b->version);
279 a84cbb2a 2004-04-19 devnull h->entry = e4(b->entry);
280 a84cbb2a 2004-04-19 devnull h->phoff = e4(b->phoff);
281 a84cbb2a 2004-04-19 devnull h->shoff = e4(b->shoff);
282 a84cbb2a 2004-04-19 devnull h->flags = e4(b->flags);
283 a84cbb2a 2004-04-19 devnull h->ehsize = e2(b->ehsize);
284 a84cbb2a 2004-04-19 devnull h->phentsize = e2(b->phentsize);
285 a84cbb2a 2004-04-19 devnull h->phnum = e2(b->phnum);
286 a84cbb2a 2004-04-19 devnull h->shentsize = e2(b->shentsize);
287 a84cbb2a 2004-04-19 devnull h->shnum = e2(b->shnum);
288 a84cbb2a 2004-04-19 devnull h->shstrndx = e2(b->shstrndx);
289 a84cbb2a 2004-04-19 devnull }
290 a84cbb2a 2004-04-19 devnull
291 a84cbb2a 2004-04-19 devnull static void
292 a84cbb2a 2004-04-19 devnull unpackprog(ElfHdr *h, ElfProg *p, ElfProgBytes *b)
293 a84cbb2a 2004-04-19 devnull {
294 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
295 a84cbb2a 2004-04-19 devnull
296 a84cbb2a 2004-04-19 devnull e4 = h->e4;
297 a84cbb2a 2004-04-19 devnull p->type = e4(b->type);
298 a84cbb2a 2004-04-19 devnull p->offset = e4(b->offset);
299 a84cbb2a 2004-04-19 devnull p->vaddr = e4(b->vaddr);
300 a84cbb2a 2004-04-19 devnull p->paddr = e4(b->paddr);
301 a84cbb2a 2004-04-19 devnull p->filesz = e4(b->filesz);
302 a84cbb2a 2004-04-19 devnull p->memsz = e4(b->memsz);
303 a84cbb2a 2004-04-19 devnull p->flags = e4(b->flags);
304 a84cbb2a 2004-04-19 devnull p->align = e4(b->align);
305 a84cbb2a 2004-04-19 devnull }
306 a84cbb2a 2004-04-19 devnull
307 a84cbb2a 2004-04-19 devnull static void
308 a84cbb2a 2004-04-19 devnull unpacksect(ElfHdr *h, ElfSect *s, ElfSectBytes *b)
309 a84cbb2a 2004-04-19 devnull {
310 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
311 a84cbb2a 2004-04-19 devnull
312 a84cbb2a 2004-04-19 devnull e4 = h->e4;
313 35afcc6c 2006-04-20 devnull s->name = (char*)(uintptr)e4(b->name);
314 a84cbb2a 2004-04-19 devnull s->type = e4(b->type);
315 a84cbb2a 2004-04-19 devnull s->flags = e4(b->flags);
316 a84cbb2a 2004-04-19 devnull s->addr = e4(b->addr);
317 a84cbb2a 2004-04-19 devnull s->offset = e4(b->offset);
318 a84cbb2a 2004-04-19 devnull s->size = e4(b->size);
319 a84cbb2a 2004-04-19 devnull s->link = e4(b->link);
320 a84cbb2a 2004-04-19 devnull s->info = e4(b->info);
321 a84cbb2a 2004-04-19 devnull s->align = e4(b->align);
322 a84cbb2a 2004-04-19 devnull s->entsize = e4(b->entsize);
323 a84cbb2a 2004-04-19 devnull }
324 a84cbb2a 2004-04-19 devnull
325 a84cbb2a 2004-04-19 devnull ElfSect*
326 a84cbb2a 2004-04-19 devnull elfsection(Elf *elf, char *name)
327 a84cbb2a 2004-04-19 devnull {
328 a84cbb2a 2004-04-19 devnull int i;
329 a84cbb2a 2004-04-19 devnull
330 a84cbb2a 2004-04-19 devnull for(i=0; i<elf->nsect; i++){
331 a84cbb2a 2004-04-19 devnull if(elf->sect[i].name == name)
332 a84cbb2a 2004-04-19 devnull return &elf->sect[i];
333 a84cbb2a 2004-04-19 devnull if(elf->sect[i].name && name
334 a84cbb2a 2004-04-19 devnull && strcmp(elf->sect[i].name, name) == 0)
335 a84cbb2a 2004-04-19 devnull return &elf->sect[i];
336 a84cbb2a 2004-04-19 devnull }
337 a84cbb2a 2004-04-19 devnull werrstr("elf section '%s' not found", name);
338 a84cbb2a 2004-04-19 devnull return nil;
339 a84cbb2a 2004-04-19 devnull }
340 a84cbb2a 2004-04-19 devnull
341 a84cbb2a 2004-04-19 devnull int
342 a84cbb2a 2004-04-19 devnull elfmap(Elf *elf, ElfSect *sect)
343 a84cbb2a 2004-04-19 devnull {
344 a84cbb2a 2004-04-19 devnull if(sect->base)
345 a84cbb2a 2004-04-19 devnull return 0;
346 a84cbb2a 2004-04-19 devnull if((sect->base = malloc(sect->size)) == nil)
347 a84cbb2a 2004-04-19 devnull return -1;
348 a84cbb2a 2004-04-19 devnull werrstr("short read");
349 a84cbb2a 2004-04-19 devnull if(seek(elf->fd, sect->offset, 0) < 0
350 a84cbb2a 2004-04-19 devnull || readn(elf->fd, sect->base, sect->size) != sect->size){
351 a84cbb2a 2004-04-19 devnull free(sect->base);
352 a84cbb2a 2004-04-19 devnull sect->base = nil;
353 a84cbb2a 2004-04-19 devnull return -1;
354 a84cbb2a 2004-04-19 devnull }
355 a84cbb2a 2004-04-19 devnull return 0;
356 a84cbb2a 2004-04-19 devnull }
357 a84cbb2a 2004-04-19 devnull
358 a84cbb2a 2004-04-19 devnull int
359 a84cbb2a 2004-04-19 devnull elfsym(Elf *elf, int i, ElfSym *sym)
360 a84cbb2a 2004-04-19 devnull {
361 a84cbb2a 2004-04-19 devnull ElfSect *symtab, *strtab;
362 a84cbb2a 2004-04-19 devnull uchar *p;
363 a84cbb2a 2004-04-19 devnull char *s;
364 a84cbb2a 2004-04-19 devnull ulong x;
365 a84cbb2a 2004-04-19 devnull
366 a84cbb2a 2004-04-19 devnull if(i < 0){
367 a84cbb2a 2004-04-19 devnull werrstr("bad index %d in elfsym", i);
368 a84cbb2a 2004-04-19 devnull return -1;
369 a84cbb2a 2004-04-19 devnull }
370 a84cbb2a 2004-04-19 devnull
371 a84cbb2a 2004-04-19 devnull if(i < elf->nsymtab){
372 a84cbb2a 2004-04-19 devnull symtab = elf->symtab;
373 a84cbb2a 2004-04-19 devnull strtab = elf->symstr;
374 a84cbb2a 2004-04-19 devnull extract:
375 a84cbb2a 2004-04-19 devnull if(elfmap(elf, symtab) < 0 || elfmap(elf, strtab) < 0)
376 a84cbb2a 2004-04-19 devnull return -1;
377 a84cbb2a 2004-04-19 devnull p = symtab->base + i * sizeof(ElfSymBytes);
378 929ba9b9 2004-04-20 devnull s = (char*)strtab->base;
379 a84cbb2a 2004-04-19 devnull x = elf->hdr.e4(p);
380 a84cbb2a 2004-04-19 devnull if(x >= strtab->size){
381 a84cbb2a 2004-04-19 devnull werrstr("bad symbol name offset 0x%lux", x);
382 a84cbb2a 2004-04-19 devnull return -1;
383 a84cbb2a 2004-04-19 devnull }
384 a84cbb2a 2004-04-19 devnull sym->name = s + x;
385 a84cbb2a 2004-04-19 devnull sym->value = elf->hdr.e4(p+4);
386 a84cbb2a 2004-04-19 devnull sym->size = elf->hdr.e4(p+8);
387 a84cbb2a 2004-04-19 devnull x = p[12];
388 a84cbb2a 2004-04-19 devnull sym->bind = x>>4;
389 a84cbb2a 2004-04-19 devnull sym->type = x & 0xF;
390 a84cbb2a 2004-04-19 devnull sym->other = p[13];
391 a84cbb2a 2004-04-19 devnull sym->shndx = elf->hdr.e2(p+14);
392 a84cbb2a 2004-04-19 devnull return 0;
393 a84cbb2a 2004-04-19 devnull }
394 a84cbb2a 2004-04-19 devnull i -= elf->nsymtab;
395 a84cbb2a 2004-04-19 devnull if(i < elf->ndynsym){
396 a84cbb2a 2004-04-19 devnull symtab = elf->dynsym;
397 a84cbb2a 2004-04-19 devnull strtab = elf->dynstr;
398 a84cbb2a 2004-04-19 devnull goto extract;
399 a84cbb2a 2004-04-19 devnull }
400 a84cbb2a 2004-04-19 devnull /* i -= elf->ndynsym */
401 a84cbb2a 2004-04-19 devnull
402 a84cbb2a 2004-04-19 devnull werrstr("symbol index out of range");
403 a84cbb2a 2004-04-19 devnull return -1;
404 a84cbb2a 2004-04-19 devnull }
405 a84cbb2a 2004-04-19 devnull