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.
Unified · Split
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #define ELF_PAGE_SIZE 0x1000 |
| 16 | 16 | |
| 17 | 17 | #define HAVE_SECTION_RELOC |
| 18 | +#define PCRELATIVE_DLLPLT 1 | |
| 18 | 19 | |
| 19 | 20 | enum float_abi { |
| 20 | 21 | ARM_SOFTFP_FLOAT, |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #define ELF_PAGE_SIZE 0x1000 |
| 15 | 15 | |
| 16 | 16 | #define HAVE_SECTION_RELOC |
| 17 | +#define PCRELATIVE_DLLPLT 1 | |
| 17 | 18 | |
| 18 | 19 | #else /* !TARGET_DEFS_ONLY */ |
| 19 | 20 | |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #define ELF_PAGE_SIZE 0x1000 |
| 16 | 16 | |
| 17 | 17 | #define HAVE_SECTION_RELOC |
| 18 | +#define PCRELATIVE_DLLPLT 0 | |
| 18 | 19 | |
| 19 | 20 | #else /* !TARGET_DEFS_ONLY */ |
| 20 | 21 | |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #define ELF_PAGE_SIZE 0x1000 |
| 16 | 16 | |
| 17 | 17 | #define HAVE_SECTION_RELOC |
| 18 | +#define PCRELATIVE_DLLPLT 0 | |
| 18 | 19 | |
| 19 | 20 | #else /* !TARGET_DEFS_ONLY */ |
| 20 | 21 | |
| @@ -1052,7 +1052,8 @@ ST_FUNC void build_got_entries(TCCState *s1) · 1051 unmodified lines | ||
| 1052 | 1052 | /* Proceed with PLT/GOT [entry] creation if any of the following |
| 1053 | 1053 | condition is met: |
| 1054 | 1054 | - it is an undefined reference (dynamic relocation needed) |
| 1055 | − - symbol is absolute (probably created by tcc_add_symbol) | |
| 1055 | + - symbol is absolute (probably created by tcc_add_symbol and | |
| 1056 | + thus might be too far from application code) | |
| 1056 | 1057 | - relocation requires a PLT/GOT (BUILD_GOTPLT_ENTRY or |
| 1057 | 1058 | ALWAYS_GOTPLT_ENTRY). */ |
| 1058 | 1059 | if (sym->st_shndx != SHN_UNDEF && |
| @@ -1060,6 +1061,15 @@ ST_FUNC void build_got_entries(TCCState *s1) · 1 unmodified line | ||
| 1060 | 1061 | relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY) |
| 1061 | 1062 | continue; |
| 1062 | 1063 | |
| 1064 | + /* Building a dynamic library but target is not capable of PC | |
| 1065 | + relative PLT entries. It can thus only use PLT entries if | |
| 1066 | + it expects one to be used (ALWAYS_GOTPLT_ENTRY). */ | |
| 1067 | + if (sym->st_shndx == SHN_UNDEF && | |
| 1068 | + s1->output_type == TCC_OUTPUT_DLL && | |
| 1069 | + !PCRELATIVE_DLLPLT && | |
| 1070 | + relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY) | |
| 1071 | + continue; | |
| 1072 | + | |
| 1063 | 1073 | #ifdef TCC_TARGET_X86_64 |
| 1064 | 1074 | if (type == R_X86_64_PLT32 && |
| 1065 | 1075 | ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) { |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #define ELF_PAGE_SIZE 0x200000 |
| 16 | 16 | |
| 17 | 17 | #define HAVE_SECTION_RELOC |
| 18 | +#define PCRELATIVE_DLLPLT 1 | |
| 18 | 19 | |
| 19 | 20 | #else /* !TARGET_DEFS_ONLY */ |
| 20 | 21 | |