From: Russ Cox Date: Wed, 31 Aug 2011 11:02:46 +0000 (-0400) Subject: runtime: make arm work on Ubuntu Natty qemu X-Git-Tag: weekly.2011-09-01~11 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4304de6e0c64653ddf5d57c7724b28b859ce28af;p=gostls13.git runtime: make arm work on Ubuntu Natty qemu R=golang-dev, r CC=golang-dev https://golang.org/cl/4963050 --- diff --git a/src/cmd/ld/elf.c b/src/cmd/ld/elf.c index f9f9ef6b21..00cfc8c8c9 100644 --- a/src/cmd/ld/elf.c +++ b/src/cmd/ld/elf.c @@ -77,6 +77,19 @@ elf64phdr(ElfPhdr *e) void elf32phdr(ElfPhdr *e) { + int frag; + + if(e->type == PT_LOAD) { + // Correct ELF loaders will do this implicitly, + // but buggy ELF loaders like the one in some + // versions of QEMU won't. + frag = e->vaddr&(e->align-1); + e->off -= frag; + e->vaddr -= frag; + e->paddr -= frag; + e->filesz += frag; + e->memsz += frag; + } LPUT(e->type); LPUT(e->off); LPUT(e->vaddr); diff --git a/src/pkg/runtime/linux/mem.c b/src/pkg/runtime/linux/mem.c index ad0fac6d3f..6c5c908cc5 100644 --- a/src/pkg/runtime/linux/mem.c +++ b/src/pkg/runtime/linux/mem.c @@ -6,23 +6,26 @@ enum { ENOMEM = 12, + _PAGE_SIZE = 4096, }; static int32 addrspace_free(void *v, uintptr n) { - uintptr page_size = 4096; + int32 errval; + uintptr chunk; uintptr off; - int8 one_byte; + static byte vec[4096]; - for(off = 0; off < n; off += page_size) { - int32 errval = runtime·mincore((int8 *)v + off, page_size, (void *)&one_byte); + for(off = 0; off < n; off += chunk) { + chunk = _PAGE_SIZE * sizeof vec; + if(chunk > (n - off)) + chunk = n - off; + errval = runtime·mincore((int8*)v + off, chunk, vec); // errval is 0 if success, or -(error_code) if error. if (errval == 0 || errval != -ENOMEM) return 0; } - USED(v); - USED(n); return 1; } @@ -72,7 +75,7 @@ runtime·SysReserve(void *v, uintptr n) return v; p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); - if(p < (void*)4096) { + if((uintptr)p < 4096 || -(uintptr)p < 4096) { return nil; } return p; diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc index b9fe36db6d..84e0ac4795 100644 --- a/src/pkg/runtime/malloc.goc +++ b/src/pkg/runtime/malloc.goc @@ -248,6 +248,7 @@ runtime·mallocinit(void) byte *p; uintptr arena_size, bitmap_size; extern byte end[]; + byte *want; runtime·InitSizes(); @@ -307,9 +308,13 @@ runtime·mallocinit(void) // not as an absolute requirement. If we ask for the end // of the data segment but the operating system requires // a little more space before we can start allocating, it will - // give out a slightly higher pointer. That's fine. - // Run with what we get back. - p = runtime·SysReserve(end, bitmap_size + arena_size); + // give out a slightly higher pointer. Except QEMU, which + // is buggy, as usual: it won't adjust the pointer upward. + // So adjust it upward a little bit ourselves: 1/4 MB to get + // away from the running binary image and then round up + // to a MB boundary. + want = (byte*)(((uintptr)end + (1<<18) + (1<<20) - 1)&~((1<<20)-1)); + p = runtime·SysReserve(want, bitmap_size + arena_size); if(p == nil) runtime·throw("runtime: cannot reserve arena virtual address space"); }