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