summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPepe Iborra <pepeiborra@fb.com>2020-11-04 13:55:39 -0800
committerGHC GitLab CI <ghc-ci@gitlab-haskell.org>2020-11-24 01:17:25 +0000
commiteecf9f2726fb2508314a42860915edd13c752b34 (patch)
treebd8c7f01a48b98b02a16938455b4a8a98f16dd9c
parent237180d278f89b9528568f1e6ff6acd0376d7228 (diff)
downloadhaskell-eecf9f2726fb2508314a42860915edd13c752b34.tar.gz
Revert "Add a RTS option -xp to load PIC object anywhere in address space"
This reverts commit cb3f710d952c0a2bad539f76c2ab6d07ba894bea.
-rw-r--r--docs/users_guide/runtime_control.rst28
-rw-r--r--includes/rts/Flags.h12
-rw-r--r--libraries/base/GHC/RTS/Flags.hsc3
-rw-r--r--rts/Linker.c33
-rw-r--r--rts/RtsFlags.c11
-rw-r--r--rts/linker/Elf.c25
-rw-r--r--rts/linker/MachO.c21
-rw-r--r--rts/linker/SymbolExtras.c61
8 files changed, 73 insertions, 121 deletions
diff --git a/docs/users_guide/runtime_control.rst b/docs/users_guide/runtime_control.rst
index 0048a51837..a5c2f1474f 100644
--- a/docs/users_guide/runtime_control.rst
+++ b/docs/users_guide/runtime_control.rst
@@ -241,28 +241,6 @@ Miscellaneous RTS options
crashes if exception handling are enabled. In order to get more information
in compiled executables, C code or DLLs symbols need to be available.
-
-.. rts-flag:: -xp
-
- On 64-bit machines, the runtime linker usually needs to map object code
- into the low 2Gb of the address space, due to the x86_64 small memory model
- where most symbol references are 32 bits. The problem is that this 2Gb of
- address space can fill up, especially if you're loading a very large number
- of object files into GHCi.
-
- This flag offers a workaround, albeit a slightly convoluted one. To be able
- to load an object file outside of the low 2Gb, the object code needs to be
- compiled with ``-fPIC -fexternal-dynamic-refs``. When the ``+RTS -xp`` flag
- is passed, the linker will assume that all object files were compiled with
- ``-fPIC -fexternal-dynamic-refs`` and load them anywhere in the address
- space. It's up to you to arrange that the object files you load (including
- all packages) were compiled in the right way. If this is not the case for
- an object, the linker will probably fail with an error message when the
- problem is detected.
-
- On some platforms where PIC is always the case, e.g. x86_64 MacOS X, this
- flag is enabled by default.
-
.. rts-flag:: -xm ⟨address⟩
.. index::
@@ -272,10 +250,8 @@ Miscellaneous RTS options
This option is for working around memory allocation
problems only. Do not use unless GHCi fails with a message like
- “\ ``failed to mmap() memory below 2Gb``\ ”. Consider recompiling
- the objects with ``-fPIC -fexternal-dynamic-refs`` and using the
- ``-xp`` flag instead. If you need to use this option to get GHCi
- working on your machine, please file a bug.
+ “\ ``failed to mmap() memory below 2Gb``\ ”. If you need to use this
+ option to get GHCi working on your machine, please file a bug.
On 64-bit machines, the RTS needs to allocate memory in the low 2Gb
of the address space. Support for this across different operating
diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h
index 3582e6abde..63450d5ece 100644
--- a/includes/rts/Flags.h
+++ b/includes/rts/Flags.h
@@ -188,17 +188,6 @@ typedef struct _CONCURRENT_FLAGS {
*/
#define DEFAULT_TICK_INTERVAL USToTime(10000)
-/*
- * When linkerAlwaysPic is true, the runtime linker assume that all object
- * files were compiled with -fPIC -fexternal-dynamic-refs and load them
- * anywhere in the address space.
- */
-#if defined(x86_64_HOST_ARCH) && defined(darwin_HOST_OS)
-#define DEFAULT_LINKER_ALWAYS_PIC true
-#else
-#define DEFAULT_LINKER_ALWAYS_PIC false
-#endif
-
/* See Note [Synchronization of flags and base APIs] */
typedef struct _MISC_FLAGS {
Time tickInterval; /* units: TIME_RESOLUTION */
@@ -208,7 +197,6 @@ typedef struct _MISC_FLAGS {
bool generate_stack_trace;
bool machineReadable;
bool internalCounters; /* See Note [Internal Counter Stats] */
- bool linkerAlwaysPic; /* Assume the object code is always PIC */
StgWord linkerMemBase; /* address to ask the OS for memory
* for the linker, NULL ==> off */
} MISC_FLAGS;
diff --git a/libraries/base/GHC/RTS/Flags.hsc b/libraries/base/GHC/RTS/Flags.hsc
index 249bcd5a98..12cb828e6a 100644
--- a/libraries/base/GHC/RTS/Flags.hsc
+++ b/libraries/base/GHC/RTS/Flags.hsc
@@ -139,7 +139,6 @@ data MiscFlags = MiscFlags
, generateStackTrace :: Bool
, machineReadable :: Bool
, internalCounters :: Bool
- , linkerAlwaysPic :: Bool
, linkerMemBase :: Word
-- ^ address to ask the OS for memory for the linker, 0 ==> off
} deriving ( Show -- ^ @since 4.8.0.0
@@ -445,8 +444,6 @@ getMiscFlags = do
(#{peek MISC_FLAGS, machineReadable} ptr :: IO CBool))
<*> (toBool <$>
(#{peek MISC_FLAGS, internalCounters} ptr :: IO CBool))
- <*> (toBool <$>
- (#{peek MISC_FLAGS, linkerAlwaysPic} ptr :: IO CBool))
<*> #{peek MISC_FLAGS, linkerMemBase} ptr
getDebugFlags :: IO DebugFlags
diff --git a/rts/Linker.c b/rts/Linker.c
index 05f40b6e7f..4c69d0832e 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -74,6 +74,10 @@
# include <mach-o/fat.h>
#endif
+#if defined(x86_64_HOST_ARCH) && defined(darwin_HOST_OS)
+#define ALWAYS_PIC
+#endif
+
#if defined(dragonfly_HOST_OS)
#include <sys/tls.h>
#endif
@@ -199,7 +203,9 @@ static void freeNativeCode_ELF (ObjectCode *nc);
* We pick a default address based on the OS, but also make this
* configurable via an RTS flag (+RTS -xm)
*/
-#if defined(MAP_32BIT) || DEFAULT_LINKER_ALWAYS_PIC
+#if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
+
+#if defined(MAP_32BIT)
// Try to use MAP_32BIT
#define MMAP_32BIT_BASE_DEFAULT 0
#else
@@ -208,6 +214,7 @@ static void freeNativeCode_ELF (ObjectCode *nc);
#endif
static void *mmap_32bit_base = (void *)MMAP_32BIT_BASE_DEFAULT;
+#endif
static void ghciRemoveSymbolTable(HashTable *table, const SymbolName* key,
ObjectCode *owner)
@@ -478,10 +485,12 @@ initLinker_ (int retain_cafs)
}
# endif
+#if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
if (RtsFlags.MiscFlags.linkerMemBase != 0) {
// User-override for mmap_32bit_base
mmap_32bit_base = (void*)RtsFlags.MiscFlags.linkerMemBase;
}
+#endif
if (RTS_LINKER_USE_MMAP)
m32_allocator_init();
@@ -1009,30 +1018,29 @@ mmapForLinker (size_t bytes, uint32_t flags, int fd, int offset)
void *map_addr = NULL;
void *result;
size_t size;
- uint32_t tryMap32Bit = RtsFlags.MiscFlags.linkerAlwaysPic
- ? 0
- : TRY_MAP_32BIT;
static uint32_t fixed = 0;
IF_DEBUG(linker, debugBelch("mmapForLinker: start\n"));
size = roundUpToPage(bytes);
+#if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
mmap_again:
if (mmap_32bit_base != 0) {
map_addr = mmap_32bit_base;
}
+#endif
IF_DEBUG(linker,
debugBelch("mmapForLinker: \tprotection %#0x\n",
PROT_EXEC | PROT_READ | PROT_WRITE));
IF_DEBUG(linker,
debugBelch("mmapForLinker: \tflags %#0x\n",
- MAP_PRIVATE | tryMap32Bit | fixed | flags));
+ MAP_PRIVATE | TRY_MAP_32BIT | fixed | flags));
result = mmap(map_addr, size,
PROT_EXEC|PROT_READ|PROT_WRITE,
- MAP_PRIVATE|tryMap32Bit|fixed|flags, fd, offset);
+ MAP_PRIVATE|TRY_MAP_32BIT|fixed|flags, fd, offset);
if (result == MAP_FAILED) {
sysErrorBelch("mmap %" FMT_Word " bytes at %p",(W_)size,map_addr);
@@ -1040,9 +1048,8 @@ mmap_again:
return NULL;
}
-#if defined(x86_64_HOST_ARCH)
- if (RtsFlags.MiscFlags.linkerAlwaysPic) {
- } else if (mmap_32bit_base != 0) {
+#if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
+ if (mmap_32bit_base != 0) {
if (result == map_addr) {
mmap_32bit_base = (StgWord8*)map_addr + size;
} else {
@@ -1222,10 +1229,10 @@ void freeObjectCode (ObjectCode *oc)
#if defined(NEED_SYMBOL_EXTRAS) && (!defined(x86_64_HOST_ARCH) \
|| !defined(mingw32_HOST_OS))
if (RTS_LINKER_USE_MMAP) {
- if (!USE_CONTIGUOUS_MMAP && !RtsFlags.MiscFlags.linkerAlwaysPic &&
- oc->symbol_extras != NULL) {
- m32_free(oc->symbol_extras, sizeof(SymbolExtra) * oc->n_symbol_extras);
- }
+ if (!USE_CONTIGUOUS_MMAP && oc->symbol_extras != NULL) {
+ m32_free(oc->symbol_extras,
+ sizeof(SymbolExtra) * oc->n_symbol_extras);
+ }
}
else {
stgFree(oc->symbol_extras);
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c
index 37eafa5c55..ff9635ab24 100644
--- a/rts/RtsFlags.c
+++ b/rts/RtsFlags.c
@@ -236,7 +236,6 @@ void initRtsFlagsDefaults(void)
RtsFlags.MiscFlags.generate_dump_file = false;
RtsFlags.MiscFlags.machineReadable = false;
RtsFlags.MiscFlags.internalCounters = false;
- RtsFlags.MiscFlags.linkerAlwaysPic = DEFAULT_LINKER_ALWAYS_PIC;
RtsFlags.MiscFlags.linkerMemBase = 0;
#if defined(THREADED_RTS)
@@ -458,11 +457,6 @@ usage_text[] = {
" -e<n> Maximum number of outstanding local sparks (default: 4096)",
#endif
#if defined(x86_64_HOST_ARCH)
-#if !DEFAULT_LINKER_ALWAYS_PIC
-" -xp Assume that all object files were compiled with -fPIC",
-" -fexternal-dynamic-refs and load them anywhere in the address",
-" space",
-#endif
" -xm Base address to mmap memory in the GHCi linker",
" (hex; must be <80000000)",
#endif
@@ -1508,11 +1502,6 @@ error = true;
break;
#if defined(x86_64_HOST_ARCH)
- case 'p': /* linkerAlwaysPic */
- OPTION_UNSAFE;
- RtsFlags.MiscFlags.linkerAlwaysPic = true;
- break;
-
case 'm': /* linkerMemBase */
OPTION_UNSAFE;
if (rts_argv[arg][3] != '\0') {
diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
index 8954d68965..157e43b385 100644
--- a/rts/linker/Elf.c
+++ b/rts/linker/Elf.c
@@ -169,8 +169,6 @@ 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)");
@@ -320,7 +318,6 @@ ocDeinit_ELF(ObjectCode * oc)
}
stgFree(oc->info);
- oc->info = NULL;
}
}
@@ -753,7 +750,7 @@ ocGetNames_ELF ( ObjectCode* oc )
start = mem;
mapped_start = mem;
#else
- if (USE_CONTIGUOUS_MMAP || RtsFlags.MiscFlags.linkerAlwaysPic) {
+ if (USE_CONTIGUOUS_MMAP) {
// already mapped.
start = oc->image + offset;
alloc = SECTION_NOMEM;
@@ -1616,6 +1613,9 @@ 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 =
@@ -1632,6 +1632,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
Elf64_Sword payload = off;
memcpy((void*)P, &payload, sizeof(payload));
+#endif
break;
}
@@ -1644,6 +1645,9 @@ 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)
@@ -1659,11 +1663,15 @@ 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)
@@ -1679,6 +1687,7 @@ 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:
@@ -1700,6 +1709,9 @@ 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 */
@@ -1717,12 +1729,16 @@ 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)
@@ -1737,6 +1753,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
Elf64_Sword payload = off;
memcpy((void*)P, &payload, sizeof(payload));
+#endif
break;
}
#endif
diff --git a/rts/linker/MachO.c b/rts/linker/MachO.c
index de7a156403..8bdf35ee6b 100644
--- a/rts/linker/MachO.c
+++ b/rts/linker/MachO.c
@@ -99,8 +99,6 @@ bool ocMprotect_MachO( ObjectCode *oc );
void
ocInit_MachO(ObjectCode * oc)
{
- ocDeinit_MachO(oc);
-
oc->info = (struct ObjectCodeFormatInfo*)stgCallocBytes(
1, sizeof *oc->info,
"ocInit_MachO(ObjectCodeFormatInfo)");
@@ -162,19 +160,16 @@ ocInit_MachO(ObjectCode * oc)
void
ocDeinit_MachO(ObjectCode * oc) {
- if (oc->info != NULL) {
- if(oc->info->n_macho_symbols > 0) {
- stgFree(oc->info->macho_symbols);
- }
+ if(oc->info->n_macho_symbols > 0) {
+ stgFree(oc->info->macho_symbols);
+ }
#if defined(aarch64_HOST_ARCH)
- freeGot(oc);
- for(int i = 0; i < oc->n_sections; i++) {
- freeStubs(&oc->sections[i]);
- }
-#endif
- stgFree(oc->info);
- oc->info = NULL;
+ freeGot(oc);
+ for(int i = 0; i < oc->n_sections; i++) {
+ freeStubs(&oc->sections[i]);
}
+#endif
+ stgFree(oc->info);
}
static int
diff --git a/rts/linker/SymbolExtras.c b/rts/linker/SymbolExtras.c
index 4c40b10877..88541f44d0 100644
--- a/rts/linker/SymbolExtras.c
+++ b/rts/linker/SymbolExtras.c
@@ -19,12 +19,6 @@
#include "linker/SymbolExtras.h"
#include "linker/M32Alloc.h"
-#if defined(OBJFORMAT_ELF)
-# include "linker/Elf.h"
-#elif defined(OBJFORMAT_MACHO)
-# include "linker/MachO.h"
-#endif
-
#include <string.h>
#if RTS_LINKER_USE_MMAP
#include <sys/mman.h>
@@ -52,24 +46,8 @@
int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first )
{
size_t n;
- void* oldImage = oc->image;
-
- if (count > 0) {
- if (!RTS_LINKER_USE_MMAP) {
-
- // round up to the nearest 4
- int aligned = (oc->fileSize + 3) & ~3;
- int misalignment = oc->misalignment;
- oc->image -= misalignment;
- oc->image = stgReallocBytes( oc->image,
- misalignment +
- aligned + sizeof (SymbolExtra) * count,
- "ocAllocateSymbolExtras" );
- oc->image += misalignment;
-
- oc->symbol_extras = (SymbolExtra *) (oc->image + aligned);
- } else if (USE_CONTIGUOUS_MMAP || RtsFlags.MiscFlags.linkerAlwaysPic) {
+ if (RTS_LINKER_USE_MMAP && USE_CONTIGUOUS_MMAP) {
n = roundUpToPage(oc->fileSize);
/* Keep image and symbol_extras contiguous */
@@ -85,37 +63,42 @@ int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first )
oc->imageMapped = true;
oc->fileSize = n + (sizeof(SymbolExtra) * count);
oc->symbol_extras = (SymbolExtra *) (oc->image + n);
- if (mprotect(new, allocated_size,
- PROT_READ | PROT_WRITE | PROT_EXEC) != 0) {
- sysErrorBelch("unable to protect memory");
+ if(mprotect(new, allocated_size, PROT_READ | PROT_EXEC) != 0) {
+ sysErrorBelch("unable to protect memory");
}
}
else {
oc->symbol_extras = NULL;
return 0;
}
- } else {
+ }
+ else if( count > 0 ) {
+ if (RTS_LINKER_USE_MMAP) {
+ n = roundUpToPage(oc->fileSize);
+
oc->symbol_extras = m32_alloc(sizeof(SymbolExtra) * count, 8);
if (oc->symbol_extras == NULL) return 0;
}
+ else {
+ // round up to the nearest 4
+ int aligned = (oc->fileSize + 3) & ~3;
+ int misalignment = oc->misalignment;
+
+ oc->image -= misalignment;
+ oc->image = stgReallocBytes( oc->image,
+ misalignment +
+ aligned + sizeof (SymbolExtra) * count,
+ "ocAllocateSymbolExtras" );
+ oc->image += misalignment;
+
+ oc->symbol_extras = (SymbolExtra *) (oc->image + aligned);
+ }
}
if (oc->symbol_extras != NULL) {
memset( oc->symbol_extras, 0, sizeof (SymbolExtra) * count );
}
- // ObjectCodeFormatInfo contains computed addresses based on offset to
- // image, if the address of image changes, we need to invalidate
- // the ObjectCodeFormatInfo and recompute it.
- if (oc->image != oldImage) {
-#if defined(OBJFORMAT_MACHO)
- ocInit_MachO( oc );
-#endif
-#if defined(OBJFORMAT_ELF)
- ocInit_ELF( oc );
-#endif
- }
-
oc->first_symbol_extra = first;
oc->n_symbol_extras = count;