1
2
3
4
5
6
7 package ld
8
9 import (
10 "debug/elf"
11 "internal/testenv"
12 "os"
13 "path/filepath"
14 "runtime"
15 "strings"
16 "testing"
17 )
18
19 func TestDynSymShInfo(t *testing.T) {
20 t.Parallel()
21 testenv.MustHaveGoBuild(t)
22 dir := t.TempDir()
23
24 const prog = `
25 package main
26
27 import "net"
28
29 func main() {
30 net.Dial("", "")
31 }
32 `
33 src := filepath.Join(dir, "issue33358.go")
34 if err := os.WriteFile(src, []byte(prog), 0666); err != nil {
35 t.Fatal(err)
36 }
37
38 binFile := filepath.Join(dir, "issue33358")
39 cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", binFile, src)
40 if out, err := cmd.CombinedOutput(); err != nil {
41 t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
42 }
43
44 fi, err := os.Open(binFile)
45 if err != nil {
46 t.Fatalf("failed to open built file: %v", err)
47 }
48 defer fi.Close()
49
50 elfFile, err := elf.NewFile(fi)
51 if err != nil {
52 t.Skip("The system may not support ELF, skipped.")
53 }
54
55 section := elfFile.Section(".dynsym")
56 if section == nil {
57 t.Fatal("no dynsym")
58 }
59
60 symbols, err := elfFile.DynamicSymbols()
61 if err != nil {
62 t.Fatalf("failed to get dynamic symbols: %v", err)
63 }
64
65 var numLocalSymbols uint32
66 for i, s := range symbols {
67 if elf.ST_BIND(s.Info) != elf.STB_LOCAL {
68 numLocalSymbols = uint32(i + 1)
69 break
70 }
71 }
72
73 if section.Info != numLocalSymbols {
74 t.Fatalf("Unexpected sh info, want greater than 0, got: %d", section.Info)
75 }
76 }
77
78 func TestNoDuplicateNeededEntries(t *testing.T) {
79 testenv.MustHaveGoBuild(t)
80 testenv.MustHaveCGO(t)
81
82
83
84 pair := runtime.GOOS + "-" + runtime.GOARCH
85 switch pair {
86 case "linux-amd64", "linux-arm64", "freebsd-amd64", "openbsd-amd64":
87 default:
88 t.Skip("no need for test on " + pair)
89 }
90
91 t.Parallel()
92
93 dir := t.TempDir()
94
95 wd, err := os.Getwd()
96 if err != nil {
97 t.Fatalf("Failed to get working directory: %v", err)
98 }
99
100 path := filepath.Join(dir, "x")
101 argv := []string{"build", "-o", path, filepath.Join(wd, "testdata", "issue39256")}
102 out, err := testenv.Command(t, testenv.GoToolPath(t), argv...).CombinedOutput()
103 if err != nil {
104 t.Fatalf("Build failure: %s\n%s\n", err, string(out))
105 }
106
107 f, err := elf.Open(path)
108 if err != nil {
109 t.Fatalf("Failed to open ELF file: %v", err)
110 }
111 libs, err := f.ImportedLibraries()
112 if err != nil {
113 t.Fatalf("Failed to read imported libraries: %v", err)
114 }
115
116 var count int
117 for _, lib := range libs {
118 if lib == "libc.so" || strings.HasPrefix(lib, "libc.so.") {
119 count++
120 }
121 }
122
123 if got, want := count, 1; got != want {
124 t.Errorf("Got %d entries for `libc.so`, want %d", got, want)
125 }
126 }
127
128 func TestShStrTabAttributesIssue62600(t *testing.T) {
129 t.Parallel()
130 testenv.MustHaveGoBuild(t)
131 dir := t.TempDir()
132
133 const prog = `
134 package main
135
136 func main() {
137 println("whee")
138 }
139 `
140 src := filepath.Join(dir, "issue62600.go")
141 if err := os.WriteFile(src, []byte(prog), 0666); err != nil {
142 t.Fatal(err)
143 }
144
145 binFile := filepath.Join(dir, "issue62600")
146 cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", binFile, src)
147 if out, err := cmd.CombinedOutput(); err != nil {
148 t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
149 }
150
151 fi, err := os.Open(binFile)
152 if err != nil {
153 t.Fatalf("failed to open built file: %v", err)
154 }
155 defer fi.Close()
156
157 elfFile, err := elf.NewFile(fi)
158 if err != nil {
159 t.Skip("The system may not support ELF, skipped.")
160 }
161
162 section := elfFile.Section(".shstrtab")
163 if section == nil {
164 t.Fatal("no .shstrtab")
165 }
166
167
168
169
170 if section.Addr != 0 {
171 t.Fatalf("expected Addr == 0 for .shstrtab got %x", section.Addr)
172 }
173 if section.Size == 0 {
174 t.Fatal("expected nonzero Size for .shstrtab got 0")
175 }
176 if section.Flags&elf.SHF_ALLOC != 0 {
177 t.Fatal("expected zero alloc flag got nonzero for .shstrtab")
178 }
179 for idx, p := range elfFile.Progs {
180 if section.Offset >= p.Off && section.Offset < p.Off+p.Filesz {
181 t.Fatalf("badly formed .shstrtab, is contained in segment %d", idx)
182 }
183 }
184 }
185
View as plain text