diff options
Diffstat (limited to 'libgo/runtime/mem.c')
-rw-r--r-- | libgo/runtime/mem.c | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/libgo/runtime/mem.c b/libgo/runtime/mem.c index 4d6c742..f62a4d3 100644 --- a/libgo/runtime/mem.c +++ b/libgo/runtime/mem.c @@ -38,12 +38,11 @@ runtime_SysAlloc(uintptr n) p = runtime_mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, fd, 0); if (p == MAP_FAILED) { if(errno == EACCES) { - printf("mmap: access denied\n"); - printf("If you're running SELinux, enable execmem for this process.\n"); - } else { - printf("mmap: errno=%d\n", errno); + printf("runtime: mmap: access denied\n"); + printf("if you're running SELinux, enable execmem for this process.\n"); + exit(2); } - exit(2); + return nil; } return p; } @@ -63,14 +62,61 @@ runtime_SysFree(void *v, uintptr n) runtime_munmap(v, n); } +void* +runtime_SysReserve(void *v, uintptr n) +{ + int fd = -1; + + // On 64-bit, people with ulimit -v set complain if we reserve too + // much address space. Instead, assume that the reservation is okay + // and check the assumption in SysMap. + if(sizeof(void*) == 8) + return v; + +#ifdef USE_DEV_ZERO + if (dev_zero == -1) { + dev_zero = open("/dev/zero", O_RDONLY); + if (dev_zero < 0) { + printf("open /dev/zero: errno=%d\n", errno); + exit(2); + } + } + fd = dev_zero; +#endif + + return runtime_mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, fd, 0); +} + void -runtime_SysMemInit(void) +runtime_SysMap(void *v, uintptr n) { - // Code generators assume that references to addresses - // on the first page will fault. Map the page explicitly with - // no permissions, to head off possible bugs like the system - // allocating that page as the virtual address space fills. - // Ignore any error, since other systems might be smart - // enough to never allow anything there. - runtime_mmap(nil, 4096, PROT_NONE, MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0); + void *p; + int fd = -1; + + mstats.sys += n; + +#ifdef USE_DEV_ZERO + if (dev_zero == -1) { + dev_zero = open("/dev/zero", O_RDONLY); + if (dev_zero < 0) { + printf("open /dev/zero: errno=%d\n", errno); + exit(2); + } + } + fd = dev_zero; +#endif + + // On 64-bit, we don't actually have v reserved, so tread carefully. + if(sizeof(void*) == 8) { + p = runtime_mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, fd, 0); + if(p != v) { + runtime_printf("runtime: address space conflict: map(%p) = %p\n", v, p); + runtime_throw("runtime: address space conflict"); + } + return; + } + + p = runtime_mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, fd, 0); + if(p != v) + runtime_throw("runtime: cannot map pages in arena address space"); } |