diff options
author | Ben Gamari <ben@smart-cactus.org> | 2018-10-30 14:47:53 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2018-10-30 16:12:00 -0400 |
commit | 9cbf6f2baf793e361d41b9c36497c5601ff22253 (patch) | |
tree | a6fcb61e43f95c23d046301edf41a727959054ad /rts/linker | |
parent | 7e1690d17b39a9491e46b12297adad8d0c89b550 (diff) | |
download | haskell-9cbf6f2baf793e361d41b9c36497c5601ff22253.tar.gz |
Revert "Allocate bss section within proper range of other sections"
This reverts commit e019ec94f12268dd92ea5d5204e9e57e7ebf10ca.
This sadly breaks the external interpreter on i386.
For instance, see https://circleci.com/gh/ghc/ghc/10925.
Diffstat (limited to 'rts/linker')
-rw-r--r-- | rts/linker/Elf.c | 73 | ||||
-rw-r--r-- | rts/linker/Elf.h | 2 | ||||
-rw-r--r-- | rts/linker/MachO.c | 27 | ||||
-rw-r--r-- | rts/linker/MachO.h | 2 | ||||
-rw-r--r-- | rts/linker/PEi386.c | 2 | ||||
-rw-r--r-- | rts/linker/PEi386.h | 2 | ||||
-rw-r--r-- | rts/linker/SymbolExtras.c | 31 | ||||
-rw-r--r-- | rts/linker/SymbolExtras.h | 2 |
8 files changed, 64 insertions, 77 deletions
diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c index 0a7ffaec21..fe87aed0b0 100644 --- a/rts/linker/Elf.c +++ b/rts/linker/Elf.c @@ -579,7 +579,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; @@ -681,31 +681,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)"); @@ -1881,27 +1873,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 @@ -1911,15 +1898,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 7d5ff32276..ff8ef7a1e4 100644 --- a/rts/linker/MachO.c +++ b/rts/linker/MachO.c @@ -186,10 +186,10 @@ resolveImports( #if NEED_SYMBOL_EXTRAS #if defined(powerpc_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")); // Find out the first and last undefined external // symbol, so we don't have to allocate too many @@ -218,31 +218,28 @@ ocAllocateExtras_MachO(ObjectCode* oc) } if (max >= min) { - return ocAllocateExtras(oc, max - min + 1, min, 0); + return ocAllocateSymbolExtras(oc, max - min + 1, min); } - return ocAllocateExtras(oc, 0, 0, 0); + return ocAllocateSymbolExtras(oc,0,0); } #elif 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 bf642d8b23..ab4583da7c 100644 --- a/rts/linker/PEi386.c +++ b/rts/linker/PEi386.c @@ -1777,7 +1777,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..4c40b10877 100644 --- a/rts/linker/SymbolExtras.c +++ b/rts/linker/SymbolExtras.c @@ -31,11 +31,10 @@ #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,11 +49,12 @@ filled in by makeSymbolExtra below. */ -int ocAllocateExtras(ObjectCode* oc, int count, int first, int bssSize) +int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first ) { + size_t n; void* oldImage = oc->image; - if (count > 0 || bssSize > 0) { + if (count > 0) { if (!RTS_LINKER_USE_MMAP) { // round up to the nearest 4 @@ -65,15 +65,16 @@ int ocAllocateExtras(ObjectCode* oc, int count, int first, int bssSize) oc->image = stgReallocBytes( oc->image, misalignment + aligned + sizeof (SymbolExtra) * count, - "ocAllocateExtras" ); + "ocAllocateSymbolExtras" ); 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); + 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,10 +83,12 @@ 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_WRITE | PROT_EXEC) != 0) { + sysErrorBelch("unable to protect memory"); + } } else { oc->symbol_extras = NULL; 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, |