mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 19:03:59 +08:00
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
This commit is contained in:
parent
e6df04c105
commit
cba8a572c2
@ -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.
|
||||
|
@ -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) $@
|
||||
|
||||
|
@ -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) $@
|
||||
|
||||
|
26
libgo/configure
vendored
26
libgo/configure
vendored
@ -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=
|
||||
|
@ -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=
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -157,6 +157,7 @@ ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
FUNCTION_DESCRIPTORS = @FUNCTION_DESCRIPTORS@
|
||||
GOARCH = @GOARCH@
|
||||
GOC = @GOC@
|
||||
GOFLAGS = @GOFLAGS@
|
||||
|
Loading…
Reference in New Issue
Block a user