diff mbox series

libgo patch committed: glibc ptrace is a varargs function

Message ID CAOyqgcWog3DUCNq=rqk4_hi7hNrOPjnkG5MVi-KpphNOE0_B_A@mail.gmail.com
State New
Headers show
Series libgo patch committed: glibc ptrace is a varargs function | expand

Commit Message

Ian Lance Taylor Sept. 17, 2020, 7:14 p.m. UTC
This patch by Paul Murphy fixes calls from libgo to ptrace.  In glibc,
ptrace is actually declared as a variadic function.  On ppc64le the
ABI requires to the caller to allocate space for the parameters and
allows the caller to modify them.

On ppc64le, depending on how and what version of GCC is used, it will
save to parameter save area.  This happened to clobber a saved LR, and
caused syscall.TestExecPtrace to fail with a timeout when the tracee
segfaults, and waits for the parent process to inspect.

Wrap the ptrace function to avoid directly calling glibc's ptrace from go.

This resolves GCC PR #92567 and https://golang.org/issue/36698.

Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian
e70264072c595701eb9df189e46b25da52d832b3
diff mbox series

Patch

diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index df9d2118dfd..6b590f6fd94 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@ 
-a47485cd0e9ce6a8b3e88e53ccc0a440f0bd4351
+6fd6418efb983827717f648a11bb5ca6fe93af30
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/syscall/libcall_glibc.go b/libgo/go/syscall/libcall_glibc.go
index a90fc9b3f8b..823343d5075 100644
--- a/libgo/go/syscall/libcall_glibc.go
+++ b/libgo/go/syscall/libcall_glibc.go
@@ -32,7 +32,7 @@  func Futimes(fd int, tv []Timeval) (err error) {
 }
 
 //sys	ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
-//ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long
+//__go_ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long
 
 //sys	accept4(fd int, sa *RawSockaddrAny, len *Socklen_t, flags int) (nfd int, err error)
 //accept4(fd _C_int, sa *RawSockaddrAny, len *Socklen_t, flags _C_int) _C_int
diff --git a/libgo/go/syscall/libcall_linux.go b/libgo/go/syscall/libcall_linux.go
index 88286c07b6e..78fda0ea7ef 100644
--- a/libgo/go/syscall/libcall_linux.go
+++ b/libgo/go/syscall/libcall_linux.go
@@ -11,7 +11,7 @@  import (
 )
 
 //sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno)
-//ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long
+//__go_ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long
 
 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
 	// The peek requests are machine-size oriented, so we wrap it
diff --git a/libgo/runtime/go-varargs.c b/libgo/runtime/go-varargs.c
index 2b186ef8b81..f9270a97bfd 100644
--- a/libgo/runtime/go-varargs.c
+++ b/libgo/runtime/go-varargs.c
@@ -18,6 +18,9 @@ 
 #ifdef HAVE_SYS_SYSCALL_H
 #include <sys/syscall.h>
 #endif
+#ifdef HAVE_SYS_PTRACE_H
+#include <sys/ptrace.h>
+#endif
 
 /* The syscall package calls C functions.  The Go compiler can not
    represent a C varargs functions.  On some systems it's important
@@ -110,3 +113,16 @@  __go_syscall6(uintptr_t flag, uintptr_t a1, uintptr_t a2, uintptr_t a3,
 }
 
 #endif
+
+#ifdef HAVE_SYS_PTRACE_H
+
+// Despite documented appearances, this is actually implemented as
+// a variadic function within glibc.
+
+long
+__go_ptrace(int request, pid_t pid, uintptr_t addr, uintptr_t data)
+{
+  return ptrace (request, pid, addr, data);
+}
+
+#endif