diff options
author | Pepe Iborra <pepeiborra@fb.com> | 2020-11-04 13:55:39 -0800 |
---|---|---|
committer | GHC GitLab CI <ghc-ci@gitlab-haskell.org> | 2020-11-24 01:17:25 +0000 |
commit | eecf9f2726fb2508314a42860915edd13c752b34 (patch) | |
tree | bd8c7f01a48b98b02a16938455b4a8a98f16dd9c | |
parent | 237180d278f89b9528568f1e6ff6acd0376d7228 (diff) | |
download | haskell-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.rst | 28 | ||||
-rw-r--r-- | includes/rts/Flags.h | 12 | ||||
-rw-r--r-- | libraries/base/GHC/RTS/Flags.hsc | 3 | ||||
-rw-r--r-- | rts/Linker.c | 33 | ||||
-rw-r--r-- | rts/RtsFlags.c | 11 | ||||
-rw-r--r-- | rts/linker/Elf.c | 25 | ||||
-rw-r--r-- | rts/linker/MachO.c | 21 | ||||
-rw-r--r-- | rts/linker/SymbolExtras.c | 61 |
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; |