Commit cba8a572 by Ian Lance Taylor

re PR go/89172 (FAIL: runtime/pprof)

	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
parent e6df04c1
c9581de3804f94c5a74ce14befce5c57368722b9 74533ed435a1a77e6f9ec8f6cf5db1695c2568e8
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -539,6 +539,7 @@ s-cpu: Makefile ...@@ -539,6 +539,7 @@ s-cpu: Makefile
rm -f cpugen.go.tmp rm -f cpugen.go.tmp
echo "package cpu" > cpugen.go.tmp echo "package cpu" > cpugen.go.tmp
echo "const CacheLinePadSize = `$(SHELL) $(srcdir)/goarch.sh $(GOARCH) cachelinesize`" >> 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 $(SHELL) $(srcdir)/mvifdiff.sh cpugen.go.tmp cpugen.go
$(STAMP) $@ $(STAMP) $@
......
...@@ -397,6 +397,7 @@ ECHO_T = @ECHO_T@ ...@@ -397,6 +397,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@ EGREP = @EGREP@
EXEEXT = @EXEEXT@ EXEEXT = @EXEEXT@
FGREP = @FGREP@ FGREP = @FGREP@
FUNCTION_DESCRIPTORS = @FUNCTION_DESCRIPTORS@
GOARCH = @GOARCH@ GOARCH = @GOARCH@
GOC = @GOC@ GOC = @GOC@
GOFLAGS = @GOFLAGS@ GOFLAGS = @GOFLAGS@
...@@ -2635,6 +2636,7 @@ s-cpu: Makefile ...@@ -2635,6 +2636,7 @@ s-cpu: Makefile
rm -f cpugen.go.tmp rm -f cpugen.go.tmp
echo "package cpu" > cpugen.go.tmp echo "package cpu" > cpugen.go.tmp
echo "const CacheLinePadSize = `$(SHELL) $(srcdir)/goarch.sh $(GOARCH) cachelinesize`" >> 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 $(SHELL) $(srcdir)/mvifdiff.sh cpugen.go.tmp cpugen.go
$(STAMP) $@ $(STAMP) $@
......
...@@ -661,6 +661,7 @@ GO_SYSCALL_OS_ARCH_FILE ...@@ -661,6 +661,7 @@ GO_SYSCALL_OS_ARCH_FILE
GO_SYSCALL_OS_FILE GO_SYSCALL_OS_FILE
GO_LIBCALL_OS_ARCH_FILE GO_LIBCALL_OS_ARCH_FILE
GO_LIBCALL_OS_FILE GO_LIBCALL_OS_FILE
FUNCTION_DESCRIPTORS
ALLGOARCHFAMILY ALLGOARCHFAMILY
ALLGOARCH ALLGOARCH
GOARCH GOARCH
...@@ -11343,7 +11344,7 @@ else ...@@ -11343,7 +11344,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 11346 "configure" #line 11347 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
...@@ -11449,7 +11450,7 @@ else ...@@ -11449,7 +11450,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 11452 "configure" #line 11453 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
...@@ -14088,6 +14089,27 @@ esac ...@@ -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_FILE=
GO_LIBCALL_OS_ARCH_FILE= GO_LIBCALL_OS_ARCH_FILE=
GO_SYSCALL_OS_FILE= GO_SYSCALL_OS_FILE=
......
...@@ -353,6 +353,20 @@ AC_SUBST(GOARCH) ...@@ -353,6 +353,20 @@ AC_SUBST(GOARCH)
AC_SUBST(ALLGOARCH) AC_SUBST(ALLGOARCH)
AC_SUBST(ALLGOARCHFAMILY) 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. dnl Some files are only present when needed for specific architectures.
GO_LIBCALL_OS_FILE= GO_LIBCALL_OS_FILE=
GO_LIBCALL_OS_ARCH_FILE= GO_LIBCALL_OS_ARCH_FILE=
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"fmt" "fmt"
internalcpu "internal/cpu"
"io" "io"
"io/ioutil" "io/ioutil"
"runtime" "runtime"
...@@ -28,7 +29,14 @@ func funcPC(f interface{}) uintptr { ...@@ -28,7 +29,14 @@ func funcPC(f interface{}) uintptr {
data unsafe.Pointer data unsafe.Pointer
} }
i := (*iface)(unsafe.Pointer(&f)) 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 // A profileBuilder writes a profile incrementally from a
......
...@@ -446,7 +446,14 @@ func releaseSudog(s *sudog) { ...@@ -446,7 +446,14 @@ func releaseSudog(s *sudog) {
//go:nosplit //go:nosplit
func funcPC(f interface{}) uintptr { func funcPC(f interface{}) uintptr {
i := (*iface)(unsafe.Pointer(&f)) 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 { func lockedOSThread() bool {
......
...@@ -157,6 +157,7 @@ ECHO_T = @ECHO_T@ ...@@ -157,6 +157,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@ EGREP = @EGREP@
EXEEXT = @EXEEXT@ EXEEXT = @EXEEXT@
FGREP = @FGREP@ FGREP = @FGREP@
FUNCTION_DESCRIPTORS = @FUNCTION_DESCRIPTORS@
GOARCH = @GOARCH@ GOARCH = @GOARCH@
GOC = @GOC@ GOC = @GOC@
GOFLAGS = @GOFLAGS@ GOFLAGS = @GOFLAGS@
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment