mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-26 03:50:07 +08:00
tccelf: use plt-reloc instead of relocplt
This commit is contained in:
parent
e4f151c4cd
commit
02795106e1
10
arm-link.c
10
arm-link.c
@ -167,15 +167,11 @@ ST_FUNC void relocate_plt(TCCState *s1)
|
||||
}
|
||||
}
|
||||
|
||||
if (s1->got->relocplt) {
|
||||
int mem = s1->output_type == TCC_OUTPUT_MEMORY;
|
||||
if (s1->plt->reloc) {
|
||||
ElfW_Rel *rel;
|
||||
|
||||
p = s1->got->data;
|
||||
for_each_elem(s1->got->relocplt, 0, rel, ElfW_Rel) {
|
||||
int sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
write32le(p + rel->r_offset, mem ? sym->st_value : s1->plt->sh_addr);
|
||||
for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
|
||||
write32le(p + rel->r_offset, s1->plt->sh_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
arm64-link.c
10
arm64-link.c
@ -155,15 +155,11 @@ ST_FUNC void relocate_plt(TCCState *s1)
|
||||
}
|
||||
}
|
||||
|
||||
if (s1->got->relocplt) {
|
||||
int mem = s1->output_type == TCC_OUTPUT_MEMORY;
|
||||
if (s1->plt->reloc) {
|
||||
ElfW_Rel *rel;
|
||||
|
||||
p = s1->got->data;
|
||||
for_each_elem(s1->got->relocplt, 0, rel, ElfW_Rel) {
|
||||
int sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
write64le(p + rel->r_offset, mem ? sym->st_value : s1->plt->sh_addr);
|
||||
for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
|
||||
write64le(p + rel->r_offset, s1->plt->sh_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
i386-link.c
12
i386-link.c
@ -121,7 +121,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_
|
||||
/* The PLT slot refers to the relocation entry it needs via offset.
|
||||
The reloc entry is created below, so its offset is the current
|
||||
data_offset */
|
||||
relofs = s1->got->relocplt ? s1->got->relocplt->data_offset : 0;
|
||||
relofs = s1->plt->reloc ? s1->plt->reloc->data_offset : 0;
|
||||
|
||||
/* Jump to GOT entry where ld.so initially put the address of ip + 4 */
|
||||
p = section_ptr_add(plt, 16);
|
||||
@ -157,16 +157,12 @@ ST_FUNC void relocate_plt(TCCState *s1)
|
||||
}
|
||||
}
|
||||
|
||||
if (s1->got->relocplt) {
|
||||
int mem = s1->output_type == TCC_OUTPUT_MEMORY;
|
||||
if (s1->plt->reloc) {
|
||||
ElfW_Rel *rel;
|
||||
int x = s1->plt->sh_addr + 16 + 6;
|
||||
|
||||
p = s1->got->data;
|
||||
for_each_elem(s1->got->relocplt, 0, rel, ElfW_Rel) {
|
||||
int sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
write32le(p + rel->r_offset, mem ? sym->st_value : x);
|
||||
for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
|
||||
write32le(p + rel->r_offset, x);
|
||||
x += 16;
|
||||
}
|
||||
}
|
||||
|
@ -154,15 +154,11 @@ ST_FUNC void relocate_plt(TCCState *s1)
|
||||
}
|
||||
}
|
||||
|
||||
if (s1->got->relocplt) {
|
||||
int mem = s1->output_type == TCC_OUTPUT_MEMORY;
|
||||
if (s1->plt->reloc) {
|
||||
ElfW_Rel *rel;
|
||||
|
||||
p = s1->got->data;
|
||||
for_each_elem(s1->got->relocplt, 0, rel, ElfW_Rel) {
|
||||
int sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
write64le(p + rel->r_offset, mem ? sym->st_value + rel->r_addend : s1->plt->sh_addr);
|
||||
for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
|
||||
write64le(p + rel->r_offset, s1->plt->sh_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
5
tcc.h
5
tcc.h
@ -423,7 +423,6 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
||||
# define ElfW_Rel ElfW(Rela)
|
||||
# define SHT_RELX SHT_RELA
|
||||
# define REL_SECTION_FMT ".rela%s"
|
||||
# define RELPLT_SECTION_FMT ".rela.plt"
|
||||
#else
|
||||
# define ELFCLASSW ELFCLASS32
|
||||
# define ElfW(type) Elf##32##_##type
|
||||
@ -431,7 +430,6 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
||||
# define ElfW_Rel ElfW(Rel)
|
||||
# define SHT_RELX SHT_REL
|
||||
# define REL_SECTION_FMT ".rel%s"
|
||||
# define RELPLT_SECTION_FMT ".rel.plt"
|
||||
#endif
|
||||
/* target address type */
|
||||
#define addr_t ElfW(Addr)
|
||||
@ -593,7 +591,6 @@ typedef struct Section {
|
||||
struct Section *reloc; /* corresponding section for relocation, if any */
|
||||
struct Section *hash; /* hash table for symbols */
|
||||
struct Section *prev; /* previous section on section stack */
|
||||
struct Section *relocplt;/* reloc with JMP_SLOTs */
|
||||
char name[1]; /* section name */
|
||||
} Section;
|
||||
|
||||
@ -1588,7 +1585,7 @@ ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value);
|
||||
|
||||
ST_FUNC void resolve_common_syms(TCCState *s1);
|
||||
ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve);
|
||||
ST_FUNC void relocate_section(TCCState *s1, Section *s);
|
||||
ST_FUNC void relocate_sections(TCCState *s1);
|
||||
|
||||
ST_FUNC ssize_t full_read(int fd, void *buf, size_t count);
|
||||
ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size);
|
||||
|
180
tccelf.c
180
tccelf.c
@ -737,25 +737,18 @@ ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
|
||||
char buf[256];
|
||||
Section *sr;
|
||||
ElfW_Rel *rel;
|
||||
int jmp_slot = type == R_JMP_SLOT;
|
||||
|
||||
sr = jmp_slot ? s->relocplt : s->reloc;
|
||||
sr = s->reloc;
|
||||
if (!sr) {
|
||||
/* if no relocation section, create it */
|
||||
if (jmp_slot)
|
||||
snprintf(buf, sizeof(buf), RELPLT_SECTION_FMT);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
|
||||
snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
|
||||
/* if the symtab is allocated, then we consider the relocation
|
||||
are also */
|
||||
sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
|
||||
sr->sh_entsize = sizeof(ElfW_Rel);
|
||||
sr->link = symtab;
|
||||
sr->sh_info = s->sh_num;
|
||||
if (jmp_slot)
|
||||
s->relocplt = sr;
|
||||
else
|
||||
s->reloc = sr;
|
||||
s->reloc = sr;
|
||||
}
|
||||
rel = section_ptr_add(sr, sizeof(ElfW_Rel));
|
||||
rel->r_offset = offset;
|
||||
@ -957,9 +950,8 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
|
||||
|
||||
/* relocate a given section (CPU dependent) by applying the relocations
|
||||
in the associated relocation section */
|
||||
ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
static void relocate_section(TCCState *s1, Section *s, Section *sr)
|
||||
{
|
||||
Section *sr = s->reloc;
|
||||
ElfW_Rel *rel;
|
||||
ElfW(Sym) *sym;
|
||||
int type, sym_index;
|
||||
@ -967,7 +959,6 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
addr_t tgt, addr;
|
||||
|
||||
qrel = (ElfW_Rel *)sr->data;
|
||||
|
||||
for_each_elem(sr, 0, rel, ElfW_Rel) {
|
||||
ptr = s->data + rel->r_offset;
|
||||
sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
@ -980,6 +971,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
addr = s->sh_addr + rel->r_offset;
|
||||
relocate(s1, rel, type, ptr, addr, tgt);
|
||||
}
|
||||
#ifndef ELF_OBJ_ONLY
|
||||
/* if the relocation is allocated, we change its symbol table */
|
||||
if (sr->sh_flags & SHF_ALLOC) {
|
||||
sr->link = s1->dynsym;
|
||||
@ -991,20 +983,37 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
sr->data_offset = sr->sh_size = r;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* relocate all sections */
|
||||
ST_FUNC void relocate_sections(TCCState *s1)
|
||||
{
|
||||
int i;
|
||||
Section *s, *sr;
|
||||
|
||||
for (i = 1; i < s1->nb_sections; ++i) {
|
||||
sr = s1->sections[i];
|
||||
if (sr->sh_type != SHT_RELX)
|
||||
continue;
|
||||
s = s1->sections[sr->sh_info];
|
||||
if (s != s1->got
|
||||
|| s1->static_link
|
||||
|| s1->output_type == TCC_OUTPUT_MEMORY) {
|
||||
relocate_section(s1, s, sr);
|
||||
}
|
||||
#ifndef ELF_OBJ_ONLY
|
||||
if (sr->sh_flags & SHF_ALLOC) {
|
||||
ElfW_Rel *rel;
|
||||
/* relocate relocation table in 'sr' */
|
||||
for_each_elem(sr, 0, rel, ElfW_Rel)
|
||||
rel->r_offset += s->sh_addr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ELF_OBJ_ONLY
|
||||
/* relocate relocation table in 'sr' */
|
||||
static void relocate_rel(TCCState *s1, Section *sr)
|
||||
{
|
||||
Section *s;
|
||||
ElfW_Rel *rel;
|
||||
|
||||
s = s1->sections[sr->sh_info];
|
||||
for_each_elem(sr, 0, rel, ElfW_Rel)
|
||||
rel->r_offset += s->sh_addr;
|
||||
}
|
||||
|
||||
/* count the number of dynamic relocations so that we can reserve
|
||||
their space */
|
||||
static int prepare_dynamic_rel(TCCState *s1, Section *sr)
|
||||
@ -1099,6 +1108,7 @@ static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
|
||||
unsigned got_offset;
|
||||
char plt_name[100];
|
||||
int len;
|
||||
Section *s_rel;
|
||||
|
||||
need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
|
||||
attr = get_sym_attr(s1, sym_index, 1);
|
||||
@ -1109,6 +1119,15 @@ static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
|
||||
if (need_plt_entry ? attr->plt_offset : attr->got_offset)
|
||||
return attr;
|
||||
|
||||
s_rel = s1->got;
|
||||
if (need_plt_entry) {
|
||||
if (!s1->plt) {
|
||||
s1->plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
|
||||
s1->plt->sh_entsize = 4;
|
||||
}
|
||||
s_rel = s1->plt;
|
||||
}
|
||||
|
||||
/* create the GOT entry */
|
||||
got_offset = s1->got->data_offset;
|
||||
section_ptr_add(s1->got, PTR_SIZE);
|
||||
@ -1123,6 +1142,7 @@ static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
|
||||
|
||||
sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
|
||||
name = (char *) symtab_section->link->data + sym->st_name;
|
||||
//printf("sym %d %s\n", need_plt_entry, name);
|
||||
|
||||
if (s1->dynsym) {
|
||||
if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
|
||||
@ -1147,7 +1167,7 @@ static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
|
||||
attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
|
||||
sym->st_size, sym->st_info, 0,
|
||||
sym->st_shndx, name);
|
||||
put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
|
||||
put_elf_reloc(s1->dynsym, s_rel, got_offset, dyn_reloc_type,
|
||||
attr->dyn_index);
|
||||
}
|
||||
} else {
|
||||
@ -1156,12 +1176,6 @@ static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
|
||||
}
|
||||
|
||||
if (need_plt_entry) {
|
||||
if (!s1->plt) {
|
||||
s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
|
||||
SHF_ALLOC | SHF_EXECINSTR);
|
||||
s1->plt->sh_entsize = 4;
|
||||
}
|
||||
|
||||
attr->plt_offset = create_plt_entry(s1, got_offset, attr);
|
||||
|
||||
/* create a symbol 'sym@plt' for the PLT jump vector */
|
||||
@ -1172,7 +1186,6 @@ static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
|
||||
strcpy(plt_name + len, "@plt");
|
||||
attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
|
||||
ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
|
||||
|
||||
} else {
|
||||
attr->got_offset = got_offset;
|
||||
}
|
||||
@ -1181,14 +1194,18 @@ static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
|
||||
}
|
||||
|
||||
/* build GOT and PLT entries */
|
||||
static void build_got_entries_pass(TCCState *s1, int pass)
|
||||
/* Two passes because R_JMP_SLOT should become first. Some targets
|
||||
(arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
|
||||
ST_FUNC void build_got_entries(TCCState *s1)
|
||||
{
|
||||
Section *s;
|
||||
ElfW_Rel *rel;
|
||||
ElfW(Sym) *sym;
|
||||
int i, type, gotplt_entry, reloc_type, sym_index;
|
||||
struct sym_attr *attr;
|
||||
int pass = 0;
|
||||
|
||||
redo:
|
||||
for(i = 1; i < s1->nb_sections; i++) {
|
||||
s = s1->sections[i];
|
||||
if (s->sh_type != SHT_RELX)
|
||||
@ -1252,7 +1269,7 @@ static void build_got_entries_pass(TCCState *s1, int pass)
|
||||
(ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
|
||||
ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
|
||||
s1->output_type == TCC_OUTPUT_EXE)) {
|
||||
if (pass == 0)
|
||||
if (pass != 0)
|
||||
continue;
|
||||
rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
|
||||
continue;
|
||||
@ -1261,16 +1278,17 @@ static void build_got_entries_pass(TCCState *s1, int pass)
|
||||
reloc_type = code_reloc(type);
|
||||
if (reloc_type == -1)
|
||||
tcc_error ("Unknown relocation type: %d", type);
|
||||
else if (reloc_type != 0) {
|
||||
jmp_slot:
|
||||
|
||||
if (reloc_type != 0) {
|
||||
jmp_slot:
|
||||
if (pass != 0)
|
||||
continue;
|
||||
reloc_type = R_JMP_SLOT;
|
||||
} else
|
||||
} else {
|
||||
if (pass != 1)
|
||||
continue;
|
||||
reloc_type = R_GLOB_DAT;
|
||||
|
||||
|
||||
if ((pass == 0 && reloc_type == R_GLOB_DAT) ||
|
||||
(pass == 1 && reloc_type == R_JMP_SLOT))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!s1->got)
|
||||
build_got(s1);
|
||||
@ -1284,16 +1302,13 @@ static void build_got_entries_pass(TCCState *s1, int pass)
|
||||
rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (++pass < 2)
|
||||
goto redo;
|
||||
|
||||
ST_FUNC void build_got_entries(TCCState *s1)
|
||||
{
|
||||
int i;
|
||||
/* .rel.plt refers to .got actually */
|
||||
if (s1->plt && s1->plt->reloc)
|
||||
s1->plt->reloc->sh_info = s1->got->sh_num;
|
||||
|
||||
/* Two passes because R_JMP_SLOT should become first.
|
||||
Some targets (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
|
||||
for (i = 0; i < 2; i++)
|
||||
build_got_entries_pass(s1, i);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1931,8 +1946,6 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr,
|
||||
roinf->sh_offset = roinf->sh_addr = roinf->sh_size = 0;
|
||||
|
||||
for(j = 0; j < phfill; j++) {
|
||||
Section *relocplt = s1->got ? s1->got->relocplt : NULL;
|
||||
|
||||
ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
|
||||
if (j == 0)
|
||||
ph->p_flags = PF_R | PF_X;
|
||||
@ -1973,10 +1986,13 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr,
|
||||
if (k != 1)
|
||||
continue;
|
||||
} else if (s->sh_type == SHT_RELX) {
|
||||
if (k != 2 && s != relocplt)
|
||||
continue;
|
||||
else if (k != 3 && s == relocplt)
|
||||
continue;
|
||||
if (s1->plt && s == s1->plt->reloc) {
|
||||
if (k != 3)
|
||||
continue;
|
||||
} else {
|
||||
if (k != 2)
|
||||
continue;
|
||||
}
|
||||
} else if (s->sh_type == SHT_NOBITS) {
|
||||
if (k != 6)
|
||||
continue;
|
||||
@ -2155,10 +2171,10 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
|
||||
put_dt(dynamic, DT_RELA, dyninf->rel_addr);
|
||||
put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
|
||||
put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
|
||||
if (s1->got && s1->got->relocplt) {
|
||||
if (s1->plt && s1->plt->reloc) {
|
||||
put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
|
||||
put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
|
||||
put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
|
||||
put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
|
||||
put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
|
||||
put_dt(dynamic, DT_PLTREL, DT_RELA);
|
||||
}
|
||||
put_dt(dynamic, DT_RELACOUNT, 0);
|
||||
@ -2166,10 +2182,10 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
|
||||
put_dt(dynamic, DT_REL, dyninf->rel_addr);
|
||||
put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
|
||||
put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
|
||||
if (s1->got && s1->got->relocplt) {
|
||||
if (s1->plt && s1->plt->reloc) {
|
||||
put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
|
||||
put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
|
||||
put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
|
||||
put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
|
||||
put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
|
||||
put_dt(dynamic, DT_PLTREL, DT_REL);
|
||||
}
|
||||
put_dt(dynamic, DT_RELCOUNT, 0);
|
||||
@ -2208,38 +2224,6 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
|
||||
put_dt(dynamic, DT_NULL, 0);
|
||||
}
|
||||
|
||||
/* Relocate remaining sections and symbols (that is those not related to
|
||||
dynamic linking) */
|
||||
static int final_sections_reloc(TCCState *s1)
|
||||
{
|
||||
int i;
|
||||
Section *s;
|
||||
|
||||
relocate_syms(s1, s1->symtab, 0);
|
||||
|
||||
if (s1->nb_errors != 0)
|
||||
return -1;
|
||||
|
||||
/* relocate sections */
|
||||
/* XXX: ignore sections with allocated relocations ? */
|
||||
for(i = 1; i < s1->nb_sections; i++) {
|
||||
s = s1->sections[i];
|
||||
if (s->reloc && (s != s1->got || s1->static_link))
|
||||
relocate_section(s1, s);
|
||||
}
|
||||
|
||||
/* relocate relocation entries if the relocation tables are
|
||||
allocated in the executable */
|
||||
for(i = 1; i < s1->nb_sections; i++) {
|
||||
s = s1->sections[i];
|
||||
if ((s->sh_flags & SHF_ALLOC) &&
|
||||
s->sh_type == SHT_RELX) {
|
||||
relocate_rel(s1, s);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove gaps between RELX sections.
|
||||
These gaps are a result of final_sections_reloc. Here some relocs are removed.
|
||||
The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
|
||||
@ -2250,7 +2234,7 @@ static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
|
||||
int i;
|
||||
unsigned long file_offset = 0;
|
||||
Section *s;
|
||||
Section *relocplt = s1->got ? s1->got->relocplt : NULL;
|
||||
Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
|
||||
|
||||
/* dynamic relocation table information, for .dynamic section */
|
||||
dyninf->rel_addr = dyninf->rel_size = 0;
|
||||
@ -2724,9 +2708,11 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||
|
||||
/* if building executable or DLL, then relocate each section
|
||||
except the GOT which is already relocated */
|
||||
ret = final_sections_reloc(s1);
|
||||
if (ret)
|
||||
relocate_syms(s1, s1->symtab, 0);
|
||||
ret = -1;
|
||||
if (s1->nb_errors != 0)
|
||||
goto the_end;
|
||||
relocate_sections(s1);
|
||||
if (dynamic) {
|
||||
update_reloc_sections (s1, &dyninf);
|
||||
dynamic->data_offset = dyninf.data_offset;
|
||||
|
10
tccmacho.c
10
tccmacho.c
@ -809,22 +809,14 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename)
|
||||
check_relocs(s1, &mo);
|
||||
ret = check_symbols(s1, &mo);
|
||||
if (!ret) {
|
||||
int i;
|
||||
Section *s;
|
||||
collect_sections(s1, &mo);
|
||||
relocate_syms(s1, s1->symtab, 0);
|
||||
mo.ep->entryoff = get_sym_addr(s1, "main", 1, 1)
|
||||
- get_segment(&mo, 1)->vmaddr;
|
||||
if (s1->nb_errors)
|
||||
goto do_ret;
|
||||
|
||||
for(i = 1; i < s1->nb_sections; i++) {
|
||||
s = s1->sections[i];
|
||||
if (s->reloc)
|
||||
relocate_section(s1, s);
|
||||
}
|
||||
relocate_sections(s1);
|
||||
convert_symbols(s1, &mo);
|
||||
|
||||
macho_write(s1, &mo, fp);
|
||||
}
|
||||
|
||||
|
12
tccpe.c
12
tccpe.c
@ -982,7 +982,7 @@ static void pe_build_exports(struct pe_info *pe)
|
||||
for (ord = 0; ord < sym_count; ++ord)
|
||||
{
|
||||
p = sorted[ord], sym_index = p->index, name = p->name;
|
||||
/* insert actual address later in relocate_section() */
|
||||
/* insert actual address later in relocate_sections() */
|
||||
put_elf_reloc(symtab_section, pe->thunk,
|
||||
func_o, R_XXX_RELATIVE, sym_index);
|
||||
*(DWORD*)(pe->thunk->data + name_o)
|
||||
@ -1937,7 +1937,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
|
||||
}
|
||||
}
|
||||
|
||||
/* need this for 'tccelf.c:relocate_section()' */
|
||||
/* need this for 'tccelf.c:relocate_sections()' */
|
||||
if (TCC_OUTPUT_DLL == s1->output_type)
|
||||
s1->output_type = TCC_OUTPUT_EXE;
|
||||
if (TCC_OUTPUT_MEMORY == s1->output_type)
|
||||
@ -1996,7 +1996,6 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
|
||||
{
|
||||
int ret;
|
||||
struct pe_info pe;
|
||||
int i;
|
||||
|
||||
memset(&pe, 0, sizeof pe);
|
||||
pe.filename = filename;
|
||||
@ -2018,12 +2017,7 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
|
||||
pe_assign_addresses(&pe);
|
||||
relocate_syms(s1, s1->symtab, 0);
|
||||
s1->pe_imagebase = pe.imagebase;
|
||||
for (i = 1; i < s1->nb_sections; ++i) {
|
||||
Section *s = s1->sections[i];
|
||||
if (s->reloc) {
|
||||
relocate_section(s1, s);
|
||||
}
|
||||
}
|
||||
relocate_sections(s1);
|
||||
pe.start_addr = (DWORD)
|
||||
(get_sym_addr(s1, pe.start_symbol, 1, 1) - pe.imagebase);
|
||||
if (s1->nb_errors)
|
||||
|
10
tccrun.c
10
tccrun.c
@ -277,15 +277,11 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
|
||||
s1->pe_imagebase = mem;
|
||||
#endif
|
||||
|
||||
/* relocate each section */
|
||||
for(i = 1; i < s1->nb_sections; i++) {
|
||||
s = s1->sections[i];
|
||||
if (s->reloc)
|
||||
relocate_section(s1, s);
|
||||
}
|
||||
#if !defined(TCC_TARGET_PE) || defined(TCC_TARGET_MACHO)
|
||||
/* relocate sections */
|
||||
#ifndef TCC_TARGET_PE
|
||||
relocate_plt(s1);
|
||||
#endif
|
||||
relocate_sections(s1);
|
||||
|
||||
for(i = 1; i < s1->nb_sections; i++) {
|
||||
s = s1->sections[i];
|
||||
|
@ -131,7 +131,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_
|
||||
/* The PLT slot refers to the relocation entry it needs via offset.
|
||||
The reloc entry is created below, so its offset is the current
|
||||
data_offset */
|
||||
relofs = s1->got->relocplt ? s1->got->relocplt->data_offset : 0;
|
||||
relofs = s1->plt->reloc ? s1->plt->reloc->data_offset : 0;
|
||||
|
||||
/* Jump to GOT entry where ld.so initially put the address of ip + 4 */
|
||||
p = section_ptr_add(plt, 16);
|
||||
@ -169,16 +169,12 @@ ST_FUNC void relocate_plt(TCCState *s1)
|
||||
}
|
||||
}
|
||||
|
||||
if (s1->got->relocplt) {
|
||||
int mem = s1->output_type == TCC_OUTPUT_MEMORY;
|
||||
if (s1->plt->reloc) {
|
||||
ElfW_Rel *rel;
|
||||
int x = s1->plt->sh_addr + 16 + 6;
|
||||
|
||||
p = s1->got->data;
|
||||
for_each_elem(s1->got->relocplt, 0, rel, ElfW_Rel) {
|
||||
int sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
write64le(p + rel->r_offset, mem ? sym->st_value : x);
|
||||
for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
|
||||
write64le(p + rel->r_offset, x);
|
||||
x += 16;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user