summaryrefslogtreecommitdiff
path: root/rts/Linker.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2008-11-20 15:40:14 +0000
committerSimon Marlow <marlowsd@gmail.com>2008-11-20 15:40:14 +0000
commit69db8adf9c151d9e997a95b09b14e2b0c740c6be (patch)
treeb729c0e4408ccc5c50946e72edc0dedaa62eb6b8 /rts/Linker.c
parent117dc73b8a8f6a4184a825a96c372480377f4680 (diff)
downloadhaskell-69db8adf9c151d9e997a95b09b14e2b0c740c6be.tar.gz
round the size up to a page in mmapForLinker() instead of in the caller
Diffstat (limited to 'rts/Linker.c')
-rw-r--r--rts/Linker.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/rts/Linker.c b/rts/Linker.c
index 4fcfadead5..3b2dd1e6a6 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1294,11 +1294,17 @@ static unsigned int PLTSize(void);
#endif
#ifdef USE_MMAP
+#define ROUND_UP(x,size) ((x + size - 1) & ~(size - 1))
+
static void *
mmapForLinker (size_t bytes, nat flags, int fd)
{
void *map_addr = NULL;
void *result;
+ int pagesize, size;
+
+ pagesize = getpagesize();
+ size = ROUND_UP(bytes, pagesize);
#if defined(x86_64_HOST_ARCH)
mmap_again:
@@ -1308,7 +1314,7 @@ mmap_again:
}
#endif
- result = mmap(map_addr, bytes, PROT_EXEC|PROT_READ|PROT_WRITE,
+ result = mmap(map_addr, size, PROT_EXEC|PROT_READ|PROT_WRITE,
MAP_PRIVATE|TRY_MAP_32BIT|flags, fd, 0);
if (result == MAP_FAILED) {
@@ -1319,17 +1325,17 @@ mmap_again:
#if defined(x86_64_HOST_ARCH)
if (mmap_32bit_base != 0) {
if (result == map_addr) {
- mmap_32bit_base = map_addr + bytes;
+ mmap_32bit_base = map_addr + size;
} else {
if ((W_)result > 0x80000000) {
// oops, we were given memory over 2Gb
// ... try allocating memory somewhere else?;
- barf("loadObj: failed to mmap() memory below 2Gb; asked for %lu bytes at %p, got %p. Try specifying an address with +RTS -xm<addr> -RTS", bytes, map_addr, result);
+ barf("loadObj: failed to mmap() memory below 2Gb; asked for %lu bytes at %p, got %p. Try specifying an address with +RTS -xm<addr> -RTS", size, map_addr, result);
} else {
// hmm, we were given memory somewhere else, but it's
// still under 2Gb so we can use it. Next time, ask
// for memory right after the place we just got some
- mmap_32bit_base = (void*)result + bytes;
+ mmap_32bit_base = (void*)result + size;
}
}
} else {
@@ -1337,7 +1343,7 @@ mmap_again:
// oops, we were given memory over 2Gb
// ... try allocating memory somewhere else?;
debugTrace(DEBUG_linker,"MAP_32BIT didn't work; gave us %lu bytes at 0x%p", bytes, result);
- munmap(result, bytes);
+ munmap(result, size);
// Set a base address and try again... (guess: 1Gb)
mmap_32bit_base = (void*)0x40000000;
@@ -1360,9 +1366,9 @@ loadObj( char *path )
{
ObjectCode* oc;
struct stat st;
- int r, n;
+ int r;
#ifdef USE_MMAP
- int fd, pagesize;
+ int fd;
#else
FILE *f;
#endif
@@ -1422,8 +1428,6 @@ loadObj( char *path )
objects = oc;
#ifdef USE_MMAP
-#define ROUND_UP(x,size) ((x + size - 1) & ~(size - 1))
-
/* On many architectures malloc'd memory isn't executable, so we need to use mmap. */
#if defined(openbsd_HOST_OS)
@@ -1434,10 +1438,11 @@ loadObj( char *path )
if (fd == -1)
barf("loadObj: can't open `%s'", path);
- pagesize = getpagesize();
-
#ifdef ia64_HOST_ARCH
/* The PLT needs to be right before the object */
+ {
+ int pagesize, n;
+ pagesize = getpagesize();
n = ROUND_UP(PLTSize(), pagesize);
oc->plt = mmap(NULL, n, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (oc->plt == MAP_FAILED)
@@ -1445,17 +1450,15 @@ loadObj( char *path )
oc->pltIndex = 0;
map_addr = oc->plt + n;
-#endif
n = ROUND_UP(oc->fileSize, pagesize);
-
-#ifdef ia64_HOST_ARCH
oc->image = mmap(map_addr, n, PROT_EXEC|PROT_READ|PROT_WRITE,
MAP_PRIVATE|TRY_MAP_32BIT, fd, 0);
if (oc->image == MAP_FAILED)
barf("loadObj: can't map `%s'", path);
+ }
#else
- oc->image = mmapForLinker(n, 0, fd);
+ oc->image = mmapForLinker(oc->fileSize, 0, fd);
#endif
close(fd);