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