mirror of
https://github.com/mirror/tinycc.git
synced 2026-08-18 11:03:27 +08:00
lazy binding
Currently tcc does not use lazy binding. It puts all relocations in the RELX
section and solve them all at startup.
This was not working on bsd.
tcc.h:
- New RELPLT_SECTION_FMT for plt relocations
- New entry relocplt in struct Section
tccelf.c:
- put_elf_reloca: put R_JMP_SLOT in relocplt section
- build_got_entries*: Use two passes because R_JMP_SLOT and R_GLOB_DAT
can not be intermixed on some targets (arm, arm64)
- layout_sections: Calculate correct size relocplt section for DT_ values.
Make sure relocplt is last
- fill_dynamic: Add DT_ values when got is filled
move DT_VERSYM because dynamic linker cannot handle it standone
- Add note section for NetBSD
arm-link.c/arm64-link.c/i386-link.c/riscv64-link.c/x86_64-link.c:
- fill got table with pointer to plt section or symbol value in case
of TCC_OUTPUT_MEMORY
arm-link.c/arm64-link.c:
- fix offset first plt entry
i386-link.c/x86_64-link.c:
- use correct reloc entry
- use relofs - sizeof (ElfW_Rel) because the reloc is already done
lib/bcheck.c:
- no __libc_freeres on FreeBSD and NetBSD
tests/Makefile:
- Add -fno-stack-protector for OpenBSD
tests/tests2/Makefile:
- disable 106_pthread/114_bound_signal
This commit is contained in:
22
i386-link.c
22
i386-link.c
@@ -16,7 +16,7 @@
|
||||
#define ELF_PAGE_SIZE 0x1000
|
||||
|
||||
#define PCRELATIVE_DLLPLT 0
|
||||
#define RELOCATE_DLLPLT 0
|
||||
#define RELOCATE_DLLPLT 1
|
||||
|
||||
#else /* !TARGET_DEFS_ONLY */
|
||||
|
||||
@@ -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->reloc ? s1->got->reloc->data_offset : 0;
|
||||
relofs = s1->got->relocplt ? s1->got->relocplt->data_offset : 0;
|
||||
|
||||
/* Jump to GOT entry where ld.so initially put the address of ip + 4 */
|
||||
p = section_ptr_add(plt, 16);
|
||||
@@ -129,7 +129,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_
|
||||
p[1] = modrm;
|
||||
write32le(p + 2, got_offset);
|
||||
p[6] = 0x68; /* push $xxx */
|
||||
write32le(p + 7, relofs);
|
||||
write32le(p + 7, relofs - sizeof (ElfW_Rel));
|
||||
p[11] = 0xe9; /* jmp plt_start */
|
||||
write32le(p + 12, -(plt->data_offset));
|
||||
return plt_offset;
|
||||
@@ -147,7 +147,7 @@ ST_FUNC void relocate_plt(TCCState *s1)
|
||||
p = s1->plt->data;
|
||||
p_end = p + s1->plt->data_offset;
|
||||
|
||||
if (p < p_end) {
|
||||
if (s1->output_type != TCC_OUTPUT_DLL && p < p_end) {
|
||||
add32le(p + 2, s1->got->sh_addr);
|
||||
add32le(p + 8, s1->got->sh_addr);
|
||||
p += 16;
|
||||
@@ -156,6 +156,20 @@ ST_FUNC void relocate_plt(TCCState *s1)
|
||||
p += 16;
|
||||
}
|
||||
}
|
||||
|
||||
if (s1->got->relocplt) {
|
||||
int mem = s1->output_type == TCC_OUTPUT_MEMORY;
|
||||
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);
|
||||
x += 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user