aboutsummaryrefslogtreecommitdiff
path: root/tccelf.c
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2016-12-10 09:14:29 +0000
committerThomas Preud'homme <robotux@celest.fr>2016-12-10 09:44:09 +0000
commit0bf262864c95e555fbd077b8f30e64652d9113a6 (patch)
tree406f10fb08531733d18f2bf739e843e9573eb17a /tccelf.c
parente0fe69050d2df59da7370875c4f5eb557618e20c (diff)
downloadtinycc-0bf262864c95e555fbd077b8f30e64652d9113a6.tar.gz
tinycc-0bf262864c95e555fbd077b8f30e64652d9113a6.tar.bz2
Fix PLT creation for i386
i386 target does not have PC relative loads. Its ABI therefore require ebx register to points to the GOT when executing a PLT entry. This means that PLT entry cannot be used transparently, the compiler needs to expect execution of a PLT entry to be able to use one, that is a PLT entry should only be created if the relocation explicitely asks for it (eg. R_386_PLT32). This patch creates a new target macro PCRELATIVE_DLLPLT to indicate whether a target can do a PC relative load in PLT entry when building a dynamic library. Executable do not normally pose a problem because they are loaded at a fixed address and thus the absolute address of GOT can be used. Note that in such a case, if the compiler does not use a PLT aware relocation for external access then the code relocation will fall on the dynamic loader since there is no PLT entry to relocate too.
Diffstat (limited to 'tccelf.c')
-rw-r--r--tccelf.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/tccelf.c b/tccelf.c
index 7f1679d..df7375c 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -1052,7 +1052,8 @@ ST_FUNC void build_got_entries(TCCState *s1)
/* Proceed with PLT/GOT [entry] creation if any of the following
condition is met:
- it is an undefined reference (dynamic relocation needed)
- - symbol is absolute (probably created by tcc_add_symbol)
+ - symbol is absolute (probably created by tcc_add_symbol and
+ thus might be too far from application code)
- relocation requires a PLT/GOT (BUILD_GOTPLT_ENTRY or
ALWAYS_GOTPLT_ENTRY). */
if (sym->st_shndx != SHN_UNDEF &&
@@ -1060,6 +1061,15 @@ ST_FUNC void build_got_entries(TCCState *s1)
relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY)
continue;
+ /* Building a dynamic library but target is not capable of PC
+ relative PLT entries. It can thus only use PLT entries if
+ it expects one to be used (ALWAYS_GOTPLT_ENTRY). */
+ if (sym->st_shndx == SHN_UNDEF &&
+ s1->output_type == TCC_OUTPUT_DLL &&
+ !PCRELATIVE_DLLPLT &&
+ relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY)
+ continue;
+
#ifdef TCC_TARGET_X86_64
if (type == R_X86_64_PLT32 &&
ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) {