]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: skip symbol references when looking for missing symbols
authorJoel Sing <joel@sing.id.au>
Fri, 30 Aug 2019 15:02:04 +0000 (01:02 +1000)
committerJoel Sing <joel@sing.id.au>
Sat, 4 Jan 2020 12:10:10 +0000 (12:10 +0000)
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: I3cb2477b2ad4baa7c2007323b983eb29404b0aac
Reviewed-on: https://go-review.googlesource.com/c/go/+/192597
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Joel Sing <joel@sing.id.au>

src/cmd/link/internal/ld/link.go
src/cmd/link/link_test.go

index 124f7d9001fcad1e551a689b0f7d2e95386cc16a..df3845fac3c4d61ea1d7f2ac67fb97f12b579ab3 100644 (file)
@@ -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
                                }
                        }
index 1515f97558402516cd091fef0b3caa5c5f13e4cf..1a86638c2f5d536f125c3ed2798c6d73b0377ed8 100644 (file)
@@ -172,6 +172,85 @@ main.x: relocation target main.zero not defined
        }
 }
 
+func TestIssue33979(t *testing.T) {
+       testenv.MustHaveGoBuild(t)
+       testenv.MustHaveCGO(t)
+
+       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")
+       }
+       got := string(out)
+       want := "main(.text): relocation target undefined not defined\n"
+       if !strings.Contains(got, want) {
+               t.Fatalf("got:\n%swant:\n%s", got, want)
+       }
+}
+
 func TestBuildForTvOS(t *testing.T) {
        testenv.MustHaveCGO(t)
        testenv.MustHaveGoBuild(t)