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