re PR go/89172 (FAIL: runtime/pprof)
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 27 Feb 2019 22:35:10 +0000 (22:35 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 27 Feb 2019 22:35:10 +0000 (22:35 +0000)
PR go/89172
    internal/cpu, runtime, runtime/pprof: handle function descriptors

    When using PPC64 ELF ABI v1 a function address is not a PC, but is the
    address of a function descriptor.  The first field in the function
    descriptor is the actual PC (see
    http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#FUNC-DES).
    The libbacktrace library knows about this, and libgo uses actual PC
    values consistently except for the helper function funcPC that appears
    in both runtime and runtime/pprof.

    This patch fixes funcPC by recording, in the internal/cpu package,
    whether function descriptors are being used.  We have to check for
    function descriptors using a C compiler check, because GCC can be
    configured using --with-abi to select the ELF ABI to use.

    Fixes https://gcc.gnu.org/PR89172

    Reviewed-on: https://go-review.googlesource.com/c/162978

From-SVN: r269266

gcc/go/gofrontend/MERGE
libgo/Makefile.am
libgo/Makefile.in
libgo/configure
libgo/configure.ac
libgo/go/runtime/pprof/proto.go
libgo/go/runtime/proc.go
libgo/testsuite/Makefile.in

index b2f065d66a00f184184de71cfeeeee5f1bdec62a..749e523e7df5754c9f0007677fc882f16f9bc1d0 100644 (file)
@@ -1,4 +1,4 @@
-c9581de3804f94c5a74ce14befce5c57368722b9
+74533ed435a1a77e6f9ec8f6cf5db1695c2568e8
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 1f78111445b78652f316a4c8b2a6d5fb7bba3b9f..aeaa203ce5a3518745c61ab8fa2e1f0e9c58911d 100644 (file)
@@ -539,6 +539,7 @@ s-cpu: Makefile
        rm -f cpugen.go.tmp
        echo "package cpu" > cpugen.go.tmp
        echo "const CacheLinePadSize = `$(SHELL) $(srcdir)/goarch.sh $(GOARCH) cachelinesize`" >> cpugen.go.tmp
+       echo "const FunctionDescriptors = $(FUNCTION_DESCRIPTORS)" >> cpugen.go.tmp
        $(SHELL) $(srcdir)/mvifdiff.sh cpugen.go.tmp cpugen.go
        $(STAMP) $@
 
index 0b26158dd7d77f033171a6c521c18730b85a06da..7f398918c57f7b00fbe9b36781e617b6ef39d2b4 100644 (file)
@@ -397,6 +397,7 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
+FUNCTION_DESCRIPTORS = @FUNCTION_DESCRIPTORS@
 GOARCH = @GOARCH@
 GOC = @GOC@
 GOFLAGS = @GOFLAGS@
@@ -2635,6 +2636,7 @@ s-cpu: Makefile
        rm -f cpugen.go.tmp
        echo "package cpu" > cpugen.go.tmp
        echo "const CacheLinePadSize = `$(SHELL) $(srcdir)/goarch.sh $(GOARCH) cachelinesize`" >> cpugen.go.tmp
+       echo "const FunctionDescriptors = $(FUNCTION_DESCRIPTORS)" >> cpugen.go.tmp
        $(SHELL) $(srcdir)/mvifdiff.sh cpugen.go.tmp cpugen.go
        $(STAMP) $@
 
index 0b8ebce3f9c38b5fa582184647c9b0c7c82f1aeb..06b68b0f4169de012d7b4c347d14cd0ccdf181aa 100755 (executable)
@@ -661,6 +661,7 @@ GO_SYSCALL_OS_ARCH_FILE
 GO_SYSCALL_OS_FILE
 GO_LIBCALL_OS_ARCH_FILE
 GO_LIBCALL_OS_FILE
+FUNCTION_DESCRIPTORS
 ALLGOARCHFAMILY
 ALLGOARCH
 GOARCH
@@ -11343,7 +11344,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11346 "configure"
+#line 11347 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11449,7 +11450,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11452 "configure"
+#line 11453 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -14088,6 +14089,27 @@ esac
 
 
 
+FUNCTION_DESCRIPTORS=false
+case ${host} in
+  rs6000*-*-* | powerpc*-*-*)
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#if _CALL_ELF == 1
+#error descriptors
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  FUNCTION_DESCRIPTORS=false
+else
+  FUNCTION_DESCRIPTORS=true
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    ;;
+esac
+
+
 GO_LIBCALL_OS_FILE=
 GO_LIBCALL_OS_ARCH_FILE=
 GO_SYSCALL_OS_FILE=
index 44b59482c531c240602582a51eab9736d2bd7347..03c07fe88381bac0c894e8865f0244c7a7bdcc8f 100644 (file)
@@ -353,6 +353,20 @@ AC_SUBST(GOARCH)
 AC_SUBST(ALLGOARCH)
 AC_SUBST(ALLGOARCHFAMILY)
 
+FUNCTION_DESCRIPTORS=false
+case ${host} in
+  rs6000*-*-* | powerpc*-*-*)
+    AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+#if _CALL_ELF == 1
+#error descriptors
+#endif
+])],
+       [FUNCTION_DESCRIPTORS=false],
+       [FUNCTION_DESCRIPTORS=true])
+    ;;
+esac
+AC_SUBST(FUNCTION_DESCRIPTORS)
+
 dnl Some files are only present when needed for specific architectures.
 GO_LIBCALL_OS_FILE=
 GO_LIBCALL_OS_ARCH_FILE=
index b82e738f9414cd2a2f16170cc19b93c4475e1bdb..27cd09e7870f20761a7aeb461f185bcb33e52fa1 100644 (file)
@@ -8,6 +8,7 @@ import (
        "bytes"
        "compress/gzip"
        "fmt"
+       internalcpu "internal/cpu"
        "io"
        "io/ioutil"
        "runtime"
@@ -28,7 +29,14 @@ func funcPC(f interface{}) uintptr {
                data unsafe.Pointer
        }
        i := (*iface)(unsafe.Pointer(&f))
-       return **(**uintptr)(i.data)
+       r := **(**uintptr)(i.data)
+       if internalcpu.FunctionDescriptors {
+               // With PPC64 ELF ABI v1 function descriptors the
+               // function address is a pointer to a struct whose
+               // first field is the actual PC.
+               r = *(*uintptr)(unsafe.Pointer(r))
+       }
+       return r
 }
 
 // A profileBuilder writes a profile incrementally from a
index 1c944d64752b9b0f978fe4893086e5c8952d36e5..0e6c9e19b09746a56b102db62626ac8e54885b03 100644 (file)
@@ -446,7 +446,14 @@ func releaseSudog(s *sudog) {
 //go:nosplit
 func funcPC(f interface{}) uintptr {
        i := (*iface)(unsafe.Pointer(&f))
-       return **(**uintptr)(i.data)
+       r := **(**uintptr)(i.data)
+       if cpu.FunctionDescriptors {
+               // With PPC64 ELF ABI v1 function descriptors the
+               // function address is a pointer to a struct whose
+               // first field is the actual PC.
+               r = *(*uintptr)(unsafe.Pointer(r))
+       }
+       return r
 }
 
 func lockedOSThread() bool {
index 035a9fa9d1bfbab24c1d111dfc7c0e715ae6d688..130758927053c631e16f096767e3734bd3d6ca5c 100644 (file)
@@ -157,6 +157,7 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
+FUNCTION_DESCRIPTORS = @FUNCTION_DESCRIPTORS@
 GOARCH = @GOARCH@
 GOC = @GOC@
 GOFLAGS = @GOFLAGS@