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