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