aboutsummaryrefslogtreecommitdiff
path: root/libgo/go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-02-27 22:35:10 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-02-27 22:35:10 +0000
commitcba8a572c208078c1c6eb9845b54f960526c53c0 (patch)
tree2533982aacf337307ee72ee82ae77f3cb01fbd58 /libgo/go
parente6df04c105464436e700013e1f665ebf0f94c9f2 (diff)
downloadgcc-cba8a572c208078c1c6eb9845b54f960526c53c0.zip
gcc-cba8a572c208078c1c6eb9845b54f960526c53c0.tar.gz
gcc-cba8a572c208078c1c6eb9845b54f960526c53c0.tar.bz2
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
Diffstat (limited to 'libgo/go')
-rw-r--r--libgo/go/runtime/pprof/proto.go10
-rw-r--r--libgo/go/runtime/proc.go9
2 files changed, 17 insertions, 2 deletions
diff --git a/libgo/go/runtime/pprof/proto.go b/libgo/go/runtime/pprof/proto.go
index b82e738..27cd09e 100644
--- a/libgo/go/runtime/pprof/proto.go
+++ b/libgo/go/runtime/pprof/proto.go
@@ -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
diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go
index 1c944d6..0e6c9e1 100644
--- a/libgo/go/runtime/proc.go
+++ b/libgo/go/runtime/proc.go
@@ -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 {