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 443d6288 2012-02-19 rsc void *p;
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 a84cbb2a 2004-04-19 devnull
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);
248 a84cbb2a 2004-04-19 devnull }
249 443d6288 2012-02-19 rsc free(p);
250 a84cbb2a 2004-04-19 devnull
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;
256 a84cbb2a 2004-04-19 devnull }
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;
260 a84cbb2a 2004-04-19 devnull
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;
264 a84cbb2a 2004-04-19 devnull
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;
269 a84cbb2a 2004-04-19 devnull else{
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);
272 a84cbb2a 2004-04-19 devnull }
273 a84cbb2a 2004-04-19 devnull }
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;
278 a84cbb2a 2004-04-19 devnull else{
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);
281 a84cbb2a 2004-04-19 devnull }
282 a84cbb2a 2004-04-19 devnull }
283 a84cbb2a 2004-04-19 devnull
284 a84cbb2a 2004-04-19 devnull e->bss = elfsection(e, ".bss");
285 a84cbb2a 2004-04-19 devnull
286 a84cbb2a 2004-04-19 devnull nosects:
287 a84cbb2a 2004-04-19 devnull return e;
288 a84cbb2a 2004-04-19 devnull
289 a84cbb2a 2004-04-19 devnull err:
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;
295 a84cbb2a 2004-04-19 devnull }
296 a84cbb2a 2004-04-19 devnull
297 a84cbb2a 2004-04-19 devnull void
298 a84cbb2a 2004-04-19 devnull elfclose(Elf *elf)
299 a84cbb2a 2004-04-19 devnull {
300 a84cbb2a 2004-04-19 devnull int i;
301 a84cbb2a 2004-04-19 devnull
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);
308 a84cbb2a 2004-04-19 devnull }
309 a84cbb2a 2004-04-19 devnull
310 a84cbb2a 2004-04-19 devnull static void
311 443d6288 2012-02-19 rsc unpackhdr(ElfHdr *h, void *v)
312 a84cbb2a 2004-04-19 devnull {
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;
318 a84cbb2a 2004-04-19 devnull
319 443d6288 2012-02-19 rsc b = v;
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;
328 a84cbb2a 2004-04-19 devnull break;
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;
333 a84cbb2a 2004-04-19 devnull break;
334 a84cbb2a 2004-04-19 devnull default:
335 a84cbb2a 2004-04-19 devnull return;
336 a84cbb2a 2004-04-19 devnull }
337 a84cbb2a 2004-04-19 devnull h->abi = b->ident[7];
338 a84cbb2a 2004-04-19 devnull h->abiversion = b->ident[8];
339 a84cbb2a 2004-04-19 devnull
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;
343 a84cbb2a 2004-04-19 devnull
344 443d6288 2012-02-19 rsc if(h->class == ElfClass64)
345 443d6288 2012-02-19 rsc goto b64;
346 443d6288 2012-02-19 rsc
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);
360 443d6288 2012-02-19 rsc return;
361 443d6288 2012-02-19 rsc
362 443d6288 2012-02-19 rsc b64:
363 443d6288 2012-02-19 rsc b64 = v;
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);
377 443d6288 2012-02-19 rsc return;
378 a84cbb2a 2004-04-19 devnull }
379 a84cbb2a 2004-04-19 devnull
380 a84cbb2a 2004-04-19 devnull static void
381 443d6288 2012-02-19 rsc unpackprog(ElfHdr *h, ElfProg *p, void *v)
382 a84cbb2a 2004-04-19 devnull {
383 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
384 443d6288 2012-02-19 rsc u64int (*e8)(uchar*);
385 a84cbb2a 2004-04-19 devnull
386 443d6288 2012-02-19 rsc if(h->class == ElfClass32) {
387 443d6288 2012-02-19 rsc ElfProgBytes *b;
388 443d6288 2012-02-19 rsc
389 443d6288 2012-02-19 rsc b = v;
390 443d6288 2012-02-19 rsc e4 = h->e4;
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);
399 443d6288 2012-02-19 rsc } else {
400 443d6288 2012-02-19 rsc ElfProgBytes64 *b;
401 443d6288 2012-02-19 rsc
402 443d6288 2012-02-19 rsc b = v;
403 443d6288 2012-02-19 rsc e4 = h->e4;
404 443d6288 2012-02-19 rsc e8 = h->e8;
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);
413 443d6288 2012-02-19 rsc }
414 a84cbb2a 2004-04-19 devnull }
415 a84cbb2a 2004-04-19 devnull
416 a84cbb2a 2004-04-19 devnull static void
417 443d6288 2012-02-19 rsc unpacksect(ElfHdr *h, ElfSect *s, void *v)
418 a84cbb2a 2004-04-19 devnull {
419 a84cbb2a 2004-04-19 devnull u32int (*e4)(uchar*);
420 443d6288 2012-02-19 rsc u64int (*e8)(uchar*);
421 a84cbb2a 2004-04-19 devnull
422 443d6288 2012-02-19 rsc if(h->class == ElfClass32) {
423 443d6288 2012-02-19 rsc ElfSectBytes *b;
424 443d6288 2012-02-19 rsc
425 443d6288 2012-02-19 rsc b = v;
426 443d6288 2012-02-19 rsc e4 = h->e4;
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);
437 443d6288 2012-02-19 rsc } else {
438 443d6288 2012-02-19 rsc ElfSectBytes64 *b;
439 443d6288 2012-02-19 rsc
440 443d6288 2012-02-19 rsc b = v;
441 443d6288 2012-02-19 rsc e4 = h->e4;
442 443d6288 2012-02-19 rsc e8 = h->e8;
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);
453 443d6288 2012-02-19 rsc }
454 a84cbb2a 2004-04-19 devnull }
455 a84cbb2a 2004-04-19 devnull
456 a84cbb2a 2004-04-19 devnull ElfSect*
457 a84cbb2a 2004-04-19 devnull elfsection(Elf *elf, char *name)
458 a84cbb2a 2004-04-19 devnull {
459 a84cbb2a 2004-04-19 devnull int i;
460 a84cbb2a 2004-04-19 devnull
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];
467 a84cbb2a 2004-04-19 devnull }
468 a84cbb2a 2004-04-19 devnull werrstr("elf section '%s' not found", name);
469 a84cbb2a 2004-04-19 devnull return nil;
470 a84cbb2a 2004-04-19 devnull }
471 a84cbb2a 2004-04-19 devnull
472 a84cbb2a 2004-04-19 devnull int
473 a84cbb2a 2004-04-19 devnull elfmap(Elf *elf, ElfSect *sect)
474 a84cbb2a 2004-04-19 devnull {
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;
485 a84cbb2a 2004-04-19 devnull }
486 a84cbb2a 2004-04-19 devnull return 0;
487 a84cbb2a 2004-04-19 devnull }
488 a84cbb2a 2004-04-19 devnull
489 a84cbb2a 2004-04-19 devnull int
490 a84cbb2a 2004-04-19 devnull elfsym(Elf *elf, int i, ElfSym *sym)
491 a84cbb2a 2004-04-19 devnull {
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;
496 a84cbb2a 2004-04-19 devnull
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;
500 a84cbb2a 2004-04-19 devnull }
501 a84cbb2a 2004-04-19 devnull
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);
514 443d6288 2012-02-19 rsc return -1;
515 443d6288 2012-02-19 rsc }
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);
519 443d6288 2012-02-19 rsc x = p[12];
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);
524 443d6288 2012-02-19 rsc } else {
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);
530 443d6288 2012-02-19 rsc return -1;
531 443d6288 2012-02-19 rsc }
532 443d6288 2012-02-19 rsc sym->name = s + x;
533 443d6288 2012-02-19 rsc x = p[4];
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);
540 a84cbb2a 2004-04-19 devnull }
541 a84cbb2a 2004-04-19 devnull return 0;
542 a84cbb2a 2004-04-19 devnull }
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;
548 a84cbb2a 2004-04-19 devnull }
549 a84cbb2a 2004-04-19 devnull /* i -= elf->ndynsym */
550 a84cbb2a 2004-04-19 devnull
551 a84cbb2a 2004-04-19 devnull werrstr("symbol index out of range");
552 a84cbb2a 2004-04-19 devnull return -1;
553 a84cbb2a 2004-04-19 devnull }
554 a84cbb2a 2004-04-19 devnull