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 | #define ELF_PAGE_SIZE 0x1000 | 15 | #define ELF_PAGE_SIZE 0x1000 |
| 16 | 16 | ||
| 17 | #define HAVE_SECTION_RELOC | 17 | #define HAVE_SECTION_RELOC |
| 18 | #define PCRELATIVE_DLLPLT 1 | ||
| 18 | 19 | ||
| 19 | enum float_abi { | 20 | enum float_abi { |
| 20 | ARM_SOFTFP_FLOAT, | 21 | ARM_SOFTFP_FLOAT, |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | #define ELF_PAGE_SIZE 0x1000 | 14 | #define ELF_PAGE_SIZE 0x1000 |
| 15 | 15 | ||
| 16 | #define HAVE_SECTION_RELOC | 16 | #define HAVE_SECTION_RELOC |
| 17 | #define PCRELATIVE_DLLPLT 1 | ||
| 17 | 18 | ||
| 18 | #else /* !TARGET_DEFS_ONLY */ | 19 | #else /* !TARGET_DEFS_ONLY */ |
| 19 | 20 | ||
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #define ELF_PAGE_SIZE 0x1000 | 15 | #define ELF_PAGE_SIZE 0x1000 |
| 16 | 16 | ||
| 17 | #define HAVE_SECTION_RELOC | 17 | #define HAVE_SECTION_RELOC |
| 18 | #define PCRELATIVE_DLLPLT 0 | ||
| 18 | 19 | ||
| 19 | #else /* !TARGET_DEFS_ONLY */ | 20 | #else /* !TARGET_DEFS_ONLY */ |
| 20 | 21 | ||
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #define ELF_PAGE_SIZE 0x1000 | 15 | #define ELF_PAGE_SIZE 0x1000 |
| 16 | 16 | ||
| 17 | #define HAVE_SECTION_RELOC | 17 | #define HAVE_SECTION_RELOC |
| 18 | #define PCRELATIVE_DLLPLT 0 | ||
| 18 | 19 | ||
| 19 | #else /* !TARGET_DEFS_ONLY */ | 20 | #else /* !TARGET_DEFS_ONLY */ |
| 20 | 21 | ||
| @@ -1052,7 +1052,8 @@ ST_FUNC void build_got_entries(TCCState *s1) · 1051 unmodified lines | |||
| 1052 | /* Proceed with PLT/GOT [entry] creation if any of the following | 1052 | /* Proceed with PLT/GOT [entry] creation if any of the following |
| 1053 | condition is met: | 1053 | condition is met: |
| 1054 | - it is an undefined reference (dynamic relocation needed) | 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 | - relocation requires a PLT/GOT (BUILD_GOTPLT_ENTRY or | 1057 | - relocation requires a PLT/GOT (BUILD_GOTPLT_ENTRY or |
| 1057 | ALWAYS_GOTPLT_ENTRY). */ | 1058 | ALWAYS_GOTPLT_ENTRY). */ |
| 1058 | if (sym->st_shndx != SHN_UNDEF && | 1059 | if (sym->st_shndx != SHN_UNDEF && |
| @@ -1060,6 +1061,15 @@ ST_FUNC void build_got_entries(TCCState *s1) · 1 unmodified line | |||
| 1060 | relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY) | 1061 | relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY) |
| 1061 | continue; | 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 | #ifdef TCC_TARGET_X86_64 | 1073 | #ifdef TCC_TARGET_X86_64 |
| 1064 | if (type == R_X86_64_PLT32 && | 1074 | if (type == R_X86_64_PLT32 && |
| 1065 | ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) { | 1075 | ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) { |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #define ELF_PAGE_SIZE 0x200000 | 15 | #define ELF_PAGE_SIZE 0x200000 |
| 16 | 16 | ||
| 17 | #define HAVE_SECTION_RELOC | 17 | #define HAVE_SECTION_RELOC |
| 18 | #define PCRELATIVE_DLLPLT 1 | ||
| 18 | 19 | ||
| 19 | #else /* !TARGET_DEFS_ONLY */ | 20 | #else /* !TARGET_DEFS_ONLY */ |
| 20 | 21 | ||