From 02795106e154d0daa6cd525415b44db0298e6c3a Mon Sep 17 00:00:00 2001 From: grischka Date: Thu, 28 Jan 2021 14:20:05 +0100 Subject: [PATCH] tccelf: use plt-reloc instead of relocplt --- arm-link.c | 10 +-- arm64-link.c | 10 +-- i386-link.c | 12 ++-- riscv64-link.c | 10 +-- tcc.h | 5 +- tccelf.c | 180 +++++++++++++++++++++++-------------------------- tccmacho.c | 10 +-- tccpe.c | 12 +--- tccrun.c | 10 +-- x86_64-link.c | 12 ++-- 10 files changed, 108 insertions(+), 163 deletions(-) diff --git a/arm-link.c b/arm-link.c index 420639a0..5d40f843 100644 --- a/arm-link.c +++ b/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); } } } diff --git a/arm64-link.c b/arm64-link.c index 8acd2aff..e4305fe5 100644 --- a/arm64-link.c +++ b/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); } } } diff --git a/i386-link.c b/i386-link.c index c9414693..a7969f07 100644 --- a/i386-link.c +++ b/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; } } diff --git a/riscv64-link.c b/riscv64-link.c index dbc3ee44..2aeefefb 100644 --- a/riscv64-link.c +++ b/riscv64-link.c @@ -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); } } } diff --git a/tcc.h b/tcc.h index 3f8647d1..81c1fc37 100644 --- a/tcc.h +++ b/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); diff --git a/tccelf.c b/tccelf.c index 64623cac..b6ed54e3 100644 --- a/tccelf.c +++ b/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; diff --git a/tccmacho.c b/tccmacho.c index ec05ffd0..ebc5091b 100644 --- a/tccmacho.c +++ b/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); } diff --git a/tccpe.c b/tccpe.c index 3f5965fd..70b83ed8 100644 --- a/tccpe.c +++ b/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) diff --git a/tccrun.c b/tccrun.c index 1d753b0e..4eeb3f1e 100644 --- a/tccrun.c +++ b/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]; diff --git a/x86_64-link.c b/x86_64-link.c index e072379d..83e8f1bb 100644 --- a/x86_64-link.c +++ b/x86_64-link.c @@ -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; } }