diff options
-rw-r--r-- | configure.ac | 28 | ||||
-rw-r--r-- | rts/Linker.c | 54 |
2 files changed, 47 insertions, 35 deletions
diff --git a/configure.ac b/configure.ac index ff0dc054af..4adf9c5558 100644 --- a/configure.ac +++ b/configure.ac @@ -1062,6 +1062,34 @@ if test "$use_large_address_space" = "yes" ; then AC_DEFINE([USE_LARGE_ADDRESS_SPACE], [1], [Enable single heap address space support]) fi +dnl ** Use MMAP in the runtime linker? +dnl -------------------------------------------------------------- + +case ${TargetOS} in + linux|freebsd|dragonfly|netbsd|openbsd|kfreebsdgnu|gnu|solaris2) + RtsLinkerUseMmap=1 + ;; + darwin) + # Don't use mmap on powerpc/darwin as the mmap there doesn't support + # reallocating. Reallocating is needed to allocate jump islands just + # after each object image. Jumps to these jump islands use relative + # branches which are limited to offsets that can be represented in + # 24-bits. + if test "$TargetArch" != "powerpc" ; then + RtsLinkerUseMmap=1 + else + RtsLinkerUseMmap=0 + fi + ;; + *) + # Windows (which doesn't have mmap) and everything else. + RtsLinkerUseMmap=0 + ;; + esac + +AC_DEFINE_UNQUOTED([RTS_LINKER_USE_MMAP], [$RtsLinkerUseMmap], + [Use mmap in the runtime linker]) + dnl ** Have libdw? dnl -------------------------------------------------------------- AC_ARG_ENABLE(libdw, diff --git a/rts/Linker.c b/rts/Linker.c index 09d4f6a8f9..61b10d8e0e 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -52,19 +52,7 @@ #include <dlfcn.h> #endif -#if (defined(powerpc_HOST_ARCH) && defined(linux_HOST_OS)) \ - || (!defined(powerpc_HOST_ARCH) && \ - ( defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || \ - defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS ) || \ - defined(openbsd_HOST_OS ) || defined(darwin_HOST_OS ) || \ - defined(kfreebsdgnu_HOST_OS) || defined(gnu_HOST_OS ) || \ - defined(solaris2_HOST_OS))) -/* Don't use mmap on powerpc/darwin as the mmap there doesn't support - * reallocating but we need to allocate jump islands just after each - * object images. Otherwise relative branches to jump islands can fail - * due to 24-bits displacement overflow. - */ -#define USE_MMAP 1 +#if RTS_LINKER_USE_MMAP #include <fcntl.h> #include <sys/mman.h> @@ -72,10 +60,6 @@ #include <unistd.h> #endif -#else - -#define USE_MMAP 0 - #endif @@ -90,7 +74,7 @@ #define SHORT_REL_BRANCH 1 #endif -#if (USE_MMAP && defined(SHORT_REL_BRANCH) && defined(linux_HOST_OS)) +#if (RTS_LINKER_USE_MMAP && defined(SHORT_REL_BRANCH) && defined(linux_HOST_OS)) #define USE_CONTIGUOUS_MMAP 1 #else #define USE_CONTIGUOUS_MMAP 0 @@ -397,7 +381,7 @@ typedef WINBOOL(WINAPI *LPRemoveDLLDirectory)(DLL_DIRECTORY_COOKIE Cookie); static void freeProddableBlocks (ObjectCode *oc); -#if USE_MMAP +#if RTS_LINKER_USE_MMAP /** * An allocated page being filled by the allocator */ @@ -825,7 +809,7 @@ initLinker_ (int retain_cafs) addDLLHandle(WSTR("*.exe"), GetModuleHandle(NULL)); #endif -#if USE_MMAP +#if RTS_LINKER_USE_MMAP m32_allocator_init(&allocator); #endif @@ -1493,7 +1477,7 @@ void ghci_enquire ( char* addr ) } #endif -#if USE_MMAP +#if RTS_LINKER_USE_MMAP #define ROUND_UP(x,size) ((x + size - 1) & ~(size - 1)) #define ROUND_DOWN(x,size) (x & ~(size - 1)) @@ -1834,7 +1818,7 @@ m32_alloc(m32_allocator m32, unsigned int size, * END (M32 ALLOCATOR) ***************************************************************************/ -#endif // USE_MMAP +#endif // RTS_LINKER_USE_MMAP /* * Remove symbols from the symbol table, and free oc->symbols. @@ -1892,7 +1876,7 @@ freePreloadObjectFile (ObjectCode *oc) #else - if (USE_MMAP && oc->imageMapped) { + if (RTS_LINKER_USE_MMAP && oc->imageMapped) { munmap(oc->image, oc->fileSize); } else { @@ -1924,7 +1908,7 @@ void freeObjectCode (ObjectCode *oc) for (i=0; i < oc->n_sections; i++) { if (oc->sections[i].start != NULL) { switch(oc->sections[i].alloc){ -#if USE_MMAP +#if RTS_LINKER_USE_MMAP case SECTION_MMAP: munmap(oc->sections[i].mapped_start, oc->sections[i].mapped_size); @@ -1950,7 +1934,7 @@ void freeObjectCode (ObjectCode *oc) /* Free symbol_extras. On x86_64 Windows, symbol_extras are allocated * alongside the image, so we don't need to free. */ #if NEED_SYMBOL_EXTRAS && (!defined(x86_64_HOST_ARCH) || !defined(mingw32_HOST_OS)) - if (USE_MMAP) { + if (RTS_LINKER_USE_MMAP) { if (!USE_CONTIGUOUS_MMAP && oc->symbol_extras != NULL) { m32_free(oc->symbol_extras, sizeof(SymbolExtra) * oc->n_symbol_extras); @@ -2386,7 +2370,7 @@ static HsInt loadArchive_ (pathchar *path) #endif memberSize); #elif defined(darwin_HOST_OS) - if (USE_MMAP) + if (RTS_LINKER_USE_MMAP) image = mmapForLinker(memberSize, MAP_ANONYMOUS, -1, 0); else { /* See loadObj() */ @@ -2484,7 +2468,7 @@ static HsInt loadArchive_ (pathchar *path) barf("loadArchive: GNU-variant index found, but already have an index, while reading filename from `%s'", path); } IF_DEBUG(linker, debugBelch("loadArchive: Found GNU-variant file index\n")); -#if USE_MMAP +#if RTS_LINKER_USE_MMAP gnuFileIndex = mmapForLinker(memberSize + 1, MAP_ANONYMOUS, -1, 0); #else gnuFileIndex = stgMallocBytes(memberSize + 1, "loadArchive(image)"); @@ -2542,14 +2526,14 @@ static HsInt loadArchive_ (pathchar *path) stgFree(fileName); if (gnuFileIndex != NULL) { -#if USE_MMAP +#if RTS_LINKER_USE_MMAP munmap(gnuFileIndex, gnuFileIndexSize + 1); #else stgFree(gnuFileIndex); #endif } -#if USE_MMAP +#if RTS_LINKER_USE_MMAP m32_allocator_flush(&allocator); #endif @@ -2588,7 +2572,7 @@ preloadObjectFile (pathchar *path) fileSize = st.st_size; -#if USE_MMAP +#if RTS_LINKER_USE_MMAP int fd; /* On many architectures malloc'd memory isn't executable, so we need to use @@ -2609,7 +2593,7 @@ preloadObjectFile (pathchar *path) // not 32-bit yet, we'll remap later close(fd); -#else /* !USE_MMAP */ +#else /* !RTS_LINKER_USE_MMAP */ FILE *f; /* load the image into memory */ @@ -2664,7 +2648,7 @@ preloadObjectFile (pathchar *path) return NULL; } -#endif /* USE_MMAP */ +#endif /* RTS_LINKER_USE_MMAP */ oc = mkOc(path, image, fileSize, rtsTrue, NULL, misalignment); @@ -3056,7 +3040,7 @@ static int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first ) { StgWord n; - if (USE_MMAP && USE_CONTIGUOUS_MMAP) { + if (RTS_LINKER_USE_MMAP && USE_CONTIGUOUS_MMAP) { n = roundUpToPage(oc->fileSize); /* Keep image and symbol_extras contiguous */ @@ -3078,7 +3062,7 @@ static int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first ) } } else if( count > 0 ) { - if (USE_MMAP) { + if (RTS_LINKER_USE_MMAP) { n = roundUpToPage(oc->fileSize); oc->symbol_extras = m32_alloc(&allocator, @@ -7004,7 +6988,7 @@ ocGetNames_MachO(ObjectCode* oc) if((sections[i].flags & SECTION_TYPE) == S_ZEROFILL) { char * zeroFillArea; - if (USE_MMAP) { + if (RTS_LINKER_USE_MMAP) { zeroFillArea = mmapForLinker(sections[i].size, MAP_ANONYMOUS, -1, 0); if (zeroFillArea == NULL) return 0; |