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