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