Add patch that fixes issue in ppc64le

Fix: https://golang.org/issue/39991
Add sources
This commit is contained in:
Alejandro Sáez 2020-07-06 13:52:40 +02:00
parent 91d21a3bde
commit 0cb15e561e
4 changed files with 192 additions and 4 deletions

1
.gitignore vendored
View File

@ -84,3 +84,4 @@
/go1.14.src.tar.gz
/go1.14.2.src.tar.gz
/go1.14.3.src.tar.gz
/go1.14.4.src.tar.gz

View File

@ -0,0 +1,178 @@
From 457c3cea934db4b8883c9b932912367e02170a61 Mon Sep 17 00:00:00 2001
From: Cherry Zhang <cherryyz@google.com>
Date: Fri, 03 Jul 2020 14:28:15 -0400
Subject: [PATCH] [release-branch.go1.14] cmd/link: detect trampoline of deferreturn call
This is a backport of CL 234105. This is not a clean cherry-pick,
as CL 234105 is for the new linker, whereas we still use the old
linker here. This CL backports the logic.
The runtime needs to find the PC of the deferreturn call in a few
places. So for functions that have defer, we record the PC of
deferreturn call in its funcdata.
For very large binaries, the deferreturn call could be made
through a trampoline. The current code of finding deferreturn PC
fails in this case. This CL handles the trampoline as well.
Fixes #39991.
Updates #39049.
Change-Id: I929be54d6ae436f5294013793217dc2a35f080d4
Reviewed-on: https://go-review.googlesource.com/c/go/+/234105
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
---
diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go
index f2fb654..c4f529a 100644
--- a/src/cmd/link/internal/arm/asm.go
+++ b/src/cmd/link/internal/arm/asm.go
@@ -470,8 +470,12 @@
offset := (signext24(r.Add&0xffffff) + 2) * 4
var tramp *sym.Symbol
for i := 0; ; i++ {
- name := r.Sym.Name + fmt.Sprintf("%+d-tramp%d", offset, i)
+ oName := r.Sym.Name
+ name := oName + fmt.Sprintf("%+d-tramp%d", offset, i)
tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
+ if oName == "runtime.deferreturn" {
+ tramp.Attr.Set(sym.AttrDeferReturnTramp, true)
+ }
if tramp.Type == sym.SDYNIMPORT {
// don't reuse trampoline defined in other module
continue
diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go
index 3e8135c..43e1661 100644
--- a/src/cmd/link/internal/ld/pcln.go
+++ b/src/cmd/link/internal/ld/pcln.go
@@ -276,7 +276,7 @@
// set the resumption point to PC_B.
lastWasmAddr = uint32(r.Add)
}
- if r.Type.IsDirectCall() && r.Sym != nil && r.Sym.Name == "runtime.deferreturn" {
+ if r.Type.IsDirectCall() && r.Sym != nil && (r.Sym.Name == "runtime.deferreturn" || r.Sym.Attr.DeferReturnTramp()) {
if ctxt.Arch.Family == sys.Wasm {
deferreturn = lastWasmAddr - 1
} else {
diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go
index 9fbcff5..e84689d 100644
--- a/src/cmd/link/internal/ppc64/asm.go
+++ b/src/cmd/link/internal/ppc64/asm.go
@@ -667,7 +667,8 @@
// target is at some offset within the function. Calls to duff+8 and duff+256 must appear as
// distinct trampolines.
- name := r.Sym.Name
+ oName := r.Sym.Name
+ name := oName
if r.Add == 0 {
name = name + fmt.Sprintf("-tramp%d", i)
} else {
@@ -677,6 +678,9 @@
// Look up the trampoline in case it already exists
tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
+ if oName == "runtime.deferreturn" {
+ tramp.Attr.Set(sym.AttrDeferReturnTramp, true)
+ }
if tramp.Value == 0 {
break
}
diff --git a/src/cmd/link/internal/sym/attribute.go b/src/cmd/link/internal/sym/attribute.go
index 4b69bf3..773b6a4 100644
--- a/src/cmd/link/internal/sym/attribute.go
+++ b/src/cmd/link/internal/sym/attribute.go
@@ -81,7 +81,10 @@
// AttrReadOnly indicates whether the symbol's content (Symbol.P) is backed by
// read-only memory.
AttrReadOnly
- // 19 attributes defined so far.
+ // AttrDeferReturnTramp indicates the symbol is a trampoline of a deferreturn
+ // call.
+ AttrDeferReturnTramp
+ // 20 attributes defined so far.
)
func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 }
@@ -103,6 +106,7 @@
func (a Attribute) Container() bool { return a&AttrContainer != 0 }
func (a Attribute) TopFrame() bool { return a&AttrTopFrame != 0 }
func (a Attribute) ReadOnly() bool { return a&AttrReadOnly != 0 }
+func (a Attribute) DeferReturnTramp() bool { return a&AttrDeferReturnTramp != 0 }
func (a Attribute) CgoExport() bool {
return a.CgoExportDynamic() || a.CgoExportStatic()
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index 4f792bd..f5efb51 100644
--- a/src/cmd/link/link_test.go
+++ b/src/cmd/link/link_test.go
@@ -447,3 +447,66 @@
t.Errorf("unexpected output:\n%s", out)
}
}
+
+const testTrampSrc = `
+package main
+import "fmt"
+func main() {
+ fmt.Println("hello")
+
+ defer func(){
+ if e := recover(); e == nil {
+ panic("did not panic")
+ }
+ }()
+ f1()
+}
+
+// Test deferreturn trampolines. See issue #39049.
+func f1() { defer f2() }
+func f2() { panic("XXX") }
+`
+
+func TestTrampoline(t *testing.T) {
+ // Test that trampoline insertion works as expected.
+ // For stress test, we set -debugtramp=2 flag, which sets a very low
+ // threshold for trampoline generation, and essentially all cross-package
+ // calls will use trampolines.
+ switch runtime.GOARCH {
+ case "arm", "ppc64", "ppc64le":
+ default:
+ t.Skipf("trampoline insertion is not implemented on %s", runtime.GOARCH)
+ }
+ if runtime.GOOS == "aix" {
+ t.Skip("trampolines on AIX doesn't work in Go 1.14") // fixed in Go 1.15
+ }
+
+ testenv.MustHaveGoBuild(t)
+
+ tmpdir, err := ioutil.TempDir("", "TestTrampoline")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tmpdir)
+
+ src := filepath.Join(tmpdir, "hello.go")
+ err = ioutil.WriteFile(src, []byte(testTrampSrc), 0666)
+ if err != nil {
+ t.Fatal(err)
+ }
+ exe := filepath.Join(tmpdir, "hello.exe")
+
+ cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-debugtramp=2", "-o", exe, src)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("build failed: %v\n%s", err, out)
+ }
+ cmd = exec.Command(exe)
+ out, err = cmd.CombinedOutput()
+ if err != nil {
+ t.Errorf("executable failed to run: %v\n%s", err, out)
+ }
+ if string(out) != "hello\n" {
+ t.Errorf("unexpected output:\n%s", out)
+ }
+}

