1
2
3
4
5 package obj
6
7 import (
8 "bytes"
9 "cmd/internal/goobj"
10 "cmd/internal/sys"
11 "internal/testenv"
12 "io/ioutil"
13 "os"
14 "os/exec"
15 "path/filepath"
16 "testing"
17 "unsafe"
18 )
19
20 var dummyArch = LinkArch{Arch: sys.ArchAMD64}
21
22 func TestContentHash64(t *testing.T) {
23 s1 := &LSym{P: []byte("A")}
24 s2 := &LSym{P: []byte("A\x00\x00\x00")}
25 s1.Set(AttrContentAddressable, true)
26 s2.Set(AttrContentAddressable, true)
27 h1 := contentHash64(s1)
28 h2 := contentHash64(s2)
29 if h1 != h2 {
30 t.Errorf("contentHash64(s1)=%x, contentHash64(s2)=%x, expect equal", h1, h2)
31 }
32
33 ctxt := Linknew(&dummyArch)
34 s3 := ctxt.Int64Sym(int64('A'))
35 h3 := contentHash64(s3)
36 if h1 != h3 {
37 t.Errorf("contentHash64(s1)=%x, contentHash64(s3)=%x, expect equal", h1, h3)
38 }
39 }
40
41 func TestContentHash(t *testing.T) {
42 syms := []*LSym{
43 &LSym{P: []byte("TestSymbol")},
44 &LSym{P: []byte("TestSymbol")},
45 &LSym{P: []byte("TestSymbol2")},
46 &LSym{P: []byte("")},
47 &LSym{P: []byte("")},
48 &LSym{P: []byte("")},
49 &LSym{P: []byte("")},
50 }
51 for _, s := range syms {
52 s.Set(AttrContentAddressable, true)
53 s.PkgIdx = goobj.PkgIdxHashed
54 }
55
56 r := Addrel(syms[3])
57 r.Sym = syms[0]
58
59 r = Addrel(syms[4])
60 r.Sym = syms[0]
61
62 r = Addrel(syms[5])
63 r.Sym = syms[1]
64
65 r = Addrel(syms[6])
66 r.Sym = syms[2]
67
68
69 h := make([]goobj.HashType, len(syms))
70 w := &writer{}
71 for i := range h {
72 h[i] = w.contentHash(syms[i])
73 }
74
75 tests := []struct {
76 a, b int
77 equal bool
78 }{
79 {0, 1, true},
80 {0, 2, false},
81 {3, 4, true},
82 {3, 5, true},
83 {3, 6, false},
84 }
85 for _, test := range tests {
86 if (h[test.a] == h[test.b]) != test.equal {
87 eq := "equal"
88 if !test.equal {
89 eq = "not equal"
90 }
91 t.Errorf("h%d=%x, h%d=%x, expect %s", test.a, h[test.a], test.b, h[test.b], eq)
92 }
93 }
94 }
95
96 func TestSymbolTooLarge(t *testing.T) {
97 testenv.MustHaveGoBuild(t)
98 if unsafe.Sizeof(uintptr(0)) < 8 {
99 t.Skip("skip on 32-bit architectures")
100 }
101
102 tmpdir, err := ioutil.TempDir("", "TestSymbolTooLarge")
103 if err != nil {
104 t.Fatal(err)
105 }
106 defer os.RemoveAll(tmpdir)
107
108 src := filepath.Join(tmpdir, "p.go")
109 err = ioutil.WriteFile(src, []byte("package p; var x [1<<32]byte"), 0666)
110 if err != nil {
111 t.Fatalf("failed to write source file: %v\n", err)
112 }
113 obj := filepath.Join(tmpdir, "p.o")
114 cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-o", obj, src)
115 out, err := cmd.CombinedOutput()
116 if err == nil {
117 t.Fatalf("did not fail\noutput: %s", out)
118 }
119 const want = "symbol too large"
120 if !bytes.Contains(out, []byte(want)) {
121 t.Errorf("unexpected error message: want: %q, got: %s", want, out)
122 }
123 }
124
View as plain text