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
2468 "net.newWindowsFile": {"net"},
2469 "testing/synctest.testingSynctestTest": {"testing/synctest"},
2470 "runtime.addmoduledata": {},
2471 }
2472
2473
2474 func (l *Loader) checkLinkname(pkg, name string, s Sym) {
2475 if l.flags&FlagCheckLinkname == 0 {
2476 return
2477 }
2478
2479 error := func() {
2480 log.Fatalf("%s: invalid reference to %s", pkg, name)
2481 }
2482 pkgs, ok := blockedLinknames[name]
2483 if ok {
2484 for _, p := range pkgs {
2485 if pkg == p {
2486 return
2487 }
2488
2489
2490 if strings.HasPrefix(pkg, "crypto/internal/fips140/v") {
2491 parts := strings.Split(pkg, "/")
2492 parts = append(parts[:3], parts[4:]...)
2493 pkg := strings.Join(parts, "/")
2494 if pkg == p {
2495 return
2496 }
2497 }
2498 }
2499 error()
2500 }
2501 r, li := l.toLocal(s)
2502 if r == l.extReader {
2503 return
2504 }
2505 if !r.Std() {
2506 return
2507 }
2508 if r.unit.Lib.Pkg == pkg {
2509 return
2510 }
2511 osym := r.Sym(li)
2512 if osym.IsLinkname() || osym.ABIWrapper() {
2513
2514
2515
2516
2517
2518 return
2519 }
2520 error()
2521 }
2522
2523
2524
2525
2526
2527 func (l *Loader) TopLevelSym(s Sym) bool {
2528 return topLevelSym(l.SymName(s), l.SymType(s))
2529 }
2530
2531
2532
2533
2534
2535 func topLevelSym(sname string, skind sym.SymKind) bool {
2536 if sname != "" {
2537 return true
2538 }
2539 switch skind {
2540 case sym.SDWARFFCN, sym.SDWARFABSFCN, sym.SDWARFTYPE, sym.SDWARFCONST, sym.SDWARFCUINFO, sym.SDWARFRANGE, sym.SDWARFLOC, sym.SDWARFLINES, sym.SGOFUNC:
2541 return true
2542 default:
2543 return false
2544 }
2545 }
2546
2547
2548
2549
2550
2551
2552
2553
2554 func (l *Loader) cloneToExternal(symIdx Sym) *extSymPayload {
2555 if l.IsExternal(symIdx) {
2556 panic("sym is already external, no need for clone")
2557 }
2558
2559
2560 r, li := l.toLocal(symIdx)
2561 osym := r.Sym(li)
2562 sname := osym.Name(r.Reader)
2563 sver := abiToVer(osym.ABI(), r.version)
2564 skind := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
2565
2566
2567 pi := l.newPayload(sname, sver)
2568 pp := l.payloads[pi]
2569 pp.kind = skind
2570 pp.ver = sver
2571 pp.size = int64(osym.Siz())
2572 pp.objidx = r.objidx
2573
2574
2575
2576 if li < uint32(r.NAlldef()) {
2577
2578
2579 relocs := l.Relocs(symIdx)
2580 pp.relocs = make([]goobj.Reloc, relocs.Count())
2581 for i := range pp.relocs {
2582
2583
2584 rel := relocs.At(i)
2585 pp.relocs[i].Set(rel.Off(), rel.Siz(), uint16(rel.Type()), rel.Add(), goobj.SymRef{PkgIdx: 0, SymIdx: uint32(rel.Sym())})
2586 }
2587
2588
2589 pp.data = r.Data(li)
2590 }
2591
2592
2593
2594 auxs := r.Auxs(li)
2595 pp.auxs = auxs
2596
2597
2598
2599
2600 l.objSyms[symIdx] = objSym{l.extReader.objidx, uint32(pi)}
2601 l.extReader.syms = append(l.extReader.syms, symIdx)
2602
2603
2604 l.SetAttrDuplicateOK(symIdx, r.Sym(li).Dupok())
2605 l.SetAttrShared(symIdx, r.Shared())
2606
2607 return pp
2608 }
2609
2610
2611
2612
2613
2614
2615
2616 func (l *Loader) CopySym(src, dst Sym) {
2617 if !l.IsExternal(dst) {
2618 panic("dst is not external")
2619 }
2620 if !l.IsExternal(src) {
2621 panic("src is not external")
2622 }
2623 l.payloads[l.extIndex(dst)] = l.payloads[l.extIndex(src)]
2624 l.SetSymPkg(dst, l.SymPkg(src))
2625
2626 }
2627
2628
2629
2630 func (l *Loader) CreateExtSym(name string, ver int) Sym {
2631 return l.newExtSym(name, ver)
2632 }
2633
2634
2635
2636 func (l *Loader) CreateStaticSym(name string) Sym {
2637
2638
2639 l.anonVersion--
2640 return l.newExtSym(name, l.anonVersion)
2641 }
2642
2643 func (l *Loader) FreeSym(i Sym) {
2644 if l.IsExternal(i) {
2645 pp := l.getPayload(i)
2646 *pp = extSymPayload{}
2647 }
2648 }
2649
2650
2651
2652 type relocId struct {
2653 sym Sym
2654 ridx int
2655 }
2656
2657
2658
2659 func (l *Loader) SetRelocVariant(s Sym, ri int, v sym.RelocVariant) {
2660
2661 if relocs := l.Relocs(s); ri >= relocs.Count() {
2662 panic("invalid relocation ID")
2663 }
2664 if l.relocVariant == nil {
2665 l.relocVariant = make(map[relocId]sym.RelocVariant)
2666 }
2667 if v != 0 {
2668 l.relocVariant[relocId{s, ri}] = v
2669 } else {
2670 delete(l.relocVariant, relocId{s, ri})
2671 }
2672 }
2673
2674
2675
2676 func (l *Loader) RelocVariant(s Sym, ri int) sym.RelocVariant {
2677 return l.relocVariant[relocId{s, ri}]
2678 }
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690 func (l *Loader) UndefinedRelocTargets(limit int) ([]Sym, []Sym) {
2691 result, fromr := []Sym{}, []Sym{}
2692 outerloop:
2693 for si := Sym(1); si < Sym(len(l.objSyms)); si++ {
2694 relocs := l.Relocs(si)
2695 for ri := 0; ri < relocs.Count(); ri++ {
2696 r := relocs.At(ri)
2697 rs := r.Sym()
2698 if rs != 0 && l.SymType(rs) == sym.SXREF && l.SymName(rs) != ".got" {
2699 result = append(result, rs)
2700 fromr = append(fromr, si)
2701 if limit != -1 && len(result) >= limit {
2702 break outerloop
2703 }
2704 }
2705 }
2706 }
2707 return result, fromr
2708 }
2709
2710
2711
2712
2713
2714 func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool, extsyms []Sym) []Sym {
2715
2716
2717 for _, lib := range libs {
2718 if len(lib.Textp) != 0 {
2719 panic("expected empty Textp slice for library")
2720 }
2721 if len(lib.DupTextSyms) != 0 {
2722 panic("expected empty DupTextSyms slice for library")
2723 }
2724 }
2725
2726
2727
2728
2729
2730
2731 assignedToUnit := MakeBitmap(l.NSym() + 1)
2732
2733
2734 textp := []Sym{}
2735 for _, sym := range extsyms {
2736 if !l.attrReachable.Has(sym) {
2737 continue
2738 }
2739 textp = append(textp, sym)
2740 }
2741
2742
2743
2744 for _, r := range l.objs[goObjStart:] {
2745 lib := r.unit.Lib
2746 for i, n := uint32(0), uint32(r.NAlldef()); i < n; i++ {
2747 gi := l.toGlobal(r, i)
2748 if !l.attrReachable.Has(gi) {
2749 continue
2750 }
2751 osym := r.Sym(i)
2752 st := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
2753 if !st.IsText() {
2754 continue
2755 }
2756 dupok := osym.Dupok()
2757 if r2, i2 := l.toLocal(gi); r2 != r || i2 != i {
2758
2759
2760
2761
2762 lib.DupTextSyms = append(lib.DupTextSyms, gi)
2763 continue
2764 }
2765 if dupok {
2766 lib.DupTextSyms = append(lib.DupTextSyms, gi)
2767 continue
2768 }
2769
2770 lib.Textp = append(lib.Textp, gi)
2771 }
2772 }
2773
2774
2775 for _, doInternal := range [2]bool{true, false} {
2776 for idx, lib := range libs {
2777 if intlibs[idx] != doInternal {
2778 continue
2779 }
2780 lists := [2][]sym.LoaderSym{lib.Textp, lib.DupTextSyms}
2781 for i, list := range lists {
2782 for _, s := range list {
2783 sym := s
2784 if !assignedToUnit.Has(sym) {
2785 textp = append(textp, sym)
2786 unit := l.SymUnit(sym)
2787 if unit != nil {
2788 unit.Textp = append(unit.Textp, s)
2789 assignedToUnit.Set(sym)
2790 }
2791
2792
2793
2794
2795
2796 if i == 1 && l.SymPkg(sym) != lib.Pkg {
2797 l.SetSymPkg(sym, lib.Pkg)
2798 }
2799 }
2800 }
2801 }
2802 lib.Textp = nil
2803 lib.DupTextSyms = nil
2804 }
2805 }
2806
2807 return textp
2808 }
2809
2810
2811 type ErrorReporter struct {
2812 ldr *Loader
2813 AfterErrorAction func()
2814 }
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824 func (reporter *ErrorReporter) Errorf(s Sym, format string, args ...interface{}) {
2825 if s != 0 && reporter.ldr.SymName(s) != "" {
2826
2827
2828 format = strings.ReplaceAll(reporter.ldr.SymName(s), "%", "%%") + ": " + format
2829 } else {
2830 format = fmt.Sprintf("sym %d: %s", s, format)
2831 }
2832 format += "\n"
2833 fmt.Fprintf(os.Stderr, format, args...)
2834 reporter.AfterErrorAction()
2835 }
2836
2837
2838 func (l *Loader) GetErrorReporter() *ErrorReporter {
2839 return l.errorReporter
2840 }
2841
2842
2843 func (l *Loader) Errorf(s Sym, format string, args ...interface{}) {
2844 l.errorReporter.Errorf(s, format, args...)
2845 }
2846
2847
2848 func (l *Loader) Stat() string {
2849 s := fmt.Sprintf("%d symbols, %d reachable\n", l.NSym(), l.NReachableSym())
2850 s += fmt.Sprintf("\t%d package symbols, %d hashed symbols, %d non-package symbols, %d external symbols\n",
2851 l.npkgsyms, l.nhashedsyms, int(l.extStart)-l.npkgsyms-l.nhashedsyms, l.NSym()-int(l.extStart))
2852 return s
2853 }
2854
2855
2856 func (l *Loader) Dump() {
2857 fmt.Println("objs")
2858 for _, r := range l.objs[goObjStart:] {
2859 if r != nil {
2860 fmt.Println(r.unit.Lib)
2861 }
2862 }
2863 fmt.Println("extStart:", l.extStart)
2864 fmt.Println("Nsyms:", len(l.objSyms))
2865 fmt.Println("syms")
2866 for i := Sym(1); i < Sym(len(l.objSyms)); i++ {
2867 pi := ""
2868 if l.IsExternal(i) {
2869 pi = fmt.Sprintf("<ext %d>", l.extIndex(i))
2870 }
2871 sect := ""
2872 if l.SymSect(i) != nil {
2873 sect = l.SymSect(i).Name
2874 }
2875 fmt.Printf("%v %v %v %v %x %v\n", i, l.SymName(i), l.SymType(i), pi, l.SymValue(i), sect)
2876 }
2877 fmt.Println("symsByName")
2878 for name, i := range l.symsByName[0] {
2879 fmt.Println(i, name, 0)
2880 }
2881 for name, i := range l.symsByName[1] {
2882 fmt.Println(i, name, 1)
2883 }
2884 fmt.Println("payloads:")
2885 for i := range l.payloads {
2886 pp := l.payloads[i]
2887 fmt.Println(i, pp.name, pp.ver, pp.kind)
2888 }
2889 }
2890
View as plain text