summaryrefslogtreecommitdiff
path: root/rts/linker/Elf.c
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2018-10-30 14:47:53 -0400
committerBen Gamari <ben@smart-cactus.org>2018-10-30 16:12:00 -0400
commit9cbf6f2baf793e361d41b9c36497c5601ff22253 (patch)
treea6fcb61e43f95c23d046301edf41a727959054ad /rts/linker/Elf.c
parent7e1690d17b39a9491e46b12297adad8d0c89b550 (diff)
downloadhaskell-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/Elf.c')
-rw-r--r--rts/linker/Elf.c73
1 files changed, 30 insertions, 43 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 */