Source file src/pkg/cmd/link/internal/ld/ld.go
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 "cmd/link/internal/sym"
36 "io/ioutil"
37 "log"
38 "os"
39 "path"
40 "path/filepath"
41 "strconv"
42 "strings"
43 )
44
45 func (ctxt *Link) readImportCfg(file string) {
46 ctxt.PackageFile = make(map[string]string)
47 ctxt.PackageShlib = make(map[string]string)
48 data, err := ioutil.ReadFile(file)
49 if err != nil {
50 log.Fatalf("-importcfg: %v", err)
51 }
52
53 for lineNum, line := range strings.Split(string(data), "\n") {
54 lineNum++
55 line = strings.TrimSpace(line)
56 if line == "" {
57 continue
58 }
59 if line == "" || strings.HasPrefix(line, "#") {
60 continue
61 }
62
63 var verb, args string
64 if i := strings.Index(line, " "); i < 0 {
65 verb = line
66 } else {
67 verb, args = line[:i], strings.TrimSpace(line[i+1:])
68 }
69 var before, after string
70 if i := strings.Index(args, "="); i >= 0 {
71 before, after = args[:i], args[i+1:]
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 }
87 }
88 }
89
90 func pkgname(ctxt *Link, lib string) string {
91 name := path.Clean(lib)
92
93
94 if ctxt.PackageFile != nil {
95 return name
96 }
97
98
99 pkg := name
100 if len(pkg) >= 2 && pkg[len(pkg)-2] == '.' {
101 pkg = pkg[:len(pkg)-2]
102 }
103 return pkg
104 }
105
106 func findlib(ctxt *Link, lib string) (string, bool) {
107 name := path.Clean(lib)
108
109 var pname string
110 isshlib := false
111
112 if ctxt.linkShared && ctxt.PackageShlib[name] != "" {
113 pname = ctxt.PackageShlib[name]
114 isshlib = true
115 } else if ctxt.PackageFile != nil {
116 pname = ctxt.PackageFile[name]
117 if pname == "" {
118 ctxt.Logf("cannot find package %s (using -importcfg)\n", name)
119 return "", false
120 }
121 } else {
122 if filepath.IsAbs(name) {
123 pname = name
124 } else {
125 pkg := pkgname(ctxt, lib)
126
127
128
129
130
131
132
133 if !strings.HasSuffix(name, ".a") && !strings.HasSuffix(name, ".o") {
134 name += ".a"
135 }
136
137 for _, dir := range ctxt.Libdir {
138 if ctxt.linkShared {
139 pname = filepath.Join(dir, pkg+".shlibname")
140 if _, err := os.Stat(pname); err == nil {
141 isshlib = true
142 break
143 }
144 }
145 pname = filepath.Join(dir, name)
146 if _, err := os.Stat(pname); err == nil {
147 break
148 }
149 }
150 }
151 pname = path.Clean(pname)
152 }
153
154 return pname, isshlib
155 }
156
157 func addlib(ctxt *Link, src string, obj string, lib string) *sym.Library {
158 pkg := pkgname(ctxt, lib)
159
160
161 if l := ctxt.LibraryByPkg[pkg]; l != nil {
162 return l
163 }
164
165 pname, isshlib := findlib(ctxt, lib)
166
167 if ctxt.Debugvlog > 1 {
168 ctxt.Logf("%5.2f addlib: %s %s pulls in %s isshlib %v\n", elapsed(), obj, src, pname, isshlib)
169 }
170
171 if isshlib {
172 return addlibpath(ctxt, src, obj, "", pkg, pname)
173 }
174 return addlibpath(ctxt, src, obj, pname, pkg, "")
175 }
176
177
185 func addlibpath(ctxt *Link, srcref string, objref string, file string, pkg string, shlib string) *sym.Library {
186 if l := ctxt.LibraryByPkg[pkg]; l != nil {
187 return l
188 }
189
190 if ctxt.Debugvlog > 1 {
191 ctxt.Logf("%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s shlib: %s\n", Cputime(), srcref, objref, file, pkg, shlib)
192 }
193
194 l := &sym.Library{}
195 ctxt.LibraryByPkg[pkg] = l
196 ctxt.Library = append(ctxt.Library, l)
197 l.Objref = objref
198 l.Srcref = srcref
199 l.File = file
200 l.Pkg = pkg
201 if shlib != "" {
202 if strings.HasSuffix(shlib, ".shlibname") {
203 data, err := ioutil.ReadFile(shlib)
204 if err != nil {
205 Errorf(nil, "cannot read %s: %v", shlib, err)
206 }
207 shlib = strings.TrimSpace(string(data))
208 }
209 l.Shlib = shlib
210 }
211 return l
212 }
213
214 func atolwhex(s string) int64 {
215 n, _ := strconv.ParseInt(s, 0, 64)
216 return n
217 }
218
View as plain text