summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Trofimovich <slyfox@gentoo.org>2015-06-23 07:39:34 -0500
committerAustin Seipp <austin@well-typed.com>2015-06-23 07:39:46 -0500
commitc0847967caf51ea4ca88d0ffc25fe1bd99dcabed (patch)
treef3f6b1efd8cc4a759c9831842dd0d2df02d9041e
parent55843f1c43ec3721a924cbbe5d422798819030c1 (diff)
downloadhaskell-c0847967caf51ea4ca88d0ffc25fe1bd99dcabed.tar.gz
powerpc: add basic support for PLT relocations (#10402)
Commit a93ab43ab5f40cadbedea2f6342b93c245e91434 enabled support for proper PIC relocations from assembler. Commit adds support for relocations of type: R_PPC_REL16_HI R_PPC_REL16_HA R_PPC_REL16_LO R_PPC_PLTREL24 They are used only when GHC is built in DYNAMIC_GHC_PROGRAMS = NO mode. Verified by running the following test: // cat a.c #include <stdio.h> void ffi_a_hello (int i) { fprintf (stderr, "WEEEEEEEE: i=%d\n", i); } -- cat A.hs {-# LANGUAGE ForeignFunctionInterface #-} module A where import Foreign.C foreign import ccall "ffi_a_hello" a :: CInt -> IO () # ghc -fPIC -c a.c -fforce-recomp # ghc -fPIC -c A.hs -fforce-recomp # ghc --interactive ./a.o A ... *A> a 42 WEEEEEEEE: i=42 See gory details in Trac #10402. Signed-off-by: Colin Watson <cjwatson@debian.org> Signed-off-by: Sergei Trofimovich <siarheit@google.com> Reviewed By: bgamari, austin Differential Revision: https://phabricator.haskell.org/D996 GHC Trac Issues: #10402
-rw-r--r--rts/Linker.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/rts/Linker.c b/rts/Linker.c
index f3b170b501..2437e8366b 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -5952,6 +5952,9 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
*(Elf32_Word *) P = value - P;
break;
+ case R_PPC_PLTREL24:
+ value -= 0x8000; /* See Note [.LCTOC1 in PPC PIC code] */
+ /* fallthrough */
case R_PPC_REL24:
delta = value - P;
@@ -5972,6 +5975,18 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
*(Elf_Word *) P = (*(Elf_Word *) P & 0xfc000003)
| (delta & 0x3fffffc);
break;
+
+ case R_PPC_REL16_LO:
+ *(Elf32_Half*) P = value - P;
+ break;
+
+ case R_PPC_REL16_HI:
+ *(Elf32_Half*) P = (value - P) >> 16;
+ break;
+
+ case R_PPC_REL16_HA:
+ *(Elf32_Half*) P = (value + 0x8000 - P) >> 16;
+ break;
# endif
#if x86_64_HOST_ARCH