Revert "Add macro to browse reloc and sym entries"

This reverts commit 3cbc7a2dcc.
master
Thomas Preud'homme 2014-02-02 20:02:12 +08:00
parent e5a706a091
commit 2eb844f8b5
1 changed files with 77 additions and 37 deletions

114
tccelf.c
View File

@ -330,12 +330,6 @@ ST_FUNC void put_stabd(int type, int other, int desc)
put_stabs(NULL, type, other, desc, 0); put_stabs(NULL, type, other, desc, 0);
} }
/* Browse each elem of type <type> in section <sec> starting at elem <startoff>
using variable <elem> */
#define for_each_elem(sec, startoff, elem, type) \
for (elem = (type *) sec->data + startoff; \
elem < (type *) (sec->data + sec->data_offset); elem++)
/* In an ELF file symbol table, the local symbols must appear below /* In an ELF file symbol table, the local symbols must appear below
the global and weak ones. Since TCC cannot sort it while generating the global and weak ones. Since TCC cannot sort it while generating
the code, we must do it after. All the relocation tables are also the code, we must do it after. All the relocation tables are also
@ -346,7 +340,7 @@ static void sort_syms(TCCState *s1, Section *s)
ElfW(Sym) *new_syms; ElfW(Sym) *new_syms;
int nb_syms, i; int nb_syms, i;
ElfW(Sym) *p, *q; ElfW(Sym) *p, *q;
ElfW_Rel *rel; ElfW_Rel *rel, *rel_end;
Section *sr; Section *sr;
int type, sym_index; int type, sym_index;
@ -385,7 +379,10 @@ static void sort_syms(TCCState *s1, Section *s)
for(i = 1; i < s1->nb_sections; i++) { for(i = 1; i < s1->nb_sections; i++) {
sr = s1->sections[i]; sr = s1->sections[i];
if (sr->sh_type == SHT_RELX && sr->link == s) { if (sr->sh_type == SHT_RELX && sr->link == s) {
for_each_elem(sr, 0, rel, ElfW_Rel) { rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
for(rel = (ElfW_Rel *)sr->data;
rel < rel_end;
rel++) {
sym_index = ELFW(R_SYM)(rel->r_info); sym_index = ELFW(R_SYM)(rel->r_info);
type = ELFW(R_TYPE)(rel->r_info); type = ELFW(R_TYPE)(rel->r_info);
sym_index = old_to_new_syms[sym_index]; sym_index = old_to_new_syms[sym_index];
@ -400,10 +397,13 @@ static void sort_syms(TCCState *s1, Section *s)
/* relocate common symbols in the .bss section */ /* relocate common symbols in the .bss section */
ST_FUNC void relocate_common_syms(void) ST_FUNC void relocate_common_syms(void)
{ {
ElfW(Sym) *sym; ElfW(Sym) *sym, *sym_end;
unsigned long offset, align; unsigned long offset, align;
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
for(sym = (ElfW(Sym) *)symtab_section->data + 1;
sym < sym_end;
sym++) {
if (sym->st_shndx == SHN_COMMON) { if (sym->st_shndx == SHN_COMMON) {
/* align symbol */ /* align symbol */
align = sym->st_value; align = sym->st_value;
@ -421,11 +421,14 @@ ST_FUNC void relocate_common_syms(void)
true and output error if undefined symbol. */ true and output error if undefined symbol. */
ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
{ {
ElfW(Sym) *sym, *esym; ElfW(Sym) *sym, *esym, *sym_end;
int sym_bind, sh_num, sym_index; int sym_bind, sh_num, sym_index;
const char *name; const char *name;
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
for(sym = (ElfW(Sym) *)symtab_section->data + 1;
sym < sym_end;
sym++) {
sh_num = sym->st_shndx; sh_num = sym->st_shndx;
if (sh_num == SHN_UNDEF) { if (sh_num == SHN_UNDEF) {
name = strtab_section->data + sym->st_name; name = strtab_section->data + sym->st_name;
@ -508,7 +511,7 @@ static addr_t add_jmp_table(TCCState *s1, int val)
ST_FUNC void relocate_section(TCCState *s1, Section *s) ST_FUNC void relocate_section(TCCState *s1, Section *s)
{ {
Section *sr; Section *sr;
ElfW_Rel *rel; ElfW_Rel *rel, *rel_end, *qrel;
ElfW(Sym) *sym; ElfW(Sym) *sym;
int type, sym_index; int type, sym_index;
unsigned char *ptr; unsigned char *ptr;
@ -518,7 +521,11 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
#endif #endif
sr = s->reloc; sr = s->reloc;
for_each_elem(sr, 0, rel, ElfW_Rel) { rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
qrel = (ElfW_Rel *)sr->data;
for(rel = qrel;
rel < rel_end;
rel++) {
ptr = s->data + rel->r_offset; ptr = s->data + rel->r_offset;
sym_index = ELFW(R_SYM)(rel->r_info); sym_index = ELFW(R_SYM)(rel->r_info);
@ -886,22 +893,27 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
static void relocate_rel(TCCState *s1, Section *sr) static void relocate_rel(TCCState *s1, Section *sr)
{ {
Section *s; Section *s;
ElfW_Rel *rel; ElfW_Rel *rel, *rel_end;
s = s1->sections[sr->sh_info]; s = s1->sections[sr->sh_info];
for_each_elem(sr, 0, rel, ElfW_Rel) rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
for(rel = (ElfW_Rel *)sr->data;
rel < rel_end;
rel++) {
rel->r_offset += s->sh_addr; rel->r_offset += s->sh_addr;
}
} }
/* count the number of dynamic relocations so that we can reserve /* count the number of dynamic relocations so that we can reserve
their space */ their space */
static int prepare_dynamic_rel(TCCState *s1, Section *sr) static int prepare_dynamic_rel(TCCState *s1, Section *sr)
{ {
ElfW_Rel *rel; ElfW_Rel *rel, *rel_end;
int sym_index, esym_index, type, count; int sym_index, esym_index, type, count;
count = 0; count = 0;
for_each_elem(sr, 0, rel, ElfW_Rel) { rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
sym_index = ELFW(R_SYM)(rel->r_info); sym_index = ELFW(R_SYM)(rel->r_info);
type = ELFW(R_TYPE)(rel->r_info); type = ELFW(R_TYPE)(rel->r_info);
switch(type) { switch(type) {
@ -1133,7 +1145,7 @@ static void put_got_entry(TCCState *s1,
ST_FUNC void build_got_entries(TCCState *s1) ST_FUNC void build_got_entries(TCCState *s1)
{ {
Section *s; Section *s;
ElfW_Rel *rel; ElfW_Rel *rel, *rel_end;
ElfW(Sym) *sym; ElfW(Sym) *sym;
int i, type, reloc_type, sym_index; int i, type, reloc_type, sym_index;
@ -1144,7 +1156,10 @@ ST_FUNC void build_got_entries(TCCState *s1)
/* no need to handle got relocations */ /* no need to handle got relocations */
if (s->link != symtab_section) if (s->link != symtab_section)
continue; continue;
for_each_elem(s, 0, rel, ElfW_Rel) { rel_end = (ElfW_Rel *)(s->data + s->data_offset);
for(rel = (ElfW_Rel *)s->data;
rel < rel_end;
rel++) {
type = ELFW(R_TYPE)(rel->r_info); type = ELFW(R_TYPE)(rel->r_info);
switch(type) { switch(type) {
#if defined(TCC_TARGET_I386) #if defined(TCC_TARGET_I386)
@ -1451,11 +1466,12 @@ static void tcc_output_binary(TCCState *s1, FILE *f,
void patch_dynsym_undef(TCCState *s1, Section *s) void patch_dynsym_undef(TCCState *s1, Section *s)
{ {
uint32_t *gotd = (void *)s1->got->data; uint32_t *gotd = (void *)s1->got->data;
ElfW(Sym) *sym; ElfW(Sym) *sym, *sym_end;
gotd += 3; /* dummy entries in .got */ gotd += 3; /* dummy entries in .got */
/* relocate symbols in .dynsym */ /* relocate symbols in .dynsym */
for_each_elem(s, 1, sym, ElfW(Sym)) { sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++) {
if (sym->st_shndx == SHN_UNDEF) { if (sym->st_shndx == SHN_UNDEF) {
*gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */ *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
sym->st_value = 0; sym->st_value = 0;
@ -1469,9 +1485,10 @@ void patch_dynsym_undef(TCCState *s1, Section *s)
/* zero plt offsets of weak symbols in .dynsym */ /* zero plt offsets of weak symbols in .dynsym */
void patch_dynsym_undef(TCCState *s1, Section *s) void patch_dynsym_undef(TCCState *s1, Section *s)
{ {
ElfW(Sym) *sym; ElfW(Sym) *sym, *sym_end;
for_each_elem(s, 1, sym, ElfW(Sym)) sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++)
if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK) if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
sym->st_value = 0; sym->st_value = 0;
} }
@ -1497,7 +1514,7 @@ ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
ST_FUNC void fill_got(TCCState *s1) ST_FUNC void fill_got(TCCState *s1)
{ {
Section *s; Section *s;
ElfW_Rel *rel; ElfW_Rel *rel, *rel_end;
int i; int i;
for(i = 1; i < s1->nb_sections; i++) { for(i = 1; i < s1->nb_sections; i++) {
@ -1507,7 +1524,8 @@ ST_FUNC void fill_got(TCCState *s1)
/* no need to handle got relocations */ /* no need to handle got relocations */
if (s->link != symtab_section) if (s->link != symtab_section)
continue; continue;
for_each_elem(s, 0, rel, ElfW_Rel) { rel_end = (ElfW_Rel *) (s->data + s->data_offset);
for(rel = (ElfW_Rel *) s->data; rel < rel_end; rel++) {
switch (ELFW(R_TYPE) (rel->r_info)) { switch (ELFW(R_TYPE) (rel->r_info)) {
case R_X86_64_GOT32: case R_X86_64_GOT32:
case R_X86_64_GOTPCREL: case R_X86_64_GOTPCREL:
@ -1565,7 +1583,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
if (!s1->static_link) { if (!s1->static_link) {
const char *name; const char *name;
int sym_index, index; int sym_index, index;
ElfW(Sym) *esym; ElfW(Sym) *esym, *sym_end;
if (file_type == TCC_OUTPUT_EXE) { if (file_type == TCC_OUTPUT_EXE) {
char *ptr; char *ptr;
@ -1604,8 +1622,12 @@ static int elf_output_file(TCCState *s1, const char *filename)
is found, then we add it in the PLT. If a symbol is found, then we add it in the PLT. If a symbol
STT_OBJECT is found, we add it in the .bss section with STT_OBJECT is found, we add it in the .bss section with
a suitable relocation */ a suitable relocation */
sym_end = (ElfW(Sym) *)(symtab_section->data +
symtab_section->data_offset);
if (file_type == TCC_OUTPUT_EXE) { if (file_type == TCC_OUTPUT_EXE) {
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { for(sym = (ElfW(Sym) *)symtab_section->data + 1;
sym < sym_end;
sym++) {
if (sym->st_shndx == SHN_UNDEF) { if (sym->st_shndx == SHN_UNDEF) {
name = symtab_section->link->data + sym->st_name; name = symtab_section->link->data + sym->st_name;
sym_index = find_elf_sym(s1->dynsymtab_section, name); sym_index = find_elf_sym(s1->dynsymtab_section, name);
@ -1626,7 +1648,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
sym - (ElfW(Sym) *)symtab_section->data); sym - (ElfW(Sym) *)symtab_section->data);
} else if (type == STT_OBJECT) { } else if (type == STT_OBJECT) {
unsigned long offset; unsigned long offset;
ElfW(Sym) *dynsym; ElfW(Sym) *dynsym, *dynsym_end;
offset = bss_section->data_offset; offset = bss_section->data_offset;
/* XXX: which alignment ? */ /* XXX: which alignment ? */
offset = (offset + 16 - 1) & -16; offset = (offset + 16 - 1) & -16;
@ -1635,7 +1657,11 @@ static int elf_output_file(TCCState *s1, const char *filename)
bss_section->sh_num, name); bss_section->sh_num, name);
/* Ensure R_COPY works for weak symbol aliases */ /* Ensure R_COPY works for weak symbol aliases */
if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) { if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) { dynsym_end = (ElfW(Sym) *)
(s1->dynsymtab_section->data +
s1->dynsymtab_section->data_offset);
for(dynsym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
dynsym < dynsym_end; dynsym++) {
if ((dynsym->st_value == esym->st_value) if ((dynsym->st_value == esym->st_value)
&& (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) { && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
char *dynname; char *dynname;
@ -1681,7 +1707,11 @@ static int elf_output_file(TCCState *s1, const char *filename)
/* now look at unresolved dynamic symbols and export /* now look at unresolved dynamic symbols and export
corresponding symbol */ corresponding symbol */
for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) { sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
s1->dynsymtab_section->data_offset);
for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
esym < sym_end;
esym++) {
if (esym->st_shndx == SHN_UNDEF) { if (esym->st_shndx == SHN_UNDEF) {
name = s1->dynsymtab_section->link->data + esym->st_name; name = s1->dynsymtab_section->link->data + esym->st_name;
sym_index = find_elf_sym(symtab_section, name); sym_index = find_elf_sym(symtab_section, name);
@ -1706,7 +1736,9 @@ static int elf_output_file(TCCState *s1, const char *filename)
/* shared library case : we simply export all the global symbols */ /* shared library case : we simply export all the global symbols */
nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym)); nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms); s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { for(sym = (ElfW(Sym) *)symtab_section->data + 1;
sym < sym_end;
sym++) {
if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
#if defined(TCC_OUTPUT_DLL_WITH_PLT) #if defined(TCC_OUTPUT_DLL_WITH_PLT)
if ((ELFW(ST_TYPE)(sym->st_info) == STT_FUNC || if ((ELFW(ST_TYPE)(sym->st_info) == STT_FUNC ||
@ -1995,6 +2027,8 @@ static int elf_output_file(TCCState *s1, const char *filename)
/* if dynamic section, then add corresponing program header */ /* if dynamic section, then add corresponing program header */
if (dynamic) { if (dynamic) {
ElfW(Sym) *sym_end;
ph = &phdr[phnum - 1]; ph = &phdr[phnum - 1];
ph->p_type = PT_DYNAMIC; ph->p_type = PT_DYNAMIC;
@ -2056,7 +2090,10 @@ static int elf_output_file(TCCState *s1, const char *filename)
} }
/* relocate symbols in .dynsym */ /* relocate symbols in .dynsym */
for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) { sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
sym < sym_end;
sym++) {
if (sym->st_shndx == SHN_UNDEF) { if (sym->st_shndx == SHN_UNDEF) {
/* relocate to the PLT if the symbol corresponds /* relocate to the PLT if the symbol corresponds
to a PLT entry */ to a PLT entry */
@ -2328,7 +2365,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
char *sh_name, *name; char *sh_name, *name;
SectionMergeInfo *sm_table, *sm; SectionMergeInfo *sm_table, *sm;
ElfW(Sym) *sym, *symtab; ElfW(Sym) *sym, *symtab;
ElfW_Rel *rel; ElfW_Rel *rel, *rel_end;
Section *s; Section *s;
int stab_index; int stab_index;
@ -2548,7 +2585,10 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
case SHT_RELX: case SHT_RELX:
/* take relocation offset information */ /* take relocation offset information */
offseti = sm_table[sh->sh_info].offset; offseti = sm_table[sh->sh_info].offset;
for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) { rel_end = (ElfW_Rel *)(s->data + s->data_offset);
for(rel = (ElfW_Rel *)(s->data + offset);
rel < rel_end;
rel++) {
int type; int type;
unsigned sym_index; unsigned sym_index;
/* convert symbol index */ /* convert symbol index */