]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: make arm work on Ubuntu Natty qemu
authorRuss Cox <rsc@golang.org>
Wed, 31 Aug 2011 11:02:46 +0000 (07:02 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 31 Aug 2011 11:02:46 +0000 (07:02 -0400)
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/4963050

src/cmd/ld/elf.c
src/pkg/runtime/linux/mem.c
src/pkg/runtime/malloc.goc

index f9f9ef6b2178fd2aed2e5398b670c7f765641434..00cfc8c8c9ea11d4aa823c75ae8b016eeda95d74 100644 (file)
@@ -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);
index ad0fac6d3f48fcc0c20ab66a34aef7ffba66dd53..6c5c908cc59261e4ef3a5a3d680d3759305c7dee 100644 (file)
@@ -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;
index b9fe36db6d814de4bf8fbb07f1c9d76221f9f799..84e0ac4795eb595a1fc6b21b44d73f0570736c3f 100644 (file)
@@ -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");
        }