go: runtime: crosscompiled to AIX/ppc64 not working in IBMi PASE (AIX7.2) due to "not in usable address space"

I want to crosscompile a simple Hello-World example to IBM-i PASE environment. This is a AIX 7.2 subsystem on the IBMi (AS400). Normally AIX compiled code should work in this environment.

But when i want to run the test application i get the following error:

runtime: memory allocated by OS [0x700000028000000, 0x70000002c000000) not in usable address space: base outside usable address space
fatal error: memory reservation exceeds address space limit

runtime stack:
runtime.throw(0x1000d9f06, 0x2e)
        /usr/lib/go-1.14/src/runtime/panic.go:1116 +0x68 fp=0xffffffffffff590 sp=0xffffffffffff550 pc=0x100032e08
runtime.(*mheap).sysAlloc(0x180037440, 0x400000, 0x100062a18, 0x9001000a01a1450)
        /usr/lib/go-1.14/src/runtime/malloc.go:706 +0x838 fp=0xffffffffffff660 sp=0xffffffffffff590 pc=0x10000a9a8
runtime.(*mheap).grow(0x180037440, 0x1, 0x0)
        /usr/lib/go-1.14/src/runtime/mheap.go:1286 +0x18c fp=0xffffffffffff6f0 sp=0xffffffffffff660 pc=0x10002586c
runtime.(*mheap).allocSpan(0x180037440, 0x1, 0x2a000100062a18, 0x18004d8e8, 0x900000000332200)
        /usr/lib/go-1.14/src/runtime/mheap.go:1124 +0x748 fp=0xffffffffffff780 sp=0xffffffffffff6f0 pc=0x100025578
runtime.(*mheap).alloc.func1()
        /usr/lib/go-1.14/src/runtime/mheap.go:871 +0x7c fp=0xffffffffffff7e8 sp=0xffffffffffff780 pc=0x10005e26c
runtime.systemstack(0xffffffffffff840)
        /usr/lib/go-1.14/src/runtime/asm_ppc64x.s:295 +0xd0 fp=0xffffffffffff808 sp=0xffffffffffff7e8 pc=0x1000604c0

...

Is this a problem which can be solved easily? How can i fix this?

This is the go code i compiled

package main

import "fmt"

func main() {
   fmt.Println("hello world22e")

}

i tried the crosscompile from windows and linux with the same result.

greetings, Franz

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Comments: 57 (11 by maintainers)

Most upvoted comments

i futher investigated the “System error - error data is: -1 9 (64002005)”. The underlaying reason is that os.MkDir and os.MkDirAll are sometimes returning without the directory been created. i have done an ugly hack and call xmkdirall and xmkdir 10 times. with this the 64002005 errors go away.

maybe someone has an idea why this commands return without creating the dir immediately.

Here is the diff. You can bootstrap amd compile go with that (xmkdir… are ugly i know. maybe someone could suggest a clean solution):

compile command:

GOTMPDIR=/develop/tmp CGO_ENABLED=0 GOROOT_BOOTSTRAP=/develop/go-aix-ppc64-bootstrap/ ./make.bash

diff --git a/src/cmd/compile/internal/noder/lex.go b/src/cmd/compile/internal/noder/lex.go
index 60b724d154..48c608e243 100644
--- a/src/cmd/compile/internal/noder/lex.go
+++ b/src/cmd/compile/internal/noder/lex.go
@@ -115,8 +115,8 @@ func (p *noder) pragcgo(pos syntax.Pos, text string) {
                                // or "lib.a/libname.so.X"
                                n := strings.Split(f[3], "/")
                                if len(n) != 2 || !strings.HasSuffix(n[0], ".a") || (!strings.HasSuffix(n[1], ".o") && !strings.Contains(n[1], ".so.")) {
-                                       p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_dynamic local [remote ["lib.a/object.o"]]`})
-                                       return
+//                                     p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_dynamic local [remote ["lib.a/object.o"]]`})
+//                                     return
                                }
                        }
                default:
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index acf38e3785..f8f16a934f 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -1507,6 +1507,7 @@ func goCmd(goBinary string, cmd string, args ...string) {
        if gohostos == "plan9" && os.Getenv("sysname") == "vx32" {
                goCmd = append(goCmd, "-p=1")
        }
+       goCmd = append(goCmd, "-p=1")  //IBMi

        run(workdir, ShowOutput|CheckExit, append(goCmd, args...)...)
 }
diff --git a/src/cmd/dist/util.go b/src/cmd/dist/util.go
index e99375f538..659f35bca5 100644
--- a/src/cmd/dist/util.go
+++ b/src/cmd/dist/util.go
@@ -114,7 +114,7 @@ func run(dir string, mode int, cmd ...string) string {
        return string(data)
 }

-var maxbg = 4 /* maximum number of jobs to run at once */
+var maxbg = 1 /* maximum number of jobs to run at once */

 var (
        bgwork = make(chan func(), 1e5)
@@ -261,6 +261,17 @@ func xmkdir(p string) {
        if err != nil {
                fatalf("%v", err)
        }
+       os.Mkdir(p, 0777)
+       os.Mkdir(p, 0777)
+       os.Mkdir(p, 0777)
+       os.Mkdir(p, 0777)
+       os.Mkdir(p, 0777)
+       os.Mkdir(p, 0777)
+       os.Mkdir(p, 0777)
+       os.Mkdir(p, 0777)
+       os.Mkdir(p, 0777)
+       os.Mkdir(p, 0777)
+       os.Mkdir(p, 0777)
 }

 // xmkdirall creates the directory p and its parents, as needed.
@@ -269,6 +280,17 @@ func xmkdirall(p string) {
        if err != nil {
                fatalf("%v", err)
        }
+       os.MkdirAll(p, 0777)
+       os.MkdirAll(p, 0777)
+       os.MkdirAll(p, 0777)
+       os.MkdirAll(p, 0777)
+       os.MkdirAll(p, 0777)
+       os.MkdirAll(p, 0777)
+       os.MkdirAll(p, 0777)
+       os.MkdirAll(p, 0777)
+       os.MkdirAll(p, 0777)
+       os.MkdirAll(p, 0777)
+       os.MkdirAll(p, 0777)
 }

 // xremove removes the file p.
diff --git a/src/runtime/lfstack_64bit.go b/src/runtime/lfstack_64bit.go
index 4812dd1156..670932e792 100644
--- a/src/runtime/lfstack_64bit.go
+++ b/src/runtime/lfstack_64bit.go
@@ -53,7 +53,8 @@ func lfstackUnpack(val uint64) *lfnode {
                return (*lfnode)(unsafe.Pointer(uintptr(int64(val) >> cntBits << 3)))
        }
        if GOARCH == "ppc64" && GOOS == "aix" {
-               return (*lfnode)(unsafe.Pointer(uintptr((val >> aixCntBits << 3) | 0xa<<56)))
+//             return (*lfnode)(unsafe.Pointer(uintptr((val >> aixCntBits << 3) | 0xa<<56)))
+               return (*lfnode)(unsafe.Pointer(uintptr((val >> aixCntBits << 3) | 0x7<<56)))
        }
        return (*lfnode)(unsafe.Pointer(uintptr(val >> cntBits << 3)))
 }
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index 8435f96532..664c94c872 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -302,7 +302,8 @@ const (
        //
        // On other platforms, the user address space is contiguous
        // and starts at 0, so no offset is necessary.
-       arenaBaseOffset = 0xffff800000000000*sys.GoarchAmd64 + 0x0a00000000000000*sys.GoosAix
+//     arenaBaseOffset = 0xffff800000000000*sys.GoarchAmd64 + 0x0a00000000000000*sys.GoosAix
+       arenaBaseOffset = 0xffff800000000000*sys.GoarchAmd64 + 0x0700000000000000*sys.GoosAix
        // A typed version of this constant that will make it into DWARF (for viewcore).
        arenaBaseOffsetUintptr = uintptr(arenaBaseOffset)

@@ -539,7 +540,8 @@ func mallocinit() {
                                        // to avoid collisions with others mmaps done by non-go programs.
                                        continue
                                }
-                               p = uintptr(i)<<40 | uintptrMask&(0xa0<<52)
+//                             p = uintptr(i)<<40 | uintptrMask&(0xa0<<52)
+                               p = uintptr(i)<<40 | uintptrMask&(0x70<<52)
                        default:
                                p = uintptr(i)<<40 | uintptrMask&(0x00c0<<32)
                        }