summaryrefslogtreecommitdiffstats
path: root/BaseTools/Source/C/GenFw
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2016-08-04 10:39:29 +0200
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2016-08-08 08:26:41 +0200
commitc9f297559be5fd60aefda24b18e77a4208c8dede (patch)
treec4676cdcd8b52079c62723ee12b9d3a7b60a8dbe /BaseTools/Source/C/GenFw
parent74bbe31b8d485da26ec7ffad5e78b8384a9eb9a5 (diff)
downloadedk2-c9f297559be5fd60aefda24b18e77a4208c8dede.tar.gz
edk2-c9f297559be5fd60aefda24b18e77a4208c8dede.tar.bz2
edk2-c9f297559be5fd60aefda24b18e77a4208c8dede.zip
BaseTools X64: fold PLT relocations into simple relative references
For X64/GCC, we use position independent code with hidden visibility to inform the compiler that symbol references are never resolved at runtime, which removes the need for PLTs and GOTs. However, in some cases, GCC has been reported to still emit PLT based relocations, which we need to handle in the ELF to PE/COFF perform by GenFw. Unlike GOT based relocations, which are non-trivial to handle since the indirections in the code can not be fixed up easily (although relocation types exist for X64 that annotate relocation targets as suitable for relaxation), PLT relocations simply point to jump targets, and we can relax such relocations by resolving them using the symbol directly rather than via a PLT entry that does nothing more than tail call the function we already know it is going to call (since all symbol references are resolved in the same module). So handle R_X86_64_PLT32 as a R_X86_64_PC32 relocation. Suggested-by: Steven Shi <steven.shi@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Liming Gao <liming.gao@intel.com>
Diffstat (limited to 'BaseTools/Source/C/GenFw')
-rw-r--r--BaseTools/Source/C/GenFw/Elf64Convert.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c
index 944c94b8f8..708c1a1d91 100644
--- a/BaseTools/Source/C/GenFw/Elf64Convert.c
+++ b/BaseTools/Source/C/GenFw/Elf64Convert.c
@@ -785,6 +785,17 @@ WriteSections64 (
*(INT32 *)Targ = (INT32)((INT64)(*(INT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
VerboseMsg ("Relocation: 0x%08X", *(UINT32*)Targ);
break;
+
+ case R_X86_64_PLT32:
+ //
+ // Treat R_X86_64_PLT32 relocations as R_X86_64_PC32: this is
+ // possible since we know all code symbol references resolve to
+ // definitions in the same module (UEFI has no shared libraries),
+ // and so there is never a reason to jump via a PLT entry,
+ // allowing us to resolve the reference using the symbol directly.
+ //
+ VerboseMsg ("Treating R_X86_64_PLT32 as R_X86_64_PC32 ...");
+ /* fall through */
case R_X86_64_PC32:
//
// Relative relocation: Symbol - Ip + Addend
@@ -935,6 +946,7 @@ WriteRelocations64 (
switch (ELF_R_TYPE(Rel->r_info)) {
case R_X86_64_NONE:
case R_X86_64_PC32:
+ case R_X86_64_PLT32:
break;
case R_X86_64_64:
VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X",