diff options
Diffstat (limited to 'libgo/go')
-rw-r--r-- | libgo/go/cmd/go/build.go | 44 | ||||
-rw-r--r-- | libgo/go/runtime/malloc.go | 7 | ||||
-rw-r--r-- | libgo/go/runtime/mem_gccgo.go | 5 | ||||
-rw-r--r-- | libgo/go/runtime/stubs.go | 4 | ||||
-rw-r--r-- | libgo/go/runtime/testdata/testprogcgo/callback.go | 4 | ||||
-rw-r--r-- | libgo/go/syscall/libcall_linux.go | 4 | ||||
-rw-r--r-- | libgo/go/syscall/syscall_linux_alpha.go | 32 | ||||
-rw-r--r-- | libgo/go/syscall/syscall_linux_s390.go | 22 | ||||
-rw-r--r-- | libgo/go/syscall/syscall_linux_s390x.go | 37 |
9 files changed, 93 insertions, 66 deletions
diff --git a/libgo/go/cmd/go/build.go b/libgo/go/cmd/go/build.go index 7e98379675f..9623b9c32be 100644 --- a/libgo/go/cmd/go/build.go +++ b/libgo/go/cmd/go/build.go @@ -342,16 +342,20 @@ func buildModeInit() { } return p } - switch platform { - case "darwin/arm", "darwin/arm64": - codegenArg = "-shared" - default: - switch goos { - case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris": - // Use -shared so that the result is - // suitable for inclusion in a PIE or - // shared library. + if gccgo { + codegenArg = "-fPIC" + } else { + switch platform { + case "darwin/arm", "darwin/arm64": codegenArg = "-shared" + default: + switch goos { + case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris": + // Use -shared so that the result is + // suitable for inclusion in a PIE or + // shared library. + codegenArg = "-shared" + } } } exeSuffix = ".a" @@ -374,10 +378,14 @@ func buildModeInit() { case "default": switch platform { case "android/arm", "android/arm64", "android/amd64", "android/386": - codegenArg = "-shared" + if !gccgo { + codegenArg = "-shared" + } ldBuildmode = "pie" case "darwin/arm", "darwin/arm64": - codegenArg = "-shared" + if !gccgo { + codegenArg = "-shared" + } fallthrough default: ldBuildmode = "exe" @@ -387,7 +395,7 @@ func buildModeInit() { ldBuildmode = "exe" case "pie": if gccgo { - fatalf("-buildmode=pie not supported by gccgo") + codegenArg = "-fPIE" } else { switch platform { case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x", @@ -1053,7 +1061,7 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha // Install header for cgo in c-archive and c-shared modes. if p.usesCgo() && (buildBuildmode == "c-archive" || buildBuildmode == "c-shared") { hdrTarget := a.target[:len(a.target)-len(filepath.Ext(a.target))] + ".h" - if buildContext.Compiler == "gccgo" { + if buildContext.Compiler == "gccgo" && *buildO == "" { // For the header file, remove the "lib" // added by go/build, so we generate pkg.h // rather than libpkg.h. @@ -3025,6 +3033,8 @@ func (tools gccgoToolchain) link(b *builder, root *action, out string, allaction ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc", "-lc", "-lgcc") case "shared": ldflags = append(ldflags, "-zdefs", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc") + case "pie": + ldflags = append(ldflags, "-pie") default: fatalf("-buildmode=%s not supported for gccgo", buildmode) @@ -3082,8 +3092,7 @@ func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile stri if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" { defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`) } - switch goarch { - case "386", "amd64": + if b.gccSupportsFlag("-fsplit-stack") { defs = append(defs, "-fsplit-stack") } defs = tools.maybePIC(defs) @@ -3100,7 +3109,7 @@ func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile stri // maybePIC adds -fPIC to the list of arguments if needed. func (tools gccgoToolchain) maybePIC(args []string) []string { switch buildBuildmode { - case "c-shared", "shared", "plugin": + case "c-archive", "c-shared", "shared", "plugin": args = append(args, "-fPIC") } return args @@ -3418,8 +3427,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil } if _, ok := buildToolchain.(gccgoToolchain); ok { - switch goarch { - case "386", "amd64": + if b.gccSupportsFlag("-fsplit-stack") { cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack") } cgoflags = append(cgoflags, "-gccgo") diff --git a/libgo/go/runtime/malloc.go b/libgo/go/runtime/malloc.go index 05a69c98aad..3912fc2da58 100644 --- a/libgo/go/runtime/malloc.go +++ b/libgo/go/runtime/malloc.go @@ -291,6 +291,8 @@ func mallocinit() { // allocation at 0x40 << 32 because when using 4k pages with 3-level // translation buffers, the user address space is limited to 39 bits // On darwin/arm64, the address space is even smaller. + // On AIX, mmap adresses range start at 0x07000000_00000000 for 64 bits + // processes. arenaSize := round(_MaxMem, _PageSize) bitmapSize = arenaSize / (sys.PtrSize * 8 / 2) spansSize = arenaSize / _PageSize * sys.PtrSize @@ -301,12 +303,15 @@ func mallocinit() { p = uintptr(i)<<40 | uintptrMask&(0x0013<<28) case GOARCH == "arm64": p = uintptr(i)<<40 | uintptrMask&(0x0040<<32) + case GOOS == "aix": + i = 1 + p = uintptr(i)<<32 | uintptrMask&(0x70<<52) default: p = uintptr(i)<<40 | uintptrMask&(0x00c0<<32) } pSize = bitmapSize + spansSize + arenaSize + _PageSize p = uintptr(sysReserve(unsafe.Pointer(p), pSize, &reserved)) - if p != 0 { + if p != 0 || GOOS == "aix" { // Useless to loop on AIX, as i is forced to 1 break } } diff --git a/libgo/go/runtime/mem_gccgo.go b/libgo/go/runtime/mem_gccgo.go index 161ff26b137..ea3e5ebab4e 100644 --- a/libgo/go/runtime/mem_gccgo.go +++ b/libgo/go/runtime/mem_gccgo.go @@ -270,6 +270,11 @@ func sysMap(v unsafe.Pointer, n uintptr, reserved bool, sysStat *uint64) { return } + if GOOS == "aix" { + // AIX does not allow mapping a range that is already mapped. + // So always unmap first even if it is already unmapped. + munmap(v, n) + } p := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, mmapFD, 0) if uintptr(p) == _MAP_FAILED && errno() == _ENOMEM { throw("runtime: out of memory") diff --git a/libgo/go/runtime/stubs.go b/libgo/go/runtime/stubs.go index a3d091811d5..30d87c4121b 100644 --- a/libgo/go/runtime/stubs.go +++ b/libgo/go/runtime/stubs.go @@ -422,13 +422,13 @@ func getPanicking() uint32 { return panicking } -// Temporary for gccgo until we initialize ncpu in Go. +// Called by C code to set the number of CPUs. //go:linkname setncpu runtime.setncpu func setncpu(n int32) { ncpu = n } -// Temporary for gccgo until we reliably initialize physPageSize in Go. +// Called by C code to set the page size. //go:linkname setpagesize runtime.setpagesize func setpagesize(s uintptr) { if physPageSize == 0 { diff --git a/libgo/go/runtime/testdata/testprogcgo/callback.go b/libgo/go/runtime/testdata/testprogcgo/callback.go index 7b58f4a207e..a49fc19b284 100644 --- a/libgo/go/runtime/testdata/testprogcgo/callback.go +++ b/libgo/go/runtime/testdata/testprogcgo/callback.go @@ -23,7 +23,9 @@ static void foo() { pthread_t th; pthread_attr_t attr; pthread_attr_init(&attr); - pthread_attr_setstacksize(&attr, 256 << 10); + // For gccgo use a stack size large enough for all the callbacks, + // in case we are on a platform that does not support -fsplit-stack. + pthread_attr_setstacksize(&attr, 512 * 10000); pthread_create(&th, &attr, thr, 0); pthread_join(th, 0); } diff --git a/libgo/go/syscall/libcall_linux.go b/libgo/go/syscall/libcall_linux.go index b58b2ddd6ea..5f4778400b0 100644 --- a/libgo/go/syscall/libcall_linux.go +++ b/libgo/go/syscall/libcall_linux.go @@ -212,7 +212,7 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) { //flock(fd _C_int, how _C_int) _C_int //sys Fstatfs(fd int, buf *Statfs_t) (err error) -//fstatfs(fd _C_int, buf *Statfs_t) _C_int +//fstatfs64(fd _C_int, buf *Statfs_t) _C_int func Gettid() (tid int) { r1, _, _ := Syscall(SYS_GETTID, 0, 0, 0) @@ -360,7 +360,7 @@ func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n i } //sys Statfs(path string, buf *Statfs_t) (err error) -//statfs(path *byte, buf *Statfs_t) _C_int +//statfs64(path *byte, buf *Statfs_t) _C_int //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sync_file_range(fd _C_int, off Offset_t, n Offset_t, flags _C_uint) _C_int diff --git a/libgo/go/syscall/syscall_linux_alpha.go b/libgo/go/syscall/syscall_linux_alpha.go index 713546cb057..5115b9b7c21 100644 --- a/libgo/go/syscall/syscall_linux_alpha.go +++ b/libgo/go/syscall/syscall_linux_alpha.go @@ -8,38 +8,6 @@ package syscall import "unsafe" -type PtraceRegs struct { - R0 uint64 - R1 uint64 - R2 uint64 - R3 uint64 - R4 uint64 - R5 uint64 - R6 uint64 - R7 uint64 - R8 uint64 - R19 uint64 - R20 uint64 - R21 uint64 - R22 uint64 - R23 uint64 - R24 uint64 - R25 uint64 - R26 uint64 - R27 uint64 - R28 uint64 - Hae uint64 - Trap_a0 uint64 - Trap_a1 uint64 - Trap_a2 uint64 - Ps uint64 - Pc uint64 - Gp uint64 - R16 uint64 - R17 uint64 - R18 uint64 -} - func (r *PtraceRegs) PC() uint64 { return r.Pc } diff --git a/libgo/go/syscall/syscall_linux_s390.go b/libgo/go/syscall/syscall_linux_s390.go index a744f6b7841..8b005427eef 100644 --- a/libgo/go/syscall/syscall_linux_s390.go +++ b/libgo/go/syscall/syscall_linux_s390.go @@ -4,18 +4,30 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// See the s390x version for why we don't use GETREGSET/SETREGSET + package syscall import "unsafe" -func (r *PtraceRegs) PC() uint64 { return uint64(r.Psw.Addr) } +func (r *PtraceRegs) PC() uint64 { return uint64(r.Psw.addr) } -func (r *PtraceRegs) SetPC(pc uint64) { r.Psw.Addr = uint32(pc) } +func (r *PtraceRegs) SetPC(pc uint64) { r.Psw.addr = uint32(pc) } -func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { - return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +func PtraceGetRegs(pid int, regs *PtraceRegs) (err error) { + parea := _ptrace_area{ + _sizeof_ptrace_area, + 0, + uint32(uintptr(unsafe.Pointer(regs))), + } + return ptrace(PTRACE_PEEKUSR_AREA, pid, uintptr(unsafe.Pointer(&parea)), 0) } func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { - return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) + parea := _ptrace_area{ + _sizeof_ptrace_area, + 0, + uint32(uintptr(unsafe.Pointer(regs))), + } + return ptrace(PTRACE_POKEUSR_AREA, pid, uintptr(unsafe.Pointer(&parea)), 0) } diff --git a/libgo/go/syscall/syscall_linux_s390x.go b/libgo/go/syscall/syscall_linux_s390x.go index 44d567983c8..1767a6e5c61 100644 --- a/libgo/go/syscall/syscall_linux_s390x.go +++ b/libgo/go/syscall/syscall_linux_s390x.go @@ -4,18 +4,45 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// The PtraceRegs struct generated for go looks like this: +// +// type PtraceRegs struct +// { +// Psw _psw_t; +// Gprs [15+1]uint64; +// Acrs [15+1]uint32; +// Orig_gpr2 uint64; +// Fp_regs _s390_fp_regs; +// Per_info _per_struct; +// Ieee_instruction_pointer uint64; +// } +// +// The GETREGSET/SETREGSET ptrace commands on S/390 only read/write +// the content up to Orig_gpr2. Hence, we use +// PEEKUSR_AREA/POKEUSR_AREA like GDB does. + package syscall import "unsafe" -func (r *PtraceRegs) PC() uint64 { return r.Psw.Addr } +func (r *PtraceRegs) PC() uint64 { return r.Psw.addr } -func (r *PtraceRegs) SetPC(pc uint64) { r.Psw.Addr = pc } +func (r *PtraceRegs) SetPC(pc uint64) { r.Psw.addr = pc } -func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { - return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +func PtraceGetRegs(pid int, regs *PtraceRegs) (err error) { + parea := _ptrace_area{ + _sizeof_ptrace_area, + 0, + uint64(uintptr(unsafe.Pointer(regs))), + } + return ptrace(PTRACE_PEEKUSR_AREA, pid, uintptr(unsafe.Pointer(&parea)), 0) } func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { - return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) + parea := _ptrace_area{ + _sizeof_ptrace_area, + 0, + uint64(uintptr(unsafe.Pointer(regs))), + } + return ptrace(PTRACE_POKEUSR_AREA, pid, uintptr(unsafe.Pointer(&parea)), 0) } |