Revert "Add macro to browse reloc and sym entries"
This reverts commit 3cbc7a2dcc
.
This commit is contained in:
parent
e5a706a091
commit
2eb844f8b5
1 changed files with 77 additions and 37 deletions
110
tccelf.c
110
tccelf.c
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue