]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/link/internal/loader/loader.go
cmd/link: delete oReader.flags
[gostls13.git] / src / cmd / link / internal / loader / loader.go
1 // Copyright 2019 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package loader
6
7 import (
8         "bytes"
9         "cmd/internal/bio"
10         "cmd/internal/goobj"
11         "cmd/internal/obj"
12         "cmd/internal/objabi"
13         "cmd/internal/sys"
14         "cmd/link/internal/sym"
15         "debug/elf"
16         "fmt"
17         "log"
18         "math/bits"
19         "os"
20         "sort"
21         "strings"
22 )
23
24 var _ = fmt.Print
25
26 // Sym encapsulates a global symbol index, used to identify a specific
27 // Go symbol. The 0-valued Sym is corresponds to an invalid symbol.
28 type Sym int
29
30 // Relocs encapsulates the set of relocations on a given symbol; an
31 // instance of this type is returned by the Loader Relocs() method.
32 type Relocs struct {
33         rs []goobj.Reloc
34
35         li uint32   // local index of symbol whose relocs we're examining
36         r  *oReader // object reader for containing package
37         l  *Loader  // loader
38 }
39
40 // ExtReloc contains the payload for an external relocation.
41 type ExtReloc struct {
42         Xsym Sym
43         Xadd int64
44         Type objabi.RelocType
45         Size uint8
46 }
47
48 // Reloc holds a "handle" to access a relocation record from an
49 // object file.
50 type Reloc struct {
51         *goobj.Reloc
52         r *oReader
53         l *Loader
54 }
55
56 func (rel Reloc) Type() objabi.RelocType     { return objabi.RelocType(rel.Reloc.Type()) &^ objabi.R_WEAK }
57 func (rel Reloc) Weak() bool                 { return objabi.RelocType(rel.Reloc.Type())&objabi.R_WEAK != 0 }
58 func (rel Reloc) SetType(t objabi.RelocType) { rel.Reloc.SetType(uint16(t)) }
59 func (rel Reloc) Sym() Sym                   { return rel.l.resolve(rel.r, rel.Reloc.Sym()) }
60 func (rel Reloc) SetSym(s Sym)               { rel.Reloc.SetSym(goobj.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) }
61 func (rel Reloc) IsMarker() bool             { return rel.Siz() == 0 }
62
63 // Aux holds a "handle" to access an aux symbol record from an
64 // object file.
65 type Aux struct {
66         *goobj.Aux
67         r *oReader
68         l *Loader
69 }
70
71 func (a Aux) Sym() Sym { return a.l.resolve(a.r, a.Aux.Sym()) }
72
73 // oReader is a wrapper type of obj.Reader, along with some
74 // extra information.
75 type oReader struct {
76         *goobj.Reader
77         unit         *sym.CompilationUnit
78         version      int // version of static symbol
79         pkgprefix    string
80         syms         []Sym    // Sym's global index, indexed by local index
81         pkg          []uint32 // indices of referenced package by PkgIdx (index into loader.objs array)
82         ndef         int      // cache goobj.Reader.NSym()
83         nhashed64def int      // cache goobj.Reader.NHashed64Def()
84         nhasheddef   int      // cache goobj.Reader.NHashedDef()
85         objidx       uint32   // index of this reader in the objs slice
86 }
87
88 // Total number of defined symbols (package symbols, hashed symbols, and
89 // non-package symbols).
90 func (r *oReader) NAlldef() int { return r.ndef + r.nhashed64def + r.nhasheddef + r.NNonpkgdef() }
91
92 type objIdx struct {
93         r *oReader
94         i Sym // start index
95 }
96
97 // objSym represents a symbol in an object file. It is a tuple of
98 // the object and the symbol's local index.
99 // For external symbols, objidx is the index of l.extReader (extObj),
100 // s is its index into the payload array.
101 // {0, 0} represents the nil symbol.
102 type objSym struct {
103         objidx uint32 // index of the object (in l.objs array)
104         s      uint32 // local index
105 }
106
107 type nameVer struct {
108         name string
109         v    int
110 }
111
112 type Bitmap []uint32
113
114 // set the i-th bit.
115 func (bm Bitmap) Set(i Sym) {
116         n, r := uint(i)/32, uint(i)%32
117         bm[n] |= 1 << r
118 }
119
120 // unset the i-th bit.
121 func (bm Bitmap) Unset(i Sym) {
122         n, r := uint(i)/32, uint(i)%32
123         bm[n] &^= (1 << r)
124 }
125
126 // whether the i-th bit is set.
127 func (bm Bitmap) Has(i Sym) bool {
128         n, r := uint(i)/32, uint(i)%32
129         return bm[n]&(1<<r) != 0
130 }
131
132 // return current length of bitmap in bits.
133 func (bm Bitmap) Len() int {
134         return len(bm) * 32
135 }
136
137 // return the number of bits set.
138 func (bm Bitmap) Count() int {
139         s := 0
140         for _, x := range bm {
141                 s += bits.OnesCount32(x)
142         }
143         return s
144 }
145
146 func MakeBitmap(n int) Bitmap {
147         return make(Bitmap, (n+31)/32)
148 }
149
150 // growBitmap insures that the specified bitmap has enough capacity,
151 // reallocating (doubling the size) if needed.
152 func growBitmap(reqLen int, b Bitmap) Bitmap {
153         curLen := b.Len()
154         if reqLen > curLen {
155                 b = append(b, MakeBitmap(reqLen+1-curLen)...)
156         }
157         return b
158 }
159
160 type symAndSize struct {
161         sym  Sym
162         size uint32
163 }
164
165 // A Loader loads new object files and resolves indexed symbol references.
166 //
167 // Notes on the layout of global symbol index space:
168 //
169 // - Go object files are read before host object files; each Go object
170 //   read adds its defined package symbols to the global index space.
171 //   Nonpackage symbols are not yet added.
172 //
173 // - In loader.LoadNonpkgSyms, add non-package defined symbols and
174 //   references in all object files to the global index space.
175 //
176 // - Host object file loading happens; the host object loader does a
177 //   name/version lookup for each symbol it finds; this can wind up
178 //   extending the external symbol index space range. The host object
179 //   loader stores symbol payloads in loader.payloads using SymbolBuilder.
180 //
181 // - Each symbol gets a unique global index. For duplicated and
182 //   overwriting/overwritten symbols, the second (or later) appearance
183 //   of the symbol gets the same global index as the first appearance.
184 type Loader struct {
185         start       map[*oReader]Sym // map from object file to its start index
186         objs        []objIdx         // sorted by start index (i.e. objIdx.i)
187         extStart    Sym              // from this index on, the symbols are externally defined
188         builtinSyms []Sym            // global index of builtin symbols
189
190         objSyms []objSym // global index mapping to local index
191
192         symsByName    [2]map[string]Sym // map symbol name to index, two maps are for ABI0 and ABIInternal
193         extStaticSyms map[nameVer]Sym   // externally defined static symbols, keyed by name
194
195         extReader    *oReader // a dummy oReader, for external symbols
196         payloadBatch []extSymPayload
197         payloads     []*extSymPayload // contents of linker-materialized external syms
198         values       []int64          // symbol values, indexed by global sym index
199
200         sects    []*sym.Section // sections
201         symSects []uint16       // symbol's section, index to sects array
202
203         align []uint8 // symbol 2^N alignment, indexed by global index
204
205         deferReturnTramp map[Sym]bool // whether the symbol is a trampoline of a deferreturn call
206
207         objByPkg map[string]uint32 // map package path to the index of its Go object reader
208
209         anonVersion int // most recently assigned ext static sym pseudo-version
210
211         // Bitmaps and other side structures used to store data used to store
212         // symbol flags/attributes; these are to be accessed via the
213         // corresponding loader "AttrXXX" and "SetAttrXXX" methods. Please
214         // visit the comments on these methods for more details on the
215         // semantics / interpretation of the specific flags or attribute.
216         attrReachable        Bitmap // reachable symbols, indexed by global index
217         attrOnList           Bitmap // "on list" symbols, indexed by global index
218         attrLocal            Bitmap // "local" symbols, indexed by global index
219         attrNotInSymbolTable Bitmap // "not in symtab" symbols, indexed by global idx
220         attrUsedInIface      Bitmap // "used in interface" symbols, indexed by global idx
221         attrVisibilityHidden Bitmap // hidden symbols, indexed by ext sym index
222         attrDuplicateOK      Bitmap // dupOK symbols, indexed by ext sym index
223         attrShared           Bitmap // shared symbols, indexed by ext sym index
224         attrExternal         Bitmap // external symbols, indexed by ext sym index
225
226         attrReadOnly         map[Sym]bool     // readonly data for this sym
227         attrSpecial          map[Sym]struct{} // "special" frame symbols
228         attrCgoExportDynamic map[Sym]struct{} // "cgo_export_dynamic" symbols
229         attrCgoExportStatic  map[Sym]struct{} // "cgo_export_static" symbols
230         generatedSyms        map[Sym]struct{} // symbols that generate their content
231
232         // Outer and Sub relations for symbols.
233         // TODO: figure out whether it's more efficient to just have these
234         // as fields on extSymPayload (note that this won't be a viable
235         // strategy if somewhere in the linker we set sub/outer for a
236         // non-external sym).
237         outer map[Sym]Sym
238         sub   map[Sym]Sym
239
240         dynimplib   map[Sym]string      // stores Dynimplib symbol attribute
241         dynimpvers  map[Sym]string      // stores Dynimpvers symbol attribute
242         localentry  map[Sym]uint8       // stores Localentry symbol attribute
243         extname     map[Sym]string      // stores Extname symbol attribute
244         elfType     map[Sym]elf.SymType // stores elf type symbol property
245         elfSym      map[Sym]int32       // stores elf sym symbol property
246         localElfSym map[Sym]int32       // stores "local" elf sym symbol property
247         symPkg      map[Sym]string      // stores package for symbol, or library for shlib-derived syms
248         plt         map[Sym]int32       // stores dynimport for pe objects
249         got         map[Sym]int32       // stores got for pe objects
250         dynid       map[Sym]int32       // stores Dynid for symbol
251
252         relocVariant map[relocId]sym.RelocVariant // stores variant relocs
253
254         // Used to implement field tracking; created during deadcode if
255         // field tracking is enabled. Reachparent[K] contains the index of
256         // the symbol that triggered the marking of symbol K as live.
257         Reachparent []Sym
258
259         // CgoExports records cgo-exported symbols by SymName.
260         CgoExports map[string]Sym
261
262         flags uint32
263
264         hasUnknownPkgPath bool // if any Go object has unknown package path
265
266         strictDupMsgs int // number of strict-dup warning/errors, when FlagStrictDups is enabled
267
268         elfsetstring elfsetstringFunc
269
270         errorReporter *ErrorReporter
271
272         npkgsyms    int // number of package symbols, for accounting
273         nhashedsyms int // number of hashed symbols, for accounting
274 }
275
276 const (
277         pkgDef = iota
278         hashed64Def
279         hashedDef
280         nonPkgDef
281         nonPkgRef
282 )
283
284 // objidx
285 const (
286         nilObj = iota
287         extObj
288         goObjStart
289 )
290
291 type elfsetstringFunc func(str string, off int)
292
293 // extSymPayload holds the payload (data + relocations) for linker-synthesized
294 // external symbols (note that symbol value is stored in a separate slice).
295 type extSymPayload struct {
296         name   string // TODO: would this be better as offset into str table?
297         size   int64
298         ver    int
299         kind   sym.SymKind
300         objidx uint32 // index of original object if sym made by cloneToExternal
301         relocs []goobj.Reloc
302         data   []byte
303         auxs   []goobj.Aux
304 }
305
306 const (
307         // Loader.flags
308         FlagStrictDups = 1 << iota
309 )
310
311 func NewLoader(flags uint32, elfsetstring elfsetstringFunc, reporter *ErrorReporter) *Loader {
312         nbuiltin := goobj.NBuiltin()
313         extReader := &oReader{objidx: extObj}
314         ldr := &Loader{
315                 start:                make(map[*oReader]Sym),
316                 objs:                 []objIdx{{}, {extReader, 0}}, // reserve index 0 for nil symbol, 1 for external symbols
317                 objSyms:              make([]objSym, 1, 1),         // This will get overwritten later.
318                 extReader:            extReader,
319                 symsByName:           [2]map[string]Sym{make(map[string]Sym, 80000), make(map[string]Sym, 50000)}, // preallocate ~2MB for ABI0 and ~1MB for ABI1 symbols
320                 objByPkg:             make(map[string]uint32),
321                 outer:                make(map[Sym]Sym),
322                 sub:                  make(map[Sym]Sym),
323                 dynimplib:            make(map[Sym]string),
324                 dynimpvers:           make(map[Sym]string),
325                 localentry:           make(map[Sym]uint8),
326                 extname:              make(map[Sym]string),
327                 attrReadOnly:         make(map[Sym]bool),
328                 elfType:              make(map[Sym]elf.SymType),
329                 elfSym:               make(map[Sym]int32),
330                 localElfSym:          make(map[Sym]int32),
331                 symPkg:               make(map[Sym]string),
332                 plt:                  make(map[Sym]int32),
333                 got:                  make(map[Sym]int32),
334                 dynid:                make(map[Sym]int32),
335                 attrSpecial:          make(map[Sym]struct{}),
336                 attrCgoExportDynamic: make(map[Sym]struct{}),
337                 attrCgoExportStatic:  make(map[Sym]struct{}),
338                 generatedSyms:        make(map[Sym]struct{}),
339                 deferReturnTramp:     make(map[Sym]bool),
340                 extStaticSyms:        make(map[nameVer]Sym),
341                 builtinSyms:          make([]Sym, nbuiltin),
342                 flags:                flags,
343                 elfsetstring:         elfsetstring,
344                 errorReporter:        reporter,
345                 sects:                []*sym.Section{nil}, // reserve index 0 for nil section
346         }
347         reporter.ldr = ldr
348         return ldr
349 }
350
351 // Add object file r, return the start index.
352 func (l *Loader) addObj(pkg string, r *oReader) Sym {
353         if _, ok := l.start[r]; ok {
354                 panic("already added")
355         }
356         pkg = objabi.PathToPrefix(pkg) // the object file contains escaped package path
357         if _, ok := l.objByPkg[pkg]; !ok {
358                 l.objByPkg[pkg] = r.objidx
359         }
360         i := Sym(len(l.objSyms))
361         l.start[r] = i
362         l.objs = append(l.objs, objIdx{r, i})
363         if r.NeedNameExpansion() && !r.FromAssembly() {
364                 l.hasUnknownPkgPath = true
365         }
366         return i
367 }
368
369 // Add a symbol from an object file, return the global index.
370 // If the symbol already exist, it returns the index of that symbol.
371 func (st *loadState) addSym(name string, ver int, r *oReader, li uint32, kind int, osym *goobj.Sym) Sym {
372         l := st.l
373         if l.extStart != 0 {
374                 panic("addSym called after external symbol is created")
375         }
376         i := Sym(len(l.objSyms))
377         addToGlobal := func() {
378                 l.objSyms = append(l.objSyms, objSym{r.objidx, li})
379         }
380         if name == "" && kind != hashed64Def && kind != hashedDef {
381                 addToGlobal()
382                 return i // unnamed aux symbol
383         }
384         if ver == r.version {
385                 // Static symbol. Add its global index but don't
386                 // add to name lookup table, as it cannot be
387                 // referenced by name.
388                 addToGlobal()
389                 return i
390         }
391         switch kind {
392         case pkgDef:
393                 // Defined package symbols cannot be dup to each other.
394                 // We load all the package symbols first, so we don't need
395                 // to check dup here.
396                 // We still add it to the lookup table, as it may still be
397                 // referenced by name (e.g. through linkname).
398                 l.symsByName[ver][name] = i
399                 addToGlobal()
400                 return i
401         case hashed64Def, hashedDef:
402                 // Hashed (content-addressable) symbol. Check the hash
403                 // but don't add to name lookup table, as they are not
404                 // referenced by name. Also no need to do overwriting
405                 // check, as same hash indicates same content.
406                 var checkHash func() (symAndSize, bool)
407                 var addToHashMap func(symAndSize)
408                 var h64 uint64        // only used for hashed64Def
409                 var h *goobj.HashType // only used for hashedDef
410                 if kind == hashed64Def {
411                         checkHash = func() (symAndSize, bool) {
412                                 h64 = r.Hash64(li - uint32(r.ndef))
413                                 s, existed := st.hashed64Syms[h64]
414                                 return s, existed
415                         }
416                         addToHashMap = func(ss symAndSize) { st.hashed64Syms[h64] = ss }
417                 } else {
418                         checkHash = func() (symAndSize, bool) {
419                                 h = r.Hash(li - uint32(r.ndef+r.nhashed64def))
420                                 s, existed := st.hashedSyms[*h]
421                                 return s, existed
422                         }
423                         addToHashMap = func(ss symAndSize) { st.hashedSyms[*h] = ss }
424                 }
425                 siz := osym.Siz()
426                 if s, existed := checkHash(); existed {
427                         // The content hash is built from symbol data and relocations. In the
428                         // object file, the symbol data may not always contain trailing zeros,
429                         // e.g. for [5]int{1,2,3} and [100]int{1,2,3}, the data is same
430                         // (although the size is different).
431                         // Also, for short symbols, the content hash is the identity function of
432                         // the 8 bytes, and trailing zeros doesn't change the hash value, e.g.
433                         // hash("A") == hash("A\0\0\0").
434                         // So when two symbols have the same hash, we need to use the one with
435                         // larger size.
436                         if siz > s.size {
437                                 // New symbol has larger size, use the new one. Rewrite the index mapping.
438                                 l.objSyms[s.sym] = objSym{r.objidx, li}
439                                 addToHashMap(symAndSize{s.sym, siz})
440                         }
441                         return s.sym
442                 }
443                 addToHashMap(symAndSize{i, siz})
444                 addToGlobal()
445                 return i
446         }
447
448         // Non-package (named) symbol. Check if it already exists.
449         oldi, existed := l.symsByName[ver][name]
450         if !existed {
451                 l.symsByName[ver][name] = i
452                 addToGlobal()
453                 return i
454         }
455         // symbol already exists
456         if osym.Dupok() {
457                 if l.flags&FlagStrictDups != 0 {
458                         l.checkdup(name, r, li, oldi)
459                 }
460                 // Fix for issue #47185 -- given two dupok symbols with
461                 // different sizes, favor symbol with larger size. See
462                 // also issue #46653.
463                 szdup := l.SymSize(oldi)
464                 sz := int64(r.Sym(li).Siz())
465                 if szdup < sz {
466                         // new symbol overwrites old symbol.
467                         l.objSyms[oldi] = objSym{r.objidx, li}
468                 }
469                 return oldi
470         }
471         oldr, oldli := l.toLocal(oldi)
472         oldsym := oldr.Sym(oldli)
473         if oldsym.Dupok() {
474                 return oldi
475         }
476         overwrite := r.DataSize(li) != 0
477         if overwrite {
478                 // new symbol overwrites old symbol.
479                 oldtyp := sym.AbiSymKindToSymKind[objabi.SymKind(oldsym.Type())]
480                 if !(oldtyp.IsData() && oldr.DataSize(oldli) == 0) {
481                         log.Fatalf("duplicated definition of symbol %s, from %s and %s", name, r.unit.Lib.Pkg, oldr.unit.Lib.Pkg)
482                 }
483                 l.objSyms[oldi] = objSym{r.objidx, li}
484         } else {
485                 // old symbol overwrites new symbol.
486                 typ := sym.AbiSymKindToSymKind[objabi.SymKind(oldsym.Type())]
487                 if !typ.IsData() { // only allow overwriting data symbol
488                         log.Fatalf("duplicated definition of symbol %s, from %s and %s", name, r.unit.Lib.Pkg, oldr.unit.Lib.Pkg)
489                 }
490         }
491         return oldi
492 }
493
494 // newExtSym creates a new external sym with the specified
495 // name/version.
496 func (l *Loader) newExtSym(name string, ver int) Sym {
497         i := Sym(len(l.objSyms))
498         if l.extStart == 0 {
499                 l.extStart = i
500         }
501         l.growValues(int(i) + 1)
502         l.growAttrBitmaps(int(i) + 1)
503         pi := l.newPayload(name, ver)
504         l.objSyms = append(l.objSyms, objSym{l.extReader.objidx, uint32(pi)})
505         l.extReader.syms = append(l.extReader.syms, i)
506         return i
507 }
508
509 // LookupOrCreateSym looks up the symbol with the specified name/version,
510 // returning its Sym index if found. If the lookup fails, a new external
511 // Sym will be created, entered into the lookup tables, and returned.
512 func (l *Loader) LookupOrCreateSym(name string, ver int) Sym {
513         i := l.Lookup(name, ver)
514         if i != 0 {
515                 return i
516         }
517         i = l.newExtSym(name, ver)
518         static := ver >= sym.SymVerStatic || ver < 0
519         if static {
520                 l.extStaticSyms[nameVer{name, ver}] = i
521         } else {
522                 l.symsByName[ver][name] = i
523         }
524         return i
525 }
526
527 // AddCgoExport records a cgo-exported symbol in l.CgoExports.
528 // This table is used to identify the correct Go symbol ABI to use
529 // to resolve references from host objects (which don't have ABIs).
530 func (l *Loader) AddCgoExport(s Sym) {
531         if l.CgoExports == nil {
532                 l.CgoExports = make(map[string]Sym)
533         }
534         l.CgoExports[l.SymName(s)] = s
535 }
536
537 // LookupOrCreateCgoExport is like LookupOrCreateSym, but if ver
538 // indicates a global symbol, it uses the CgoExport table to determine
539 // the appropriate symbol version (ABI) to use. ver must be either 0
540 // or a static symbol version.
541 func (l *Loader) LookupOrCreateCgoExport(name string, ver int) Sym {
542         if ver >= sym.SymVerStatic {
543                 return l.LookupOrCreateSym(name, ver)
544         }
545         if ver != 0 {
546                 panic("ver must be 0 or a static version")
547         }
548         // Look for a cgo-exported symbol from Go.
549         if s, ok := l.CgoExports[name]; ok {
550                 return s
551         }
552         // Otherwise, this must just be a symbol in the host object.
553         // Create a version 0 symbol for it.
554         return l.LookupOrCreateSym(name, 0)
555 }
556
557 func (l *Loader) IsExternal(i Sym) bool {
558         r, _ := l.toLocal(i)
559         return l.isExtReader(r)
560 }
561
562 func (l *Loader) isExtReader(r *oReader) bool {
563         return r == l.extReader
564 }
565
566 // For external symbol, return its index in the payloads array.
567 // XXX result is actually not a global index. We (ab)use the Sym type
568 // so we don't need conversion for accessing bitmaps.
569 func (l *Loader) extIndex(i Sym) Sym {
570         _, li := l.toLocal(i)
571         return Sym(li)
572 }
573
574 // Get a new payload for external symbol, return its index in
575 // the payloads array.
576 func (l *Loader) newPayload(name string, ver int) int {
577         pi := len(l.payloads)
578         pp := l.allocPayload()
579         pp.name = name
580         pp.ver = ver
581         l.payloads = append(l.payloads, pp)
582         l.growExtAttrBitmaps()
583         return pi
584 }
585
586 // getPayload returns a pointer to the extSymPayload struct for an
587 // external symbol if the symbol has a payload. Will panic if the
588 // symbol in question is bogus (zero or not an external sym).
589 func (l *Loader) getPayload(i Sym) *extSymPayload {
590         if !l.IsExternal(i) {
591                 panic(fmt.Sprintf("bogus symbol index %d in getPayload", i))
592         }
593         pi := l.extIndex(i)
594         return l.payloads[pi]
595 }
596
597 // allocPayload allocates a new payload.
598 func (l *Loader) allocPayload() *extSymPayload {
599         batch := l.payloadBatch
600         if len(batch) == 0 {
601                 batch = make([]extSymPayload, 1000)
602         }
603         p := &batch[0]
604         l.payloadBatch = batch[1:]
605         return p
606 }
607
608 func (ms *extSymPayload) Grow(siz int64) {
609         if int64(int(siz)) != siz {
610                 log.Fatalf("symgrow size %d too long", siz)
611         }
612         if int64(len(ms.data)) >= siz {
613                 return
614         }
615         if cap(ms.data) < int(siz) {
616                 cl := len(ms.data)
617                 ms.data = append(ms.data, make([]byte, int(siz)+1-cl)...)
618                 ms.data = ms.data[0:cl]
619         }
620         ms.data = ms.data[:siz]
621 }
622
623 // Convert a local index to a global index.
624 func (l *Loader) toGlobal(r *oReader, i uint32) Sym {
625         return r.syms[i]
626 }
627
628 // Convert a global index to a local index.
629 func (l *Loader) toLocal(i Sym) (*oReader, uint32) {
630         return l.objs[l.objSyms[i].objidx].r, l.objSyms[i].s
631 }
632
633 // Resolve a local symbol reference. Return global index.
634 func (l *Loader) resolve(r *oReader, s goobj.SymRef) Sym {
635         var rr *oReader
636         switch p := s.PkgIdx; p {
637         case goobj.PkgIdxInvalid:
638                 // {0, X} with non-zero X is never a valid sym reference from a Go object.
639                 // We steal this space for symbol references from external objects.
640                 // In this case, X is just the global index.
641                 if l.isExtReader(r) {
642                         return Sym(s.SymIdx)
643                 }
644                 if s.SymIdx != 0 {
645                         panic("bad sym ref")
646                 }
647                 return 0
648         case goobj.PkgIdxHashed64:
649                 i := int(s.SymIdx) + r.ndef
650                 return r.syms[i]
651         case goobj.PkgIdxHashed:
652                 i := int(s.SymIdx) + r.ndef + r.nhashed64def
653                 return r.syms[i]
654         case goobj.PkgIdxNone:
655                 i := int(s.SymIdx) + r.ndef + r.nhashed64def + r.nhasheddef
656                 return r.syms[i]
657         case goobj.PkgIdxBuiltin:
658                 if bi := l.builtinSyms[s.SymIdx]; bi != 0 {
659                         return bi
660                 }
661                 l.reportMissingBuiltin(int(s.SymIdx), r.unit.Lib.Pkg)
662                 return 0
663         case goobj.PkgIdxSelf:
664                 rr = r
665         default:
666                 rr = l.objs[r.pkg[p]].r
667         }
668         return l.toGlobal(rr, s.SymIdx)
669 }
670
671 // reportMissingBuiltin issues an error in the case where we have a
672 // relocation against a runtime builtin whose definition is not found
673 // when the runtime package is built. The canonical example is
674 // "runtime.racefuncenter" -- currently if you do something like
675 //
676 //    go build -gcflags=-race myprogram.go
677 //
678 // the compiler will insert calls to the builtin runtime.racefuncenter,
679 // but the version of the runtime used for linkage won't actually contain
680 // definitions of that symbol. See issue #42396 for details.
681 //
682 // As currently implemented, this is a fatal error. This has drawbacks
683 // in that if there are multiple missing builtins, the error will only
684 // cite the first one. On the plus side, terminating the link here has
685 // advantages in that we won't run the risk of panics or crashes later
686 // on in the linker due to R_CALL relocations with 0-valued target
687 // symbols.
688 func (l *Loader) reportMissingBuiltin(bsym int, reflib string) {
689         bname, _ := goobj.BuiltinName(bsym)
690         log.Fatalf("reference to undefined builtin %q from package %q",
691                 bname, reflib)
692 }
693
694 // Look up a symbol by name, return global index, or 0 if not found.
695 // This is more like Syms.ROLookup than Lookup -- it doesn't create
696 // new symbol.
697 func (l *Loader) Lookup(name string, ver int) Sym {
698         if ver >= sym.SymVerStatic || ver < 0 {
699                 return l.extStaticSyms[nameVer{name, ver}]
700         }
701         return l.symsByName[ver][name]
702 }
703
704 // Check that duplicate symbols have same contents.
705 func (l *Loader) checkdup(name string, r *oReader, li uint32, dup Sym) {
706         p := r.Data(li)
707         rdup, ldup := l.toLocal(dup)
708         pdup := rdup.Data(ldup)
709         reason := "same length but different contents"
710         if len(p) != len(pdup) {
711                 reason = fmt.Sprintf("new length %d != old length %d", len(p), len(pdup))
712         } else if bytes.Equal(p, pdup) {
713                 // For BSS symbols, we need to check size as well, see issue 46653.
714                 szdup := l.SymSize(dup)
715                 sz := int64(r.Sym(li).Siz())
716                 if szdup == sz {
717                         return
718                 }
719                 reason = fmt.Sprintf("different sizes: new size %d != old size %d",
720                         sz, szdup)
721         }
722         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)
723
724         // For the moment, allow DWARF subprogram DIEs for
725         // auto-generated wrapper functions. What seems to happen
726         // here is that we get different line numbers on formal
727         // params; I am guessing that the pos is being inherited
728         // from the spot where the wrapper is needed.
729         allowed := strings.HasPrefix(name, "go.info.go.interface") ||
730                 strings.HasPrefix(name, "go.info.go.builtin") ||
731                 strings.HasPrefix(name, "go.debuglines")
732         if !allowed {
733                 l.strictDupMsgs++
734         }
735 }
736
737 func (l *Loader) NStrictDupMsgs() int { return l.strictDupMsgs }
738
739 // Number of total symbols.
740 func (l *Loader) NSym() int {
741         return len(l.objSyms)
742 }
743
744 // Number of defined Go symbols.
745 func (l *Loader) NDef() int {
746         return int(l.extStart)
747 }
748
749 // Number of reachable symbols.
750 func (l *Loader) NReachableSym() int {
751         return l.attrReachable.Count()
752 }
753
754 // Returns the raw (unpatched) name of the i-th symbol.
755 func (l *Loader) RawSymName(i Sym) string {
756         if l.IsExternal(i) {
757                 pp := l.getPayload(i)
758                 return pp.name
759         }
760         r, li := l.toLocal(i)
761         return r.Sym(li).Name(r.Reader)
762 }
763
764 // Returns the (patched) name of the i-th symbol.
765 func (l *Loader) SymName(i Sym) string {
766         if l.IsExternal(i) {
767                 pp := l.getPayload(i)
768                 return pp.name
769         }
770         r, li := l.toLocal(i)
771         if r == nil {
772                 return "?"
773         }
774         name := r.Sym(li).Name(r.Reader)
775         if !r.NeedNameExpansion() {
776                 return name
777         }
778         return strings.Replace(name, "\"\".", r.pkgprefix, -1)
779 }
780
781 // Returns the version of the i-th symbol.
782 func (l *Loader) SymVersion(i Sym) int {
783         if l.IsExternal(i) {
784                 pp := l.getPayload(i)
785                 return pp.ver
786         }
787         r, li := l.toLocal(i)
788         return int(abiToVer(r.Sym(li).ABI(), r.version))
789 }
790
791 func (l *Loader) IsFileLocal(i Sym) bool {
792         return l.SymVersion(i) >= sym.SymVerStatic
793 }
794
795 // IsFromAssembly returns true if this symbol is derived from an
796 // object file generated by the Go assembler.
797 func (l *Loader) IsFromAssembly(i Sym) bool {
798         if l.IsExternal(i) {
799                 return false
800         }
801         r, _ := l.toLocal(i)
802         return r.FromAssembly()
803 }
804
805 // Returns the type of the i-th symbol.
806 func (l *Loader) SymType(i Sym) sym.SymKind {
807         if l.IsExternal(i) {
808                 pp := l.getPayload(i)
809                 if pp != nil {
810                         return pp.kind
811                 }
812                 return 0
813         }
814         r, li := l.toLocal(i)
815         return sym.AbiSymKindToSymKind[objabi.SymKind(r.Sym(li).Type())]
816 }
817
818 // Returns the attributes of the i-th symbol.
819 func (l *Loader) SymAttr(i Sym) uint8 {
820         if l.IsExternal(i) {
821                 // TODO: do something? External symbols have different representation of attributes.
822                 // For now, ReflectMethod, NoSplit, GoType, and Typelink are used and they cannot be
823                 // set by external symbol.
824                 return 0
825         }
826         r, li := l.toLocal(i)
827         return r.Sym(li).Flag()
828 }
829
830 // Returns the size of the i-th symbol.
831 func (l *Loader) SymSize(i Sym) int64 {
832         if l.IsExternal(i) {
833                 pp := l.getPayload(i)
834                 return pp.size
835         }
836         r, li := l.toLocal(i)
837         return int64(r.Sym(li).Siz())
838 }
839
840 // AttrReachable returns true for symbols that are transitively
841 // referenced from the entry points. Unreachable symbols are not
842 // written to the output.
843 func (l *Loader) AttrReachable(i Sym) bool {
844         return l.attrReachable.Has(i)
845 }
846
847 // SetAttrReachable sets the reachability property for a symbol (see
848 // AttrReachable).
849 func (l *Loader) SetAttrReachable(i Sym, v bool) {
850         if v {
851                 l.attrReachable.Set(i)
852         } else {
853                 l.attrReachable.Unset(i)
854         }
855 }
856
857 // AttrOnList returns true for symbols that are on some list (such as
858 // the list of all text symbols, or one of the lists of data symbols)
859 // and is consulted to avoid bugs where a symbol is put on a list
860 // twice.
861 func (l *Loader) AttrOnList(i Sym) bool {
862         return l.attrOnList.Has(i)
863 }
864
865 // SetAttrOnList sets the "on list" property for a symbol (see
866 // AttrOnList).
867 func (l *Loader) SetAttrOnList(i Sym, v bool) {
868         if v {
869                 l.attrOnList.Set(i)
870         } else {
871                 l.attrOnList.Unset(i)
872         }
873 }
874
875 // AttrLocal returns true for symbols that are only visible within the
876 // module (executable or shared library) being linked. This attribute
877 // is applied to thunks and certain other linker-generated symbols.
878 func (l *Loader) AttrLocal(i Sym) bool {
879         return l.attrLocal.Has(i)
880 }
881
882 // SetAttrLocal the "local" property for a symbol (see AttrLocal above).
883 func (l *Loader) SetAttrLocal(i Sym, v bool) {
884         if v {
885                 l.attrLocal.Set(i)
886         } else {
887                 l.attrLocal.Unset(i)
888         }
889 }
890
891 // AttrUsedInIface returns true for a type symbol that is used in
892 // an interface.
893 func (l *Loader) AttrUsedInIface(i Sym) bool {
894         return l.attrUsedInIface.Has(i)
895 }
896
897 func (l *Loader) SetAttrUsedInIface(i Sym, v bool) {
898         if v {
899                 l.attrUsedInIface.Set(i)
900         } else {
901                 l.attrUsedInIface.Unset(i)
902         }
903 }
904
905 // SymAddr checks that a symbol is reachable, and returns its value.
906 func (l *Loader) SymAddr(i Sym) int64 {
907         if !l.AttrReachable(i) {
908                 panic("unreachable symbol in symaddr")
909         }
910         return l.values[i]
911 }
912
913 // AttrNotInSymbolTable returns true for symbols that should not be
914 // added to the symbol table of the final generated load module.
915 func (l *Loader) AttrNotInSymbolTable(i Sym) bool {
916         return l.attrNotInSymbolTable.Has(i)
917 }
918
919 // SetAttrNotInSymbolTable the "not in symtab" property for a symbol
920 // (see AttrNotInSymbolTable above).
921 func (l *Loader) SetAttrNotInSymbolTable(i Sym, v bool) {
922         if v {
923                 l.attrNotInSymbolTable.Set(i)
924         } else {
925                 l.attrNotInSymbolTable.Unset(i)
926         }
927 }
928
929 // AttrVisibilityHidden symbols returns true for ELF symbols with
930 // visibility set to STV_HIDDEN. They become local symbols in
931 // the final executable. Only relevant when internally linking
932 // on an ELF platform.
933 func (l *Loader) AttrVisibilityHidden(i Sym) bool {
934         if !l.IsExternal(i) {
935                 return false
936         }
937         return l.attrVisibilityHidden.Has(l.extIndex(i))
938 }
939
940 // SetAttrVisibilityHidden sets the "hidden visibility" property for a
941 // symbol (see AttrVisibilityHidden).
942 func (l *Loader) SetAttrVisibilityHidden(i Sym, v bool) {
943         if !l.IsExternal(i) {
944                 panic("tried to set visibility attr on non-external symbol")
945         }
946         if v {
947                 l.attrVisibilityHidden.Set(l.extIndex(i))
948         } else {
949                 l.attrVisibilityHidden.Unset(l.extIndex(i))
950         }
951 }
952
953 // AttrDuplicateOK returns true for a symbol that can be present in
954 // multiple object files.
955 func (l *Loader) AttrDuplicateOK(i Sym) bool {
956         if !l.IsExternal(i) {
957                 // TODO: if this path winds up being taken frequently, it
958                 // might make more sense to copy the flag value out of the object
959                 // into a larger bitmap during preload.
960                 r, li := l.toLocal(i)
961                 return r.Sym(li).Dupok()
962         }
963         return l.attrDuplicateOK.Has(l.extIndex(i))
964 }
965
966 // SetAttrDuplicateOK sets the "duplicate OK" property for an external
967 // symbol (see AttrDuplicateOK).
968 func (l *Loader) SetAttrDuplicateOK(i Sym, v bool) {
969         if !l.IsExternal(i) {
970                 panic("tried to set dupok attr on non-external symbol")
971         }
972         if v {
973                 l.attrDuplicateOK.Set(l.extIndex(i))
974         } else {
975                 l.attrDuplicateOK.Unset(l.extIndex(i))
976         }
977 }
978
979 // AttrShared returns true for symbols compiled with the -shared option.
980 func (l *Loader) AttrShared(i Sym) bool {
981         if !l.IsExternal(i) {
982                 // TODO: if this path winds up being taken frequently, it
983                 // might make more sense to copy the flag value out of the
984                 // object into a larger bitmap during preload.
985                 r, _ := l.toLocal(i)
986                 return r.Shared()
987         }
988         return l.attrShared.Has(l.extIndex(i))
989 }
990
991 // SetAttrShared sets the "shared" property for an external
992 // symbol (see AttrShared).
993 func (l *Loader) SetAttrShared(i Sym, v bool) {
994         if !l.IsExternal(i) {
995                 panic(fmt.Sprintf("tried to set shared attr on non-external symbol %d %s", i, l.SymName(i)))
996         }
997         if v {
998                 l.attrShared.Set(l.extIndex(i))
999         } else {
1000                 l.attrShared.Unset(l.extIndex(i))
1001         }
1002 }
1003
1004 // AttrExternal returns true for function symbols loaded from host
1005 // object files.
1006 func (l *Loader) AttrExternal(i Sym) bool {
1007         if !l.IsExternal(i) {
1008                 return false
1009         }
1010         return l.attrExternal.Has(l.extIndex(i))
1011 }
1012
1013 // SetAttrExternal sets the "external" property for an host object
1014 // symbol (see AttrExternal).
1015 func (l *Loader) SetAttrExternal(i Sym, v bool) {
1016         if !l.IsExternal(i) {
1017                 panic(fmt.Sprintf("tried to set external attr on non-external symbol %q", l.RawSymName(i)))
1018         }
1019         if v {
1020                 l.attrExternal.Set(l.extIndex(i))
1021         } else {
1022                 l.attrExternal.Unset(l.extIndex(i))
1023         }
1024 }
1025
1026 // AttrSpecial returns true for a symbols that do not have their
1027 // address (i.e. Value) computed by the usual mechanism of
1028 // data.go:dodata() & data.go:address().
1029 func (l *Loader) AttrSpecial(i Sym) bool {
1030         _, ok := l.attrSpecial[i]
1031         return ok
1032 }
1033
1034 // SetAttrSpecial sets the "special" property for a symbol (see
1035 // AttrSpecial).
1036 func (l *Loader) SetAttrSpecial(i Sym, v bool) {
1037         if v {
1038                 l.attrSpecial[i] = struct{}{}
1039         } else {
1040                 delete(l.attrSpecial, i)
1041         }
1042 }
1043
1044 // AttrCgoExportDynamic returns true for a symbol that has been
1045 // specially marked via the "cgo_export_dynamic" compiler directive
1046 // written by cgo (in response to //export directives in the source).
1047 func (l *Loader) AttrCgoExportDynamic(i Sym) bool {
1048         _, ok := l.attrCgoExportDynamic[i]
1049         return ok
1050 }
1051
1052 // SetAttrCgoExportDynamic sets the "cgo_export_dynamic" for a symbol
1053 // (see AttrCgoExportDynamic).
1054 func (l *Loader) SetAttrCgoExportDynamic(i Sym, v bool) {
1055         if v {
1056                 l.attrCgoExportDynamic[i] = struct{}{}
1057         } else {
1058                 delete(l.attrCgoExportDynamic, i)
1059         }
1060 }
1061
1062 // AttrCgoExportStatic returns true for a symbol that has been
1063 // specially marked via the "cgo_export_static" directive
1064 // written by cgo.
1065 func (l *Loader) AttrCgoExportStatic(i Sym) bool {
1066         _, ok := l.attrCgoExportStatic[i]
1067         return ok
1068 }
1069
1070 // SetAttrCgoExportStatic sets the "cgo_export_static" for a symbol
1071 // (see AttrCgoExportStatic).
1072 func (l *Loader) SetAttrCgoExportStatic(i Sym, v bool) {
1073         if v {
1074                 l.attrCgoExportStatic[i] = struct{}{}
1075         } else {
1076                 delete(l.attrCgoExportStatic, i)
1077         }
1078 }
1079
1080 // IsGeneratedSym returns true if a symbol's been previously marked as a
1081 // generator symbol through the SetIsGeneratedSym. The functions for generator
1082 // symbols are kept in the Link context.
1083 func (l *Loader) IsGeneratedSym(i Sym) bool {
1084         _, ok := l.generatedSyms[i]
1085         return ok
1086 }
1087
1088 // SetIsGeneratedSym marks symbols as generated symbols. Data shouldn't be
1089 // stored in generated symbols, and a function is registered and called for
1090 // each of these symbols.
1091 func (l *Loader) SetIsGeneratedSym(i Sym, v bool) {
1092         if !l.IsExternal(i) {
1093                 panic("only external symbols can be generated")
1094         }
1095         if v {
1096                 l.generatedSyms[i] = struct{}{}
1097         } else {
1098                 delete(l.generatedSyms, i)
1099         }
1100 }
1101
1102 func (l *Loader) AttrCgoExport(i Sym) bool {
1103         return l.AttrCgoExportDynamic(i) || l.AttrCgoExportStatic(i)
1104 }
1105
1106 // AttrReadOnly returns true for a symbol whose underlying data
1107 // is stored via a read-only mmap.
1108 func (l *Loader) AttrReadOnly(i Sym) bool {
1109         if v, ok := l.attrReadOnly[i]; ok {
1110                 return v
1111         }
1112         if l.IsExternal(i) {
1113                 pp := l.getPayload(i)
1114                 if pp.objidx != 0 {
1115                         return l.objs[pp.objidx].r.ReadOnly()
1116                 }
1117                 return false
1118         }
1119         r, _ := l.toLocal(i)
1120         return r.ReadOnly()
1121 }
1122
1123 // SetAttrReadOnly sets the "data is read only" property for a symbol
1124 // (see AttrReadOnly).
1125 func (l *Loader) SetAttrReadOnly(i Sym, v bool) {
1126         l.attrReadOnly[i] = v
1127 }
1128
1129 // AttrSubSymbol returns true for symbols that are listed as a
1130 // sub-symbol of some other outer symbol. The sub/outer mechanism is
1131 // used when loading host objects (sections from the host object
1132 // become regular linker symbols and symbols go on the Sub list of
1133 // their section) and for constructing the global offset table when
1134 // internally linking a dynamic executable.
1135 //
1136 // Note that in later stages of the linker, we set Outer(S) to some
1137 // container symbol C, but don't set Sub(C). Thus we have two
1138 // distinct scenarios:
1139 //
1140 // - Outer symbol covers the address ranges of its sub-symbols.
1141 //   Outer.Sub is set in this case.
1142 // - Outer symbol doesn't conver the address ranges. It is zero-sized
1143 //   and doesn't have sub-symbols. In the case, the inner symbol is
1144 //   not actually a "SubSymbol". (Tricky!)
1145 //
1146 // This method returns TRUE only for sub-symbols in the first scenario.
1147 //
1148 // FIXME: would be better to do away with this and have a better way
1149 // to represent container symbols.
1150
1151 func (l *Loader) AttrSubSymbol(i Sym) bool {
1152         // we don't explicitly store this attribute any more -- return
1153         // a value based on the sub-symbol setting.
1154         o := l.OuterSym(i)
1155         if o == 0 {
1156                 return false
1157         }
1158         return l.SubSym(o) != 0
1159 }
1160
1161 // Note that we don't have a 'SetAttrSubSymbol' method in the loader;
1162 // clients should instead use the AddInteriorSym method to establish
1163 // containment relationships for host object symbols.
1164
1165 // Returns whether the i-th symbol has ReflectMethod attribute set.
1166 func (l *Loader) IsReflectMethod(i Sym) bool {
1167         return l.SymAttr(i)&goobj.SymFlagReflectMethod != 0
1168 }
1169
1170 // Returns whether the i-th symbol is nosplit.
1171 func (l *Loader) IsNoSplit(i Sym) bool {
1172         return l.SymAttr(i)&goobj.SymFlagNoSplit != 0
1173 }
1174
1175 // Returns whether this is a Go type symbol.
1176 func (l *Loader) IsGoType(i Sym) bool {
1177         return l.SymAttr(i)&goobj.SymFlagGoType != 0
1178 }
1179
1180 // Returns whether this symbol should be included in typelink.
1181 func (l *Loader) IsTypelink(i Sym) bool {
1182         return l.SymAttr(i)&goobj.SymFlagTypelink != 0
1183 }
1184
1185 // Returns whether this symbol is an itab symbol.
1186 func (l *Loader) IsItab(i Sym) bool {
1187         if l.IsExternal(i) {
1188                 return false
1189         }
1190         r, li := l.toLocal(i)
1191         return r.Sym(li).IsItab()
1192 }
1193
1194 // Returns whether this symbol is a dictionary symbol.
1195 func (l *Loader) IsDict(i Sym) bool {
1196         if l.IsExternal(i) {
1197                 return false
1198         }
1199         r, li := l.toLocal(i)
1200         return r.Sym(li).IsDict()
1201 }
1202
1203 // Return whether this is a trampoline of a deferreturn call.
1204 func (l *Loader) IsDeferReturnTramp(i Sym) bool {
1205         return l.deferReturnTramp[i]
1206 }
1207
1208 // Set that i is a trampoline of a deferreturn call.
1209 func (l *Loader) SetIsDeferReturnTramp(i Sym, v bool) {
1210         l.deferReturnTramp[i] = v
1211 }
1212
1213 // growValues grows the slice used to store symbol values.
1214 func (l *Loader) growValues(reqLen int) {
1215         curLen := len(l.values)
1216         if reqLen > curLen {
1217                 l.values = append(l.values, make([]int64, reqLen+1-curLen)...)
1218         }
1219 }
1220
1221 // SymValue returns the value of the i-th symbol. i is global index.
1222 func (l *Loader) SymValue(i Sym) int64 {
1223         return l.values[i]
1224 }
1225
1226 // SetSymValue sets the value of the i-th symbol. i is global index.
1227 func (l *Loader) SetSymValue(i Sym, val int64) {
1228         l.values[i] = val
1229 }
1230
1231 // AddToSymValue adds to the value of the i-th symbol. i is the global index.
1232 func (l *Loader) AddToSymValue(i Sym, val int64) {
1233         l.values[i] += val
1234 }
1235
1236 // Returns the symbol content of the i-th symbol. i is global index.
1237 func (l *Loader) Data(i Sym) []byte {
1238         if l.IsExternal(i) {
1239                 pp := l.getPayload(i)
1240                 if pp != nil {
1241                         return pp.data
1242                 }
1243                 return nil
1244         }
1245         r, li := l.toLocal(i)
1246         return r.Data(li)
1247 }
1248
1249 // FreeData clears the symbol data of an external symbol, allowing the memory
1250 // to be freed earlier. No-op for non-external symbols.
1251 // i is global index.
1252 func (l *Loader) FreeData(i Sym) {
1253         if l.IsExternal(i) {
1254                 pp := l.getPayload(i)
1255                 if pp != nil {
1256                         pp.data = nil
1257                 }
1258         }
1259 }
1260
1261 // SymAlign returns the alignment for a symbol.
1262 func (l *Loader) SymAlign(i Sym) int32 {
1263         if int(i) >= len(l.align) {
1264                 // align is extended lazily -- it the sym in question is
1265                 // outside the range of the existing slice, then we assume its
1266                 // alignment has not yet been set.
1267                 return 0
1268         }
1269         // TODO: would it make sense to return an arch-specific
1270         // alignment depending on section type? E.g. STEXT => 32,
1271         // SDATA => 1, etc?
1272         abits := l.align[i]
1273         if abits == 0 {
1274                 return 0
1275         }
1276         return int32(1 << (abits - 1))
1277 }
1278
1279 // SetSymAlign sets the alignment for a symbol.
1280 func (l *Loader) SetSymAlign(i Sym, align int32) {
1281         // Reject nonsense alignments.
1282         if align < 0 || align&(align-1) != 0 {
1283                 panic("bad alignment value")
1284         }
1285         if int(i) >= len(l.align) {
1286                 l.align = append(l.align, make([]uint8, l.NSym()-len(l.align))...)
1287         }
1288         if align == 0 {
1289                 l.align[i] = 0
1290         }
1291         l.align[i] = uint8(bits.Len32(uint32(align)))
1292 }
1293
1294 // SymValue returns the section of the i-th symbol. i is global index.
1295 func (l *Loader) SymSect(i Sym) *sym.Section {
1296         if int(i) >= len(l.symSects) {
1297                 // symSects is extended lazily -- it the sym in question is
1298                 // outside the range of the existing slice, then we assume its
1299                 // section has not yet been set.
1300                 return nil
1301         }
1302         return l.sects[l.symSects[i]]
1303 }
1304
1305 // SetSymSect sets the section of the i-th symbol. i is global index.
1306 func (l *Loader) SetSymSect(i Sym, sect *sym.Section) {
1307         if int(i) >= len(l.symSects) {
1308                 l.symSects = append(l.symSects, make([]uint16, l.NSym()-len(l.symSects))...)
1309         }
1310         l.symSects[i] = sect.Index
1311 }
1312
1313 // growSects grows the slice used to store symbol sections.
1314 func (l *Loader) growSects(reqLen int) {
1315         curLen := len(l.symSects)
1316         if reqLen > curLen {
1317                 l.symSects = append(l.symSects, make([]uint16, reqLen+1-curLen)...)
1318         }
1319 }
1320
1321 // NewSection creates a new (output) section.
1322 func (l *Loader) NewSection() *sym.Section {
1323         sect := new(sym.Section)
1324         idx := len(l.sects)
1325         if idx != int(uint16(idx)) {
1326                 panic("too many sections created")
1327         }
1328         sect.Index = uint16(idx)
1329         l.sects = append(l.sects, sect)
1330         return sect
1331 }
1332
1333 // SymDynImplib returns the "dynimplib" attribute for the specified
1334 // symbol, making up a portion of the info for a symbol specified
1335 // on a "cgo_import_dynamic" compiler directive.
1336 func (l *Loader) SymDynimplib(i Sym) string {
1337         return l.dynimplib[i]
1338 }
1339
1340 // SetSymDynimplib sets the "dynimplib" attribute for a symbol.
1341 func (l *Loader) SetSymDynimplib(i Sym, value string) {
1342         // reject bad symbols
1343         if i >= Sym(len(l.objSyms)) || i == 0 {
1344                 panic("bad symbol index in SetDynimplib")
1345         }
1346         if value == "" {
1347                 delete(l.dynimplib, i)
1348         } else {
1349                 l.dynimplib[i] = value
1350         }
1351 }
1352
1353 // SymDynimpvers returns the "dynimpvers" attribute for the specified
1354 // symbol, making up a portion of the info for a symbol specified
1355 // on a "cgo_import_dynamic" compiler directive.
1356 func (l *Loader) SymDynimpvers(i Sym) string {
1357         return l.dynimpvers[i]
1358 }
1359
1360 // SetSymDynimpvers sets the "dynimpvers" attribute for a symbol.
1361 func (l *Loader) SetSymDynimpvers(i Sym, value string) {
1362         // reject bad symbols
1363         if i >= Sym(len(l.objSyms)) || i == 0 {
1364                 panic("bad symbol index in SetDynimpvers")
1365         }
1366         if value == "" {
1367                 delete(l.dynimpvers, i)
1368         } else {
1369                 l.dynimpvers[i] = value
1370         }
1371 }
1372
1373 // SymExtname returns the "extname" value for the specified
1374 // symbol.
1375 func (l *Loader) SymExtname(i Sym) string {
1376         if s, ok := l.extname[i]; ok {
1377                 return s
1378         }
1379         return l.SymName(i)
1380 }
1381
1382 // SetSymExtname sets the  "extname" attribute for a symbol.
1383 func (l *Loader) SetSymExtname(i Sym, value string) {
1384         // reject bad symbols
1385         if i >= Sym(len(l.objSyms)) || i == 0 {
1386                 panic("bad symbol index in SetExtname")
1387         }
1388         if value == "" {
1389                 delete(l.extname, i)
1390         } else {
1391                 l.extname[i] = value
1392         }
1393 }
1394
1395 // SymElfType returns the previously recorded ELF type for a symbol
1396 // (used only for symbols read from shared libraries by ldshlibsyms).
1397 // It is not set for symbols defined by the packages being linked or
1398 // by symbols read by ldelf (and so is left as elf.STT_NOTYPE).
1399 func (l *Loader) SymElfType(i Sym) elf.SymType {
1400         if et, ok := l.elfType[i]; ok {
1401                 return et
1402         }
1403         return elf.STT_NOTYPE
1404 }
1405
1406 // SetSymElfType sets the elf type attribute for a symbol.
1407 func (l *Loader) SetSymElfType(i Sym, et elf.SymType) {
1408         // reject bad symbols
1409         if i >= Sym(len(l.objSyms)) || i == 0 {
1410                 panic("bad symbol index in SetSymElfType")
1411         }
1412         if et == elf.STT_NOTYPE {
1413                 delete(l.elfType, i)
1414         } else {
1415                 l.elfType[i] = et
1416         }
1417 }
1418
1419 // SymElfSym returns the ELF symbol index for a given loader
1420 // symbol, assigned during ELF symtab generation.
1421 func (l *Loader) SymElfSym(i Sym) int32 {
1422         return l.elfSym[i]
1423 }
1424
1425 // SetSymElfSym sets the elf symbol index for a symbol.
1426 func (l *Loader) SetSymElfSym(i Sym, es int32) {
1427         if i == 0 {
1428                 panic("bad sym index")
1429         }
1430         if es == 0 {
1431                 delete(l.elfSym, i)
1432         } else {
1433                 l.elfSym[i] = es
1434         }
1435 }
1436
1437 // SymLocalElfSym returns the "local" ELF symbol index for a given loader
1438 // symbol, assigned during ELF symtab generation.
1439 func (l *Loader) SymLocalElfSym(i Sym) int32 {
1440         return l.localElfSym[i]
1441 }
1442
1443 // SetSymLocalElfSym sets the "local" elf symbol index for a symbol.
1444 func (l *Loader) SetSymLocalElfSym(i Sym, es int32) {
1445         if i == 0 {
1446                 panic("bad sym index")
1447         }
1448         if es == 0 {
1449                 delete(l.localElfSym, i)
1450         } else {
1451                 l.localElfSym[i] = es
1452         }
1453 }
1454
1455 // SymPlt returns the PLT offset of symbol s.
1456 func (l *Loader) SymPlt(s Sym) int32 {
1457         if v, ok := l.plt[s]; ok {
1458                 return v
1459         }
1460         return -1
1461 }
1462
1463 // SetPlt sets the PLT offset of symbol i.
1464 func (l *Loader) SetPlt(i Sym, v int32) {
1465         if i >= Sym(len(l.objSyms)) || i == 0 {
1466                 panic("bad symbol for SetPlt")
1467         }
1468         if v == -1 {
1469                 delete(l.plt, i)
1470         } else {
1471                 l.plt[i] = v
1472         }
1473 }
1474
1475 // SymGot returns the GOT offset of symbol s.
1476 func (l *Loader) SymGot(s Sym) int32 {
1477         if v, ok := l.got[s]; ok {
1478                 return v
1479         }
1480         return -1
1481 }
1482
1483 // SetGot sets the GOT offset of symbol i.
1484 func (l *Loader) SetGot(i Sym, v int32) {
1485         if i >= Sym(len(l.objSyms)) || i == 0 {
1486                 panic("bad symbol for SetGot")
1487         }
1488         if v == -1 {
1489                 delete(l.got, i)
1490         } else {
1491                 l.got[i] = v
1492         }
1493 }
1494
1495 // SymDynid returns the "dynid" property for the specified symbol.
1496 func (l *Loader) SymDynid(i Sym) int32 {
1497         if s, ok := l.dynid[i]; ok {
1498                 return s
1499         }
1500         return -1
1501 }
1502
1503 // SetSymDynid sets the "dynid" property for a symbol.
1504 func (l *Loader) SetSymDynid(i Sym, val int32) {
1505         // reject bad symbols
1506         if i >= Sym(len(l.objSyms)) || i == 0 {
1507                 panic("bad symbol index in SetSymDynid")
1508         }
1509         if val == -1 {
1510                 delete(l.dynid, i)
1511         } else {
1512                 l.dynid[i] = val
1513         }
1514 }
1515
1516 // DynIdSyms returns the set of symbols for which dynID is set to an
1517 // interesting (non-default) value. This is expected to be a fairly
1518 // small set.
1519 func (l *Loader) DynidSyms() []Sym {
1520         sl := make([]Sym, 0, len(l.dynid))
1521         for s := range l.dynid {
1522                 sl = append(sl, s)
1523         }
1524         sort.Slice(sl, func(i, j int) bool { return sl[i] < sl[j] })
1525         return sl
1526 }
1527
1528 // SymGoType returns the 'Gotype' property for a given symbol (set by
1529 // the Go compiler for variable symbols). This version relies on
1530 // reading aux symbols for the target sym -- it could be that a faster
1531 // approach would be to check for gotype during preload and copy the
1532 // results in to a map (might want to try this at some point and see
1533 // if it helps speed things up).
1534 func (l *Loader) SymGoType(i Sym) Sym { return l.aux1(i, goobj.AuxGotype) }
1535
1536 // SymUnit returns the compilation unit for a given symbol (which will
1537 // typically be nil for external or linker-manufactured symbols).
1538 func (l *Loader) SymUnit(i Sym) *sym.CompilationUnit {
1539         if l.IsExternal(i) {
1540                 pp := l.getPayload(i)
1541                 if pp.objidx != 0 {
1542                         r := l.objs[pp.objidx].r
1543                         return r.unit
1544                 }
1545                 return nil
1546         }
1547         r, _ := l.toLocal(i)
1548         return r.unit
1549 }
1550
1551 // SymPkg returns the package where the symbol came from (for
1552 // regular compiler-generated Go symbols), but in the case of
1553 // building with "-linkshared" (when a symbol is read from a
1554 // shared library), will hold the library name.
1555 // NOTE: this corresponds to sym.Symbol.File field.
1556 func (l *Loader) SymPkg(i Sym) string {
1557         if f, ok := l.symPkg[i]; ok {
1558                 return f
1559         }
1560         if l.IsExternal(i) {
1561                 pp := l.getPayload(i)
1562                 if pp.objidx != 0 {
1563                         r := l.objs[pp.objidx].r
1564                         return r.unit.Lib.Pkg
1565                 }
1566                 return ""
1567         }
1568         r, _ := l.toLocal(i)
1569         return r.unit.Lib.Pkg
1570 }
1571
1572 // SetSymPkg sets the package/library for a symbol. This is
1573 // needed mainly for external symbols, specifically those imported
1574 // from shared libraries.
1575 func (l *Loader) SetSymPkg(i Sym, pkg string) {
1576         // reject bad symbols
1577         if i >= Sym(len(l.objSyms)) || i == 0 {
1578                 panic("bad symbol index in SetSymPkg")
1579         }
1580         l.symPkg[i] = pkg
1581 }
1582
1583 // SymLocalentry returns the "local entry" value for the specified
1584 // symbol.
1585 func (l *Loader) SymLocalentry(i Sym) uint8 {
1586         return l.localentry[i]
1587 }
1588
1589 // SetSymLocalentry sets the "local entry" attribute for a symbol.
1590 func (l *Loader) SetSymLocalentry(i Sym, value uint8) {
1591         // reject bad symbols
1592         if i >= Sym(len(l.objSyms)) || i == 0 {
1593                 panic("bad symbol index in SetSymLocalentry")
1594         }
1595         if value == 0 {
1596                 delete(l.localentry, i)
1597         } else {
1598                 l.localentry[i] = value
1599         }
1600 }
1601
1602 // Returns the number of aux symbols given a global index.
1603 func (l *Loader) NAux(i Sym) int {
1604         if l.IsExternal(i) {
1605                 return 0
1606         }
1607         r, li := l.toLocal(i)
1608         return r.NAux(li)
1609 }
1610
1611 // Returns the "handle" to the j-th aux symbol of the i-th symbol.
1612 func (l *Loader) Aux(i Sym, j int) Aux {
1613         if l.IsExternal(i) {
1614                 return Aux{}
1615         }
1616         r, li := l.toLocal(i)
1617         if j >= r.NAux(li) {
1618                 return Aux{}
1619         }
1620         return Aux{r.Aux(li, j), r, l}
1621 }
1622
1623 // GetFuncDwarfAuxSyms collects and returns the auxiliary DWARF
1624 // symbols associated with a given function symbol.  Prior to the
1625 // introduction of the loader, this was done purely using name
1626 // lookups, e.f. for function with name XYZ we would then look up
1627 // go.info.XYZ, etc.
1628 func (l *Loader) GetFuncDwarfAuxSyms(fnSymIdx Sym) (auxDwarfInfo, auxDwarfLoc, auxDwarfRanges, auxDwarfLines Sym) {
1629         if l.SymType(fnSymIdx) != sym.STEXT {
1630                 log.Fatalf("error: non-function sym %d/%s t=%s passed to GetFuncDwarfAuxSyms", fnSymIdx, l.SymName(fnSymIdx), l.SymType(fnSymIdx).String())
1631         }
1632         if l.IsExternal(fnSymIdx) {
1633                 // Current expectation is that any external function will
1634                 // not have auxsyms.
1635                 return
1636         }
1637         r, li := l.toLocal(fnSymIdx)
1638         auxs := r.Auxs(li)
1639         for i := range auxs {
1640                 a := &auxs[i]
1641                 switch a.Type() {
1642                 case goobj.AuxDwarfInfo:
1643                         auxDwarfInfo = l.resolve(r, a.Sym())
1644                         if l.SymType(auxDwarfInfo) != sym.SDWARFFCN {
1645                                 panic("aux dwarf info sym with wrong type")
1646                         }
1647                 case goobj.AuxDwarfLoc:
1648                         auxDwarfLoc = l.resolve(r, a.Sym())
1649                         if l.SymType(auxDwarfLoc) != sym.SDWARFLOC {
1650                                 panic("aux dwarf loc sym with wrong type")
1651                         }
1652                 case goobj.AuxDwarfRanges:
1653                         auxDwarfRanges = l.resolve(r, a.Sym())
1654                         if l.SymType(auxDwarfRanges) != sym.SDWARFRANGE {
1655                                 panic("aux dwarf ranges sym with wrong type")
1656                         }
1657                 case goobj.AuxDwarfLines:
1658                         auxDwarfLines = l.resolve(r, a.Sym())
1659                         if l.SymType(auxDwarfLines) != sym.SDWARFLINES {
1660                                 panic("aux dwarf lines sym with wrong type")
1661                         }
1662                 }
1663         }
1664         return
1665 }
1666
1667 // AddInteriorSym sets up 'interior' as an interior symbol of
1668 // container/payload symbol 'container'. An interior symbol does not
1669 // itself have data, but gives a name to a subrange of the data in its
1670 // container symbol. The container itself may or may not have a name.
1671 // This method is intended primarily for use in the host object
1672 // loaders, to capture the semantics of symbols and sections in an
1673 // object file. When reading a host object file, we'll typically
1674 // encounter a static section symbol (ex: ".text") containing content
1675 // for a collection of functions, then a series of ELF (or macho, etc)
1676 // symbol table entries each of which points into a sub-section
1677 // (offset and length) of its corresponding container symbol. Within
1678 // the go linker we create a loader.Sym for the container (which is
1679 // expected to have the actual content/payload) and then a set of
1680 // interior loader.Sym's that point into a portion of the container.
1681 func (l *Loader) AddInteriorSym(container Sym, interior Sym) {
1682         // Container symbols are expected to have content/data.
1683         // NB: this restriction may turn out to be too strict (it's possible
1684         // to imagine a zero-sized container with an interior symbol pointing
1685         // into it); it's ok to relax or remove it if we counter an
1686         // oddball host object that triggers this.
1687         if l.SymSize(container) == 0 && len(l.Data(container)) == 0 {
1688                 panic("unexpected empty container symbol")
1689         }
1690         // The interior symbols for a container are not expected to have
1691         // content/data or relocations.
1692         if len(l.Data(interior)) != 0 {
1693                 panic("unexpected non-empty interior symbol")
1694         }
1695         // Interior symbol is expected to be in the symbol table.
1696         if l.AttrNotInSymbolTable(interior) {
1697                 panic("interior symbol must be in symtab")
1698         }
1699         // Only a single level of containment is allowed.
1700         if l.OuterSym(container) != 0 {
1701                 panic("outer has outer itself")
1702         }
1703         // Interior sym should not already have a sibling.
1704         if l.SubSym(interior) != 0 {
1705                 panic("sub set for subsym")
1706         }
1707         // Interior sym should not already point at a container.
1708         if l.OuterSym(interior) != 0 {
1709                 panic("outer already set for subsym")
1710         }
1711         l.sub[interior] = l.sub[container]
1712         l.sub[container] = interior
1713         l.outer[interior] = container
1714 }
1715
1716 // OuterSym gets the outer symbol for host object loaded symbols.
1717 func (l *Loader) OuterSym(i Sym) Sym {
1718         // FIXME: add check for isExternal?
1719         return l.outer[i]
1720 }
1721
1722 // SubSym gets the subsymbol for host object loaded symbols.
1723 func (l *Loader) SubSym(i Sym) Sym {
1724         // NB: note -- no check for l.isExternal(), since I am pretty sure
1725         // that later phases in the linker set subsym for "type." syms
1726         return l.sub[i]
1727 }
1728
1729 // SetCarrierSym declares that 'c' is the carrier or container symbol
1730 // for 's'. Carrier symbols are used in the linker to as a container
1731 // for a collection of sub-symbols where the content of the
1732 // sub-symbols is effectively concatenated to form the content of the
1733 // carrier. The carrier is given a name in the output symbol table
1734 // while the sub-symbol names are not. For example, the Go compiler
1735 // emits named string symbols (type SGOSTRING) when compiling a
1736 // package; after being deduplicated, these symbols are collected into
1737 // a single unit by assigning them a new carrier symbol named
1738 // "go.string.*" (which appears in the final symbol table for the
1739 // output load module).
1740 func (l *Loader) SetCarrierSym(s Sym, c Sym) {
1741         if c == 0 {
1742                 panic("invalid carrier in SetCarrierSym")
1743         }
1744         if s == 0 {
1745                 panic("invalid sub-symbol in SetCarrierSym")
1746         }
1747         // Carrier symbols are not expected to have content/data. It is
1748         // ok for them to have non-zero size (to allow for use of generator
1749         // symbols).
1750         if len(l.Data(c)) != 0 {
1751                 panic("unexpected non-empty carrier symbol")
1752         }
1753         l.outer[s] = c
1754         // relocsym's foldSubSymbolOffset requires that we only
1755         // have a single level of containment-- enforce here.
1756         if l.outer[c] != 0 {
1757                 panic("invalid nested carrier sym")
1758         }
1759 }
1760
1761 // Initialize Reachable bitmap and its siblings for running deadcode pass.
1762 func (l *Loader) InitReachable() {
1763         l.growAttrBitmaps(l.NSym() + 1)
1764 }
1765
1766 type symWithVal struct {
1767         s Sym
1768         v int64
1769 }
1770 type bySymValue []symWithVal
1771
1772 func (s bySymValue) Len() int           { return len(s) }
1773 func (s bySymValue) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
1774 func (s bySymValue) Less(i, j int) bool { return s[i].v < s[j].v }
1775
1776 // SortSub walks through the sub-symbols for 's' and sorts them
1777 // in place by increasing value. Return value is the new
1778 // sub symbol for the specified outer symbol.
1779 func (l *Loader) SortSub(s Sym) Sym {
1780
1781         if s == 0 || l.sub[s] == 0 {
1782                 return s
1783         }
1784
1785         // Sort symbols using a slice first. Use a stable sort on the off
1786         // chance that there's more than once symbol with the same value,
1787         // so as to preserve reproducible builds.
1788         sl := []symWithVal{}
1789         for ss := l.sub[s]; ss != 0; ss = l.sub[ss] {
1790                 sl = append(sl, symWithVal{s: ss, v: l.SymValue(ss)})
1791         }
1792         sort.Stable(bySymValue(sl))
1793
1794         // Then apply any changes needed to the sub map.
1795         ns := Sym(0)
1796         for i := len(sl) - 1; i >= 0; i-- {
1797                 s := sl[i].s
1798                 l.sub[s] = ns
1799                 ns = s
1800         }
1801
1802         // Update sub for outer symbol, then return
1803         l.sub[s] = sl[0].s
1804         return sl[0].s
1805 }
1806
1807 // SortSyms sorts a list of symbols by their value.
1808 func (l *Loader) SortSyms(ss []Sym) {
1809         sort.SliceStable(ss, func(i, j int) bool { return l.SymValue(ss[i]) < l.SymValue(ss[j]) })
1810 }
1811
1812 // Insure that reachable bitmap and its siblings have enough size.
1813 func (l *Loader) growAttrBitmaps(reqLen int) {
1814         if reqLen > l.attrReachable.Len() {
1815                 // These are indexed by global symbol
1816                 l.attrReachable = growBitmap(reqLen, l.attrReachable)
1817                 l.attrOnList = growBitmap(reqLen, l.attrOnList)
1818                 l.attrLocal = growBitmap(reqLen, l.attrLocal)
1819                 l.attrNotInSymbolTable = growBitmap(reqLen, l.attrNotInSymbolTable)
1820                 l.attrUsedInIface = growBitmap(reqLen, l.attrUsedInIface)
1821         }
1822         l.growExtAttrBitmaps()
1823 }
1824
1825 func (l *Loader) growExtAttrBitmaps() {
1826         // These are indexed by external symbol index (e.g. l.extIndex(i))
1827         extReqLen := len(l.payloads)
1828         if extReqLen > l.attrVisibilityHidden.Len() {
1829                 l.attrVisibilityHidden = growBitmap(extReqLen, l.attrVisibilityHidden)
1830                 l.attrDuplicateOK = growBitmap(extReqLen, l.attrDuplicateOK)
1831                 l.attrShared = growBitmap(extReqLen, l.attrShared)
1832                 l.attrExternal = growBitmap(extReqLen, l.attrExternal)
1833         }
1834 }
1835
1836 func (relocs *Relocs) Count() int { return len(relocs.rs) }
1837
1838 // At returns the j-th reloc for a global symbol.
1839 func (relocs *Relocs) At(j int) Reloc {
1840         if relocs.l.isExtReader(relocs.r) {
1841                 return Reloc{&relocs.rs[j], relocs.r, relocs.l}
1842         }
1843         return Reloc{&relocs.rs[j], relocs.r, relocs.l}
1844 }
1845
1846 // Relocs returns a Relocs object for the given global sym.
1847 func (l *Loader) Relocs(i Sym) Relocs {
1848         r, li := l.toLocal(i)
1849         if r == nil {
1850                 panic(fmt.Sprintf("trying to get oreader for invalid sym %d\n\n", i))
1851         }
1852         return l.relocs(r, li)
1853 }
1854
1855 // Relocs returns a Relocs object given a local sym index and reader.
1856 func (l *Loader) relocs(r *oReader, li uint32) Relocs {
1857         var rs []goobj.Reloc
1858         if l.isExtReader(r) {
1859                 pp := l.payloads[li]
1860                 rs = pp.relocs
1861         } else {
1862                 rs = r.Relocs(li)
1863         }
1864         return Relocs{
1865                 rs: rs,
1866                 li: li,
1867                 r:  r,
1868                 l:  l,
1869         }
1870 }
1871
1872 func (l *Loader) auxs(i Sym) (*oReader, []goobj.Aux) {
1873         if l.IsExternal(i) {
1874                 pp := l.getPayload(i)
1875                 return l.objs[pp.objidx].r, pp.auxs
1876         } else {
1877                 r, li := l.toLocal(i)
1878                 return r, r.Auxs(li)
1879         }
1880 }
1881
1882 // Returns a specific aux symbol of type t for symbol i.
1883 func (l *Loader) aux1(i Sym, t uint8) Sym {
1884         r, auxs := l.auxs(i)
1885         for j := range auxs {
1886                 a := &auxs[j]
1887                 if a.Type() == t {
1888                         return l.resolve(r, a.Sym())
1889                 }
1890         }
1891         return 0
1892 }
1893
1894 func (l *Loader) Pcsp(i Sym) Sym { return l.aux1(i, goobj.AuxPcsp) }
1895
1896 // Returns all aux symbols of per-PC data for symbol i.
1897 // tmp is a scratch space for the pcdata slice.
1898 func (l *Loader) PcdataAuxs(i Sym, tmp []Sym) (pcsp, pcfile, pcline, pcinline Sym, pcdata []Sym) {
1899         pcdata = tmp[:0]
1900         r, auxs := l.auxs(i)
1901         for j := range auxs {
1902                 a := &auxs[j]
1903                 switch a.Type() {
1904                 case goobj.AuxPcsp:
1905                         pcsp = l.resolve(r, a.Sym())
1906                 case goobj.AuxPcline:
1907                         pcline = l.resolve(r, a.Sym())
1908                 case goobj.AuxPcfile:
1909                         pcfile = l.resolve(r, a.Sym())
1910                 case goobj.AuxPcinline:
1911                         pcinline = l.resolve(r, a.Sym())
1912                 case goobj.AuxPcdata:
1913                         pcdata = append(pcdata, l.resolve(r, a.Sym()))
1914                 }
1915         }
1916         return
1917 }
1918
1919 // Returns the number of pcdata for symbol i.
1920 func (l *Loader) NumPcdata(i Sym) int {
1921         n := 0
1922         _, auxs := l.auxs(i)
1923         for j := range auxs {
1924                 a := &auxs[j]
1925                 if a.Type() == goobj.AuxPcdata {
1926                         n++
1927                 }
1928         }
1929         return n
1930 }
1931
1932 // Returns all funcdata symbols of symbol i.
1933 // tmp is a scratch space.
1934 func (l *Loader) Funcdata(i Sym, tmp []Sym) []Sym {
1935         fd := tmp[:0]
1936         r, auxs := l.auxs(i)
1937         for j := range auxs {
1938                 a := &auxs[j]
1939                 if a.Type() == goobj.AuxFuncdata {
1940                         fd = append(fd, l.resolve(r, a.Sym()))
1941                 }
1942         }
1943         return fd
1944 }
1945
1946 // Returns the number of funcdata for symbol i.
1947 func (l *Loader) NumFuncdata(i Sym) int {
1948         n := 0
1949         _, auxs := l.auxs(i)
1950         for j := range auxs {
1951                 a := &auxs[j]
1952                 if a.Type() == goobj.AuxFuncdata {
1953                         n++
1954                 }
1955         }
1956         return n
1957 }
1958
1959 // FuncInfo provides hooks to access goobj.FuncInfo in the objects.
1960 type FuncInfo struct {
1961         l       *Loader
1962         r       *oReader
1963         data    []byte
1964         lengths goobj.FuncInfoLengths
1965 }
1966
1967 func (fi *FuncInfo) Valid() bool { return fi.r != nil }
1968
1969 func (fi *FuncInfo) Args() int {
1970         return int((*goobj.FuncInfo)(nil).ReadArgs(fi.data))
1971 }
1972
1973 func (fi *FuncInfo) Locals() int {
1974         return int((*goobj.FuncInfo)(nil).ReadLocals(fi.data))
1975 }
1976
1977 func (fi *FuncInfo) FuncID() objabi.FuncID {
1978         return (*goobj.FuncInfo)(nil).ReadFuncID(fi.data)
1979 }
1980
1981 func (fi *FuncInfo) FuncFlag() objabi.FuncFlag {
1982         return (*goobj.FuncInfo)(nil).ReadFuncFlag(fi.data)
1983 }
1984
1985 // Preload has to be called prior to invoking the various methods
1986 // below related to pcdata, funcdataoff, files, and inltree nodes.
1987 func (fi *FuncInfo) Preload() {
1988         fi.lengths = (*goobj.FuncInfo)(nil).ReadFuncInfoLengths(fi.data)
1989 }
1990
1991 func (fi *FuncInfo) NumFile() uint32 {
1992         if !fi.lengths.Initialized {
1993                 panic("need to call Preload first")
1994         }
1995         return fi.lengths.NumFile
1996 }
1997
1998 func (fi *FuncInfo) File(k int) goobj.CUFileIndex {
1999         if !fi.lengths.Initialized {
2000                 panic("need to call Preload first")
2001         }
2002         return (*goobj.FuncInfo)(nil).ReadFile(fi.data, fi.lengths.FileOff, uint32(k))
2003 }
2004
2005 // TopFrame returns true if the function associated with this FuncInfo
2006 // is an entry point, meaning that unwinders should stop when they hit
2007 // this function.
2008 func (fi *FuncInfo) TopFrame() bool {
2009         return (fi.FuncFlag() & objabi.FuncFlag_TOPFRAME) != 0
2010 }
2011
2012 type InlTreeNode struct {
2013         Parent   int32
2014         File     goobj.CUFileIndex
2015         Line     int32
2016         Func     Sym
2017         ParentPC int32
2018 }
2019
2020 func (fi *FuncInfo) NumInlTree() uint32 {
2021         if !fi.lengths.Initialized {
2022                 panic("need to call Preload first")
2023         }
2024         return fi.lengths.NumInlTree
2025 }
2026
2027 func (fi *FuncInfo) InlTree(k int) InlTreeNode {
2028         if !fi.lengths.Initialized {
2029                 panic("need to call Preload first")
2030         }
2031         node := (*goobj.FuncInfo)(nil).ReadInlTree(fi.data, fi.lengths.InlTreeOff, uint32(k))
2032         return InlTreeNode{
2033                 Parent:   node.Parent,
2034                 File:     node.File,
2035                 Line:     node.Line,
2036                 Func:     fi.l.resolve(fi.r, node.Func),
2037                 ParentPC: node.ParentPC,
2038         }
2039 }
2040
2041 func (l *Loader) FuncInfo(i Sym) FuncInfo {
2042         r, auxs := l.auxs(i)
2043         for j := range auxs {
2044                 a := &auxs[j]
2045                 if a.Type() == goobj.AuxFuncInfo {
2046                         b := r.Data(a.Sym().SymIdx)
2047                         return FuncInfo{l, r, b, goobj.FuncInfoLengths{}}
2048                 }
2049         }
2050         return FuncInfo{}
2051 }
2052
2053 // Preload a package: adds autolib.
2054 // Does not add defined package or non-packaged symbols to the symbol table.
2055 // These are done in LoadSyms.
2056 // Does not read symbol data.
2057 // Returns the fingerprint of the object.
2058 func (l *Loader) Preload(localSymVersion int, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64) goobj.FingerprintType {
2059         roObject, readonly, err := f.Slice(uint64(length)) // TODO: no need to map blocks that are for tools only (e.g. RefName)
2060         if err != nil {
2061                 log.Fatal("cannot read object file:", err)
2062         }
2063         r := goobj.NewReaderFromBytes(roObject, readonly)
2064         if r == nil {
2065                 if len(roObject) >= 8 && bytes.Equal(roObject[:8], []byte("\x00go114ld")) {
2066                         log.Fatalf("found object file %s in old format", f.File().Name())
2067                 }
2068                 panic("cannot read object file")
2069         }
2070         pkgprefix := objabi.PathToPrefix(lib.Pkg) + "."
2071         ndef := r.NSym()
2072         nhashed64def := r.NHashed64def()
2073         nhasheddef := r.NHasheddef()
2074         or := &oReader{
2075                 Reader:       r,
2076                 unit:         unit,
2077                 version:      localSymVersion,
2078                 pkgprefix:    pkgprefix,
2079                 syms:         make([]Sym, ndef+nhashed64def+nhasheddef+r.NNonpkgdef()+r.NNonpkgref()),
2080                 ndef:         ndef,
2081                 nhasheddef:   nhasheddef,
2082                 nhashed64def: nhashed64def,
2083                 objidx:       uint32(len(l.objs)),
2084         }
2085
2086         // Autolib
2087         lib.Autolib = append(lib.Autolib, r.Autolib()...)
2088
2089         // DWARF file table
2090         nfile := r.NFile()
2091         unit.FileTable = make([]string, nfile)
2092         for i := range unit.FileTable {
2093                 unit.FileTable[i] = r.File(i)
2094         }
2095
2096         l.addObj(lib.Pkg, or)
2097
2098         // The caller expects us consuming all the data
2099         f.MustSeek(length, os.SEEK_CUR)
2100
2101         return r.Fingerprint()
2102 }
2103
2104 // Holds the loader along with temporary states for loading symbols.
2105 type loadState struct {
2106         l            *Loader
2107         hashed64Syms map[uint64]symAndSize         // short hashed (content-addressable) symbols, keyed by content hash
2108         hashedSyms   map[goobj.HashType]symAndSize // hashed (content-addressable) symbols, keyed by content hash
2109 }
2110
2111 // Preload symbols of given kind from an object.
2112 func (st *loadState) preloadSyms(r *oReader, kind int) {
2113         l := st.l
2114         var start, end uint32
2115         switch kind {
2116         case pkgDef:
2117                 start = 0
2118                 end = uint32(r.ndef)
2119         case hashed64Def:
2120                 start = uint32(r.ndef)
2121                 end = uint32(r.ndef + r.nhashed64def)
2122         case hashedDef:
2123                 start = uint32(r.ndef + r.nhashed64def)
2124                 end = uint32(r.ndef + r.nhashed64def + r.nhasheddef)
2125                 if l.hasUnknownPkgPath {
2126                         // The content hash depends on symbol name expansion. If any package is
2127                         // built without fully expanded names, the content hash is unreliable.
2128                         // Treat them as named symbols.
2129                         // This is rare.
2130                         // (We don't need to do this for hashed64Def case, as there the hash
2131                         // function is simply the identity function, which doesn't depend on
2132                         // name expansion.)
2133                         kind = nonPkgDef
2134                 }
2135         case nonPkgDef:
2136                 start = uint32(r.ndef + r.nhashed64def + r.nhasheddef)
2137                 end = uint32(r.ndef + r.nhashed64def + r.nhasheddef + r.NNonpkgdef())
2138         default:
2139                 panic("preloadSyms: bad kind")
2140         }
2141         l.growAttrBitmaps(len(l.objSyms) + int(end-start))
2142         needNameExpansion := r.NeedNameExpansion()
2143         loadingRuntimePkg := r.unit.Lib.Pkg == "runtime"
2144         for i := start; i < end; i++ {
2145                 osym := r.Sym(i)
2146                 var name string
2147                 var v int
2148                 if kind != hashed64Def && kind != hashedDef { // we don't need the name, etc. for hashed symbols
2149                         name = osym.Name(r.Reader)
2150                         if needNameExpansion {
2151                                 name = strings.Replace(name, "\"\".", r.pkgprefix, -1)
2152                         }
2153                         v = abiToVer(osym.ABI(), r.version)
2154                 }
2155                 gi := st.addSym(name, v, r, i, kind, osym)
2156                 r.syms[i] = gi
2157                 if osym.Local() {
2158                         l.SetAttrLocal(gi, true)
2159                 }
2160                 if osym.UsedInIface() {
2161                         l.SetAttrUsedInIface(gi, true)
2162                 }
2163                 if strings.HasPrefix(name, "runtime.") ||
2164                         (loadingRuntimePkg && strings.HasPrefix(name, "type.")) {
2165                         if bi := goobj.BuiltinIdx(name, int(osym.ABI())); bi != -1 {
2166                                 // This is a definition of a builtin symbol. Record where it is.
2167                                 l.builtinSyms[bi] = gi
2168                         }
2169                 }
2170                 if a := int32(osym.Align()); a != 0 && a > l.SymAlign(gi) {
2171                         l.SetSymAlign(gi, a)
2172                 }
2173         }
2174 }
2175
2176 // Add syms, hashed (content-addressable) symbols, non-package symbols, and
2177 // references to external symbols (which are always named).
2178 func (l *Loader) LoadSyms(arch *sys.Arch) {
2179         // Allocate space for symbols, making a guess as to how much space we need.
2180         // This function was determined empirically by looking at the cmd/compile on
2181         // Darwin, and picking factors for hashed and hashed64 syms.
2182         var symSize, hashedSize, hashed64Size int
2183         for _, o := range l.objs[goObjStart:] {
2184                 symSize += o.r.ndef + o.r.nhasheddef/2 + o.r.nhashed64def/2 + o.r.NNonpkgdef()
2185                 hashedSize += o.r.nhasheddef / 2
2186                 hashed64Size += o.r.nhashed64def / 2
2187         }
2188         // Index 0 is invalid for symbols.
2189         l.objSyms = make([]objSym, 1, symSize)
2190
2191         st := loadState{
2192                 l:            l,
2193                 hashed64Syms: make(map[uint64]symAndSize, hashed64Size),
2194                 hashedSyms:   make(map[goobj.HashType]symAndSize, hashedSize),
2195         }
2196
2197         for _, o := range l.objs[goObjStart:] {
2198                 st.preloadSyms(o.r, pkgDef)
2199         }
2200         l.npkgsyms = l.NSym()
2201         for _, o := range l.objs[goObjStart:] {
2202                 st.preloadSyms(o.r, hashed64Def)
2203                 st.preloadSyms(o.r, hashedDef)
2204                 st.preloadSyms(o.r, nonPkgDef)
2205         }
2206         l.nhashedsyms = len(st.hashed64Syms) + len(st.hashedSyms)
2207         for _, o := range l.objs[goObjStart:] {
2208                 loadObjRefs(l, o.r, arch)
2209         }
2210         l.values = make([]int64, l.NSym(), l.NSym()+1000) // +1000 make some room for external symbols
2211 }
2212
2213 func loadObjRefs(l *Loader, r *oReader, arch *sys.Arch) {
2214         // load non-package refs
2215         ndef := uint32(r.NAlldef())
2216         needNameExpansion := r.NeedNameExpansion()
2217         for i, n := uint32(0), uint32(r.NNonpkgref()); i < n; i++ {
2218                 osym := r.Sym(ndef + i)
2219                 name := osym.Name(r.Reader)
2220                 if needNameExpansion {
2221                         name = strings.Replace(name, "\"\".", r.pkgprefix, -1)
2222                 }
2223                 v := abiToVer(osym.ABI(), r.version)
2224                 r.syms[ndef+i] = l.LookupOrCreateSym(name, v)
2225                 gi := r.syms[ndef+i]
2226                 if osym.Local() {
2227                         l.SetAttrLocal(gi, true)
2228                 }
2229                 if osym.UsedInIface() {
2230                         l.SetAttrUsedInIface(gi, true)
2231                 }
2232         }
2233
2234         // referenced packages
2235         npkg := r.NPkg()
2236         r.pkg = make([]uint32, npkg)
2237         for i := 1; i < npkg; i++ { // PkgIdx 0 is a dummy invalid package
2238                 pkg := r.Pkg(i)
2239                 objidx, ok := l.objByPkg[pkg]
2240                 if !ok {
2241                         log.Fatalf("%v: reference to nonexistent package %s", r.unit.Lib, pkg)
2242                 }
2243                 r.pkg[i] = objidx
2244         }
2245
2246         // load flags of package refs
2247         for i, n := 0, r.NRefFlags(); i < n; i++ {
2248                 rf := r.RefFlags(i)
2249                 gi := l.resolve(r, rf.Sym())
2250                 if rf.Flag2()&goobj.SymFlagUsedInIface != 0 {
2251                         l.SetAttrUsedInIface(gi, true)
2252                 }
2253         }
2254 }
2255
2256 func abiToVer(abi uint16, localSymVersion int) int {
2257         var v int
2258         if abi == goobj.SymABIstatic {
2259                 // Static
2260                 v = localSymVersion
2261         } else if abiver := sym.ABIToVersion(obj.ABI(abi)); abiver != -1 {
2262                 // Note that data symbols are "ABI0", which maps to version 0.
2263                 v = abiver
2264         } else {
2265                 log.Fatalf("invalid symbol ABI: %d", abi)
2266         }
2267         return v
2268 }
2269
2270 // TopLevelSym tests a symbol (by name and kind) to determine whether
2271 // the symbol first class sym (participating in the link) or is an
2272 // anonymous aux or sub-symbol containing some sub-part or payload of
2273 // another symbol.
2274 func (l *Loader) TopLevelSym(s Sym) bool {
2275         return topLevelSym(l.RawSymName(s), l.SymType(s))
2276 }
2277
2278 // topLevelSym tests a symbol name and kind to determine whether
2279 // the symbol first class sym (participating in the link) or is an
2280 // anonymous aux or sub-symbol containing some sub-part or payload of
2281 // another symbol.
2282 func topLevelSym(sname string, skind sym.SymKind) bool {
2283         if sname != "" {
2284                 return true
2285         }
2286         switch skind {
2287         case sym.SDWARFFCN, sym.SDWARFABSFCN, sym.SDWARFTYPE, sym.SDWARFCONST, sym.SDWARFCUINFO, sym.SDWARFRANGE, sym.SDWARFLOC, sym.SDWARFLINES, sym.SGOFUNC:
2288                 return true
2289         default:
2290                 return false
2291         }
2292 }
2293
2294 // cloneToExternal takes the existing object file symbol (symIdx)
2295 // and creates a new external symbol payload that is a clone with
2296 // respect to name, version, type, relocations, etc. The idea here
2297 // is that if the linker decides it wants to update the contents of
2298 // a symbol originally discovered as part of an object file, it's
2299 // easier to do this if we make the updates to an external symbol
2300 // payload.
2301 func (l *Loader) cloneToExternal(symIdx Sym) {
2302         if l.IsExternal(symIdx) {
2303                 panic("sym is already external, no need for clone")
2304         }
2305
2306         // Read the particulars from object.
2307         r, li := l.toLocal(symIdx)
2308         osym := r.Sym(li)
2309         sname := osym.Name(r.Reader)
2310         if r.NeedNameExpansion() {
2311                 sname = strings.Replace(sname, "\"\".", r.pkgprefix, -1)
2312         }
2313         sver := abiToVer(osym.ABI(), r.version)
2314         skind := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
2315
2316         // Create new symbol, update version and kind.
2317         pi := l.newPayload(sname, sver)
2318         pp := l.payloads[pi]
2319         pp.kind = skind
2320         pp.ver = sver
2321         pp.size = int64(osym.Siz())
2322         pp.objidx = r.objidx
2323
2324         // If this is a def, then copy the guts. We expect this case
2325         // to be very rare (one case it may come up is with -X).
2326         if li < uint32(r.NAlldef()) {
2327
2328                 // Copy relocations
2329                 relocs := l.Relocs(symIdx)
2330                 pp.relocs = make([]goobj.Reloc, relocs.Count())
2331                 for i := range pp.relocs {
2332                         // Copy the relocs slice.
2333                         // Convert local reference to global reference.
2334                         rel := relocs.At(i)
2335                         pp.relocs[i].Set(rel.Off(), rel.Siz(), uint16(rel.Type()), rel.Add(), goobj.SymRef{PkgIdx: 0, SymIdx: uint32(rel.Sym())})
2336                 }
2337
2338                 // Copy data
2339                 pp.data = r.Data(li)
2340         }
2341
2342         // If we're overriding a data symbol, collect the associated
2343         // Gotype, so as to propagate it to the new symbol.
2344         auxs := r.Auxs(li)
2345         pp.auxs = auxs
2346
2347         // Install new payload to global index space.
2348         // (This needs to happen at the end, as the accessors above
2349         // need to access the old symbol content.)
2350         l.objSyms[symIdx] = objSym{l.extReader.objidx, uint32(pi)}
2351         l.extReader.syms = append(l.extReader.syms, symIdx)
2352 }
2353
2354 // Copy the payload of symbol src to dst. Both src and dst must be external
2355 // symbols.
2356 // The intended use case is that when building/linking against a shared library,
2357 // where we do symbol name mangling, the Go object file may have reference to
2358 // the original symbol name whereas the shared library provides a symbol with
2359 // the mangled name. When we do mangling, we copy payload of mangled to original.
2360 func (l *Loader) CopySym(src, dst Sym) {
2361         if !l.IsExternal(dst) {
2362                 panic("dst is not external") //l.newExtSym(l.SymName(dst), l.SymVersion(dst))
2363         }
2364         if !l.IsExternal(src) {
2365                 panic("src is not external") //l.cloneToExternal(src)
2366         }
2367         l.payloads[l.extIndex(dst)] = l.payloads[l.extIndex(src)]
2368         l.SetSymPkg(dst, l.SymPkg(src))
2369         // TODO: other attributes?
2370 }
2371
2372 // CopyAttributes copies over all of the attributes of symbol 'src' to
2373 // symbol 'dst'.
2374 func (l *Loader) CopyAttributes(src Sym, dst Sym) {
2375         l.SetAttrReachable(dst, l.AttrReachable(src))
2376         l.SetAttrOnList(dst, l.AttrOnList(src))
2377         l.SetAttrLocal(dst, l.AttrLocal(src))
2378         l.SetAttrNotInSymbolTable(dst, l.AttrNotInSymbolTable(src))
2379         if l.IsExternal(dst) {
2380                 l.SetAttrVisibilityHidden(dst, l.AttrVisibilityHidden(src))
2381                 l.SetAttrDuplicateOK(dst, l.AttrDuplicateOK(src))
2382                 l.SetAttrShared(dst, l.AttrShared(src))
2383                 l.SetAttrExternal(dst, l.AttrExternal(src))
2384         } else {
2385                 // Some attributes are modifiable only for external symbols.
2386                 // In such cases, don't try to transfer over the attribute
2387                 // from the source even if there is a clash. This comes up
2388                 // when copying attributes from a dupOK ABI wrapper symbol to
2389                 // the real target symbol (which may not be marked dupOK).
2390         }
2391         l.SetAttrSpecial(dst, l.AttrSpecial(src))
2392         l.SetAttrCgoExportDynamic(dst, l.AttrCgoExportDynamic(src))
2393         l.SetAttrCgoExportStatic(dst, l.AttrCgoExportStatic(src))
2394         l.SetAttrReadOnly(dst, l.AttrReadOnly(src))
2395 }
2396
2397 // CreateExtSym creates a new external symbol with the specified name
2398 // without adding it to any lookup tables, returning a Sym index for it.
2399 func (l *Loader) CreateExtSym(name string, ver int) Sym {
2400         return l.newExtSym(name, ver)
2401 }
2402
2403 // CreateStaticSym creates a new static symbol with the specified name
2404 // without adding it to any lookup tables, returning a Sym index for it.
2405 func (l *Loader) CreateStaticSym(name string) Sym {
2406         // Assign a new unique negative version -- this is to mark the
2407         // symbol so that it is not included in the name lookup table.
2408         l.anonVersion--
2409         return l.newExtSym(name, l.anonVersion)
2410 }
2411
2412 func (l *Loader) FreeSym(i Sym) {
2413         if l.IsExternal(i) {
2414                 pp := l.getPayload(i)
2415                 *pp = extSymPayload{}
2416         }
2417 }
2418
2419 // relocId is essentially a <S,R> tuple identifying the Rth
2420 // relocation of symbol S.
2421 type relocId struct {
2422         sym  Sym
2423         ridx int
2424 }
2425
2426 // SetRelocVariant sets the 'variant' property of a relocation on
2427 // some specific symbol.
2428 func (l *Loader) SetRelocVariant(s Sym, ri int, v sym.RelocVariant) {
2429         // sanity check
2430         if relocs := l.Relocs(s); ri >= relocs.Count() {
2431                 panic("invalid relocation ID")
2432         }
2433         if l.relocVariant == nil {
2434                 l.relocVariant = make(map[relocId]sym.RelocVariant)
2435         }
2436         if v != 0 {
2437                 l.relocVariant[relocId{s, ri}] = v
2438         } else {
2439                 delete(l.relocVariant, relocId{s, ri})
2440         }
2441 }
2442
2443 // RelocVariant returns the 'variant' property of a relocation on
2444 // some specific symbol.
2445 func (l *Loader) RelocVariant(s Sym, ri int) sym.RelocVariant {
2446         return l.relocVariant[relocId{s, ri}]
2447 }
2448
2449 // UndefinedRelocTargets iterates through the global symbol index
2450 // space, looking for symbols with relocations targeting undefined
2451 // references. The linker's loadlib method uses this to determine if
2452 // there are unresolved references to functions in system libraries
2453 // (for example, libgcc.a), presumably due to CGO code. Return
2454 // value is a list of loader.Sym's corresponding to the undefined
2455 // cross-refs. The "limit" param controls the maximum number of
2456 // results returned; if "limit" is -1, then all undefs are returned.
2457 func (l *Loader) UndefinedRelocTargets(limit int) []Sym {
2458         result := []Sym{}
2459         for si := Sym(1); si < Sym(len(l.objSyms)); si++ {
2460                 relocs := l.Relocs(si)
2461                 for ri := 0; ri < relocs.Count(); ri++ {
2462                         r := relocs.At(ri)
2463                         rs := r.Sym()
2464                         if rs != 0 && l.SymType(rs) == sym.SXREF && l.RawSymName(rs) != ".got" {
2465                                 result = append(result, rs)
2466                                 if limit != -1 && len(result) >= limit {
2467                                         break
2468                                 }
2469                         }
2470                 }
2471         }
2472         return result
2473 }
2474
2475 // AssignTextSymbolOrder populates the Textp slices within each
2476 // library and compilation unit, insuring that packages are laid down
2477 // in dependency order (internal first, then everything else). Return value
2478 // is a slice of all text syms.
2479 func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool, extsyms []Sym) []Sym {
2480
2481         // Library Textp lists should be empty at this point.
2482         for _, lib := range libs {
2483                 if len(lib.Textp) != 0 {
2484                         panic("expected empty Textp slice for library")
2485                 }
2486                 if len(lib.DupTextSyms) != 0 {
2487                         panic("expected empty DupTextSyms slice for library")
2488                 }
2489         }
2490
2491         // Used to record which dupok symbol we've assigned to a unit.
2492         // Can't use the onlist attribute here because it will need to
2493         // clear for the later assignment of the sym.Symbol to a unit.
2494         // NB: we can convert to using onList once we no longer have to
2495         // call the regular addToTextp.
2496         assignedToUnit := MakeBitmap(l.NSym() + 1)
2497
2498         // Start off textp with reachable external syms.
2499         textp := []Sym{}
2500         for _, sym := range extsyms {
2501                 if !l.attrReachable.Has(sym) {
2502                         continue
2503                 }
2504                 textp = append(textp, sym)
2505         }
2506
2507         // Walk through all text symbols from Go object files and append
2508         // them to their corresponding library's textp list.
2509         for _, o := range l.objs[goObjStart:] {
2510                 r := o.r
2511                 lib := r.unit.Lib
2512                 for i, n := uint32(0), uint32(r.NAlldef()); i < n; i++ {
2513                         gi := l.toGlobal(r, i)
2514                         if !l.attrReachable.Has(gi) {
2515                                 continue
2516                         }
2517                         osym := r.Sym(i)
2518                         st := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
2519                         if st != sym.STEXT {
2520                                 continue
2521                         }
2522                         dupok := osym.Dupok()
2523                         if r2, i2 := l.toLocal(gi); r2 != r || i2 != i {
2524                                 // A dupok text symbol is resolved to another package.
2525                                 // We still need to record its presence in the current
2526                                 // package, as the trampoline pass expects packages
2527                                 // are laid out in dependency order.
2528                                 lib.DupTextSyms = append(lib.DupTextSyms, sym.LoaderSym(gi))
2529                                 continue // symbol in different object
2530                         }
2531                         if dupok {
2532                                 lib.DupTextSyms = append(lib.DupTextSyms, sym.LoaderSym(gi))
2533                                 continue
2534                         }
2535
2536                         lib.Textp = append(lib.Textp, sym.LoaderSym(gi))
2537                 }
2538         }
2539
2540         // Now assemble global textp, and assign text symbols to units.
2541         for _, doInternal := range [2]bool{true, false} {
2542                 for idx, lib := range libs {
2543                         if intlibs[idx] != doInternal {
2544                                 continue
2545                         }
2546                         lists := [2][]sym.LoaderSym{lib.Textp, lib.DupTextSyms}
2547                         for i, list := range lists {
2548                                 for _, s := range list {
2549                                         sym := Sym(s)
2550                                         if !assignedToUnit.Has(sym) {
2551                                                 textp = append(textp, sym)
2552                                                 unit := l.SymUnit(sym)
2553                                                 if unit != nil {
2554                                                         unit.Textp = append(unit.Textp, s)
2555                                                         assignedToUnit.Set(sym)
2556                                                 }
2557                                                 // Dupok symbols may be defined in multiple packages; the
2558                                                 // associated package for a dupok sym is chosen sort of
2559                                                 // arbitrarily (the first containing package that the linker
2560                                                 // loads). Canonicalizes its Pkg to the package with which
2561                                                 // it will be laid down in text.
2562                                                 if i == 1 /* DupTextSyms2 */ && l.SymPkg(sym) != lib.Pkg {
2563                                                         l.SetSymPkg(sym, lib.Pkg)
2564                                                 }
2565                                         }
2566                                 }
2567                         }
2568                         lib.Textp = nil
2569                         lib.DupTextSyms = nil
2570                 }
2571         }
2572
2573         return textp
2574 }
2575
2576 // ErrorReporter is a helper class for reporting errors.
2577 type ErrorReporter struct {
2578         ldr              *Loader
2579         AfterErrorAction func()
2580 }
2581
2582 // Errorf method logs an error message.
2583 //
2584 // After each error, the error actions function will be invoked; this
2585 // will either terminate the link immediately (if -h option given)
2586 // or it will keep a count and exit if more than 20 errors have been printed.
2587 //
2588 // Logging an error means that on exit cmd/link will delete any
2589 // output file and return a non-zero error code.
2590 //
2591 func (reporter *ErrorReporter) Errorf(s Sym, format string, args ...interface{}) {
2592         if s != 0 && reporter.ldr.SymName(s) != "" {
2593                 // Note: Replace is needed here because symbol names might have % in them,
2594                 // due to the use of LinkString for names of instantiating types.
2595                 format = strings.Replace(reporter.ldr.SymName(s), "%", "%%", -1) + ": " + format
2596         } else {
2597                 format = fmt.Sprintf("sym %d: %s", s, format)
2598         }
2599         format += "\n"
2600         fmt.Fprintf(os.Stderr, format, args...)
2601         reporter.AfterErrorAction()
2602 }
2603
2604 // GetErrorReporter returns the loader's associated error reporter.
2605 func (l *Loader) GetErrorReporter() *ErrorReporter {
2606         return l.errorReporter
2607 }
2608
2609 // Errorf method logs an error message. See ErrorReporter.Errorf for details.
2610 func (l *Loader) Errorf(s Sym, format string, args ...interface{}) {
2611         l.errorReporter.Errorf(s, format, args...)
2612 }
2613
2614 // Symbol statistics.
2615 func (l *Loader) Stat() string {
2616         s := fmt.Sprintf("%d symbols, %d reachable\n", l.NSym(), l.NReachableSym())
2617         s += fmt.Sprintf("\t%d package symbols, %d hashed symbols, %d non-package symbols, %d external symbols\n",
2618                 l.npkgsyms, l.nhashedsyms, int(l.extStart)-l.npkgsyms-l.nhashedsyms, l.NSym()-int(l.extStart))
2619         return s
2620 }
2621
2622 // For debugging.
2623 func (l *Loader) Dump() {
2624         fmt.Println("objs")
2625         for _, obj := range l.objs[goObjStart:] {
2626                 if obj.r != nil {
2627                         fmt.Println(obj.i, obj.r.unit.Lib)
2628                 }
2629         }
2630         fmt.Println("extStart:", l.extStart)
2631         fmt.Println("Nsyms:", len(l.objSyms))
2632         fmt.Println("syms")
2633         for i := Sym(1); i < Sym(len(l.objSyms)); i++ {
2634                 pi := ""
2635                 if l.IsExternal(i) {
2636                         pi = fmt.Sprintf("<ext %d>", l.extIndex(i))
2637                 }
2638                 sect := ""
2639                 if l.SymSect(i) != nil {
2640                         sect = l.SymSect(i).Name
2641                 }
2642                 fmt.Printf("%v %v %v %v %x %v\n", i, l.SymName(i), l.SymType(i), pi, l.SymValue(i), sect)
2643         }
2644         fmt.Println("symsByName")
2645         for name, i := range l.symsByName[0] {
2646                 fmt.Println(i, name, 0)
2647         }
2648         for name, i := range l.symsByName[1] {
2649                 fmt.Println(i, name, 1)
2650         }
2651         fmt.Println("payloads:")
2652         for i := range l.payloads {
2653                 pp := l.payloads[i]
2654                 fmt.Println(i, pp.name, pp.ver, pp.kind)
2655         }
2656 }