Revision 3b46e624 dyngen.c
b/dyngen.c | ||
---|---|---|
375 | 375 |
return (h->e_ident[EI_DATA] == ELFDATA2MSB) != |
376 | 376 |
(swaptest.b[0] == 0); |
377 | 377 |
} |
378 |
|
|
378 |
|
|
379 | 379 |
void elf_swap_ehdr(struct elfhdr *h) |
380 | 380 |
{ |
381 | 381 |
swab16s(&h->e_type); /* Object file type */ |
... | ... | |
483 | 483 |
ElfW(Sym) *sym; |
484 | 484 |
char *shstr; |
485 | 485 |
ELF_RELOC *rel; |
486 |
|
|
486 |
|
|
487 | 487 |
fd = open(filename, O_RDONLY); |
488 | 488 |
if (fd < 0) |
489 | 489 |
error("can't open file '%s'", filename); |
490 |
|
|
490 |
|
|
491 | 491 |
/* Read ELF header. */ |
492 | 492 |
if (read(fd, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) |
493 | 493 |
error("unable to read file header"); |
... | ... | |
524 | 524 |
/* read all section data */ |
525 | 525 |
sdata = malloc(sizeof(void *) * ehdr.e_shnum); |
526 | 526 |
memset(sdata, 0, sizeof(void *) * ehdr.e_shnum); |
527 |
|
|
527 |
|
|
528 | 528 |
for(i = 0;i < ehdr.e_shnum; i++) { |
529 | 529 |
sec = &shdr[i]; |
530 | 530 |
if (sec->sh_type != SHT_NOBITS) |
... | ... | |
569 | 569 |
|
570 | 570 |
symtab = (ElfW(Sym) *)sdata[symtab_sec - shdr]; |
571 | 571 |
strtab = (char *)sdata[symtab_sec->sh_link]; |
572 |
|
|
572 |
|
|
573 | 573 |
nb_syms = symtab_sec->sh_size / sizeof(ElfW(Sym)); |
574 | 574 |
if (do_swap) { |
575 | 575 |
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { |
... | ... | |
609 | 609 |
{ |
610 | 610 |
char *q; |
611 | 611 |
int c, i, len; |
612 |
|
|
612 |
|
|
613 | 613 |
if (ext_sym->e.e.e_zeroes != 0) { |
614 | 614 |
q = sym->st_name; |
615 | 615 |
for(i = 0; i < 8; i++) { |
... | ... | |
643 | 643 |
if (sym->st_syment->e_scnum == data_shndx && |
644 | 644 |
text_data >= sym->st_value && |
645 | 645 |
text_data < sym->st_value + sym->st_size) { |
646 |
|
|
646 |
|
|
647 | 647 |
return sym->st_name; |
648 | 648 |
|
649 | 649 |
} |
... | ... | |
709 | 709 |
); |
710 | 710 |
if (fd < 0) |
711 | 711 |
error("can't open file '%s'", filename); |
712 |
|
|
712 |
|
|
713 | 713 |
/* Read COFF header. */ |
714 | 714 |
if (read(fd, &fhdr, sizeof (fhdr)) != sizeof (fhdr)) |
715 | 715 |
error("unable to read file header"); |
... | ... | |
726 | 726 |
/* read all section data */ |
727 | 727 |
sdata = malloc(sizeof(void *) * fhdr.f_nscns); |
728 | 728 |
memset(sdata, 0, sizeof(void *) * fhdr.f_nscns); |
729 |
|
|
729 |
|
|
730 | 730 |
const char *p; |
731 | 731 |
for(i = 0;i < fhdr.f_nscns; i++) { |
732 | 732 |
sec = &shdr[i]; |
... | ... | |
747 | 747 |
if (!data_sec) |
748 | 748 |
error("could not find .data section"); |
749 | 749 |
coff_data_shndx = data_sec - shdr; |
750 |
|
|
750 |
|
|
751 | 751 |
coff_symtab = load_data(fd, fhdr.f_symptr, fhdr.f_nsyms*SYMESZ); |
752 | 752 |
for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) { |
753 | 753 |
for(i=0;i<8;i++) |
... | ... | |
758 | 758 |
|
759 | 759 |
n_strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), STRTAB_SIZE); |
760 | 760 |
strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), *n_strtab); |
761 |
|
|
761 |
|
|
762 | 762 |
nb_syms = fhdr.f_nsyms; |
763 | 763 |
|
764 | 764 |
for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) { |
... | ... | |
805 | 805 |
} else { |
806 | 806 |
sym->st_size = 0; |
807 | 807 |
} |
808 |
|
|
808 |
|
|
809 | 809 |
sym->st_type = ext_sym->e_type; |
810 | 810 |
sym->st_shndx = ext_sym->e_scnum; |
811 | 811 |
} |
812 | 812 |
|
813 |
|
|
813 |
|
|
814 | 814 |
/* find text relocations, if any */ |
815 | 815 |
sec = &shdr[coff_text_shndx]; |
816 | 816 |
coff_relocs = load_data(fd, sec->s_relptr, sec->s_nreloc*RELSZ); |
... | ... | |
870 | 870 |
|
871 | 871 |
if ( sym->n_type & N_STAB ) /* Debug symbols are ignored */ |
872 | 872 |
return "debug"; |
873 |
|
|
873 |
|
|
874 | 874 |
if(!name) |
875 | 875 |
return name; |
876 | 876 |
if(name[0]=='_') |
... | ... | |
953 | 953 |
{ |
954 | 954 |
unsigned int tocindex, symindex, size; |
955 | 955 |
const char *name = 0; |
956 |
|
|
956 |
|
|
957 | 957 |
/* Sanity check */ |
958 | 958 |
if(!( address >= sec_hdr->addr && address < (sec_hdr->addr + sec_hdr->size) ) ) |
959 | 959 |
return (char*)0; |
960 |
|
|
960 |
|
|
961 | 961 |
if( sec_hdr->flags & S_SYMBOL_STUBS ){ |
962 | 962 |
size = sec_hdr->reserved2; |
963 | 963 |
if(size == 0) |
964 | 964 |
error("size = 0"); |
965 |
|
|
965 |
|
|
966 | 966 |
} |
967 | 967 |
else if( sec_hdr->flags & S_LAZY_SYMBOL_POINTERS || |
968 | 968 |
sec_hdr->flags & S_NON_LAZY_SYMBOL_POINTERS) |
969 | 969 |
size = sizeof(unsigned long); |
970 | 970 |
else |
971 | 971 |
return 0; |
972 |
|
|
972 |
|
|
973 | 973 |
/* Compute our index in toc */ |
974 | 974 |
tocindex = (address - sec_hdr->addr)/size; |
975 | 975 |
symindex = tocdylib[sec_hdr->reserved1 + tocindex]; |
... | ... | |
1015 | 1015 |
|
1016 | 1016 |
/* Intruction contains an offset to the symbols pointed to, in the rel->r_symbolnum section */ |
1017 | 1017 |
sectoffset = *(uint32_t *)(text + rel->r_address) & 0xffff; |
1018 |
|
|
1018 |
|
|
1019 | 1019 |
if(sectnum==0xffffff) |
1020 | 1020 |
return 0; |
1021 | 1021 |
|
... | ... | |
1041 | 1041 |
|
1042 | 1042 |
if(rel->r_pcrel) |
1043 | 1043 |
sectoffset += rel->r_address; |
1044 |
|
|
1044 |
|
|
1045 | 1045 |
if (rel->r_type == PPC_RELOC_BR24) |
1046 | 1046 |
name = (char *)find_reloc_name_in_sec_ptr((int)sectoffset, §ion_hdr[sectnum-1]); |
1047 | 1047 |
|
... | ... | |
1080 | 1080 |
unsigned int i, j; |
1081 | 1081 |
EXE_SYM *sym; |
1082 | 1082 |
struct nlist *syment; |
1083 |
|
|
1083 |
|
|
1084 | 1084 |
fd = open(filename, O_RDONLY); |
1085 | 1085 |
if (fd < 0) |
1086 | 1086 |
error("can't open file '%s'", filename); |
1087 |
|
|
1087 |
|
|
1088 | 1088 |
/* Read Mach header. */ |
1089 | 1089 |
if (read(fd, &mach_hdr, sizeof (mach_hdr)) != sizeof (mach_hdr)) |
1090 | 1090 |
error("unable to read file header"); |
... | ... | |
1093 | 1093 |
if (!check_mach_header(mach_hdr)) { |
1094 | 1094 |
error("bad Mach header"); |
1095 | 1095 |
} |
1096 |
|
|
1096 |
|
|
1097 | 1097 |
if (mach_hdr.cputype != CPU_TYPE_POWERPC) |
1098 | 1098 |
error("Unsupported CPU"); |
1099 |
|
|
1099 |
|
|
1100 | 1100 |
if (mach_hdr.filetype != MH_OBJECT) |
1101 | 1101 |
error("Unsupported Mach Object"); |
1102 |
|
|
1102 |
|
|
1103 | 1103 |
/* read segment headers */ |
1104 | 1104 |
for(i=0, j=sizeof(mach_hdr); i<mach_hdr.ncmds ; i++) |
1105 | 1105 |
{ |
... | ... | |
1143 | 1143 |
/* read all section data */ |
1144 | 1144 |
sdata = (uint8_t **)malloc(sizeof(void *) * segment->nsects); |
1145 | 1145 |
memset(sdata, 0, sizeof(void *) * segment->nsects); |
1146 |
|
|
1146 |
|
|
1147 | 1147 |
/* Load the data in section data */ |
1148 | 1148 |
for(i = 0; i < segment->nsects; i++) { |
1149 | 1149 |
sdata[i] = load_data(fd, section_hdr[i].offset, section_hdr[i].size); |
... | ... | |
1159 | 1159 |
/* Make sure dysym was loaded */ |
1160 | 1160 |
if(!(int)dysymtabcmd) |
1161 | 1161 |
error("could not find __DYSYMTAB segment"); |
1162 |
|
|
1162 |
|
|
1163 | 1163 |
/* read the table of content of the indirect sym */ |
1164 | 1164 |
tocdylib = load_data( fd, dysymtabcmd->indirectsymoff, dysymtabcmd->nindirectsyms * sizeof(uint32_t) ); |
1165 |
|
|
1165 |
|
|
1166 | 1166 |
/* Make sure symtab was loaded */ |
1167 | 1167 |
if(!(int)symtabcmd) |
1168 | 1168 |
error("could not find __SYMTAB segment"); |
... | ... | |
1178 | 1178 |
struct nlist *sym_follow, *sym_next = 0; |
1179 | 1179 |
unsigned int j; |
1180 | 1180 |
memset(sym, 0, sizeof(*sym)); |
1181 |
|
|
1181 |
|
|
1182 | 1182 |
if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */ |
1183 | 1183 |
continue; |
1184 |
|
|
1184 |
|
|
1185 | 1185 |
memcpy(sym, syment, sizeof(*syment)); |
1186 |
|
|
1186 |
|
|
1187 | 1187 |
/* Find the following symbol in order to get the current symbol size */ |
1188 | 1188 |
for(j = 0, sym_follow = symtab_std; j < nb_syms; j++, sym_follow++) { |
1189 | 1189 |
if ( sym_follow->n_sect != 1 || sym_follow->n_type & N_STAB || !(sym_follow->n_value > sym->st_value)) |
... | ... | |
1286 | 1286 |
uint8_t data_allocated[1024]; |
1287 | 1287 |
unsigned int data_index; |
1288 | 1288 |
int type; |
1289 |
|
|
1289 |
|
|
1290 | 1290 |
memset(data_allocated, 0, sizeof(data_allocated)); |
1291 |
|
|
1291 |
|
|
1292 | 1292 |
p = p_start; |
1293 | 1293 |
min_offset = p_end - p_start; |
1294 | 1294 |
spare = 0x7fffffff; |
... | ... | |
1478 | 1478 |
} |
1479 | 1479 |
copy_size = len; |
1480 | 1480 |
} |
1481 |
#endif
|
|
1481 |
#endif |
|
1482 | 1482 |
#elif defined(HOST_PPC) |
1483 | 1483 |
{ |
1484 | 1484 |
uint8_t *p; |
... | ... | |
1510 | 1510 |
#endif |
1511 | 1511 |
if (get32((uint32_t *)p) != 0x6bfa8001) |
1512 | 1512 |
error("ret expected at the end of %s", name); |
1513 |
copy_size = p - p_start;
|
|
1513 |
copy_size = p - p_start; |
|
1514 | 1514 |
} |
1515 | 1515 |
#elif defined(HOST_IA64) |
1516 | 1516 |
{ |
... | ... | |
1611 | 1611 |
} else { |
1612 | 1612 |
error("No save at the beginning of %s", name); |
1613 | 1613 |
} |
1614 |
|
|
1614 |
|
|
1615 | 1615 |
/* Skip a preceeding nop, if present. */ |
1616 | 1616 |
if (p > p_start) { |
1617 | 1617 |
skip_insn = get32((uint32_t *)(p - 0x4)); |
1618 | 1618 |
if (skip_insn == 0x01000000) |
1619 | 1619 |
p -= 4; |
1620 | 1620 |
} |
1621 |
|
|
1621 |
|
|
1622 | 1622 |
copy_size = p - p_start; |
1623 | 1623 |
} |
1624 | 1624 |
#elif defined(HOST_ARM) |
... | ... | |
1700 | 1700 |
} |
1701 | 1701 |
} |
1702 | 1702 |
} |
1703 |
|
|
1703 |
|
|
1704 | 1704 |
nb_args = 0; |
1705 | 1705 |
while (nb_args < MAX_ARGS && args_present[nb_args]) |
1706 | 1706 |
nb_args++; |
... | ... | |
1784 | 1784 |
if (strstart(sym_name, "__op_label", &p)) { |
1785 | 1785 |
uint8_t *ptr; |
1786 | 1786 |
unsigned long offset; |
1787 |
|
|
1787 |
|
|
1788 | 1788 |
/* test if the variable refers to a label inside |
1789 | 1789 |
the code we are generating */ |
1790 | 1790 |
#ifdef CONFIG_FORMAT_COFF |
... | ... | |
1828 | 1828 |
} |
1829 | 1829 |
} |
1830 | 1830 |
} |
1831 |
#endif
|
|
1831 |
#endif |
|
1832 | 1832 |
if (val >= start_offset && val <= start_offset + copy_size) { |
1833 | 1833 |
n = strtol(p, NULL, 10); |
1834 | 1834 |
fprintf(outfile, " label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, (long)(val - start_offset)); |
... | ... | |
1973 | 1973 |
n, reloc_offset); |
1974 | 1974 |
continue; |
1975 | 1975 |
} |
1976 |
|
|
1976 |
|
|
1977 | 1977 |
get_reloc_expr(relname, sizeof(relname), sym_name); |
1978 | 1978 |
type = ELF32_R_TYPE(rel->r_info); |
1979 | 1979 |
addend = rel->r_addend; |
... | ... | |
2652 | 2652 |
gen_code(name, sym->st_value, sym->st_size, outfile, 0); |
2653 | 2653 |
} |
2654 | 2654 |
} |
2655 |
|
|
2655 |
|
|
2656 | 2656 |
} else { |
2657 | 2657 |
/* generate big code generation switch */ |
2658 | 2658 |
|
... | ... | |
2695 | 2695 |
eliminating the neeed to jump around the pool. |
2696 | 2696 |
|
2697 | 2697 |
We currently generate: |
2698 |
|
|
2698 |
|
|
2699 | 2699 |
[ For this example we assume merging would move op1_pool out of range. |
2700 | 2700 |
In practice we should be able to combine many ops before the offset |
2701 | 2701 |
limits are reached. ] |
Also available in: Unified diff