aboutsummaryrefslogtreecommitdiff
path: root/misc/cgo
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2022-10-12 16:24:34 -0400
committerCherry Mui <cherryyz@google.com>2022-10-13 18:47:30 +0000
commit9fe17a0340b1609355aa5ce1828a0cf39e0a8092 (patch)
tree73f366e6a5047c2d43cc0e71e3a81aeb3c8a465e /misc/cgo
parent36ca37f3a04aac4b67aa7fe3cfe480c891d0d53f (diff)
downloadgo-9fe17a0340b1609355aa5ce1828a0cf39e0a8092.tar.gz
go-9fe17a0340b1609355aa5ce1828a0cf39e0a8092.zip
cmd/link: don't reset variable size when handling -X flag
The linker's -X flag allows setting/changing a string variable's content at link time. Currently it resets its size then write a new string header pointing to the new content. This mostly works. But under ASAN build the string variable can have larger size than the usual 2 words, due to the red zone. Resetting the size can cause the variable to "overlap" (in ASAN's view) with other variables. Don't reset the size. Fixes #56175. Change-Id: Ib364208201a7a2fd7f44f9b1797834198736a405 Reviewed-on: https://go-review.googlesource.com/c/go/+/442635 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Cherry Mui <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'misc/cgo')
-rw-r--r--misc/cgo/testsanitizers/asan_test.go42
-rw-r--r--misc/cgo/testsanitizers/testdata/asan_linkerx/main.go28
-rw-r--r--misc/cgo/testsanitizers/testdata/asan_linkerx/p/p.go12
3 files changed, 82 insertions, 0 deletions
diff --git a/misc/cgo/testsanitizers/asan_test.go b/misc/cgo/testsanitizers/asan_test.go
index 67d097cf16..932cfb1b60 100644
--- a/misc/cgo/testsanitizers/asan_test.go
+++ b/misc/cgo/testsanitizers/asan_test.go
@@ -5,6 +5,7 @@
package sanitizers_test
import (
+ "fmt"
"strings"
"testing"
)
@@ -97,3 +98,44 @@ func TestASAN(t *testing.T) {
})
}
}
+
+func TestASANLinkerX(t *testing.T) {
+ // Test ASAN with linker's -X flag (see issue 56175).
+ goos, err := goEnv("GOOS")
+ if err != nil {
+ t.Fatal(err)
+ }
+ goarch, err := goEnv("GOARCH")
+ if err != nil {
+ t.Fatal(err)
+ }
+ // The asan tests require support for the -asan option.
+ if !aSanSupported(goos, goarch) {
+ t.Skipf("skipping on %s/%s; -asan option is not supported.", goos, goarch)
+ }
+ if !compilerRequiredAsanVersion(goos, goarch) {
+ t.Skipf("skipping on %s/%s: too old version of compiler", goos, goarch)
+ }
+
+ t.Parallel()
+ requireOvercommit(t)
+ config := configure("address")
+ config.skipIfCSanitizerBroken(t)
+
+ dir := newTempDir(t)
+ defer dir.RemoveAll(t)
+
+ var ldflags string
+ for i := 1; i <= 10; i++ {
+ ldflags += fmt.Sprintf("-X=main.S%d=%d -X=misc/cgo/testsanitizers/testdata/asan_linkerx/p.S%d=%d ", i, i, i, i)
+ }
+
+ // build the binary
+ outPath := dir.Join("main.exe")
+ cmd := config.goCmd("build", "-ldflags="+ldflags, "-o", outPath)
+ cmd.Dir = srcPath("asan_linkerx")
+ mustRun(t, cmd)
+
+ // run the binary
+ mustRun(t, hangProneCmd(outPath))
+}
diff --git a/misc/cgo/testsanitizers/testdata/asan_linkerx/main.go b/misc/cgo/testsanitizers/testdata/asan_linkerx/main.go
new file mode 100644
index 0000000000..bbd6127d90
--- /dev/null
+++ b/misc/cgo/testsanitizers/testdata/asan_linkerx/main.go
@@ -0,0 +1,28 @@
+package main
+
+import "misc/cgo/testsanitizers/testdata/asan_linkerx/p"
+
+func pstring(s *string) {
+ println(*s)
+}
+
+func main() {
+ all := []*string{
+ &S1, &S2, &S3, &S4, &S5, &S6, &S7, &S8, &S9, &S10,
+ &p.S1, &p.S2, &p.S3, &p.S4, &p.S5, &p.S6, &p.S7, &p.S8, &p.S9, &p.S10,
+ }
+ for _, ps := range all {
+ pstring(ps)
+ }
+}
+
+var S1 string
+var S2 string
+var S3 string
+var S4 string
+var S5 string
+var S6 string
+var S7 string
+var S8 string
+var S9 string
+var S10 string
diff --git a/misc/cgo/testsanitizers/testdata/asan_linkerx/p/p.go b/misc/cgo/testsanitizers/testdata/asan_linkerx/p/p.go
new file mode 100644
index 0000000000..c31f00109d
--- /dev/null
+++ b/misc/cgo/testsanitizers/testdata/asan_linkerx/p/p.go
@@ -0,0 +1,12 @@
+package p
+
+var S1 string
+var S2 string
+var S3 string
+var S4 string
+var S5 string
+var S6 string
+var S7 string
+var S8 string
+var S9 string
+var S10 string