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