1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package ld
33
34 import (
35 "log"
36 "os"
37 "path"
38 "path/filepath"
39 "strconv"
40 "strings"
41
42 "cmd/internal/goobj"
43 "cmd/link/internal/loader"
44 "cmd/link/internal/sym"
45 )
46
47 func (ctxt *Link) readImportCfg(file string) {
48 ctxt.PackageFile = make(map[string]string)
49 ctxt.PackageShlib = make(map[string]string)
50 data, err := os.ReadFile(file)
51 if err != nil {
52 log.Fatalf("-importcfg: %v", err)
53 }
54
55 for lineNum, line := range strings.Split(string(data), "\n") {
56 lineNum++
57 line = strings.TrimSpace(line)
58 if line == "" {
59 continue
60 }
61 if line == "" || strings.HasPrefix(line, "#") {
62 continue
63 }
64
65 verb, args, found := strings.Cut(line, " ")
66 if found {
67 args = strings.TrimSpace(args)
68 }
69 before, after, exist := strings.Cut(args, "=")
70 if !exist {
71 before = ""
72 }
73 switch verb {
74 default:
75 log.Fatalf("%s:%d: unknown directive %q", file, lineNum, verb)
76 case "packagefile":
77 if before == "" || after == "" {
78 log.Fatalf(`%s:%d: invalid packagefile: syntax is "packagefile path=filename"`, file, lineNum)
79 }
80 ctxt.PackageFile[before] = after
81 case "packageshlib":
82 if before == "" || after == "" {
83 log.Fatalf(`%s:%d: invalid packageshlib: syntax is "packageshlib path=filename"`, file, lineNum)
84 }
85 ctxt.PackageShlib[before] = after
86 case "modinfo":
87 s, err := strconv.Unquote(args)
88 if err != nil {
89 log.Fatalf("%s:%d: invalid modinfo: %v", file, lineNum, err)
90 }
91 addstrdata1(ctxt, "runtime.modinfo="+s)
92 }
93 }
94 }
95
96 func pkgname(ctxt *Link, lib string) string {
97 return path.Clean(lib)
98 }
99
100 func findlib(ctxt *Link, lib string) (string, bool) {
101 name := path.Clean(lib)
102
103 var pname string
104 isshlib := false
105
106 if ctxt.linkShared && ctxt.PackageShlib[name] != "" {
107 pname = ctxt.PackageShlib[name]
108 isshlib = true
109 } else if ctxt.PackageFile != nil {
110 pname = ctxt.PackageFile[name]
111 if pname == "" {
112 ctxt.Logf("cannot find package %s (using -importcfg)\n", name)
113 return "", false
114 }
115 } else {
116 pkg := pkgname(ctxt, lib)
117
118
119 for _, dir := range ctxt.Libdir {
120 if ctxt.linkShared {
121 pname = filepath.Join(dir, pkg+".shlibname")
122 if _, err := os.Stat(pname); err == nil {
123 isshlib = true
124 break
125 }
126 }
127 pname = filepath.Join(dir, name+".a")
128 if _, err := os.Stat(pname); err == nil {
129 break
130 }
131 pname = filepath.Join(dir, name+".o")
132 if _, err := os.Stat(pname); err == nil {
133 break
134 }
135 }
136 pname = filepath.Clean(pname)
137 }
138
139 return pname, isshlib
140 }
141
142 func addlib(ctxt *Link, src, obj, lib string, fingerprint goobj.FingerprintType) *sym.Library {
143 pkg := pkgname(ctxt, lib)
144
145
146 if l := ctxt.LibraryByPkg[pkg]; l != nil && !l.Fingerprint.IsZero() {
147
148
149
150
151
152 checkFingerprint(l, l.Fingerprint, src, fingerprint)
153 return l
154 }
155
156 pname, isshlib := findlib(ctxt, lib)
157
158 if ctxt.Debugvlog > 1 {
159 ctxt.Logf("addlib: %s %s pulls in %s isshlib %v\n", obj, src, pname, isshlib)
160 }
161
162 if isshlib {
163 return addlibpath(ctxt, src, obj, "", pkg, pname, fingerprint)
164 }
165 return addlibpath(ctxt, src, obj, pname, pkg, "", fingerprint)
166 }
167
168
178 func addlibpath(ctxt *Link, srcref, objref, file, pkg, shlib string, fingerprint goobj.FingerprintType) *sym.Library {
179 if l := ctxt.LibraryByPkg[pkg]; l != nil {
180 return l
181 }
182
183 if ctxt.Debugvlog > 1 {
184 ctxt.Logf("addlibpath: srcref: %s objref: %s file: %s pkg: %s shlib: %s fingerprint: %x\n", srcref, objref, file, pkg, shlib, fingerprint)
185 }
186
187 l := &sym.Library{}
188 ctxt.LibraryByPkg[pkg] = l
189 ctxt.Library = append(ctxt.Library, l)
190 l.Objref = objref
191 l.Srcref = srcref
192 l.File = file
193 l.Pkg = pkg
194 l.Fingerprint = fingerprint
195 if shlib != "" {
196 if strings.HasSuffix(shlib, ".shlibname") {
197 data, err := os.ReadFile(shlib)
198 if err != nil {
199 Errorf("cannot read %s: %v", shlib, err)
200 }
201 shlib = strings.TrimSpace(string(data))
202 }
203 l.Shlib = shlib
204 }
205 return l
206 }
207
208 func atolwhex(s string) int64 {
209 n, _ := strconv.ParseInt(s, 0, 64)
210 return n
211 }
212
213
214
215
216
217
218
219 func PrepareAddmoduledata(ctxt *Link) (*loader.SymbolBuilder, loader.Sym) {
220 if !ctxt.DynlinkingGo() {
221 return nil, 0
222 }
223 amd := ctxt.loader.LookupOrCreateSym("runtime.addmoduledata", 0)
224 if ctxt.loader.SymType(amd).IsText() && ctxt.BuildMode != BuildModePlugin {
225
226
227 return nil, 0
228 }
229 ctxt.loader.SetAttrReachable(amd, true)
230
231
232
233 ifs := ctxt.loader.LookupOrCreateSym("go:link.addmoduledata", 0)
234 initfunc := ctxt.loader.MakeSymbolUpdater(ifs)
235 ctxt.loader.SetAttrReachable(ifs, true)
236 ctxt.loader.SetAttrLocal(ifs, true)
237 initfunc.SetType(sym.STEXT)
238
239
240 if ctxt.BuildMode == BuildModePlugin {
241 ctxt.Textp = append(ctxt.Textp, amd)
242 }
243 ctxt.Textp = append(ctxt.Textp, initfunc.Sym())
244
245
246 amdi := ctxt.loader.LookupOrCreateSym("go:link.addmoduledatainit", 0)
247 initarray_entry := ctxt.loader.MakeSymbolUpdater(amdi)
248 ctxt.loader.SetAttrReachable(amdi, true)
249 ctxt.loader.SetAttrLocal(amdi, true)
250 initarray_entry.SetType(sym.SINITARR)
251 initarray_entry.AddAddr(ctxt.Arch, ifs)
252
253 return initfunc, amd
254 }
255
View as plain text