1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25: #include <stdlib.h>
26: #include <stdio.h>
27: #include <string.h>
28: #include <stdarg.h>
29: #include <inttypes.h>
30: #include <unistd.h>
31: #include <fcntl.h>
32:
33: #include "config-host.h"
34:
35:
36:
37: #if defined(CONFIG_WIN32)
38: #define CONFIG_FORMAT_COFF
39: #elif defined(CONFIG_DARWIN)
40: #define CONFIG_FORMAT_MACH
41: #else
42: #define CONFIG_FORMAT_ELF
43: #endif
44:
45: #ifdef CONFIG_FORMAT_ELF
46:
47:
48:
49:
50: #if defined(HOST_I386)
51:
52: #define ELF_CLASS ELFCLASS32
53: #define ELF_ARCH EM_386
54: #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
55: #undef ELF_USES_RELOCA
56:
57: #elif defined(HOST_X86_64)
58:
59: #define ELF_CLASS ELFCLASS64
60: #define ELF_ARCH EM_X86_64
61: #define elf_check_arch(x) ((x) == EM_X86_64)
62: #define ELF_USES_RELOCA
63:
64: #elif defined(HOST_PPC)
65:
66: #define ELF_CLASS ELFCLASS32
67: #define ELF_ARCH EM_PPC
68: #define elf_check_arch(x) ((x) == EM_PPC)
69: #define ELF_USES_RELOCA
70:
71: #elif defined(HOST_S390)
72:
73: #define ELF_CLASS ELFCLASS32
74: #define ELF_ARCH EM_S390
75: #define elf_check_arch(x) ((x) == EM_S390)
76: #define ELF_USES_RELOCA
77:
78: #elif defined(HOST_ALPHA)
79:
80: #define ELF_CLASS ELFCLASS64
81: #define ELF_ARCH EM_ALPHA
82: #define elf_check_arch(x) ((x) == EM_ALPHA)
83: #define ELF_USES_RELOCA
84:
85: #elif defined(HOST_IA64)
86:
87: #define ELF_CLASS ELFCLASS64
88: #define ELF_ARCH EM_IA_64
89: #define elf_check_arch(x) ((x) == EM_IA_64)
90: #define ELF_USES_RELOCA
91:
92: #elif defined(HOST_SPARC)
93:
94: #define ELF_CLASS ELFCLASS32
95: #define ELF_ARCH EM_SPARC
96: #define elf_check_arch(x) ((x) == EM_SPARC || (x) == EM_SPARC32PLUS)
97: #define ELF_USES_RELOCA
98:
99: #elif defined(HOST_SPARC64)
100:
101: #define ELF_CLASS ELFCLASS64
102: #define ELF_ARCH EM_SPARCV9
103: #define elf_check_arch(x) ((x) == EM_SPARCV9)
104: #define ELF_USES_RELOCA
105:
106: #elif defined(HOST_ARM)
107:
108: #define ELF_CLASS ELFCLASS32
109: #define ELF_ARCH EM_ARM
110: #define elf_check_arch(x) ((x) == EM_ARM)
111: #define ELF_USES_RELOC
112:
113: #elif defined(HOST_M68K)
114:
115: #define ELF_CLASS ELFCLASS32
116: #define ELF_ARCH EM_68K
117: #define elf_check_arch(x) ((x) == EM_68K)
118: #define ELF_USES_RELOCA
119:
120: #elif defined(HOST_MIPS)
121:
122: #define ELF_CLASS ELFCLASS32
123: #define ELF_ARCH EM_MIPS
124: #define elf_check_arch(x) ((x) == EM_MIPS)
125: #define ELF_USES_RELOC
126:
127: #elif defined(HOST_MIPS64)
128:
129:
130: #define ELF_CLASS ELFCLASS32
131: #define ELF_ARCH EM_MIPS
132: #define elf_check_arch(x) ((x) == EM_MIPS)
133: #define ELF_USES_RELOCA
134:
135: #else
136: #error unsupported CPU - please update the code
137: #endif
138:
139: #include "elf.h"
140:
141: #if ELF_CLASS == ELFCLASS32
142: typedef int32_t host_long;
143: typedef uint32_t host_ulong;
144: #define swabls(x) swab32s(x)
145: #define swablss(x) swab32ss(x)
146: #else
147: typedef int64_t host_long;
148: typedef uint64_t host_ulong;
149: #define swabls(x) swab64s(x)
150: #define swablss(x) swab64ss(x)
151: #endif
152:
153: #ifdef ELF_USES_RELOCA
154: #define SHT_RELOC SHT_RELA
155: #else
156: #define SHT_RELOC SHT_REL
157: #endif
158:
159: #define EXE_RELOC ELF_RELOC
160: #define EXE_SYM ElfW(Sym)
161:
162: #endif
163:
164: #ifdef CONFIG_FORMAT_COFF
165:
166: typedef int32_t host_long;
167: typedef uint32_t host_ulong;
168:
169: #include "a.out.h"
170:
171: #define FILENAMELEN 256
172:
173: typedef struct coff_sym {
174: struct external_syment *st_syment;
175: char st_name[FILENAMELEN];
176: uint32_t st_value;
177: int st_size;
178: uint8_t st_type;
179: uint8_t st_shndx;
180: } coff_Sym;
181:
182: typedef struct coff_rel {
183: struct external_reloc *r_reloc;
184: int r_offset;
185: uint8_t r_type;
186: } coff_Rel;
187:
188: #define EXE_RELOC struct coff_rel
189: #define EXE_SYM struct coff_sym
190:
191: #endif
192:
193: #ifdef CONFIG_FORMAT_MACH
194:
195: #include <mach-o/loader.h>
196: #include <mach-o/nlist.h>
197: #include <mach-o/reloc.h>
198: #include <mach-o/ppc/reloc.h>
199:
200: # define check_mach_header(x) (x.magic == MH_MAGIC)
201: typedef int32_t host_long;
202: typedef uint32_t host_ulong;
203:
204: struct nlist_extended
205: {
206: union {
207: char *n_name;
208: long n_strx;
209: } n_un;
210: unsigned char n_type;
211: unsigned char n_sect;
212: short st_desc;
213: unsigned long st_value;
214: unsigned long st_size;
215: };
216:
217: #define EXE_RELOC struct relocation_info
218: #define EXE_SYM struct nlist_extended
219:
220: #endif
221:
222: #include "bswap.h"
223:
224: enum {
225: OUT_GEN_OP,
226: OUT_CODE,
227: OUT_INDEX_OP,
228: };
229:
230:
231: #define OP_PREFIX "op_"
232:
233: int do_swap;
234:
235: static void __attribute__((noreturn)) __attribute__((format (printf, 1, 2))) error(const char *fmt, ...)
236: {
237: va_list ap;
238: va_start(ap, fmt);
239: fprintf(stderr, "dyngen: ");
240: vfprintf(stderr, fmt, ap);
241: fprintf(stderr, "\n");
242: va_end(ap);
243: exit(1);
244: }
245:
246: static void *load_data(int fd, long offset, unsigned int size)
247: {
248: char *data;
249:
250: data = malloc(size);
251: if (!data)
252: return NULL;
253: lseek(fd, offset, SEEK_SET);
254: if (read(fd, data, size) != size) {
255: free(data);
256: return NULL;
257: }
258: return data;
259: }
260:
261: int strstart(const char *str, const char *val, const char **ptr)
262: {
263: const char *p, *q;
264: p = str;
265: q = val;
266: while (*q != '\0') {
267: if (*p != *q)
268: return 0;
269: p++;
270: q++;
271: }
272: if (ptr)
273: *ptr = p;
274: return 1;
275: }
276:
277: void pstrcpy(char *buf, int buf_size, const char *str)
278: {
279: int c;
280: char *q = buf;
281:
282: if (buf_size <= 0)
283: return;
284:
285: for(;;) {
286: c = *str++;
287: if (c == 0 || q >= buf + buf_size - 1)
288: break;
289: *q++ = c;
290: }
291: *q = '\0';
292: }
293:
294: void swab16s(uint16_t *p)
295: {
296: *p = bswap16(*p);
297: }
298:
299: void swab32s(uint32_t *p)
300: {
301: *p = bswap32(*p);
302: }
303:
304: void swab32ss(int32_t *p)
305: {
306: *p = bswap32(*p);
307: }
308:
309: void swab64s(uint64_t *p)
310: {
311: *p = bswap64(*p);
312: }
313:
314: void swab64ss(int64_t *p)
315: {
316: *p = bswap64(*p);
317: }
318:
319: uint16_t get16(uint16_t *p)
320: {
321: uint16_t val;
322: val = *p;
323: if (do_swap)
324: val = bswap16(val);
325: return val;
326: }
327:
328: uint32_t get32(uint32_t *p)
329: {
330: uint32_t val;
331: val = *p;
332: if (do_swap)
333: val = bswap32(val);
334: return val;
335: }
336:
337: void put16(uint16_t *p, uint16_t val)
338: {
339: if (do_swap)
340: val = bswap16(val);
341: *p = val;
342: }
343:
344: void put32(uint32_t *p, uint32_t val)
345: {
346: if (do_swap)
347: val = bswap32(val);
348: *p = val;
349: }
350:
351:
352: EXE_SYM *symtab;
353: int nb_syms;
354: int text_shndx;
355: uint8_t *text;
356: EXE_RELOC *relocs;
357: int nb_relocs;
358:
359: #ifdef CONFIG_FORMAT_ELF
360:
361:
362: struct elf_shdr *shdr;
363: uint8_t **sdata;
364: struct elfhdr ehdr;
365: char *strtab;
366:
367: int elf_must_swap(struct elfhdr *h)
368: {
369: union {
370: uint32_t i;
371: uint8_t b[4];
372: } swaptest;
373:
374: swaptest.i = 1;
375: return (h->e_ident[EI_DATA] == ELFDATA2MSB) !=
376: (swaptest.b[0] == 0);
377: }
378:
379: void elf_swap_ehdr(struct elfhdr *h)
380: {
381: swab16s(&h->e_type);
382: swab16s(&h-> e_machine);
383: swab32s(&h-> e_version);
384: swabls(&h-> e_entry);
385: swabls(&h-> e_phoff);
386: swabls(&h-> e_shoff);
387: swab32s(&h-> e_flags);
388: swab16s(&h-> e_ehsize);
389: swab16s(&h-> e_phentsize);
390: swab16s(&h-> e_phnum);
391: swab16s(&h-> e_shentsize);
392: swab16s(&h-> e_shnum);
393: swab16s(&h-> e_shstrndx);
394: }
395:
396: void elf_swap_shdr(struct elf_shdr *h)
397: {
398: swab32s(&h-> sh_name);
399: swab32s(&h-> sh_type);
400: swabls(&h-> sh_flags);
401: swabls(&h-> sh_addr);
402: swabls(&h-> sh_offset);
403: swabls(&h-> sh_size);
404: swab32s(&h-> sh_link);
405: swab32s(&h-> sh_info);
406: swabls(&h-> sh_addralign);
407: swabls(&h-> sh_entsize);
408: }
409:
410: void elf_swap_phdr(struct elf_phdr *h)
411: {
412: swab32s(&h->p_type);
413: swabls(&h->p_offset);
414: swabls(&h->p_vaddr);
415: swabls(&h->p_paddr);
416: swabls(&h->p_filesz);
417: swabls(&h->p_memsz);
418: swab32s(&h->p_flags);
419: swabls(&h->p_align);
420: }
421:
422: void elf_swap_rel(ELF_RELOC *rel)
423: {
424: swabls(&rel->r_offset);
425: swabls(&rel->r_info);
426: #ifdef ELF_USES_RELOCA
427: swablss(&rel->r_addend);
428: #endif
429: }
430:
431: struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr,
432: const char *name)
433: {
434: int i;
435: const char *shname;
436: struct elf_shdr *sec;
437:
438: for(i = 0; i < shnum; i++) {
439: sec = &shdr[i];
440: if (!sec->sh_name)
441: continue;
442: shname = shstr + sec->sh_name;
443: if (!strcmp(shname, name))
444: return sec;
445: }
446: return NULL;
447: }
448:
449: int find_reloc(int sh_index)
450: {
451: struct elf_shdr *sec;
452: int i;
453:
454: for(i = 0; i < ehdr.e_shnum; i++) {
455: sec = &shdr[i];
456: if (sec->sh_type == SHT_RELOC && sec->sh_info == sh_index)
457: return i;
458: }
459: return 0;
460: }
461:
462: static host_ulong get_rel_offset(EXE_RELOC *rel)
463: {
464: return rel->r_offset;
465: }
466:
467: static char *get_rel_sym_name(EXE_RELOC *rel)
468: {
469: return strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
470: }
471:
472: static char *get_sym_name(EXE_SYM *sym)
473: {
474: return strtab + sym->st_name;
475: }
476:
477:
478: int load_object(const char *filename)
479: {
480: int fd;
481: struct elf_shdr *sec, *symtab_sec, *strtab_sec, *text_sec;
482: int i, j;
483: ElfW(Sym) *sym;
484: char *shstr;
485: ELF_RELOC *rel;
486:
487: fd = open(filename, O_RDONLY);
488: if (fd < 0)
489: error("can't open file '%s'", filename);
490:
491:
492: if (read(fd, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
493: error("unable to read file header");
494:
495:
496: if (ehdr.e_ident[EI_MAG0] != ELFMAG0
497: || ehdr.e_ident[EI_MAG1] != ELFMAG1
498: || ehdr.e_ident[EI_MAG2] != ELFMAG2
499: || ehdr.e_ident[EI_MAG3] != ELFMAG3
500: || ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
501: error("bad ELF header");
502: }
503:
504: do_swap = elf_must_swap(&ehdr);
505: if (do_swap)
506: elf_swap_ehdr(&ehdr);
507: if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
508: error("Unsupported ELF class");
509: if (ehdr.e_type != ET_REL)
510: error("ELF object file expected");
511: if (ehdr.e_version != EV_CURRENT)
512: error("Invalid ELF version");
513: if (!elf_check_arch(ehdr.e_machine))
514: error("Unsupported CPU (e_machine=%d)", ehdr.e_machine);
515:
516:
517: shdr = load_data(fd, ehdr.e_shoff, ehdr.e_shnum * sizeof(struct elf_shdr));
518: if (do_swap) {
519: for(i = 0; i < ehdr.e_shnum; i++) {
520: elf_swap_shdr(&shdr[i]);
521: }
522: }
523:
524:
525: sdata = malloc(sizeof(void *) * ehdr.e_shnum);
526: memset(sdata, 0, sizeof(void *) * ehdr.e_shnum);
527:
528: for(i = 0;i < ehdr.e_shnum; i++) {
529: sec = &shdr[i];
530: if (sec->sh_type != SHT_NOBITS)
531: sdata[i] = load_data(fd, sec->sh_offset, sec->sh_size);
532: }
533:
534: sec = &shdr[ehdr.e_shstrndx];
535: shstr = (char *)sdata[ehdr.e_shstrndx];
536:
537:
538: for(i = 0; i < ehdr.e_shnum; i++) {
539: sec = &shdr[i];
540: if (sec->sh_type == SHT_RELOC) {
541: nb_relocs = sec->sh_size / sec->sh_entsize;
542: if (do_swap) {
543: for(j = 0, rel = (ELF_RELOC *)sdata[i]; j < nb_relocs; j++, rel++)
544: elf_swap_rel(rel);
545: }
546: }
547: }
548:
549:
550: text_sec = find_elf_section(shdr, ehdr.e_shnum, shstr, ".text");
551: if (!text_sec)
552: error("could not find .text section");
553: text_shndx = text_sec - shdr;
554: text = sdata[text_shndx];
555:
556:
557: relocs = NULL;
558: nb_relocs = 0;
559: i = find_reloc(text_shndx);
560: if (i != 0) {
561: relocs = (ELF_RELOC *)sdata[i];
562: nb_relocs = shdr[i].sh_size / shdr[i].sh_entsize;
563: }
564:
565: symtab_sec = find_elf_section(shdr, ehdr.e_shnum, shstr, ".symtab");
566: if (!symtab_sec)
567: error("could not find .symtab section");
568: strtab_sec = &shdr[symtab_sec->sh_link];
569:
570: symtab = (ElfW(Sym) *)sdata[symtab_sec - shdr];
571: strtab = (char *)sdata[symtab_sec->sh_link];
572:
573: nb_syms = symtab_sec->sh_size / sizeof(ElfW(Sym));
574: if (do_swap) {
575: for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
576: swab32s(&sym->st_name);
577: swabls(&sym->