1
2
3
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 "internal/abi"
18 "io"
19 "log"
20 "math/bits"
21 "os"
22 "sort"
23 "strings"
24 )
25
26 var _ = fmt.Print
27
28
29
30 type Sym = sym.LoaderSym
31
32
33
34 type Relocs struct {
35 rs []goobj.Reloc
36
37 li uint32
38 r *oReader
39 l *Loader
40 }
41
42
43 type ExtReloc struct {
44 Xsym Sym
45 Xadd int64
46 Type objabi.RelocType
47 Size uint8
48 }
49
50
51
52 type Reloc struct {
53 *goobj.Reloc
54 r *oReader
55 l *Loader
56 }
57
58 func (rel Reloc) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc.Type()) &^ objabi.R_WEAK }
59 func (rel Reloc) Weak() bool { return objabi.RelocType(rel.Reloc.Type())&objabi.R_WEAK != 0 }
60 func (rel Reloc) SetType(t objabi.RelocType) { rel.Reloc.SetType(uint16(t)) }
61 func (rel Reloc) Sym() Sym { return rel.l.resolve(rel.r, rel.Reloc.Sym()) }
62 func (rel Reloc) SetSym(s Sym) { rel.Reloc.SetSym(goobj.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) }
63 func (rel Reloc) IsMarker() bool { return rel.Siz() == 0 }
64
65
66
67 type Aux struct {
68 *goobj.Aux
69 r *oReader
70 l *Loader
71 }
72
73 func (a Aux) Sym() Sym { return a.l.resolve(a.r, a.Aux.Sym()) }
74
75
76
77 type oReader struct {
78 *goobj.Reader
79 unit *sym.CompilationUnit
80 version int
81 pkgprefix string
82 syms []Sym
83 pkg []uint32
84 ndef int
85 nhashed64def int
86 nhasheddef int
87 objidx uint32
88 }
89
90
91
92 func (r *oReader) NAlldef() int { return r.ndef + r.nhashed64def + r.nhasheddef + r.NNonpkgdef() }
93
94
95
96
97
98
99 type objSym struct {
100 objidx uint32
101 s uint32
102 }
103
104 type nameVer struct {
105 name string
106 v int
107 }
108
109 type Bitmap []uint32
110
111
112 func (bm Bitmap) Set(i Sym) {
113 n, r := uint(i)/32, uint(i)%32
114 bm[n] |= 1 << r
115 }
116
117
118 func (bm Bitmap) Unset(i Sym) {
119 n, r := uint(i)/32, uint(i)%32
120 bm[n] &^= (1 << r)
121 }
122
123
124 func (bm Bitmap) Has(i Sym) bool {
125 n, r := uint(i)/32, uint(i)%32
126 return bm[n]&(1<<r) != 0
127 }
128
129
130 func (bm Bitmap) Len() int {
131 return len(bm) * 32
132 }
133
134
135 func (bm Bitmap) Count() int {
136 s := 0
137 for _, x := range bm {
138 s += bits.OnesCount32(x)
139 }
140 return s
141 }
142
143 func MakeBitmap(n int) Bitmap {
144 return make(Bitmap, (n+31)/32)
145 }
146
147
148
149 func growBitmap(reqLen int, b Bitmap) Bitmap {
150 curLen := b.Len()
151 if reqLen > curLen {
152 b = append(b, MakeBitmap(reqLen+1-curLen)...)
153 }
154 return b
155 }
156
157 type symAndSize struct {
158 sym Sym
159 size uint32
160 }
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181 type Loader struct {
182 objs []*oReader
183 extStart Sym
184 builtinSyms []Sym
185
186 objSyms []objSym
187
188 symsByName [2]map[string]Sym
189 extStaticSyms map[nameVer]Sym
190
191 extReader *oReader
192 payloadBatch []extSymPayload
193 payloads []*extSymPayload
194 values []int64
195
196 sects []*sym.Section
197 symSects []uint16
198
199 align []uint8
200
201 deferReturnTramp map[Sym]bool
202
203 objByPkg map[string]uint32
204
205 anonVersion int
206
207
208
209
210
211
212 attrReachable Bitmap
213 attrOnList Bitmap
214 attrLocal Bitmap
215 attrNotInSymbolTable Bitmap
216 attrUsedInIface Bitmap
217 attrSpecial Bitmap
218 attrVisibilityHidden Bitmap
219 attrDuplicateOK Bitmap
220 attrShared Bitmap
221 attrExternal Bitmap
222 generatedSyms Bitmap
223
224 attrReadOnly map[Sym]bool
225 attrCgoExportDynamic map[Sym]struct{}
226 attrCgoExportStatic map[Sym]struct{}
227
228
229 outer []Sym
230 sub map[Sym]Sym
231
232 dynimplib map[Sym]string
233 dynimpvers map[Sym]string
234 localentry map[Sym]uint8
235 extname map[Sym]string
236 elfType map[Sym]elf.SymType
237 elfSym map[Sym]int32
238 localElfSym map[Sym]int32
239 symPkg map[Sym]string
240 plt map[Sym]int32
241 got map[Sym]int32
242 dynid map[Sym]int32
243
244 relocVariant map[relocId]sym.RelocVariant
245
246
247
248
249 Reachparent []Sym
250
251
252 CgoExports map[string]Sym
253
254 WasmExports []Sym
255
256 flags uint32
257
258 strictDupMsgs int
259
260 errorReporter *ErrorReporter
261
262 npkgsyms int
263 nhashedsyms int
264 }
265
266 const (
267 pkgDef = iota
268 hashed64Def
269 hashedDef
270 nonPkgDef
271 nonPkgRef
272 )
273
274
275 const (
276 nilObj = iota
277 extObj
278 goObjStart
279 )
280
281
282
283 type extSymPayload struct {
284 name string
285 size int64
286 ver int
287 kind sym.SymKind
288 objidx uint32
289 relocs []goobj.Reloc
290 data []byte
291 auxs []goobj.Aux
292 }
293
294 const (
295
296 FlagStrictDups = 1 << iota
297 FlagCheckLinkname
298 )
299
300 func NewLoader(flags uint32, reporter *ErrorReporter) *Loader {
301 nbuiltin := goobj.NBuiltin()
302 extReader := &oReader{objidx: extObj}
303 ldr := &Loader{
304 objs: []*oReader{nil, extReader},
305 objSyms: make([]objSym, 1, 1),
306 extReader: extReader,
307 symsByName: [2]map[string]Sym{make(map[string]Sym, 80000), make(map[string]Sym, 50000)},
308 objByPkg: make(map[string]uint32),
309 sub: make(map[Sym]Sym),
310 dynimplib: make(map[Sym]string),
311 dynimpvers: make(map[Sym]string),
312 localentry: make(map[Sym]uint8),
313 extname: make(map[Sym]string),
314 attrReadOnly: make(map[Sym]bool),
315 elfType: make(map[Sym]elf.SymType),
316 elfSym: make(map[Sym]int32),
317 localElfSym: make(map[Sym]int32),
318 symPkg: make(map[Sym]string),
319 plt: make(map[Sym]int32),
320 got: make(map[Sym]int32),
321 dynid: make(map[Sym]int32),
322 attrCgoExportDynamic: make(map[Sym]struct{}),
323 attrCgoExportStatic: make(map[Sym]struct{}),
324 deferReturnTramp: make(map[Sym]bool),
325 extStaticSyms: make(map[nameVer]Sym),
326 builtinSyms: make([]Sym, nbuiltin),
327 flags: flags,
328 errorReporter: reporter,
329 sects: []*sym.Section{nil},
330 }
331 reporter.ldr = ldr
332 return ldr
333 }
334
335
336 func (l *Loader) addObj(pkg string, r *oReader) {
337 pkg = objabi.PathToPrefix(pkg)
338 if _, ok := l.objByPkg[pkg]; !ok {
339 l.objByPkg[pkg] = r.objidx
340 }
341 l.objs = append(l.objs, r)
342 }
343
344
345
346 func (st *loadState) addSym(name string, ver int, r *oReader, li uint32, kind int, osym *goobj.Sym) Sym {
347 l := st.l
348 if l.extStart != 0 {
349 panic("addSym called after external symbol is created")
350 }
351 i := Sym(len(l.objSyms))
352 if int(i) != len(l.objSyms) {
353 panic("too many symbols")
354 }
355 addToGlobal := func() {
356 l.objSyms = append(l.objSyms, objSym{r.objidx, li})
357 }
358 if name == "" && kind != hashed64Def && kind != hashedDef {
359 addToGlobal()
360 return i
361 }
362 if ver == r.version {
363
364
365
366 addToGlobal()
367 return i
368 }
369 switch kind {
370 case pkgDef:
371
372
373
374
375
376 l.symsByName[ver][name] = i
377 addToGlobal()
378 return i
379 case hashed64Def, hashedDef:
380
381
382
383
384 var checkHash func() (symAndSize, bool)
385 var addToHashMap func(symAndSize)
386 var h64 uint64
387 var h *goobj.HashType
388 if kind == hashed64Def {
389 checkHash = func() (symAndSize, bool) {
390 h64 = r.Hash64(li - uint32(r.ndef))
391 s, existed := st.hashed64Syms[h64]
392 return s, existed
393 }
394 addToHashMap = func(ss symAndSize) { st.hashed64Syms[h64] = ss }
395 } else {
396 checkHash = func() (symAndSize, bool) {
397 h = r.Hash(li - uint32(r.ndef+r.nhashed64def))
398 s, existed := st.hashedSyms[*h]
399 return s, existed
400 }
401 addToHashMap = func(ss symAndSize) { st.hashedSyms[*h] = ss }
402 }
403 siz := osym.Siz()
404 if s, existed := checkHash(); existed {
405
406
407
408
409
410
411
412
413
414 if siz > s.size {
415
416 l.objSyms[s.sym] = objSym{r.objidx, li}
417 addToHashMap(symAndSize{s.sym, siz})
418 }
419 return s.sym
420 }
421 addToHashMap(symAndSize{i, siz})
422 addToGlobal()
423 return i
424 }
425
426
427
428 oldi, existed := l.symsByName[ver][name]
429 if !existed {
430 l.symsByName[ver][name] = i
431 addToGlobal()
432 return i
433 }
434
435
436
437
438 oldsz := l.SymSize(oldi)
439 sz := int64(r.Sym(li).Siz())
440 if osym.Dupok() {
441 if l.flags&FlagStrictDups != 0 {
442 l.checkdup(name, r, li, oldi)
443 }
444 if oldsz < sz {
445
446 l.objSyms[oldi] = objSym{r.objidx, li}
447 }
448 return oldi
449 }
450 oldr, oldli := l.toLocal(oldi)
451 oldsym := oldr.Sym(oldli)
452 if oldsym.Dupok() {
453 return oldi
454 }
455
456
457
458
459
460
461
462
463
464
465
466
467
468 overwrite := r.DataSize(li) != 0 || oldsz < sz
469 if overwrite {
470
471 oldtyp := sym.AbiSymKindToSymKind[objabi.SymKind(oldsym.Type())]
472 if !(oldtyp.IsData() && oldr.DataSize(oldli) == 0) || oldsz > sz {
473 log.Fatalf("duplicated definition of symbol %s, from %s and %s", name, r.unit.Lib.Pkg, oldr.unit.Lib.Pkg)
474 }
475 l.objSyms[oldi] = objSym{r.objidx, li}
476 } else {
477
478 typ := sym.AbiSymKindToSymKind[objabi.SymKind(oldsym.Type())]
479 if !typ.IsData() {
480 log.Fatalf("duplicated definition of symbol %s, from %s and %s", name, r.unit.Lib.Pkg, oldr.unit.Lib.Pkg)
481 }
482 }
483 return oldi
484 }
485
486
487
488 func (l *Loader) newExtSym(name string, ver int) Sym {
489 i := Sym(len(l.objSyms))
490 if int(i) != len(l.objSyms) {
491 panic("too many symbols")
492 }
493 if l.extStart == 0 {
494 l.extStart = i
495 }
496 l.growValues(int(i) + 1)
497 l.growOuter(int(i) + 1)
498 l.growAttrBitmaps(int(i) + 1)
499 pi := l.newPayload(name, ver)
500 l.objSyms = append(l.objSyms, objSym{l.extReader.objidx, uint32(pi)})
501 l.extReader.syms = append(l.extReader.syms, i)
502 return i
503 }
504
505
506
507
508 func (l *Loader) LookupOrCreateSym(name string, ver int) Sym {
509 i := l.Lookup(name, ver)
510 if i != 0 {
511 return i
512 }
513 i = l.newExtSym(name, ver)
514 static := ver >= sym.SymVerStatic || ver < 0
515 if static {
516 l.extStaticSyms[nameVer{name, ver}] = i
517 } else {
518 l.symsByName[ver][name] = i
519 }
520 return i
521 }
522
523
524
525
526 func (l *Loader) AddCgoExport(s Sym) {
527 if l.CgoExports == nil {
528 l.CgoExports = make(map[string]Sym)
529 }
530 l.CgoExports[l.SymName(s)] = s
531 }
532
533
534
535
536
537 func (l *Loader) LookupOrCreateCgoExport(name string, ver int) Sym {
538 if ver >= sym.SymVerStatic {
539 return l.LookupOrCreateSym(name, ver)
540 }
541 if ver != 0 {
542 panic("ver must be 0 or a static version")
543 }
544
545 if s, ok := l.CgoExports[name]; ok {
546 return s
547 }
548
549
550 return l.LookupOrCreateSym(name, 0)
551 }
552
553 func (l *Loader) IsExternal(i Sym) bool {
554 r, _ := l.toLocal(i)
555 return l.isExtReader(r)
556 }
557
558 func (l *Loader) isExtReader(r *oReader) bool {
559 return r == l.extReader
560 }
561
562
563
564
565 func (l *Loader) extIndex(i Sym) Sym {
566 _, li := l.toLocal(i)
567 return Sym(li)
568 }
569
570
571
572 func (l *Loader) newPayload(name string, ver int) int {
573 pi := len(l.payloads)
574 pp := l.allocPayload()
575 pp.name = name
576 pp.ver = ver
577 l.payloads = append(l.payloads, pp)
578 l.growExtAttrBitmaps()
579 return pi
580 }
581
582
583
584
585 func (l *Loader) getPayload(i Sym) *extSymPayload {
586 if !l.IsExternal(i) {
587 panic(fmt.Sprintf("bogus symbol index %d in getPayload", i))
588 }
589 pi := l.extIndex(i)
590 return l.payloads[pi]
591 }
592
593
594 func (l *Loader) allocPayload() *extSymPayload {
595 batch := l.payloadBatch
596 if len(batch) == 0 {
597 batch = make([]extSymPayload, 1000)
598 }
599 p := &batch[0]
600 l.payloadBatch = batch[1:]
601 return p
602 }
603
604 func (ms *extSymPayload) Grow(siz int64) {
605 if int64(int(siz)) != siz {
606 log.Fatalf("symgrow size %d too long", siz)
607 }
608 if int64(len(ms.data)) >= siz {
609 return
610 }
611 if cap(ms.data) < int(siz) {
612 cl := len(ms.data)
613 ms.data = append(ms.data, make([]byte, int(siz)+1-cl)...)
614 ms.data = ms.data[0:cl]
615 }
616 ms.data = ms.data[:siz]
617 }
618
619
620 func (l *Loader) toGlobal(r *oReader, i uint32) Sym {
621 return r.syms[i]
622 }
623
624
625 func (l *Loader) toLocal(i Sym) (*oReader, uint32) {
626 return l.objs[l.objSyms[i].objidx], l.objSyms[i].s
627 }
628
629
630 func (l *Loader) resolve(r *oReader, s goobj.SymRef) Sym {
631 var rr *oReader
632 switch p := s.PkgIdx; p {
633 case goobj.PkgIdxInvalid:
634
635
636
637 if l.isExtReader(r) {
638 return Sym(s.SymIdx)
639 }
640 if s.SymIdx != 0 {
641 panic("bad sym ref")
642 }
643 return 0
644 case goobj.PkgIdxHashed64:
645 i := int(s.SymIdx) + r.ndef
646 return r.syms[i]
647 case goobj.PkgIdxHashed:
648 i := int(s.SymIdx) + r.ndef + r.nhashed64def
649 return r.syms[i]
650 case goobj.PkgIdxNone:
651 i := int(s.SymIdx) + r.ndef + r.nhashed64def + r.nhasheddef
652 return r.syms[i]
653 case goobj.PkgIdxBuiltin:
654 if bi := l.builtinSyms[s.SymIdx]; bi != 0 {
655 return bi
656 }
657 l.reportMissingBuiltin(int(s.SymIdx), r.unit.Lib.Pkg)
658 return 0
659 case goobj.PkgIdxSelf:
660 rr = r
661 default:
662 rr = l.objs[r.pkg[p]]
663 }
664 return l.toGlobal(rr, s.SymIdx)
665 }
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684 func (l *Loader) reportMissingBuiltin(bsym int, reflib string) {
685 bname, _ := goobj.BuiltinName(bsym)
686 log.Fatalf("reference to undefined builtin %q from package %q",
687 bname, reflib)
688 }
689
690
691
692
693 func (l *Loader) Lookup(name string, ver int) Sym {
694 if ver >= sym.SymVerStatic || ver < 0 {
695 return l.extStaticSyms[nameVer{name, ver}]
696 }
697 return l.symsByName[ver][name]
698 }
699
700
701 func (l *Loader) checkdup(name string, r *oReader, li uint32, dup Sym) {
702 p := r.Data(li)
703 rdup, ldup := l.toLocal(dup)
704 pdup := rdup.Data(ldup)
705 reason := "same length but different contents"
706 if len(p) != len(pdup) {
707 reason = fmt.Sprintf("new length %d != old length %d", len(p), len(pdup))
708 } else if bytes.Equal(p, pdup) {
709
710 szdup := l.SymSize(dup)
711 sz := int64(r.Sym(li).Siz())
712 if szdup == sz {
713 return
714 }
715 reason = fmt.Sprintf("different sizes: new size %d != old size %d",
716 sz, szdup)
717 }
718 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)
719
720
721
722
723
724
725 allowed := strings.HasPrefix(name, "go:info.go.interface") ||
726 strings.HasPrefix(name, "go:info.go.builtin") ||
727 strings.HasPrefix(name, "go:debuglines")
728 if !allowed {
729 l.strictDupMsgs++
730 }
731 }
732
733 func (l *Loader) NStrictDupMsgs() int { return l.strictDupMsgs }
734
735
736 func (l *Loader) NSym() int {
737 return len(l.objSyms)
738 }
739
740
741 func (l *Loader) NDef() int {
742 return int(l.extStart)
743 }
744
745
746 func (l *Loader) NReachableSym() int {
747 return l.attrReachable.Count()
748 }
749
750
751 func (l *Loader) SymName(i Sym) string {
752 if l.IsExternal(i) {
753 pp := l.getPayload(i)
754 return pp.name
755 }
756 r, li := l.toLocal(i)
757 if r == nil {
758 return "?"
759 }
760 return r.Sym(li).Name(r.Reader)
761 }
762
763
764 func (l *Loader) SymVersion(i Sym) int {
765 if l.IsExternal(i) {
766 pp := l.getPayload(i)
767 return pp.ver
768 }
769 r, li := l.toLocal(i)
770 return int(abiToVer(r.Sym(li).ABI(), r.version))
771 }
772
773 func (l *Loader) IsFileLocal(i Sym) bool {
774 return l.SymVersion(i) >= sym.SymVerStatic
775 }
776
777
778
779 func (l *Loader) IsFromAssembly(i Sym) bool {
780 if l.IsExternal(i) {
781 pp := l.getPayload(i)
782 if pp.objidx != 0 {
783 r := l.objs[pp.objidx]
784 return r.FromAssembly()
785 }
786 return false
787 }
788 r, _ := l.toLocal(i)
789 return r.FromAssembly()
790 }
791
792
793 func (l *Loader) SymType(i Sym) sym.SymKind {
794 if l.IsExternal(i) {
795 pp := l.getPayload(i)
796 if pp != nil {
797 return pp.kind
798 }
799 return 0
800 }
801 r, li := l.toLocal(i)
802 return sym.AbiSymKindToSymKind[objabi.SymKind(r.Sym(li).Type())]
803 }
804
805
806 func (l *Loader) SymAttr(i Sym) uint8 {
807 if l.IsExternal(i) {
808
809
810
811 return 0
812 }
813 r, li := l.toLocal(i)
814 return r.Sym(li).Flag()
815 }
816
817
818 func (l *Loader) SymSize(i Sym) int64 {
819 if l.IsExternal(i) {
820 pp := l.getPayload(i)
821 return pp.size
822 }
823 r, li := l.toLocal(i)
824 return int64(r.Sym(li).Siz())
825 }
826
827
828
829
830 func (l *Loader) AttrReachable(i Sym) bool {
831 return l.attrReachable.Has(i)
832 }
833
834
835
836 func (l *Loader) SetAttrReachable(i Sym, v bool) {
837 if v {
838 l.attrReachable.Set(i)
839 } else {
840 l.attrReachable.Unset(i)
841 }
842 }
843
844
845
846
847
848 func (l *Loader) AttrOnList(i Sym) bool {
849 return l.attrOnList.Has(i)
850 }
851
852
853
854 func (l *Loader) SetAttrOnList(i Sym, v bool) {
855 if v {
856 l.attrOnList.Set(i)
857 } else {
858 l.attrOnList.Unset(i)
859 }
860 }
861
862
863
864
865 func (l *Loader) AttrLocal(i Sym) bool {
866 return l.attrLocal.Has(i)
867 }
868
869
870 func (l *Loader) SetAttrLocal(i Sym, v bool) {
871 if v {
872 l.attrLocal.Set(i)
873 } else {
874 l.attrLocal.Unset(i)
875 }
876 }
877
878
879
880 func (l *Loader) AttrUsedInIface(i Sym) bool {
881 return l.attrUsedInIface.Has(i)
882 }
883
884 func (l *Loader) SetAttrUsedInIface(i Sym, v bool) {
885 if v {
886 l.attrUsedInIface.Set(i)
887 } else {
888 l.attrUsedInIface.Unset(i)
889 }
890 }
891
892
893 func (l *Loader) SymAddr(i Sym) int64 {
894 if !l.AttrReachable(i) {
895 panic("unreachable symbol in symaddr")
896 }
897 return l.values[i]
898 }
899
900
901
902 func (l *Loader) AttrNotInSymbolTable(i Sym) bool {
903 return l.attrNotInSymbolTable.Has(i)
904 }
905
906
907
908 func (l *Loader) SetAttrNotInSymbolTable(i Sym, v bool) {
909 if v {
910 l.attrNotInSymbolTable.Set(i)
911 } else {
912 l.attrNotInSymbolTable.Unset(i)
913 }
914 }
915
916
917
918
919
920 func (l *Loader) AttrVisibilityHidden(i Sym) bool {
921 if !l.IsExternal(i) {
922 return false
923 }
924 return l.attrVisibilityHidden.Has(l.extIndex(i))
925 }
926
927
928
929 func (l *Loader) SetAttrVisibilityHidden(i Sym, v bool) {
930 if !l.IsExternal(i) {
931 panic("tried to set visibility attr on non-external symbol")
932 }
933 if v {
934 l.attrVisibilityHidden.Set(l.extIndex(i))
935 } else {
936 l.attrVisibilityHidden.Unset(l.extIndex(i))
937 }
938 }
939
940
941
942 func (l *Loader) AttrDuplicateOK(i Sym) bool {
943 if !l.IsExternal(i) {
944
945
946
947 r, li := l.toLocal(i)
948 return r.Sym(li).Dupok()
949 }
950 return l.attrDuplicateOK.Has(l.extIndex(i))
951 }
952
953
954
955 func (l *Loader) SetAttrDuplicateOK(i Sym, v bool) {
956 if !l.IsExternal(i) {
957 panic("tried to set dupok attr on non-external symbol")
958 }
959 if v {
960 l.attrDuplicateOK.Set(l.extIndex(i))
961 } else {
962 l.attrDuplicateOK.Unset(l.extIndex(i))
963 }
964 }
965
966
967 func (l *Loader) AttrShared(i Sym) bool {
968 if !l.IsExternal(i) {
969
970
971
972 r, _ := l.toLocal(i)
973 return r.Shared()
974 }
975 return l.attrShared.Has(l.extIndex(i))
976 }
977
978
979
980 func (l *Loader) SetAttrShared(i Sym, v bool) {
981 if !l.IsExternal(i) {
982 panic(fmt.Sprintf("tried to set shared attr on non-external symbol %d %s", i, l.SymName(i)))
983 }
984 if v {
985 l.attrShared.Set(l.extIndex(i))
986 } else {
987 l.attrShared.Unset(l.extIndex(i))
988 }
989 }
990
991
992
993 func (l *Loader) AttrExternal(i Sym) bool {
994 if !l.IsExternal(i) {
995 return false
996 }
997 return l.attrExternal.Has(l.extIndex(i))
998 }
999
1000
1001
1002 func (l *Loader) SetAttrExternal(i Sym, v bool) {
1003 if !l.IsExternal(i) {
1004 panic(fmt.Sprintf("tried to set external attr on non-external symbol %q", l.SymName(i)))
1005 }
1006 if v {
1007 l.attrExternal.Set(l.extIndex(i))
1008 } else {
1009 l.attrExternal.Unset(l.extIndex(i))
1010 }
1011 }
1012
1013
1014
1015
1016 func (l *Loader) AttrSpecial(i Sym) bool {
1017 return l.attrSpecial.Has(i)
1018 }
1019
1020
1021
1022 func (l *Loader) SetAttrSpecial(i Sym, v bool) {
1023 if v {
1024 l.attrSpecial.Set(i)
1025 } else {
1026 l.attrSpecial.Unset(i)
1027 }
1028 }
1029
1030
1031
1032
1033 func (l *Loader) AttrCgoExportDynamic(i Sym) bool {
1034 _, ok := l.attrCgoExportDynamic[i]
1035 return ok
1036 }
1037
1038
1039
1040 func (l *Loader) SetAttrCgoExportDynamic(i Sym, v bool) {
1041 if v {
1042 l.attrCgoExportDynamic[i] = struct{}{}
1043 } else {
1044 delete(l.attrCgoExportDynamic, i)
1045 }
1046 }
1047
1048
1049
1050 func (l *Loader) ForAllCgoExportDynamic(f func(Sym)) {
1051 for s := range l.attrCgoExportDynamic {
1052 f(s)
1053 }
1054 }
1055
1056
1057
1058
1059 func (l *Loader) AttrCgoExportStatic(i Sym) bool {
1060 _, ok := l.attrCgoExportStatic[i]
1061 return ok
1062 }
1063
1064
1065
1066 func (l *Loader) SetAttrCgoExportStatic(i Sym, v bool) {
1067 if v {
1068 l.attrCgoExportStatic[i] = struct{}{}
1069 } else {
1070 delete(l.attrCgoExportStatic, i)
1071 }
1072 }
1073
1074
1075
1076
1077 func (l *Loader) IsGeneratedSym(i Sym) bool {
1078 if !l.IsExternal(i) {
1079 return false
1080 }
1081 return l.generatedSyms.Has(l.extIndex(i))
1082 }
1083
1084
1085
1086
1087 func (l *Loader) SetIsGeneratedSym(i Sym, v bool) {
1088 if !l.IsExternal(i) {
1089 panic("only external symbols can be generated")
1090 }
1091 if v {
1092 l.generatedSyms.Set(l.extIndex(i))
1093 } else {
1094 l.generatedSyms.Unset(l.extIndex(i))
1095 }
1096 }
1097
1098 func (l *Loader) AttrCgoExport(i Sym) bool {
1099 return l.AttrCgoExportDynamic(i) || l.AttrCgoExportStatic(i)
1100 }
1101
1102
1103
1104 func (l *Loader) AttrReadOnly(i Sym) bool {
1105 if v, ok := l.attrReadOnly[i]; ok {
1106 return v
1107 }
1108 if l.IsExternal(i) {
1109 pp := l.getPayload(i)
1110 if pp.objidx != 0 {
1111 return l.objs[pp.objidx].ReadOnly()
1112 }
1113 return false
1114 }
1115 r, _ := l.toLocal(i)
1116 return r.ReadOnly()
1117 }
1118
1119
1120
1121 func (l *Loader) SetAttrReadOnly(i Sym, v bool) {
1122 l.attrReadOnly[i] = v
1123 }
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147 func (l *Loader) AttrSubSymbol(i Sym) bool {
1148
1149
1150 o := l.OuterSym(i)
1151 if o == 0 {
1152 return false
1153 }
1154 return l.SubSym(o) != 0
1155 }
1156
1157
1158
1159
1160
1161
1162 func (l *Loader) IsReflectMethod(i Sym) bool {
1163 return l.SymAttr(i)&goobj.SymFlagReflectMethod != 0
1164 }
1165
1166
1167 func (l *Loader) IsNoSplit(i Sym) bool {
1168 return l.SymAttr(i)&goobj.SymFlagNoSplit != 0
1169 }
1170
1171
1172 func (l *Loader) IsGoType(i Sym) bool {
1173 return l.SymAttr(i)&goobj.SymFlagGoType != 0
1174 }
1175
1176
1177 func (l *Loader) IsTypelink(i Sym) bool {
1178 return l.SymAttr(i)&goobj.SymFlagTypelink != 0
1179 }
1180
1181
1182 func (l *Loader) IsItab(i Sym) bool {
1183 if l.IsExternal(i) {
1184 return false
1185 }
1186 r, li := l.toLocal(i)
1187 return r.Sym(li).IsItab()
1188 }
1189
1190
1191 func (l *Loader) IsDict(i Sym) bool {
1192 if l.IsExternal(i) {
1193 return false
1194 }
1195 r, li := l.toLocal(i)
1196 return r.Sym(li).IsDict()
1197 }
1198
1199
1200 func (l *Loader) IsPkgInit(i Sym) bool {
1201 if l.IsExternal(i) {
1202 return false
1203 }
1204 r, li := l.toLocal(i)
1205 return r.Sym(li).IsPkgInit()
1206 }
1207
1208
1209 func (l *Loader) IsDeferReturnTramp(i Sym) bool {
1210 return l.deferReturnTramp[i]
1211 }
1212
1213
1214 func (l *Loader) SetIsDeferReturnTramp(i Sym, v bool) {
1215 l.deferReturnTramp[i] = v
1216 }
1217
1218
1219 func (l *Loader) growValues(reqLen int) {
1220 curLen := len(l.values)
1221 if reqLen > curLen {
1222 l.values = append(l.values, make([]int64, reqLen+1-curLen)...)
1223 }
1224 }
1225
1226
1227 func (l *Loader) SymValue(i Sym) int64 {
1228 return l.values[i]
1229 }
1230
1231
1232 func (l *Loader) SetSymValue(i Sym, val int64) {
1233 l.values[i] = val
1234 }
1235
1236
1237 func (l *Loader) AddToSymValue(i Sym, val int64) {
1238 l.values[i] += val
1239 }
1240
1241
1242 func (l *Loader) Data(i Sym) []byte {
1243 if l.IsExternal(i) {
1244 pp := l.getPayload(i)
1245 if pp != nil {
1246 return pp.data
1247 }
1248 return nil
1249 }
1250 r, li := l.toLocal(i)
1251 return r.Data(li)
1252 }
1253
1254
1255 func (l *Loader) DataString(i Sym) string {
1256 if l.IsExternal(i) {
1257 pp := l.getPayload(i)
1258 return string(pp.data)
1259 }
1260 r, li := l.toLocal(i)
1261 return r.DataString(li)
1262 }
1263
1264
1265
1266
1267 func (l *Loader) FreeData(i Sym) {
1268 if l.IsExternal(i) {
1269 pp := l.getPayload(i)
1270 if pp != nil {
1271 pp.data = nil
1272 }
1273 }
1274 }
1275
1276
1277 func (l *Loader) SymAlign(i Sym) int32 {
1278 if int(i) >= len(l.align) {
1279
1280
1281
1282 return 0
1283 }
1284
1285
1286
1287 abits := l.align[i]
1288 if abits == 0 {
1289 return 0
1290 }
1291 return int32(1 << (abits - 1))
1292 }
1293
1294
1295 func (l *Loader) SetSymAlign(i Sym, align int32) {
1296
1297 if align < 0 || align&(align-1) != 0 {
1298 panic("bad alignment value")
1299 }
1300 if int(i) >= len(l.align) {
1301 l.align = append(l.align, make([]uint8, l.NSym()-len(l.align))...)
1302 }
1303 if align == 0 {
1304 l.align[i] = 0
1305 }
1306 l.align[i] = uint8(bits.Len32(uint32(align)))
1307 }
1308
1309
1310 func (l *Loader) SymSect(i Sym) *sym.Section {
1311 if int(i) >= len(l.symSects) {
1312
1313
1314
1315 return nil
1316 }
1317 return l.sects[l.symSects[i]]
1318 }
1319
1320
1321 func (l *Loader) SetSymSect(i Sym, sect *sym.Section) {
1322 if int(i) >= len(l.symSects) {
1323 l.symSects = append(l.symSects, make([]uint16, l.NSym()-len(l.symSects))...)
1324 }
1325 l.symSects[i] = sect.Index
1326 }
1327
1328
1329 func (l *Loader) NewSection() *sym.Section {
1330 sect := new(sym.Section)
1331 idx := len(l.sects)
1332 if idx != int(uint16(idx)) {
1333 panic("too many sections created")
1334 }
1335 sect.Index = uint16(idx)
1336 l.sects = append(l.sects, sect)
1337 return sect
1338 }
1339
1340
1341
1342
1343 func (l *Loader) SymDynimplib(i Sym) string {
1344 return l.dynimplib[i]
1345 }
1346
1347
1348 func (l *Loader) SetSymDynimplib(i Sym, value string) {
1349
1350 if i >= Sym(len(l.objSyms)) || i == 0 {
1351 panic("bad symbol index in SetDynimplib")
1352 }
1353 if value == "" {
1354 delete(l.dynimplib, i)
1355 } else {
1356 l.dynimplib[i] = value
1357 }
1358 }
1359
1360
1361
1362
1363 func (l *Loader) SymDynimpvers(i Sym) string {
1364 return l.dynimpvers[i]
1365 }
1366
1367
1368 func (l *Loader) SetSymDynimpvers(i Sym, value string) {
1369
1370 if i >= Sym(len(l.objSyms)) || i == 0 {
1371 panic("bad symbol index in SetDynimpvers")
1372 }
1373 if value == "" {
1374 delete(l.dynimpvers, i)
1375 } else {
1376 l.dynimpvers[i] = value
1377 }
1378 }
1379
1380
1381
1382 func (l *Loader) SymExtname(i Sym) string {
1383 if s, ok := l.extname[i]; ok {
1384 return s
1385 }
1386 return l.SymName(i)
1387 }
1388
1389
1390 func (l *Loader) SetSymExtname(i Sym, value string) {
1391
1392 if i >= Sym(len(l.objSyms)) || i == 0 {
1393 panic("bad symbol index in SetExtname")
1394 }
1395 if value == "" {
1396 delete(l.extname, i)
1397 } else {
1398 l.extname[i] = value
1399 }
1400 }
1401
1402
1403
1404
1405
1406 func (l *Loader) SymElfType(i Sym) elf.SymType {
1407 if et, ok := l.elfType[i]; ok {
1408 return et
1409 }
1410 return elf.STT_NOTYPE
1411 }
1412
1413
1414 func (l *Loader) SetSymElfType(i Sym, et elf.SymType) {
1415
1416 if i >= Sym(len(l.objSyms)) || i == 0 {
1417 panic("bad symbol index in SetSymElfType")
1418 }
1419 if et == elf.STT_NOTYPE {
1420 delete(l.elfType, i)
1421 } else {
1422 l.elfType[i] = et
1423 }
1424 }
1425
1426
1427
1428 func (l *Loader) SymElfSym(i Sym) int32 {
1429 return l.elfSym[i]
1430 }
1431
1432
1433 func (l *Loader) SetSymElfSym(i Sym, es int32) {
1434 if i == 0 {
1435 panic("bad sym index")
1436 }
1437 if es == 0 {
1438 delete(l.elfSym, i)
1439 } else {
1440 l.elfSym[i] = es
1441 }
1442 }
1443
1444
1445
1446 func (l *Loader) SymLocalElfSym(i Sym) int32 {
1447 return l.localElfSym[i]
1448 }
1449
1450
1451 func (l *Loader) SetSymLocalElfSym(i Sym, es int32) {
1452 if i == 0 {
1453 panic("bad sym index")
1454 }
1455 if es == 0 {
1456 delete(l.localElfSym, i)
1457 } else {
1458 l.localElfSym[i] = es
1459 }
1460 }
1461
1462
1463 func (l *Loader) SymPlt(s Sym) int32 {
1464 if v, ok := l.plt[s]; ok {
1465 return v
1466 }
1467 return -1
1468 }
1469
1470
1471 func (l *Loader) SetPlt(i Sym, v int32) {
1472 if i >= Sym(len(l.objSyms)) || i == 0 {
1473 panic("bad symbol for SetPlt")
1474 }
1475 if v == -1 {
1476 delete(l.plt, i)
1477 } else {
1478 l.plt[i] = v
1479 }
1480 }
1481
1482
1483 func (l *Loader) SymGot(s Sym) int32 {
1484 if v, ok := l.got[s]; ok {
1485 return v
1486 }
1487 return -1
1488 }
1489
1490
1491 func (l *Loader) SetGot(i Sym, v int32) {
1492 if i >= Sym(len(l.objSyms)) || i == 0 {
1493 panic("bad symbol for SetGot")
1494 }
1495 if v == -1 {
1496 delete(l.got, i)
1497 } else {
1498 l.got[i] = v
1499 }
1500 }
1501
1502
1503 func (l *Loader) SymDynid(i Sym) int32 {
1504 if s, ok := l.dynid[i]; ok {
1505 return s
1506 }
1507 return -1
1508 }
1509
1510
1511 func (l *Loader) SetSymDynid(i Sym, val int32) {
1512
1513 if i >= Sym(len(l.objSyms)) || i == 0 {
1514 panic("bad symbol index in SetSymDynid")
1515 }
1516 if val == -1 {
1517 delete(l.dynid, i)
1518 } else {
1519 l.dynid[i] = val
1520 }
1521 }
1522
1523
1524
1525
1526 func (l *Loader) DynidSyms() []Sym {
1527 sl := make([]Sym, 0, len(l.dynid))
1528 for s := range l.dynid {
1529 sl = append(sl, s)
1530 }
1531 sort.Slice(sl, func(i, j int) bool { return sl[i] < sl[j] })
1532 return sl
1533 }
1534
1535
1536
1537
1538
1539
1540
1541 func (l *Loader) SymGoType(i Sym) Sym { return l.aux1(i, goobj.AuxGotype) }
1542
1543
1544
1545 func (l *Loader) SymUnit(i Sym) *sym.CompilationUnit {
1546 if l.IsExternal(i) {
1547 pp := l.getPayload(i)
1548 if pp.objidx != 0 {
1549 r := l.objs[pp.objidx]
1550 return r.unit
1551 }
1552 return nil
1553 }
1554 r, _ := l.toLocal(i)
1555 return r.unit
1556 }
1557
1558
1559
1560
1561
1562
1563 func (l *Loader) SymPkg(i Sym) string {
1564 if f, ok := l.symPkg[i]; ok {
1565 return f
1566 }
1567 if l.IsExternal(i) {
1568 pp := l.getPayload(i)
1569 if pp.objidx != 0 {
1570 r := l.objs[pp.objidx]
1571 return r.unit.Lib.Pkg
1572 }
1573 return ""
1574 }
1575 r, _ := l.toLocal(i)
1576 return r.unit.Lib.Pkg
1577 }
1578
1579
1580
1581
1582 func (l *Loader) SetSymPkg(i Sym, pkg string) {
1583
1584 if i >= Sym(len(l.objSyms)) || i == 0 {
1585 panic("bad symbol index in SetSymPkg")
1586 }
1587 l.symPkg[i] = pkg
1588 }
1589
1590
1591
1592
1593
1594 func (l *Loader) SymLocalentry(i Sym) uint8 {
1595 return l.localentry[i]
1596 }
1597
1598
1599 func (l *Loader) SetSymLocalentry(i Sym, value uint8) {
1600
1601 if i >= Sym(len(l.objSyms)) || i == 0 {
1602 panic("bad symbol index in SetSymLocalentry")
1603 }
1604 if value == 0 {
1605 delete(l.localentry, i)
1606 } else {
1607 l.localentry[i] = value
1608 }
1609 }
1610
1611
1612 func (l *Loader) NAux(i Sym) int {
1613 if l.IsExternal(i) {
1614 return 0
1615 }
1616 r, li := l.toLocal(i)
1617 return r.NAux(li)
1618 }
1619
1620
1621 func (l *Loader) Aux(i Sym, j int) Aux {
1622 if l.IsExternal(i) {
1623 return Aux{}
1624 }
1625 r, li := l.toLocal(i)
1626 if j >= r.NAux(li) {
1627 return Aux{}
1628 }
1629 return Aux{r.Aux(li, j), r, l}
1630 }
1631
1632
1633
1634
1635
1636
1637
1638 func (l *Loader) WasmImportSym(fnSymIdx Sym) Sym {
1639 if !l.SymType(fnSymIdx).IsText() {
1640 log.Fatalf("error: non-function sym %d/%s t=%s passed to WasmImportSym", fnSymIdx, l.SymName(fnSymIdx), l.SymType(fnSymIdx).String())
1641 }
1642 return l.aux1(fnSymIdx, goobj.AuxWasmImport)
1643 }
1644
1645 func (l *Loader) WasmTypeSym(s Sym) Sym {
1646 return l.aux1(s, goobj.AuxWasmType)
1647 }
1648
1649
1650
1651 func (l *Loader) SEHUnwindSym(fnSymIdx Sym) Sym {
1652 if !l.SymType(fnSymIdx).IsText() {
1653 log.Fatalf("error: non-function sym %d/%s t=%s passed to SEHUnwindSym", fnSymIdx, l.SymName(fnSymIdx), l.SymType(fnSymIdx).String())
1654 }
1655
1656 return l.aux1(fnSymIdx, goobj.AuxSehUnwindInfo)
1657 }
1658
1659
1660
1661
1662
1663
1664 func (l *Loader) GetFuncDwarfAuxSyms(fnSymIdx Sym) (auxDwarfInfo, auxDwarfLoc, auxDwarfRanges, auxDwarfLines Sym) {
1665 if !l.SymType(fnSymIdx).IsText() {
1666 log.Fatalf("error: non-function sym %d/%s t=%s passed to GetFuncDwarfAuxSyms", fnSymIdx, l.SymName(fnSymIdx), l.SymType(fnSymIdx).String())
1667 }
1668 r, auxs := l.auxs(fnSymIdx)
1669
1670 for i := range auxs {
1671 a := &auxs[i]
1672 switch a.Type() {
1673 case goobj.AuxDwarfInfo:
1674 auxDwarfInfo = l.resolve(r, a.Sym())
1675 if l.SymType(auxDwarfInfo) != sym.SDWARFFCN {
1676 panic("aux dwarf info sym with wrong type")
1677 }
1678 case goobj.AuxDwarfLoc:
1679 auxDwarfLoc = l.resolve(r, a.Sym())
1680 if l.SymType(auxDwarfLoc) != sym.SDWARFLOC {
1681 panic("aux dwarf loc sym with wrong type")
1682 }
1683 case goobj.AuxDwarfRanges:
1684 auxDwarfRanges = l.resolve(r, a.Sym())
1685 if l.SymType(auxDwarfRanges) != sym.SDWARFRANGE {
1686 panic("aux dwarf ranges sym with wrong type")
1687 }
1688 case goobj.AuxDwarfLines:
1689 auxDwarfLines = l.resolve(r, a.Sym())
1690 if l.SymType(auxDwarfLines) != sym.SDWARFLINES {
1691 panic("aux dwarf lines sym with wrong type")
1692 }
1693 }
1694 }
1695 return
1696 }
1697
1698 func (l *Loader) GetVarDwarfAuxSym(i Sym) Sym {
1699 aux := l.aux1(i, goobj.AuxDwarfInfo)
1700 if aux != 0 && l.SymType(aux) != sym.SDWARFVAR {
1701 fmt.Println(l.SymName(i), l.SymType(i), l.SymType(aux), sym.SDWARFVAR)
1702 panic("aux dwarf info sym with wrong type")
1703 }
1704 return aux
1705 }
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721 func (l *Loader) AddInteriorSym(container Sym, interior Sym) {
1722
1723
1724
1725
1726
1727 if l.SymSize(container) == 0 && len(l.Data(container)) == 0 {
1728 panic("unexpected empty container symbol")
1729 }
1730
1731
1732 if len(l.Data(interior)) != 0 {
1733 panic("unexpected non-empty interior symbol")
1734 }
1735
1736 if l.AttrNotInSymbolTable(interior) {
1737 panic("interior symbol must be in symtab")
1738 }
1739
1740 if l.OuterSym(container) != 0 {
1741 panic("outer has outer itself")
1742 }
1743
1744 if l.SubSym(interior) != 0 {
1745 panic("sub set for subsym")
1746 }
1747
1748 if l.OuterSym(interior) != 0 {
1749 panic("outer already set for subsym")
1750 }
1751 l.sub[interior] = l.sub[container]
1752 l.sub[container] = interior
1753 l.outer[interior] = container
1754 }
1755
1756
1757 func (l *Loader) OuterSym(i Sym) Sym {
1758 return l.outer[i]
1759 }
1760
1761
1762 func (l *Loader) SubSym(i Sym) Sym {
1763 return l.sub[i]
1764 }
1765
1766
1767 func (l *Loader) growOuter(reqLen int) {
1768 curLen := len(l.outer)
1769 if reqLen > curLen {
1770 l.outer = append(l.outer, make([]Sym, reqLen-curLen)...)
1771 }
1772 }
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785 func (l *Loader) SetCarrierSym(s Sym, c Sym) {
1786 if c == 0 {
1787 panic("invalid carrier in SetCarrierSym")
1788 }
1789 if s == 0 {
1790 panic("invalid sub-symbol in SetCarrierSym")
1791 }
1792
1793
1794
1795 if len(l.Data(c)) != 0 {
1796 panic("unexpected non-empty carrier symbol")
1797 }
1798 l.outer[s] = c
1799
1800
1801 if l.outer[c] != 0 {
1802 panic("invalid nested carrier sym")
1803 }
1804 }
1805
1806
1807 func (l *Loader) InitReachable() {
1808 l.growAttrBitmaps(l.NSym() + 1)
1809 }
1810
1811 type symWithVal struct {
1812 s Sym
1813 v int64
1814 }
1815 type bySymValue []symWithVal
1816
1817 func (s bySymValue) Len() int { return len(s) }
1818 func (s bySymValue) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
1819 func (s bySymValue) Less(i, j int) bool { return s[i].v < s[j].v }
1820
1821
1822
1823
1824 func (l *Loader) SortSub(s Sym) Sym {
1825
1826 if s == 0 || l.sub[s] == 0 {
1827 return s
1828 }
1829
1830
1831
1832
1833 sl := []symWithVal{}
1834 for ss := l.sub[s]; ss != 0; ss = l.sub[ss] {
1835 sl = append(sl, symWithVal{s: ss, v: l.SymValue(ss)})
1836 }
1837 sort.Stable(bySymValue(sl))
1838
1839
1840 ns := Sym(0)
1841 for i := len(sl) - 1; i >= 0; i-- {
1842 s := sl[i].s
1843 l.sub[s] = ns
1844 ns = s
1845 }
1846
1847
1848 l.sub[s] = sl[0].s
1849 return sl[0].s
1850 }
1851
1852
1853 func (l *Loader) SortSyms(ss []Sym) {
1854 sort.SliceStable(ss, func(i, j int) bool { return l.SymValue(ss[i]) < l.SymValue(ss[j]) })
1855 }
1856
1857
1858 func (l *Loader) growAttrBitmaps(reqLen int) {
1859 if reqLen > l.attrReachable.Len() {
1860
1861 l.attrReachable = growBitmap(reqLen, l.attrReachable)
1862 l.attrOnList = growBitmap(reqLen, l.attrOnList)
1863 l.attrLocal = growBitmap(reqLen, l.attrLocal)
1864 l.attrNotInSymbolTable = growBitmap(reqLen, l.attrNotInSymbolTable)
1865 l.attrUsedInIface = growBitmap(reqLen, l.attrUsedInIface)
1866 l.attrSpecial = growBitmap(reqLen, l.attrSpecial)
1867 }
1868 l.growExtAttrBitmaps()
1869 }
1870
1871 func (l *Loader) growExtAttrBitmaps() {
1872
1873 extReqLen := len(l.payloads)
1874 if extReqLen > l.attrVisibilityHidden.Len() {
1875 l.attrVisibilityHidden = growBitmap(extReqLen, l.attrVisibilityHidden)
1876 l.attrDuplicateOK = growBitmap(extReqLen, l.attrDuplicateOK)
1877 l.attrShared = growBitmap(extReqLen, l.attrShared)
1878 l.attrExternal = growBitmap(extReqLen, l.attrExternal)
1879 l.generatedSyms = growBitmap(extReqLen, l.generatedSyms)
1880 }
1881 }
1882
1883 func (relocs *Relocs) Count() int { return len(relocs.rs) }
1884
1885
1886 func (relocs *Relocs) At(j int) Reloc {
1887 if relocs.l.isExtReader(relocs.r) {
1888 return Reloc{&relocs.rs[j], relocs.r, relocs.l}
1889 }
1890 return Reloc{&relocs.rs[j], relocs.r, relocs.l}
1891 }
1892
1893
1894 func (l *Loader) Relocs(i Sym) Relocs {
1895 r, li := l.toLocal(i)
1896 if r == nil {
1897 panic(fmt.Sprintf("trying to get oreader for invalid sym %d\n\n", i))
1898 }
1899 return l.relocs(r, li)
1900 }
1901
1902
1903 func (l *Loader) relocs(r *oReader, li uint32) Relocs {
1904 var rs []goobj.Reloc
1905 if l.isExtReader(r) {
1906 pp := l.payloads[li]
1907 rs = pp.relocs
1908 } else {
1909 rs = r.Relocs(li)
1910 }
1911 return Relocs{
1912 rs: rs,
1913 li: li,
1914 r: r,
1915 l: l,
1916 }
1917 }
1918
1919 func (l *Loader) auxs(i Sym) (*oReader, []goobj.Aux) {
1920 if l.IsExternal(i) {
1921 pp := l.getPayload(i)
1922 return l.objs[pp.objidx], pp.auxs
1923 } else {
1924 r, li := l.toLocal(i)
1925 return r, r.Auxs(li)
1926 }
1927 }
1928
1929
1930 func (l *Loader) aux1(i Sym, t uint8) Sym {
1931 r, auxs := l.auxs(i)
1932 for j := range auxs {
1933 a := &auxs[j]
1934 if a.Type() == t {
1935 return l.resolve(r, a.Sym())
1936 }
1937 }
1938 return 0
1939 }
1940
1941 func (l *Loader) Pcsp(i Sym) Sym { return l.aux1(i, goobj.AuxPcsp) }
1942
1943
1944
1945 func (l *Loader) PcdataAuxs(i Sym, tmp []Sym) (pcsp, pcfile, pcline, pcinline Sym, pcdata []Sym) {
1946 pcdata = tmp[:0]
1947 r, auxs := l.auxs(i)
1948 for j := range auxs {
1949 a := &auxs[j]
1950 switch a.Type() {
1951 case goobj.AuxPcsp:
1952 pcsp = l.resolve(r, a.Sym())
1953 case goobj.AuxPcline:
1954 pcline = l.resolve(r, a.Sym())
1955 case goobj.AuxPcfile:
1956 pcfile = l.resolve(r, a.Sym())
1957 case goobj.AuxPcinline:
1958 pcinline = l.resolve(r, a.Sym())
1959 case goobj.AuxPcdata:
1960 pcdata = append(pcdata, l.resolve(r, a.Sym()))
1961 }
1962 }
1963 return
1964 }
1965
1966
1967 func (l *Loader) NumPcdata(i Sym) int {
1968 n := 0
1969 _, auxs := l.auxs(i)
1970 for j := range auxs {
1971 a := &auxs[j]
1972 if a.Type() == goobj.AuxPcdata {
1973 n++
1974 }
1975 }
1976 return n
1977 }
1978
1979
1980
1981 func (l *Loader) Funcdata(i Sym, tmp []Sym) []Sym {
1982 fd := tmp[:0]
1983 r, auxs := l.auxs(i)
1984 for j := range auxs {
1985 a := &auxs[j]
1986 if a.Type() == goobj.AuxFuncdata {
1987 fd = append(fd, l.resolve(r, a.Sym()))
1988 }
1989 }
1990 return fd
1991 }
1992
1993
1994 func (l *Loader) NumFuncdata(i Sym) int {
1995 n := 0
1996 _, auxs := l.auxs(i)
1997 for j := range auxs {
1998 a := &auxs[j]
1999 if a.Type() == goobj.AuxFuncdata {
2000 n++
2001 }
2002 }
2003 return n
2004 }
2005
2006
2007 type FuncInfo struct {
2008 l *Loader
2009 r *oReader
2010 data []byte
2011 lengths goobj.FuncInfoLengths
2012 }
2013
2014 func (fi *FuncInfo) Valid() bool { return fi.r != nil }
2015
2016 func (fi *FuncInfo) Args() int {
2017 return int((*goobj.FuncInfo)(nil).ReadArgs(fi.data))
2018 }
2019
2020 func (fi *FuncInfo) Locals() int {
2021 return int((*goobj.FuncInfo)(nil).ReadLocals(fi.data))
2022 }
2023
2024 func (fi *FuncInfo) FuncID() abi.FuncID {
2025 return (*goobj.FuncInfo)(nil).ReadFuncID(fi.data)
2026 }
2027
2028 func (fi *FuncInfo) FuncFlag() abi.FuncFlag {
2029 return (*goobj.FuncInfo)(nil).ReadFuncFlag(fi.data)
2030 }
2031
2032 func (fi *FuncInfo) StartLine() int32 {
2033 return (*goobj.FuncInfo)(nil).ReadStartLine(fi.data)
2034 }
2035
2036
2037
2038 func (fi *FuncInfo) Preload() {
2039 fi.lengths = (*goobj.FuncInfo)(nil).ReadFuncInfoLengths(fi.data)
2040 }
2041
2042 func (fi *FuncInfo) NumFile() uint32 {
2043 if !fi.lengths.Initialized {
2044 panic("need to call Preload first")
2045 }
2046 return fi.lengths.NumFile
2047 }
2048
2049 func (fi *FuncInfo) File(k int) goobj.CUFileIndex {
2050 if !fi.lengths.Initialized {
2051 panic("need to call Preload first")
2052 }
2053 return (*goobj.FuncInfo)(nil).ReadFile(fi.data, fi.lengths.FileOff, uint32(k))
2054 }
2055
2056
2057
2058
2059 func (fi *FuncInfo) TopFrame() bool {
2060 return (fi.FuncFlag() & abi.FuncFlagTopFrame) != 0
2061 }
2062
2063 type InlTreeNode struct {
2064 Parent int32
2065 File goobj.CUFileIndex
2066 Line int32
2067 Func Sym
2068 ParentPC int32
2069 }
2070
2071 func (fi *FuncInfo) NumInlTree() uint32 {
2072 if !fi.lengths.Initialized {
2073 panic("need to call Preload first")
2074 }
2075 return fi.lengths.NumInlTree
2076 }
2077
2078 func (fi *FuncInfo) InlTree(k int) InlTreeNode {
2079 if !fi.lengths.Initialized {
2080 panic("need to call Preload first")
2081 }
2082 node := (*goobj.FuncInfo)(nil).ReadInlTree(fi.data, fi.lengths.InlTreeOff, uint32(k))
2083 return InlTreeNode{
2084 Parent: node.Parent,
2085 File: node.File,
2086 Line: node.Line,
2087 Func: fi.l.resolve(fi.r, node.Func),
2088 ParentPC: node.ParentPC,
2089 }
2090 }
2091
2092 func (l *Loader) FuncInfo(i Sym) FuncInfo {
2093 r, auxs := l.auxs(i)
2094 for j := range auxs {
2095 a := &auxs[j]
2096 if a.Type() == goobj.AuxFuncInfo {
2097 b := r.Data(a.Sym().SymIdx)
2098 return FuncInfo{l, r, b, goobj.FuncInfoLengths{}}
2099 }
2100 }
2101 return FuncInfo{}
2102 }
2103
2104
2105
2106
2107
2108
2109 func (l *Loader) Preload(localSymVersion int, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64) goobj.FingerprintType {
2110 roObject, readonly, err := f.Slice(uint64(length))
2111 if err != nil {
2112 log.Fatal("cannot read object file:", err)
2113 }
2114 r := goobj.NewReaderFromBytes(roObject, readonly)
2115 if r == nil {
2116 if len(roObject) >= 8 && bytes.Equal(roObject[:8], []byte("\x00go114ld")) {
2117 log.Fatalf("found object file %s in old format", f.File().Name())
2118 }
2119 panic("cannot read object file")
2120 }
2121 pkgprefix := objabi.PathToPrefix(lib.Pkg) + "."
2122 ndef := r.NSym()
2123 nhashed64def := r.NHashed64def()
2124 nhasheddef := r.NHasheddef()
2125 or := &oReader{
2126 Reader: r,
2127 unit: unit,
2128 version: localSymVersion,
2129 pkgprefix: pkgprefix,
2130 syms: make([]Sym, ndef+nhashed64def+nhasheddef+r.NNonpkgdef()+r.NNonpkgref()),
2131 ndef: ndef,
2132 nhasheddef: nhasheddef,
2133 nhashed64def: nhashed64def,
2134 objidx: uint32(len(l.objs)),
2135 }
2136
2137 if r.Unlinkable() {
2138 log.Fatalf("link: unlinkable object (from package %s) - compiler requires -p flag", lib.Pkg)
2139 }
2140
2141
2142 lib.Autolib = append(lib.Autolib, r.Autolib()...)
2143
2144
2145 nfile := r.NFile()
2146 unit.FileTable = make([]string, nfile)
2147 for i := range unit.FileTable {
2148 unit.FileTable[i] = r.File(i)
2149 }
2150
2151 l.addObj(lib.Pkg, or)
2152
2153
2154 f.MustSeek(length, io.SeekCurrent)
2155
2156 return r.Fingerprint()
2157 }
2158
2159
2160 type loadState struct {
2161 l *Loader
2162 hashed64Syms map[uint64]symAndSize
2163 hashedSyms map[goobj.HashType]symAndSize
2164
2165 linknameVarRefs []linknameVarRef
2166 }
2167
2168 type linknameVarRef struct {
2169 pkg string
2170 name string
2171 sym Sym
2172 }
2173
2174
2175 func (st *loadState) preloadSyms(r *oReader, kind int) {
2176 l := st.l
2177 var start, end uint32
2178 switch kind {
2179 case pkgDef:
2180 start = 0
2181 end = uint32(r.ndef)
2182 case hashed64Def:
2183 start = uint32(r.ndef)
2184 end = uint32(r.ndef + r.nhashed64def)
2185 case hashedDef:
2186 start = uint32(r.ndef + r.nhashed64def)
2187 end = uint32(r.ndef + r.nhashed64def + r.nhasheddef)
2188 case nonPkgDef:
2189 start = uint32(r.ndef + r.nhashed64def + r.nhasheddef)
2190 end = uint32(r.ndef + r.nhashed64def + r.nhasheddef + r.NNonpkgdef())
2191 default:
2192 panic("preloadSyms: bad kind")
2193 }
2194 l.growAttrBitmaps(len(l.objSyms) + int(end-start))
2195 loadingRuntimePkg := r.unit.Lib.Pkg == "runtime"
2196 for i := start; i < end; i++ {
2197 osym := r.Sym(i)
2198 var name string
2199 var v int
2200 if kind != hashed64Def && kind != hashedDef {
2201 name = osym.Name(r.Reader)
2202 v = abiToVer(osym.ABI(), r.version)
2203 }
2204 gi := st.addSym(name, v, r, i, kind, osym)
2205 r.syms[i] = gi
2206 if kind == nonPkgDef && osym.IsLinkname() && r.DataSize(i) == 0 && strings.Contains(name, ".") {
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217 st.linknameVarRefs = append(st.linknameVarRefs, linknameVarRef{r.unit.Lib.Pkg, name, gi})
2218 }
2219 if osym.Local() {
2220 l.SetAttrLocal(gi, true)
2221 }
2222 if osym.UsedInIface() {
2223 l.SetAttrUsedInIface(gi, true)
2224 }
2225 if strings.HasPrefix(name, "runtime.") ||
2226 (loadingRuntimePkg && strings.HasPrefix(name, "type:")) {
2227 if bi := goobj.BuiltinIdx(name, int(osym.ABI())); bi != -1 {
2228
2229 l.builtinSyms[bi] = gi
2230 }
2231 }
2232 if a := int32(osym.Align()); a != 0 && a > l.SymAlign(gi) {
2233 l.SetSymAlign(gi, a)
2234 }
2235 if osym.WasmExport() {
2236 l.WasmExports = append(l.WasmExports, gi)
2237 }
2238 }
2239 }
2240
2241
2242
2243 func (l *Loader) LoadSyms(arch *sys.Arch) {
2244
2245
2246
2247 var symSize, hashedSize, hashed64Size int
2248 for _, r := range l.objs[goObjStart:] {
2249 symSize += r.ndef + r.nhasheddef/2 + r.nhashed64def/2 + r.NNonpkgdef()
2250 hashedSize += r.nhasheddef / 2
2251 hashed64Size += r.nhashed64def / 2
2252 }
2253
2254 l.objSyms = make([]objSym, 1, symSize)
2255
2256 st := loadState{
2257 l: l,
2258 hashed64Syms: make(map[uint64]symAndSize, hashed64Size),
2259 hashedSyms: make(map[goobj.HashType]symAndSize, hashedSize),
2260 }
2261
2262 for _, r := range l.objs[goObjStart:] {
2263 st.preloadSyms(r, pkgDef)
2264 }
2265 l.npkgsyms = l.NSym()
2266 for _, r := range l.objs[goObjStart:] {
2267 st.preloadSyms(r, hashed64Def)
2268 st.preloadSyms(r, hashedDef)
2269 st.preloadSyms(r, nonPkgDef)
2270 }
2271 for _, vr := range st.linknameVarRefs {
2272 l.checkLinkname(vr.pkg, vr.name, vr.sym)
2273 }
2274 l.nhashedsyms = len(st.hashed64Syms) + len(st.hashedSyms)
2275 for _, r := range l.objs[goObjStart:] {
2276 loadObjRefs(l, r, arch)
2277 }
2278 l.values = make([]int64, l.NSym(), l.NSym()+1000)
2279 l.outer = make([]Sym, l.NSym(), l.NSym()+1000)
2280 }
2281
2282 func loadObjRefs(l *Loader, r *oReader, arch *sys.Arch) {
2283
2284 ndef := uint32(r.NAlldef())
2285 for i, n := uint32(0), uint32(r.NNonpkgref()); i < n; i++ {
2286 osym := r.Sym(ndef + i)
2287 name := osym.Name(r.Reader)
2288 v := abiToVer(osym.ABI(), r.version)
2289 gi := l.LookupOrCreateSym(name, v)
2290 r.syms[ndef+i] = gi
2291 if osym.IsLinkname() {
2292
2293
2294
2295
2296 l.checkLinkname(r.unit.Lib.Pkg, name, gi)
2297 }
2298 if osym.Local() {
2299 l.SetAttrLocal(gi, true)
2300 }
2301 if osym.UsedInIface() {
2302 l.SetAttrUsedInIface(gi, true)
2303 }
2304 }
2305
2306
2307 npkg := r.NPkg()
2308 r.pkg = make([]uint32, npkg)
2309 for i := 1; i < npkg; i++ {
2310 pkg := r.Pkg(i)
2311 objidx, ok := l.objByPkg[pkg]
2312 if !ok {
2313 log.Fatalf("%v: reference to nonexistent package %s", r.unit.Lib, pkg)
2314 }
2315 r.pkg[i] = objidx
2316 }
2317
2318
2319 for i, n := 0, r.NRefFlags(); i < n; i++ {
2320 rf := r.RefFlags(i)
2321 gi := l.resolve(r, rf.Sym())
2322 if rf.Flag2()&goobj.SymFlagUsedInIface != 0 {
2323 l.SetAttrUsedInIface(gi, true)
2324 }
2325 }
2326 }
2327
2328 func abiToVer(abi uint16, localSymVersion int) int {
2329 var v int
2330 if abi == goobj.SymABIstatic {
2331
2332 v = localSymVersion
2333 } else if abiver := sym.ABIToVersion(obj.ABI(abi)); abiver != -1 {
2334
2335 v = abiver
2336 } else {
2337 log.Fatalf("invalid symbol ABI: %d", abi)
2338 }
2339 return v
2340 }
2341
2342
2343
2344
2345
2346
2347
2348 var blockedLinknames = map[string][]string{
2349
2350 "runtime.coroswitch": {"iter"},
2351 "runtime.newcoro": {"iter"},
2352
2353 "go:fipsinfo": {"crypto/internal/fips140/check"},
2354
2355
2356 "crypto/internal/fips140.fatal": {"crypto/internal/fips140"},
2357 "crypto/internal/fips140.getIndicator": {"crypto/internal/fips140"},
2358 "crypto/internal/fips140.setIndicator": {"crypto/internal/fips140"},
2359 "crypto/internal/sysrand.fatal": {"crypto/internal/sysrand"},
2360 "crypto/rand.fatal": {"crypto/rand"},
2361 "internal/runtime/maps.errNilAssign": {"internal/runtime/maps"},
2362 "internal/runtime/maps.fatal": {"internal/runtime/maps"},
2363 "internal/runtime/maps.mapKeyError": {"internal/runtime/maps"},
2364 "internal/runtime/maps.newarray": {"internal/runtime/maps"},
2365 "internal/runtime/maps.newobject": {"internal/runtime/maps"},
2366 "internal/runtime/maps.typedmemclr": {"internal/runtime/maps"},
2367 "internal/runtime/maps.typedmemmove": {"internal/runtime/maps"},
2368 "internal/sync.fatal": {"internal/sync"},
2369 "internal/sync.runtime_canSpin": {"internal/sync"},
2370 "internal/sync.runtime_doSpin": {"internal/sync"},
2371 "internal/sync.runtime_nanotime": {"internal/sync"},
2372 "internal/sync.runtime_Semrelease": {"internal/sync"},
2373 "internal/sync.runtime_SemacquireMutex": {"internal/sync"},
2374 "internal/sync.throw": {"internal/sync"},
2375 "internal/synctest.Run": {"internal/synctest"},
2376 "internal/synctest.Wait": {"internal/synctest"},
2377 "internal/synctest.acquire": {"internal/synctest"},
2378 "internal/synctest.release": {"internal/synctest"},
2379 "internal/synctest.inBubble": {"internal/synctest"},
2380 "runtime.getStaticuint64s": {"reflect"},
2381 "sync.runtime_SemacquireWaitGroup": {"sync"},
2382 "time.runtimeNow": {"time"},
2383 "time.runtimeNano": {"time"},
2384
2385
2386 "runtime.mapaccess1": {"runtime"},
2387 "runtime.mapaccess1_fast32": {"runtime"},
2388 "runtime.mapaccess1_fast64": {"runtime"},
2389 "runtime.mapaccess1_faststr": {"runtime"},
2390 "runtime.mapdelete_fast32": {"runtime"},
2391 "runtime.mapdelete_fast64": {"runtime"},
2392 "runtime.mapdelete_faststr": {"runtime"},
2393 }
2394
2395
2396 func (l *Loader) checkLinkname(pkg, name string, s Sym) {
2397 if l.flags&FlagCheckLinkname == 0 {
2398 return
2399 }
2400
2401 error := func() {
2402 log.Fatalf("%s: invalid reference to %s", pkg, name)
2403 }
2404 pkgs, ok := blockedLinknames[name]
2405 if ok {
2406 for _, p := range pkgs {
2407 if pkg == p {
2408 return
2409 }
2410
2411
2412 if strings.HasPrefix(pkg, "crypto/internal/fips140/v") {
2413 parts := strings.Split(pkg, "/")
2414 parts = append(parts[:3], parts[4:]...)
2415 pkg := strings.Join(parts, "/")
2416 if pkg == p {
2417 return
2418 }
2419 }
2420 }
2421 error()
2422 }
2423 r, li := l.toLocal(s)
2424 if r == l.extReader {
2425 return
2426 }
2427 if !r.Std() {
2428 return
2429 }
2430 if r.unit.Lib.Pkg == pkg {
2431 return
2432 }
2433 osym := r.Sym(li)
2434 if osym.IsLinkname() || osym.ABIWrapper() {
2435
2436
2437
2438
2439
2440 return
2441 }
2442 error()
2443 }
2444
2445
2446
2447
2448
2449 func (l *Loader) TopLevelSym(s Sym) bool {
2450 return topLevelSym(l.SymName(s), l.SymType(s))
2451 }
2452
2453
2454
2455
2456
2457 func topLevelSym(sname string, skind sym.SymKind) bool {
2458 if sname != "" {
2459 return true
2460 }
2461 switch skind {
2462 case sym.SDWARFFCN, sym.SDWARFABSFCN, sym.SDWARFTYPE, sym.SDWARFCONST, sym.SDWARFCUINFO, sym.SDWARFRANGE, sym.SDWARFLOC, sym.SDWARFLINES, sym.SGOFUNC:
2463 return true
2464 default:
2465 return false
2466 }
2467 }
2468
2469
2470
2471
2472
2473
2474
2475
2476 func (l *Loader) cloneToExternal(symIdx Sym) {
2477 if l.IsExternal(symIdx) {
2478 panic("sym is already external, no need for clone")
2479 }
2480
2481
2482 r, li := l.toLocal(symIdx)
2483 osym := r.Sym(li)
2484 sname := osym.Name(r.Reader)
2485 sver := abiToVer(osym.ABI(), r.version)
2486 skind := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
2487
2488
2489 pi := l.newPayload(sname, sver)
2490 pp := l.payloads[pi]
2491 pp.kind = skind
2492 pp.ver = sver
2493 pp.size = int64(osym.Siz())
2494 pp.objidx = r.objidx
2495
2496
2497
2498 if li < uint32(r.NAlldef()) {
2499
2500
2501 relocs := l.Relocs(symIdx)
2502 pp.relocs = make([]goobj.Reloc, relocs.Count())
2503 for i := range pp.relocs {
2504
2505
2506 rel := relocs.At(i)
2507 pp.relocs[i].Set(rel.Off(), rel.Siz(), uint16(rel.Type()), rel.Add(), goobj.SymRef{PkgIdx: 0, SymIdx: uint32(rel.Sym())})
2508 }
2509
2510
2511 pp.data = r.Data(li)
2512 }
2513
2514
2515
2516 auxs := r.Auxs(li)
2517 pp.auxs = auxs
2518
2519
2520
2521
2522 l.objSyms[symIdx] = objSym{l.extReader.objidx, uint32(pi)}
2523 l.extReader.syms = append(l.extReader.syms, symIdx)
2524
2525
2526 l.SetAttrDuplicateOK(symIdx, r.Sym(li).Dupok())
2527 l.SetAttrShared(symIdx, r.Shared())
2528 }
2529
2530
2531
2532
2533
2534
2535
2536 func (l *Loader) CopySym(src, dst Sym) {
2537 if !l.IsExternal(dst) {
2538 panic("dst is not external")
2539 }
2540 if !l.IsExternal(src) {
2541 panic("src is not external")
2542 }
2543 l.payloads[l.extIndex(dst)] = l.payloads[l.extIndex(src)]
2544 l.SetSymPkg(dst, l.SymPkg(src))
2545
2546 }
2547
2548
2549
2550 func (l *Loader) CreateExtSym(name string, ver int) Sym {
2551 return l.newExtSym(name, ver)
2552 }
2553
2554
2555
2556 func (l *Loader) CreateStaticSym(name string) Sym {
2557
2558
2559 l.anonVersion--
2560 return l.newExtSym(name, l.anonVersion)
2561 }
2562
2563 func (l *Loader) FreeSym(i Sym) {
2564 if l.IsExternal(i) {
2565 pp := l.getPayload(i)
2566 *pp = extSymPayload{}
2567 }
2568 }
2569
2570
2571
2572 type relocId struct {
2573 sym Sym
2574 ridx int
2575 }
2576
2577
2578
2579 func (l *Loader) SetRelocVariant(s Sym, ri int, v sym.RelocVariant) {
2580
2581 if relocs := l.Relocs(s); ri >= relocs.Count() {
2582 panic("invalid relocation ID")
2583 }
2584 if l.relocVariant == nil {
2585 l.relocVariant = make(map[relocId]sym.RelocVariant)
2586 }
2587 if v != 0 {
2588 l.relocVariant[relocId{s, ri}] = v
2589 } else {
2590 delete(l.relocVariant, relocId{s, ri})
2591 }
2592 }
2593
2594
2595
2596 func (l *Loader) RelocVariant(s Sym, ri int) sym.RelocVariant {
2597 return l.relocVariant[relocId{s, ri}]
2598 }
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610 func (l *Loader) UndefinedRelocTargets(limit int) ([]Sym, []Sym) {
2611 result, fromr := []Sym{}, []Sym{}
2612 outerloop:
2613 for si := Sym(1); si < Sym(len(l.objSyms)); si++ {
2614 relocs := l.Relocs(si)
2615 for ri := 0; ri < relocs.Count(); ri++ {
2616 r := relocs.At(ri)
2617 rs := r.Sym()
2618 if rs != 0 && l.SymType(rs) == sym.SXREF && l.SymName(rs) != ".got" {
2619 result = append(result, rs)
2620 fromr = append(fromr, si)
2621 if limit != -1 && len(result) >= limit {
2622 break outerloop
2623 }
2624 }
2625 }
2626 }
2627 return result, fromr
2628 }
2629
2630
2631
2632
2633
2634 func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool, extsyms []Sym) []Sym {
2635
2636
2637 for _, lib := range libs {
2638 if len(lib.Textp) != 0 {
2639 panic("expected empty Textp slice for library")
2640 }
2641 if len(lib.DupTextSyms) != 0 {
2642 panic("expected empty DupTextSyms slice for library")
2643 }
2644 }
2645
2646
2647
2648
2649
2650
2651 assignedToUnit := MakeBitmap(l.NSym() + 1)
2652
2653
2654 textp := []Sym{}
2655 for _, sym := range extsyms {
2656 if !l.attrReachable.Has(sym) {
2657 continue
2658 }
2659 textp = append(textp, sym)
2660 }
2661
2662
2663
2664 for _, r := range l.objs[goObjStart:] {
2665 lib := r.unit.Lib
2666 for i, n := uint32(0), uint32(r.NAlldef()); i < n; i++ {
2667 gi := l.toGlobal(r, i)
2668 if !l.attrReachable.Has(gi) {
2669 continue
2670 }
2671 osym := r.Sym(i)
2672 st := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
2673 if !st.IsText() {
2674 continue
2675 }
2676 dupok := osym.Dupok()
2677 if r2, i2 := l.toLocal(gi); r2 != r || i2 != i {
2678
2679
2680
2681
2682 lib.DupTextSyms = append(lib.DupTextSyms, sym.LoaderSym(gi))
2683 continue
2684 }
2685 if dupok {
2686 lib.DupTextSyms = append(lib.DupTextSyms, sym.LoaderSym(gi))
2687 continue
2688 }
2689
2690 lib.Textp = append(lib.Textp, sym.LoaderSym(gi))
2691 }
2692 }
2693
2694
2695 for _, doInternal := range [2]bool{true, false} {
2696 for idx, lib := range libs {
2697 if intlibs[idx] != doInternal {
2698 continue
2699 }
2700 lists := [2][]sym.LoaderSym{lib.Textp, lib.DupTextSyms}
2701 for i, list := range lists {
2702 for _, s := range list {
2703 sym := Sym(s)
2704 if !assignedToUnit.Has(sym) {
2705 textp = append(textp, sym)
2706 unit := l.SymUnit(sym)
2707 if unit != nil {
2708 unit.Textp = append(unit.Textp, s)
2709 assignedToUnit.Set(sym)
2710 }
2711
2712
2713
2714
2715
2716 if i == 1 && l.SymPkg(sym) != lib.Pkg {
2717 l.SetSymPkg(sym, lib.Pkg)
2718 }
2719 }
2720 }
2721 }
2722 lib.Textp = nil
2723 lib.DupTextSyms = nil
2724 }
2725 }
2726
2727 return textp
2728 }
2729
2730
2731 type ErrorReporter struct {
2732 ldr *Loader
2733 AfterErrorAction func()
2734 }
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744 func (reporter *ErrorReporter) Errorf(s Sym, format string, args ...interface{}) {
2745 if s != 0 && reporter.ldr.SymName(s) != "" {
2746
2747
2748 format = strings.Replace(reporter.ldr.SymName(s), "%", "%%", -1) + ": " + format
2749 } else {
2750 format = fmt.Sprintf("sym %d: %s", s, format)
2751 }
2752 format += "\n"
2753 fmt.Fprintf(os.Stderr, format, args...)
2754 reporter.AfterErrorAction()
2755 }
2756
2757
2758 func (l *Loader) GetErrorReporter() *ErrorReporter {
2759 return l.errorReporter
2760 }
2761
2762
2763 func (l *Loader) Errorf(s Sym, format string, args ...interface{}) {
2764 l.errorReporter.Errorf(s, format, args...)
2765 }
2766
2767
2768 func (l *Loader) Stat() string {
2769 s := fmt.Sprintf("%d symbols, %d reachable\n", l.NSym(), l.NReachableSym())
2770 s += fmt.Sprintf("\t%d package symbols, %d hashed symbols, %d non-package symbols, %d external symbols\n",
2771 l.npkgsyms, l.nhashedsyms, int(l.extStart)-l.npkgsyms-l.nhashedsyms, l.NSym()-int(l.extStart))
2772 return s
2773 }
2774
2775
2776 func (l *Loader) Dump() {
2777 fmt.Println("objs")
2778 for _, r := range l.objs[goObjStart:] {
2779 if r != nil {
2780 fmt.Println(r.unit.Lib)
2781 }
2782 }
2783 fmt.Println("extStart:", l.extStart)
2784 fmt.Println("Nsyms:", len(l.objSyms))
2785 fmt.Println("syms")
2786 for i := Sym(1); i < Sym(len(l.objSyms)); i++ {
2787 pi := ""
2788 if l.IsExternal(i) {
2789 pi = fmt.Sprintf("<ext %d>", l.extIndex(i))
2790 }
2791 sect := ""
2792 if l.SymSect(i) != nil {
2793 sect = l.SymSect(i).Name
2794 }
2795 fmt.Printf("%v %v %v %v %x %v\n", i, l.SymName(i), l.SymType(i), pi, l.SymValue(i), sect)
2796 }
2797 fmt.Println("symsByName")
2798 for name, i := range l.symsByName[0] {
2799 fmt.Println(i, name, 0)
2800 }
2801 for name, i := range l.symsByName[1] {
2802 fmt.Println(i, name, 1)
2803 }
2804 fmt.Println("payloads:")
2805 for i := range l.payloads {
2806 pp := l.payloads[i]
2807 fmt.Println(i, pp.name, pp.ver, pp.kind)
2808 }
2809 }
2810
View as plain text