p := r.Data(li)
rdup, ldup := l.toLocal(dup)
pdup := rdup.Data(ldup)
- if bytes.Equal(p, pdup) {
- return
- }
reason := "same length but different contents"
if len(p) != len(pdup) {
reason = fmt.Sprintf("new length %d != old length %d", len(p), len(pdup))
+ } else if bytes.Equal(p, pdup) {
+ // For BSS symbols, we need to check size as well, see issue 46653.
+ szdup := l.SymSize(dup)
+ sz := int64(r.Sym(li).Siz())
+ if szdup == sz {
+ return
+ }
+ reason = fmt.Sprintf("different sizes: new size %d != old size %d",
+ sz, szdup)
}
fmt.Fprintf(os.Stderr, "cmd/link: while reading object for '%v': duplicate symbol '%s', previous def at '%v', with mismatched payload: %s\n", r.unit.Lib, name, rdup.unit.Lib, reason)
JMP 0(PC)
`
+const testStrictDupAsmSrc3 = `
+#include "textflag.h"
+GLOBL ·rcon(SB), RODATA|DUPOK, $64
+`
+
+const testStrictDupAsmSrc4 = `
+#include "textflag.h"
+GLOBL ·rcon(SB), RODATA|DUPOK, $32
+`
+
func TestStrictDup(t *testing.T) {
// Check that -strictdups flag works.
testenv.MustHaveGoBuild(t)
+ asmfiles := []struct {
+ fname string
+ payload string
+ }{
+ {"a", testStrictDupAsmSrc1},
+ {"b", testStrictDupAsmSrc2},
+ {"c", testStrictDupAsmSrc3},
+ {"d", testStrictDupAsmSrc4},
+ }
+
t.Parallel()
tmpdir := t.TempDir()
if err != nil {
t.Fatal(err)
}
- src = filepath.Join(tmpdir, "a.s")
- err = ioutil.WriteFile(src, []byte(testStrictDupAsmSrc1), 0666)
- if err != nil {
- t.Fatal(err)
- }
- src = filepath.Join(tmpdir, "b.s")
- err = ioutil.WriteFile(src, []byte(testStrictDupAsmSrc2), 0666)
- if err != nil {
- t.Fatal(err)
+ for _, af := range asmfiles {
+ src = filepath.Join(tmpdir, af.fname+".s")
+ err = ioutil.WriteFile(src, []byte(af.payload), 0666)
+ if err != nil {
+ t.Fatal(err)
+ }
}
src = filepath.Join(tmpdir, "go.mod")
err = ioutil.WriteFile(src, []byte("module teststrictdup\n"), 0666)
cmd.Dir = tmpdir
out, err := cmd.CombinedOutput()
if err != nil {
- t.Errorf("linking with -strictdups=1 failed: %v", err)
+ t.Errorf("linking with -strictdups=1 failed: %v\n%s", err, string(out))
}
if !bytes.Contains(out, []byte("mismatched payload")) {
t.Errorf("unexpected output:\n%s", out)
if err == nil {
t.Errorf("linking with -strictdups=2 did not fail")
}
- if !bytes.Contains(out, []byte("mismatched payload")) {
+ // NB: on amd64 we get the 'new length' error, on arm64 the 'different
+ // contents' error.
+ if !(bytes.Contains(out, []byte("mismatched payload: new length")) ||
+ bytes.Contains(out, []byte("mismatched payload: same length but different contents"))) ||
+ !bytes.Contains(out, []byte("mismatched payload: different sizes")) {
t.Errorf("unexpected output:\n%s", out)
}
}