summaryrefslogtreecommitdiff
path: root/libgo/go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go')
-rw-r--r--libgo/go/cmd/go/build.go44
-rw-r--r--libgo/go/runtime/malloc.go7
-rw-r--r--libgo/go/runtime/mem_gccgo.go5
-rw-r--r--libgo/go/runtime/stubs.go4
-rw-r--r--libgo/go/runtime/testdata/testprogcgo/callback.go4
-rw-r--r--libgo/go/syscall/libcall_linux.go4
-rw-r--r--libgo/go/syscall/syscall_linux_alpha.go32
-rw-r--r--libgo/go/syscall/syscall_linux_s390.go22
-rw-r--r--libgo/go/syscall/syscall_linux_s390x.go37
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)
}