summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-01-30 10:05:19 -0500
committerBen Gamari <ben@smart-cactus.org>2019-01-30 10:05:19 -0500
commit172a59335fa6c76b17fb6795e87fbc7fcfd198e6 (patch)
tree6e5e940cb2c6ae9110807fa0d637a280c63b4220 /rts
parent76c8fd674435a652c75a96c85abbf26f1f221876 (diff)
downloadhaskell-172a59335fa6c76b17fb6795e87fbc7fcfd198e6.tar.gz
Revert "Batch merge"
This reverts commit 76c8fd674435a652c75a96c85abbf26f1f221876.
Diffstat (limited to 'rts')
-rw-r--r--rts/Linker.c90
-rw-r--r--rts/LinkerInternals.h4
-rw-r--r--rts/RtsFlags.c11
-rw-r--r--rts/linker/Elf.c112
-rw-r--r--rts/linker/Elf.h2
-rw-r--r--rts/linker/MachO.c40
-rw-r--r--rts/linker/MachO.h2
-rw-r--r--rts/linker/PEi386.c2
-rw-r--r--rts/linker/PEi386.h2
-rw-r--r--rts/linker/SymbolExtras.c84
-rw-r--r--rts/linker/SymbolExtras.h2
-rw-r--r--rts/sm/OSMem.h10
12 files changed, 158 insertions, 203 deletions
diff --git a/rts/Linker.c b/rts/Linker.c
index b6f1de9be6..ac030af837 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -72,6 +72,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
@@ -208,7 +212,9 @@ int ocTryLoad( ObjectCode* oc );
* 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
@@ -217,6 +223,7 @@ int ocTryLoad( ObjectCode* oc );
#endif
static void *mmap_32bit_base = (void *)MMAP_32BIT_BASE_DEFAULT;
+#endif
static void ghciRemoveSymbolTable(HashTable *table, const SymbolName* key,
ObjectCode *owner)
@@ -489,10 +496,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();
@@ -1000,32 +1009,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(x86_64_HOST_ARCH)
+#if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
mmap_again:
-#endif
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);
@@ -1033,9 +1039,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 {
@@ -1203,10 +1208,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);
@@ -1286,8 +1291,6 @@ mkOc( pathchar *path, char *image, int imageSize,
#if defined(NEED_SYMBOL_EXTRAS)
oc->symbol_extras = NULL;
#endif
- oc->bssBegin = NULL;
- oc->bssEnd = NULL;
oc->imageMapped = mapped;
oc->misalignment = misalignment;
@@ -1501,39 +1504,17 @@ HsInt loadOc (ObjectCode* oc)
}
/* Note [loadOc orderings]
- The order of `ocAllocateExtras` and `ocGetNames` matters. For MachO
- and ELF, `ocInit` and `ocGetNames` initialize a bunch of pointers based
- on the offset to `oc->image`, but `ocAllocateExtras` may relocate
- the address of `oc->image` and invalidate those pointers. So we must
- compute or recompute those pointers after `ocAllocateExtras`.
+ ocAllocateSymbolsExtras has only two pre-requisites, it must run after
+ preloadObjectFile and ocVerify. Neither have changed. On most targets
+ allocating the extras is independent on parsing the section data, so the
+ order between these two never mattered.
On Windows, when we have an import library we (for now, as we don't honor
the lazy loading semantics of the library and instead GHCi is already
lazy) don't use the library after ocGetNames as it just populates the
- symbol table. Allocating space for jump tables in ocAllocateExtras
+ symbol table. Allocating space for jump tables in ocAllocateSymbolExtras
would just be a waste then as we'll be stopping further processing of the
- library in the next few steps. If necessary, the actual allocation
- happens in `ocGetNames_PEi386` and `ocAllocateExtras_PEi386` simply
- set the correct pointers.
- */
-
-#if defined(NEED_SYMBOL_EXTRAS)
-# if defined(OBJFORMAT_MACHO)
- r = ocAllocateExtras_MachO ( oc );
- if (!r) {
- IF_DEBUG(linker,
- debugBelch("loadOc: ocAllocateExtras_MachO failed\n"));
- return r;
- }
-# elif defined(OBJFORMAT_ELF)
- r = ocAllocateExtras_ELF ( oc );
- if (!r) {
- IF_DEBUG(linker,
- debugBelch("loadOc: ocAllocateExtras_ELF failed\n"));
- return r;
- }
-# endif
-#endif
+ library in the next few steps. */
/* build the symbol list for this image */
# if defined(OBJFORMAT_ELF)
@@ -1551,8 +1532,22 @@ HsInt loadOc (ObjectCode* oc)
}
#if defined(NEED_SYMBOL_EXTRAS)
-# if defined(OBJFORMAT_PEi386)
- ocAllocateExtras_PEi386 ( oc );
+# if defined(OBJFORMAT_MACHO)
+ r = ocAllocateSymbolExtras_MachO ( oc );
+ if (!r) {
+ IF_DEBUG(linker,
+ debugBelch("loadOc: ocAllocateSymbolExtras_MachO failed\n"));
+ return r;
+ }
+# elif defined(OBJFORMAT_ELF)
+ r = ocAllocateSymbolExtras_ELF ( oc );
+ if (!r) {
+ IF_DEBUG(linker,
+ debugBelch("loadOc: ocAllocateSymbolExtras_ELF failed\n"));
+ return r;
+ }
+# elif defined(OBJFORMAT_PEi386)
+ ocAllocateSymbolExtras_PEi386 ( oc );
# endif
#endif
@@ -1838,3 +1833,4 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc,
start, (void*)((StgWord)start + size),
size, kind ));
}
+
diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h
index 81a09fe3ae..e284cd6a56 100644
--- a/rts/LinkerInternals.h
+++ b/rts/LinkerInternals.h
@@ -201,10 +201,6 @@ typedef struct _ObjectCode {
unsigned long first_symbol_extra;
unsigned long n_symbol_extras;
#endif
- /* Additional memory that is preallocated and contiguous with image
- which can be used used to relocate bss sections. */
- char* bssBegin;
- char* bssEnd;
ForeignExportStablePtr *stable_ptrs;
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 b647d207cb..9ea10d443f 100644
--- a/rts/linker/Elf.c
+++ b/rts/linker/Elf.c
@@ -53,13 +53,11 @@
* SILENTLY generate crashing code for data references. This hack is
* enabled by X86_64_ELF_NONPIC_HACK.
*
- * One workaround is to use shared Haskell libraries. This is the case
- * when dynamically-linked GHCi is used.
- *
- * Another workaround is to keep the static libraries but compile them
- * with -fPIC -fexternal-dynamic-refs, because that will generate PIC
- * references to data which can be relocated. This is the case when
- * +RTS -xp is passed.
+ * One workaround is to use shared Haskell libraries. This is
+ * coming. Another workaround is to keep the static libraries but
+ * compile them with -fPIC, because that will generate PIC references
+ * to data which can be relocated. The PIC code is still too green to
+ * do this systematically, though.
*
* See bug #781
* See thread http://www.haskell.org/pipermail/cvs-ghc/2007-September/038458.html
@@ -76,7 +74,7 @@
* Sym*_NeedsProto: the symbol is undefined and we add a dummy
* default proto extern void sym(void);
*/
-#define X86_64_ELF_NONPIC_HACK (!RtsFlags.MiscFlags.linkerAlwaysPic)
+#define X86_64_ELF_NONPIC_HACK 1
#if defined(sparc_HOST_ARCH)
# define ELF_TARGET_SPARC /* Used inside <elf.h> */
@@ -171,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)");
@@ -322,7 +318,6 @@ ocDeinit_ELF(ObjectCode * oc)
}
stgFree(oc->info);
- oc->info = NULL;
}
}
@@ -581,7 +576,7 @@ ocVerifyImage_ELF ( ObjectCode* oc )
/* Figure out what kind of section it is. Logic derived from
Figure 1.14 ("Special Sections") of the ELF document
("Portable Formats Specification, Version 1.1"). */
-static SectionKind getSectionKind_ELF( Elf_Shdr *hdr, int *is_bss )
+static int getSectionKind_ELF( Elf_Shdr *hdr, int *is_bss )
{
*is_bss = false;
@@ -683,31 +678,23 @@ ocGetNames_ELF ( ObjectCode* oc )
StgWord mapped_size = 0, mapped_offset = 0;
StgWord size = shdr[i].sh_size;
StgWord offset = shdr[i].sh_offset;
- StgWord align = shdr[i].sh_addralign;
if (is_bss && size > 0) {
/* This is a non-empty .bss section. Allocate zeroed space for
it, and set its .sh_offset field such that
ehdrC + .sh_offset == addr_of_zeroed_space. */
-#if defined(NEED_GOT) || RTS_LINKER_USE_MMAP
- if (USE_CONTIGUOUS_MMAP || RtsFlags.MiscFlags.linkerAlwaysPic) {
- /* The space for bss sections is already preallocated */
- ASSERT(oc->bssBegin != NULL);
- alloc = SECTION_NOMEM;
- start =
- oc->image + roundUpToAlign(oc->bssBegin - oc->image, align);
- oc->bssBegin = (char*)start + size;
- ASSERT(oc->bssBegin <= oc->bssEnd);
- } else {
- /* Use mmapForLinker to allocate .bss, otherwise the malloced
- * address might be out of range for sections that are mmaped.
- */
- alloc = SECTION_MMAP;
- start = mmapForLinker(size, MAP_ANONYMOUS, -1, 0);
- mapped_start = start;
- mapped_offset = 0;
- mapped_size = roundUpToPage(size);
- }
+#if defined(NEED_GOT)
+ /* always use mmap if we use GOT slots. Otherwise the malloced
+ * address might be out of range for sections that are mmaped.
+ */
+ alloc = SECTION_MMAP;
+ start = mmap(NULL, size,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_ANON | MAP_PRIVATE,
+ -1, 0);
+ mapped_start = start;
+ mapped_offset = 0;
+ mapped_size = roundUpToPage(size);
#else
alloc = SECTION_MALLOC;
start = stgCallocBytes(1, size, "ocGetNames_ELF(BSS)");
@@ -767,7 +754,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;
@@ -1598,6 +1585,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 =
@@ -1614,6 +1604,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
Elf64_Sword payload = off;
memcpy((void*)P, &payload, sizeof(payload));
+#endif
break;
}
@@ -1626,6 +1617,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)
@@ -1641,11 +1635,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)
@@ -1661,6 +1659,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:
@@ -1682,6 +1681,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 */
@@ -1699,12 +1701,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)
@@ -1719,6 +1725,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
}
Elf64_Sword payload = off;
memcpy((void*)P, &payload, sizeof(payload));
+#endif
break;
}
#endif
@@ -1884,27 +1891,22 @@ int ocRunInit_ELF( ObjectCode *oc )
#if defined(NEED_SYMBOL_EXTRAS)
-int ocAllocateExtras_ELF( ObjectCode *oc )
+int ocAllocateSymbolExtras_ELF( ObjectCode *oc )
{
- Elf_Ehdr *ehdr = (Elf_Ehdr *) oc->image;
- Elf_Shdr* shdr = (Elf_Shdr *) ( ((char *)oc->image) + ehdr->e_shoff );
- Elf_Shdr* symtab = NULL;
- Elf_Word shnum = elf_shnum(ehdr);
- int bssSize = 0;
-
- for (Elf_Word i = 0; i < shnum; ++i) {
- if(shdr[i].sh_type == SHT_SYMTAB) {
- symtab = &shdr[i];
- } else {
- int isBss = 0;
- getSectionKind_ELF(&shdr[i], &isBss);
- if (isBss && shdr[i].sh_size > 0) {
- bssSize += roundUpToAlign(shdr[i].sh_size, shdr[i].sh_addralign);
- }
- }
- }
+ Elf_Ehdr *ehdr;
+ Elf_Shdr* shdr;
+ Elf_Word i, shnum;
+
+ ehdr = (Elf_Ehdr *) oc->image;
+ shdr = (Elf_Shdr *) ( ((char *)oc->image) + ehdr->e_shoff );
+
+ shnum = elf_shnum(ehdr);
+
+ for( i = 0; i < shnum; i++ )
+ if( shdr[i].sh_type == SHT_SYMTAB )
+ break;
- if (symtab == NULL)
+ if( i == shnum )
{
// Not having a symbol table is not in principle a problem.
// When an object file has no symbols then the 'strip' program
@@ -1914,15 +1916,15 @@ int ocAllocateExtras_ELF( ObjectCode *oc )
return 1;
}
- if( symtab->sh_entsize != sizeof( Elf_Sym ) )
+ if( shdr[i].sh_entsize != sizeof( Elf_Sym ) )
{
errorBelch( "The entry size (%d) of the symtab isn't %d\n",
- (int) symtab->sh_entsize, (int) sizeof( Elf_Sym ) );
+ (int) shdr[i].sh_entsize, (int) sizeof( Elf_Sym ) );
return 0;
}
- return ocAllocateExtras(oc, symtab->sh_size / sizeof( Elf_Sym ), 0, bssSize);
+ return ocAllocateSymbolExtras( oc, shdr[i].sh_size / sizeof( Elf_Sym ), 0 );
}
#endif /* NEED_SYMBOL_EXTRAS */
diff --git a/rts/linker/Elf.h b/rts/linker/Elf.h
index 30c993b98c..b0d6638e6a 100644
--- a/rts/linker/Elf.h
+++ b/rts/linker/Elf.h
@@ -13,6 +13,6 @@ int ocVerifyImage_ELF ( ObjectCode* oc );
int ocGetNames_ELF ( ObjectCode* oc );
int ocResolve_ELF ( ObjectCode* oc );
int ocRunInit_ELF ( ObjectCode* oc );
-int ocAllocateExtras_ELF ( ObjectCode *oc );
+int ocAllocateSymbolExtras_ELF( ObjectCode *oc );
#include "EndPrivate.h"
diff --git a/rts/linker/MachO.c b/rts/linker/MachO.c
index ca5befca77..c6a6c28440 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
@@ -187,22 +182,19 @@ resolveImports(
#if defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH)
int
-ocAllocateExtras_MachO(ObjectCode* oc)
+ocAllocateSymbolExtras_MachO(ObjectCode* oc)
{
- IF_DEBUG(linker, debugBelch("ocAllocateExtras_MachO: start\n"));
+ IF_DEBUG(linker, debugBelch("ocAllocateSymbolExtras_MachO: start\n"));
if (NULL != oc->info->symCmd) {
- IF_DEBUG(linker,
- debugBelch("ocAllocateExtras_MachO: allocate %d symbols\n",
- oc->info->symCmd->nsyms));
- IF_DEBUG(linker, debugBelch("ocAllocateExtras_MachO: done\n"));
- return ocAllocateExtras(oc, oc->info->symCmd->nsyms, 0, 0);
+ IF_DEBUG(linker, debugBelch("ocAllocateSymbolExtras_MachO: allocate %d symbols\n", oc->info->symCmd->nsyms));
+ IF_DEBUG(linker, debugBelch("ocAllocateSymbolExtras_MachO: done\n"));
+ return ocAllocateSymbolExtras(oc, oc->info->symCmd->nsyms, 0);
}
- IF_DEBUG(linker,
- debugBelch("ocAllocateExtras_MachO: allocated no symbols\n"));
- IF_DEBUG(linker, debugBelch("ocAllocateExtras_MachO: done\n"));
- return ocAllocateExtras(oc, 0, 0, 0);
+ IF_DEBUG(linker, debugBelch("ocAllocateSymbolExtras_MachO: allocated no symbols\n"));
+ IF_DEBUG(linker, debugBelch("ocAllocateSymbolExtras_MachO: done\n"));
+ return ocAllocateSymbolExtras(oc,0,0);
}
#else
diff --git a/rts/linker/MachO.h b/rts/linker/MachO.h
index 4fb58e8668..b495c2b9b1 100644
--- a/rts/linker/MachO.h
+++ b/rts/linker/MachO.h
@@ -13,7 +13,7 @@ int ocGetNames_MachO ( ObjectCode* oc );
int ocResolve_MachO ( ObjectCode* oc );
int ocRunInit_MachO ( ObjectCode* oc );
int machoGetMisalignment( FILE * );
-int ocAllocateExtras_MachO ( ObjectCode* oc );
+int ocAllocateSymbolExtras_MachO ( ObjectCode* oc );
#if defined(powerpc_HOST_ARCH)
void machoInitSymbolsWithoutUnderscore( void );
diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c
index 6cf0d52d39..cc92fa78a2 100644
--- a/rts/linker/PEi386.c
+++ b/rts/linker/PEi386.c
@@ -1778,7 +1778,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
* so simply set correct pointer here.
*/
bool
-ocAllocateExtras_PEi386 ( ObjectCode* oc )
+ocAllocateSymbolExtras_PEi386 ( ObjectCode* oc )
{
/* If the ObjectCode was unloaded we don't need a trampoline, it's likely
an import library so we're discarding it earlier. */
diff --git a/rts/linker/PEi386.h b/rts/linker/PEi386.h
index 538f132ab5..eb5bec8b78 100644
--- a/rts/linker/PEi386.h
+++ b/rts/linker/PEi386.h
@@ -57,7 +57,7 @@ bool ocRunInit_PEi386 ( ObjectCode *oc );
bool ocGetNames_PEi386 ( ObjectCode* oc );
bool ocVerifyImage_PEi386 ( ObjectCode* oc );
SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl);
-bool ocAllocateExtras_PEi386 ( ObjectCode* oc );
+bool ocAllocateSymbolExtras_PEi386 ( ObjectCode* oc );
SymbolAddr *lookupSymbolInDLLs ( const SymbolName* lbl );
/* See Note [mingw-w64 name decoration scheme] */
/* We use myindex to calculate array addresses, rather than
diff --git a/rts/linker/SymbolExtras.c b/rts/linker/SymbolExtras.c
index a9e4c37967..88541f44d0 100644
--- a/rts/linker/SymbolExtras.c
+++ b/rts/linker/SymbolExtras.c
@@ -19,23 +19,16 @@
#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>
#endif /* RTS_LINKER_USE_MMAP */
/*
- ocAllocateExtras
+ ocAllocateSymbolExtras
Allocate additional space at the end of the object file image to make room
- for jump islands (powerpc, x86_64, arm), GOT entries (x86_64) and
- bss sections.
+ for jump islands (powerpc, x86_64, arm) and GOT entries (x86_64).
PowerPC relative branch instructions have a 24 bit displacement field.
As PPC code is always 4-byte-aligned, this yields a +-32MB range.
@@ -50,30 +43,16 @@
filled in by makeSymbolExtra below.
*/
-int ocAllocateExtras(ObjectCode* oc, int count, int first, int bssSize)
+int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first )
{
- void* oldImage = oc->image;
-
- if (count > 0 || bssSize > 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,
- "ocAllocateExtras" );
- oc->image += misalignment;
-
- oc->symbol_extras = (SymbolExtra *) (oc->image + aligned);
- } else if (USE_CONTIGUOUS_MMAP || RtsFlags.MiscFlags.linkerAlwaysPic) {
- /* Keep image, bssExtras and symbol_extras contiguous */
- size_t n = roundUpToPage(oc->fileSize);
- bssSize = roundUpToAlign(bssSize, 8);
- size_t allocated_size = n + bssSize + (sizeof(SymbolExtra) * count);
+ size_t n;
+
+ if (RTS_LINKER_USE_MMAP && USE_CONTIGUOUS_MMAP) {
+ n = roundUpToPage(oc->fileSize);
+
+ /* Keep image and symbol_extras contiguous */
+
+ size_t allocated_size = n + (sizeof(SymbolExtra) * count);
void *new = mmapForLinker(allocated_size, MAP_ANONYMOUS, -1, 0);
if (new) {
memcpy(new, oc->image, oc->fileSize);
@@ -82,37 +61,44 @@ int ocAllocateExtras(ObjectCode* oc, int count, int first, int bssSize)
}
oc->image = new;
oc->imageMapped = true;
- oc->fileSize = allocated_size;
- oc->symbol_extras = (SymbolExtra *) (oc->image + n + bssSize);
- oc->bssBegin = oc->image + n;
- oc->bssEnd = oc->image + n + bssSize;
+ oc->fileSize = n + (sizeof(SymbolExtra) * count);
+ oc->symbol_extras = (SymbolExtra *) (oc->image + n);
+ 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;
diff --git a/rts/linker/SymbolExtras.h b/rts/linker/SymbolExtras.h
index af828e66fa..4974c06e7d 100644
--- a/rts/linker/SymbolExtras.h
+++ b/rts/linker/SymbolExtras.h
@@ -7,7 +7,7 @@
#if defined(NEED_SYMBOL_EXTRAS)
-int ocAllocateExtras(ObjectCode* oc, int count, int first, int bssSize);
+int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first );
#if defined(arm_HOST_ARCH)
SymbolExtra* makeArmSymbolExtra( ObjectCode const* oc,
diff --git a/rts/sm/OSMem.h b/rts/sm/OSMem.h
index ea123e80c6..7dd0efdc23 100644
--- a/rts/sm/OSMem.h
+++ b/rts/sm/OSMem.h
@@ -32,16 +32,10 @@ roundDownToPage (size_t x)
}
INLINE_HEADER size_t
-roundUpToAlign (size_t size, size_t align)
-{
- /* alignment must always be a power of 2 */
- return (size + align - 1) & ~(align - 1);
-}
-
-INLINE_HEADER size_t
roundUpToPage (size_t x)
{
- return roundUpToAlign(x, getPageSize());
+ size_t size = getPageSize();
+ return ((x + size - 1) & ~(size - 1));
}