summaryrefslogtreecommitdiff
path: root/rts/linker
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/linker
parent76c8fd674435a652c75a96c85abbf26f1f221876 (diff)
downloadhaskell-172a59335fa6c76b17fb6795e87fbc7fcfd198e6.tar.gz
Revert "Batch merge"
This reverts commit 76c8fd674435a652c75a96c85abbf26f1f221876.
Diffstat (limited to 'rts/linker')
-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
8 files changed, 113 insertions, 133 deletions
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,