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