aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/asm
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2021-01-13 15:45:28 -0800
committerKeith Randall <khr@golang.org>2021-03-16 21:18:43 +0000
commitc870e863298a44ead08e0b797d62ea74d7b7c971 (patch)
tree6b11ed84c5443f6a9e36bcc920930bf7cfb12a69 /src/cmd/asm
parent72d98df88e3cbbbe482f7d421c6fd5cbd84423b4 (diff)
downloadgo-c870e863298a44ead08e0b797d62ea74d7b7c971.tar.gz
go-c870e863298a44ead08e0b797d62ea74d7b7c971.zip
cmd/asm: when dynamic linking, reject code that uses a clobbered R15
The assember uses R15 as scratch space when assembling global variable references in dynamically linked code. If the assembly code uses the clobbered value of R15, report an error. The user is probably expecting some other value in that register. Getting rid of the R15 use isn't very practical (we could save a register to a field in the G maybe, but that gets cumbersome). Fixes #43661 Change-Id: I43f848a3d8b8a28931ec733386b85e6e9a42d8ff Reviewed-on: https://go-review.googlesource.com/c/go/+/283474 Trust: Keith Randall <khr@golang.org> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/asm')
-rw-r--r--src/cmd/asm/internal/asm/endtoend_test.go14
-rw-r--r--src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s68
2 files changed, 81 insertions, 1 deletions
diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go
index 92cf64575b..ee2982df39 100644
--- a/src/cmd/asm/internal/asm/endtoend_test.go
+++ b/src/cmd/asm/internal/asm/endtoend_test.go
@@ -270,7 +270,7 @@ var (
errQuotesRE = regexp.MustCompile(`"([^"]*)"`)
)
-func testErrors(t *testing.T, goarch, file string) {
+func testErrors(t *testing.T, goarch, file string, flags ...string) {
input := filepath.Join("testdata", file+".s")
architecture, ctxt := setArch(goarch)
lexer := lex.NewLexer(input)
@@ -292,6 +292,14 @@ func testErrors(t *testing.T, goarch, file string) {
}
errBuf.WriteString(s)
}
+ for _, flag := range flags {
+ switch flag {
+ case "dynlink":
+ ctxt.Flag_dynlink = true
+ default:
+ t.Errorf("unknown flag %s", flag)
+ }
+ }
pList.Firstpc, ok = parser.Parse()
obj.Flushplist(ctxt, pList, nil, "")
if ok && !failed {
@@ -430,6 +438,10 @@ func TestAMD64Errors(t *testing.T) {
testErrors(t, "amd64", "amd64error")
}
+func TestAMD64DynLinkErrors(t *testing.T) {
+ testErrors(t, "amd64", "amd64dynlinkerror", "dynlink")
+}
+
func TestMIPSEndToEnd(t *testing.T) {
testEndToEnd(t, "mips", "mips")
testEndToEnd(t, "mips64", "mips64")
diff --git a/src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s b/src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s
new file mode 100644
index 0000000000..1eee1a17db
--- /dev/null
+++ b/src/cmd/asm/internal/asm/testdata/amd64dynlinkerror.s
@@ -0,0 +1,68 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test to make sure that if we use R15 after it is clobbered by
+// a global variable access while dynamic linking, we get an error.
+// See issue 43661.
+
+TEXT ·a1(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ MOVL $0, R15
+ RET
+TEXT ·a2(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ MOVQ $0, R15
+ RET
+TEXT ·a3(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ XORL R15, R15
+ RET
+TEXT ·a4(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ XORQ R15, R15
+ RET
+TEXT ·a5(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ XORL R15, R15
+ RET
+TEXT ·a6(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ POPQ R15
+ PUSHQ R15
+ RET
+TEXT ·a7(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ MOVQ R15, AX // ERROR "when dynamic linking, R15 is clobbered by a global variable access and is used here"
+ RET
+TEXT ·a8(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ ADDQ AX, R15 // ERROR "when dynamic linking, R15 is clobbered by a global variable access and is used here"
+ RET
+TEXT ·a9(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ ORQ R15, R15 // ERROR "when dynamic linking, R15 is clobbered by a global variable access and is used here"
+ RET
+TEXT ·a10(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ JEQ one
+ ORQ R15, R15 // ERROR "when dynamic linking, R15 is clobbered by a global variable access and is used here"
+one:
+ RET
+TEXT ·a11(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ JEQ one
+ JMP two
+one:
+ ORQ R15, R15 // ERROR "when dynamic linking, R15 is clobbered by a global variable access and is used here"
+two:
+ RET
+TEXT ·a12(SB), 0, $0-0
+ CMPL runtime·writeBarrier(SB), $0
+ JMP one
+two:
+ ORQ R15, R15
+ RET
+one:
+ MOVL $0, R15
+ JMP two