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