summaryrefslogtreecommitdiff
path: root/rts/linker/Elf.c
diff options
context:
space:
mode:
authorZejun Wu <watashi@fb.com>2018-10-15 13:52:36 -0400
committerBen Gamari <ben@smart-cactus.org>2018-10-15 19:24:16 -0400
commit104599f3f157613589e78627c915e4dc20ee54b4 (patch)
treee640f6b00972a83a0dda163757cf144acd4ef70d /rts/linker/Elf.c
parent165d3d5ddaecc7dbe7f5ac051834a7619463efb0 (diff)
downloadhaskell-104599f3f157613589e78627c915e4dc20ee54b4.tar.gz
Add a RTS option -xp to load PIC object anywhere in address space
Add a RTS option -xp to load PIC object anywhere in address space. We do this by relaxing the requirement of <0x80000000 result of `mmapForLinker` and implying USE_CONTIGUOUS_MMAP. We also need to change calls to `ocInit` and `ocGetNames` to avoid dangling pointers when the address of `oc->image` is changed by `ocAllocateSymbolExtra`. Test Plan: ``` $ uname -a Linux localhost 4.18.8-arch1-1-ARCH #1 SMP PREEMPT Sat Sep 15 20:34:48 UTC 2018 x86_64 GNU/Linux $ cat mk/build.mk DYNAMIC_GHC_PROGRAMS = NO DYNAMIC_BY_DEFAULT = NO GhcRTSWays += thr_debug EXTRA_HC_OPTS += -debug WAY_p_HC_OPTS += -fPIC -fexternal-dynamic-refs $ inplace/bin/ghc-stage2 --interactive -prof +RTS -xp GHCi, version 8.7.20180928: http://www.haskell.org/ghc/ :? for help ghc-stage2: R_X86_64_32 relocation out of range: ghczmprim_GHCziTypes_ZMZN_closure = 7f690bffab59 Recompile /data/users/watashi/ghc/libraries/ghc-prim/dist-install/build/HSghc-prim -0.5.3.o with -fPIC -fexternal-dynamic-refs. ghc-stage2: unable to load package `ghc-prim-0.5.3' $ strace -f -e open,mmap inplace/bin/ghc-stage2 --interactive -prof -fexternal-interpreter -opti+RTS -opti-xp ... [pid 1355283] open("/data/users/watashi/ghc/libraries/base/dist-install/build/libHSbas e-4.12.0.0_p.a", O_RDONLY) = 14 [pid 1355283] mmap(NULL, 8192, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6a84842000 [pid 1355283] open("/data/users/watashi/ghc/libraries/base/dist-install/build/libHSbas e-4.12.0.0_p.a", O_RDONLY) = 14 [pid 1355283] mmap(NULL, 8192, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6a84676000 ... Prelude> System.Posix.Process.getProcessID ... [pid 1355283] open("/data/users/watashi/ghc/libraries/unix/dist-install/build/libHSuni x-2.7.2.2_p.a", O_RDONLY) = 14 [pid 1355283] mmap(NULL, 45056, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6a67d60000 [pid 1355283] open("/data/users/watashi/ghc/libraries/unix/dist-install/build/libHSuni x-2.7.2.2_p.a", O_RDONLY) = 14 [pid 1355283] mmap(NULL, 57344, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6a67d52000 ... ``` ``` $ uname -a Darwin watashis-iMac.local 18.0.0 Darwin Kernel Version 18.0.0: Wed Aug 22 20:13:40 PDT 2018; root:xnu-4903.201.2~1/RELEASE_X86_64 x86_64 $ mv /Users/watashi/gao/ghc/libraries/integer-gmp/dist-install/build/HSintege r-gmp-1.0.2.0.o{,._DISABLE_GHC_ISSUE_15105} $ inplace/bin/ghc-stage2 --interactive +RTS -xp GHCi, version 8.7.20181003: http://www.haskell.org/ghc/ :? for help Prelude> System.Posix.Process.getProcessID 42791 Prelude> Data.Set.fromList [1 .. 10] fromList [1,2,3,4,5,6,7,8,9,10] Prelude> Leaving GHCi. $ inplace/bin/ghc-stage2 --interactive -prof -fexternal-interpreter GHCi, version 8.7.20181003: http://www.haskell.org/ghc/ :? for help Prelude> System.Posix.Process.getProcessID 42806 Prelude> Data.Set.fromList [1 .. 10] fromList [1,2,3,4,5,6,7,8,9,10] Prelude> Leaving GHCi. ``` Also test with something that used to hit the 2Gb limit and it loads and runs without problem. Reviewers: simonmar, bgamari, angerman, Phyx, hvr, erikd Reviewed By: simonmar Subscribers: rwbarton, carter Differential Revision: https://phabricator.haskell.org/D5195
Diffstat (limited to 'rts/linker/Elf.c')
-rw-r--r--rts/linker/Elf.c25
1 files changed, 4 insertions, 21 deletions
diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
index fd24a92630..fe87aed0b0 100644
--- a/rts/linker/Elf.c
+++ b/rts/linker/Elf.c
@@ -169,6 +169,8 @@ get_shndx_table(Elf_Ehdr* ehdr)
void
ocInit_ELF(ObjectCode * oc)
{
+ ocDeinit_ELF(oc);
+
oc->info = (struct ObjectCodeFormatInfo*)stgCallocBytes(
1, sizeof *oc->info,
"ocInit_Elf(ObjectCodeFormatInfo)");
@@ -318,6 +320,7 @@ ocDeinit_ELF(ObjectCode * oc)
}
stgFree(oc->info);
+ oc->info = NULL;
}
}
@@ -754,7 +757,7 @@ ocGetNames_ELF ( ObjectCode* oc )
start = mem;
mapped_start = mem;
#else
- if (USE_CONTIGUOUS_MMAP) {
+ if (USE_CONTIGUOUS_MMAP || RtsFlags.MiscFlags.linkerAlwaysPic) {
// already mapped.
start = oc->image + offset;
alloc = SECTION_NOMEM;
@@ -1584,9 +1587,6 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
case COMPAT_R_X86_64_PC32:
{
-#if defined(ALWAYS_PIC)
- barf("R_X86_64_PC32 relocation, but ALWAYS_PIC.");
-#else
StgInt64 off = value - P;
if (off != (Elf64_Sword)off && X86_64_ELF_NONPIC_HACK) {
StgInt64 pltAddress =
@@ -1603,7 +1603,6 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
Elf64_Sword payload = off;
memcpy((void*)P, &payload, sizeof(payload));
-#endif
break;
}
@@ -1616,9 +1615,6 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
case COMPAT_R_X86_64_32:
{
-#if defined(ALWAYS_PIC)
- barf("R_X86_64_32 relocation, but ALWAYS_PIC.");
-#else
if (value != (Elf64_Word)value && X86_64_ELF_NONPIC_HACK) {
StgInt64 pltAddress =
(StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)
@@ -1634,15 +1630,11 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
Elf64_Word payload = value;
memcpy((void*)P, &payload, sizeof(payload));
-#endif
break;
}
case COMPAT_R_X86_64_32S:
{
-#if defined(ALWAYS_PIC)
- barf("R_X86_64_32S relocation, but ALWAYS_PIC.");
-#else
if ((StgInt64)value != (Elf64_Sword)value && X86_64_ELF_NONPIC_HACK) {
StgInt64 pltAddress =
(StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)
@@ -1658,7 +1650,6 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
Elf64_Sword payload = value;
memcpy((void*)P, &payload, sizeof(payload));
-#endif
break;
}
case COMPAT_R_X86_64_REX_GOTPCRELX:
@@ -1680,9 +1671,6 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
#if defined(dragonfly_HOST_OS)
case COMPAT_R_X86_64_GOTTPOFF:
{
-#if defined(ALWAYS_PIC)
- barf("R_X86_64_GOTTPOFF relocation, but ALWAYS_PIC.");
-#else
/* determine the offset of S to the current thread's tls
area
XXX: Move this to the beginning of function */
@@ -1700,16 +1688,12 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
Elf64_SWord payload = off;
memcpy((void*)P, &payload, sizeof(payload));
-#endif
break;
}
#endif
case COMPAT_R_X86_64_PLT32:
{
-#if defined(ALWAYS_PIC)
- barf("R_X86_64_PLT32 relocation, but ALWAYS_PIC.");
-#else
StgInt64 off = value - P;
if (off != (Elf64_Sword)off) {
StgInt64 pltAddress = (StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)
@@ -1724,7 +1708,6 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
Elf64_Sword payload = off;
memcpy((void*)P, &payload, sizeof(payload));
-#endif
break;
}
#endif