aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2020-02-26 02:48:24 +1100
committerJoel Sing <joel@sing.id.au>2020-04-02 15:54:17 +0000
commitaa4d92b8aab63c847ab077417b809694a2a6ea81 (patch)
tree551a4601c1c4023afc20d2c96f9068739fbdfb9d
parent1dbcbcfca4692f67db7de2c1ff6a5ee59511cfa4 (diff)
downloadgo-aa4d92b8aab63c847ab077417b809694a2a6ea81.tar.gz
go-aa4d92b8aab63c847ab077417b809694a2a6ea81.zip
cmd/link: skip symbol references when looking for missing symbols
ErrorUnresolved attempts to find the missing symbol in another ABI, in order to provide more friendly error messages. However, in doing so it checks the same ABI and can find the symbol reference for the symbol that it is currently reporting the unresolved error for. Avoid this by ignoring SXREF symbols, which is the same behaviour used when linking is performed. Fixes #33979 Change-Id: I9bfc40146dec2666d25e93d3bcd1984da5c71215 Reviewed-on: https://go-review.googlesource.com/c/go/+/220917 Run-TryBot: Than McIntosh <thanm@google.com> Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r--src/cmd/link/internal/ld/link.go2
-rw-r--r--src/cmd/link/link_test.go87
2 files changed, 88 insertions, 1 deletions
diff --git a/src/cmd/link/internal/ld/link.go b/src/cmd/link/internal/ld/link.go
index 124f7d9001..df3845fac3 100644
--- a/src/cmd/link/internal/ld/link.go
+++ b/src/cmd/link/internal/ld/link.go
@@ -136,7 +136,7 @@ func (ctxt *Link) ErrorUnresolved(s *sym.Symbol, r *sym.Reloc) {
if v == -1 {
continue
}
- if rs := ctxt.Syms.ROLookup(r.Sym.Name, v); rs != nil && rs.Type != sym.Sxxx {
+ if rs := ctxt.Syms.ROLookup(r.Sym.Name, v); rs != nil && rs.Type != sym.Sxxx && rs.Type != sym.SXREF {
haveABI = abi
}
}
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index 7d87093813..b1f0e8882c 100644
--- a/src/cmd/link/link_test.go
+++ b/src/cmd/link/link_test.go
@@ -172,6 +172,93 @@ main.x: relocation target main.zero not defined
}
}
+func TestIssue33979(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ testenv.MustHaveCGO(t)
+
+ // Skip test on platforms that do not support cgo internal linking.
+ switch runtime.GOARCH {
+ case "mips", "mipsle", "mips64", "mips64le":
+ t.Skipf("Skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
+ }
+ if runtime.GOOS == "aix" {
+ t.Skipf("Skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
+ }
+
+ tmpdir, err := ioutil.TempDir("", "unresolved-")
+ if err != nil {
+ t.Fatalf("failed to create temp dir: %v", err)
+ }
+ defer os.RemoveAll(tmpdir)
+
+ write := func(name, content string) {
+ err := ioutil.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ run := func(name string, args ...string) string {
+ cmd := exec.Command(name, args...)
+ cmd.Dir = tmpdir
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("'go %s' failed: %v, output: %s", strings.Join(args, " "), err, out)
+ }
+ return string(out)
+ }
+ runGo := func(args ...string) string {
+ return run(testenv.GoToolPath(t), args...)
+ }
+
+ // Test object with undefined reference that was not generated
+ // by Go, resulting in an SXREF symbol being loaded during linking.
+ // Because of issue #33979, the SXREF symbol would be found during
+ // error reporting, resulting in confusing error messages.
+
+ write("main.go", `package main
+func main() {
+ x()
+}
+func x()
+`)
+ // The following assembly must work on all architectures.
+ write("x.s", `
+TEXT ·x(SB),0,$0
+ CALL foo(SB)
+ RET
+`)
+ write("x.c", `
+void undefined();
+
+void foo() {
+ undefined();
+}
+`)
+
+ cc := strings.TrimSpace(runGo("env", "CC"))
+ cflags := strings.Fields(runGo("env", "GOGCCFLAGS"))
+
+ // Compile, assemble and pack the Go and C code.
+ runGo("tool", "asm", "-gensymabis", "-o", "symabis", "x.s")
+ runGo("tool", "compile", "-symabis", "symabis", "-p", "main", "-o", "x1.o", "main.go")
+ runGo("tool", "asm", "-o", "x2.o", "x.s")
+ run(cc, append(cflags, "-c", "-o", "x3.o", "x.c")...)
+ runGo("tool", "pack", "c", "x.a", "x1.o", "x2.o", "x3.o")
+
+ // Now attempt to link using the internal linker.
+ cmd := exec.Command(testenv.GoToolPath(t), "tool", "link", "-linkmode=internal", "x.a")
+ cmd.Dir = tmpdir
+ out, err := cmd.CombinedOutput()
+ if err == nil {
+ t.Fatalf("expected link to fail, but it succeeded")
+ }
+ re := regexp.MustCompile(`(?m)^main\(.*text\): relocation target undefined not defined$`)
+ if !re.Match(out) {
+ t.Fatalf("got:\n%q\nwant:\n%s", out, re)
+ }
+}
+
func TestBuildForTvOS(t *testing.T) {
testenv.MustHaveCGO(t)
testenv.MustHaveGoBuild(t)