diff options
Diffstat (limited to 'rts/linker/SymbolExtras.c')
-rw-r--r-- | rts/linker/SymbolExtras.c | 84 |
1 files changed, 35 insertions, 49 deletions
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; |