// Try to find symbol under another ABI.
var reqABI, haveABI obj.ABI
haveABI = ^obj.ABI(0)
- for abi := obj.ABI(0); abi < obj.ABICount; abi++ {
- v := sym.ABIToVersion(abi)
- if v == -1 {
- continue
- }
- if v == int(r.Sym.Version) {
- reqABI = abi
- } else if ctxt.Syms.ROLookup(r.Sym.Name, v) != nil {
- haveABI = abi
+ reqABI, ok := sym.VersionToABI(int(r.Sym.Version))
+ if ok {
+ for abi := obj.ABI(0); abi < obj.ABICount; abi++ {
+ v := sym.ABIToVersion(abi)
+ if v == -1 {
+ continue
+ }
+ if rs := ctxt.Syms.ROLookup(r.Sym.Name, v); rs != nil && rs.Type != sym.Sxxx {
+ haveABI = abi
+ }
}
}
return -1
}
+func VersionToABI(v int) (obj.ABI, bool) {
+ switch v {
+ case SymVerABI0:
+ return obj.ABI0, true
+ case SymVerABIInternal:
+ return obj.ABIInternal, true
+ }
+ return ^obj.ABI(0), false
+}
+
func (s *Symbol) String() string {
if s.Version == 0 {
return s.Name
"os"
"os/exec"
"path/filepath"
+ "regexp"
"strings"
"testing"
)
// to compile the extra section.
runGo("tool", "link", "main.a")
}
+
+func TestUnresolved(t *testing.T) {
+ testenv.MustHaveGoBuild(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)
+ }
+ }
+
+ // Test various undefined references. Because of issue #29852,
+ // this used to give confusing error messages because the
+ // linker would find an undefined reference to "zero" created
+ // by the runtime package.
+
+ write("main.go", `package main
+
+func main() {
+ x()
+}
+
+func x()
+`)
+ write("main.s", `
+TEXT ·x(SB),0,$0
+ MOVD zero<>(SB), AX
+ MOVD zero(SB), AX
+ MOVD ·zero(SB), AX
+ RET
+`)
+ cmd := exec.Command(testenv.GoToolPath(t), "build")
+ cmd.Dir = tmpdir
+ cmd.Env = append(os.Environ(), []string{"GOARCH=amd64", "GOOS=linux"}...)
+ out, err := cmd.CombinedOutput()
+ if err == nil {
+ t.Fatalf("expected build to fail, but it succeeded")
+ }
+ out = regexp.MustCompile("(?m)^#.*\n").ReplaceAll(out, nil)
+ got := string(out)
+ want := `main.x: relocation target zero not defined
+main.x: relocation target zero not defined
+main.x: relocation target main.zero not defined
+`
+ if want != got {
+ t.Fatalf("want:\n%sgot:\n%s", want, got)
+ }
+}