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