View File

@ -1,5 +1,10 @@
%bcond_with bootstrap
# temporalily ignore test failures
%ifarch %{ix86} aarch64 %{arm}
%bcond_without ignore_tests
%else
%bcond_with ignore_tests
%endif
# build ids are not currently generated:
# https://code.google.com/p/go/issues/detail?id=5238
@ -215,6 +220,7 @@ Requires: go-srpm-macros
Patch1: 0001-Don-t-use-the-bundled-tzdata-at-runtime-except-for-t.patch
Patch2: 0002-syscall-expose-IfInfomsg.X__ifi_pad-on-s390x.patch
Patch3: 0003-cmd-go-disable-Google-s-proxy-and-sumdb.patch
Patch4: 0004-ppc64le-fix-missing-deferreturn.patch
# Having documentation separate was broken
Obsoletes: %{name}-docs < 1.1-4
@ -507,9 +513,11 @@ export GO_LDFLAGS="-linkmode internal"
export CGO_ENABLED=0
%endif
# workaround for https://github.com/golang/go/issues/39466 until it gests fixed
%ifarch aarch64
export CGO_CFLAGS="-mno-outline-atomics"
%endif
# Commented until the patch is ready, this work around suggested in the link avobe
# doesn't work properly
#%ifarch aarch64
#export CGO_CFLAGS="-mno-outline-atomics"
#%endif
# make sure to not timeout
export GO_TEST_TIMEOUT_SCALE=2
@ -586,6 +594,7 @@ fi
%changelog
* Tue Jun 30 2020 Alejandro Sáez <asm@redhat.com> - 1.14.4-1
- Rebase to go1.14.4
- Add patch that fixes: https://golang.org/issue/39991
- Related: BZ#1842708
* Mon May 18 2020 Álex Sáez <asm@redhat.com> - 1.14.3-1

View File

@ -1 +1 @@
SHA512 (go1.14.3.src.tar.gz) = ab7454cf5e364a4b8d3035320bb8af5a3064accba51cb98211d2ba8afb116d07cedd6f637d068b31df6185b2f26a649da910bc865c4d52ee72b2664bfb6229bc
SHA512 (go1.14.4.src.tar.gz) = b0d657ea33331062db5a4da0aff14798f292ca967a53665af1a93e04eba7a03e49a3dbc4768c4f099ec5ff25a31885750f7658f819057057093e2d7bfb085575