1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package obj
32
33 import (
34 "bufio"
35 "bytes"
36 "cmd/internal/dwarf"
37 "cmd/internal/goobj"
38 "cmd/internal/objabi"
39 "cmd/internal/src"
40 "cmd/internal/sys"
41 "encoding/binary"
42 "fmt"
43 "internal/abi"
44 "sync"
45 "sync/atomic"
46 )
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 type Addr struct {
200 Reg int16
201 Index int16
202 Scale int16
203 Type AddrType
204 Name AddrName
205 Class int8
206 Offset int64
207 Sym *LSym
208
209
210
211
212
213
214 Val interface{}
215 }
216
217 type AddrName int8
218
219 const (
220 NAME_NONE AddrName = iota
221 NAME_EXTERN
222 NAME_STATIC
223 NAME_AUTO
224 NAME_PARAM
225
226
227 NAME_GOTREF
228
229 NAME_TOCREF
230 )
231
232
233
234 type AddrType uint8
235
236 const (
237 TYPE_NONE AddrType = iota
238 TYPE_BRANCH
239 TYPE_TEXTSIZE
240 TYPE_MEM
241 TYPE_CONST
242 TYPE_FCONST
243 TYPE_SCONST
244 TYPE_REG
245 TYPE_ADDR
246 TYPE_SHIFT
247 TYPE_REGREG
248 TYPE_REGREG2
249 TYPE_INDIR
250 TYPE_REGLIST
251 TYPE_SPECIAL
252 )
253
254 func (a *Addr) Target() *Prog {
255 if a.Type == TYPE_BRANCH && a.Val != nil {
256 return a.Val.(*Prog)
257 }
258 return nil
259 }
260 func (a *Addr) SetTarget(t *Prog) {
261 if a.Type != TYPE_BRANCH {
262 panic("setting branch target when type is not TYPE_BRANCH")
263 }
264 a.Val = t
265 }
266
267 func (a *Addr) SetConst(v int64) {
268 a.Sym = nil
269 a.Type = TYPE_CONST
270 a.Offset = v
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304 type Prog struct {
305 Ctxt *Link
306 Link *Prog
307 From Addr
308 RestArgs []AddrPos
309 To Addr
310 Pool *Prog
311 Forwd *Prog
312 Rel *Prog
313 Pc int64
314 Pos src.XPos
315 Spadj int32
316 As As
317 Reg int16
318 RegTo2 int16
319 Mark uint16
320 Optab uint16
321 Scond uint8
322 Back uint8
323 Ft uint8
324 Tt uint8
325 Isize uint8
326 }
327
328
329 type AddrPos struct {
330 Addr
331 Pos OperandPos
332 }
333
334 type OperandPos int8
335
336 const (
337 Source OperandPos = iota
338 Destination
339 )
340
341
342
343 func (p *Prog) From3Type() AddrType {
344 from3 := p.GetFrom3()
345 if from3 == nil {
346 return TYPE_NONE
347 }
348 return from3.Type
349 }
350
351
352
353
354
355
356 func (p *Prog) GetFrom3() *Addr {
357 for i := range p.RestArgs {
358 if p.RestArgs[i].Pos == Source {
359 return &p.RestArgs[i].Addr
360 }
361 }
362 return nil
363 }
364
365
366 func (p *Prog) AddRestSource(a Addr) {
367 p.RestArgs = append(p.RestArgs, AddrPos{a, Source})
368 }
369
370
371 func (p *Prog) AddRestSourceReg(reg int16) {
372 p.AddRestSource(Addr{Type: TYPE_REG, Reg: reg})
373 }
374
375
376 func (p *Prog) AddRestSourceConst(off int64) {
377 p.AddRestSource(Addr{Type: TYPE_CONST, Offset: off})
378 }
379
380
381
382 func (p *Prog) AddRestDest(a Addr) {
383 p.RestArgs = append(p.RestArgs, AddrPos{a, Destination})
384 }
385
386
387
388
389 func (p *Prog) GetTo2() *Addr {
390 for i := range p.RestArgs {
391 if p.RestArgs[i].Pos == Destination {
392 return &p.RestArgs[i].Addr
393 }
394 }
395 return nil
396 }
397
398
399 func (p *Prog) AddRestSourceArgs(args []Addr) {
400 for i := range args {
401 p.RestArgs = append(p.RestArgs, AddrPos{args[i], Source})
402 }
403 }
404
405
406
407
408
409
410 type As int16
411
412
413 const (
414 AXXX As = iota
415 ACALL
416 ADUFFCOPY
417 ADUFFZERO
418 AEND
419 AFUNCDATA
420 AJMP
421 ANOP
422 APCALIGN
423 APCALIGNMAX
424 APCDATA
425 ARET
426 AGETCALLERPC
427 ATEXT
428 AUNDEF
429 A_ARCHSPECIFIC
430 )
431
432
433
434
435
436
437
438
439 const (
440 ABase386 = (1 + iota) << 11
441 ABaseARM
442 ABaseAMD64
443 ABasePPC64
444 ABaseARM64
445 ABaseMIPS
446 ABaseLoong64
447 ABaseRISCV
448 ABaseS390X
449 ABaseWasm
450
451 AllowedOpCodes = 1 << 11
452 AMask = AllowedOpCodes - 1
453 )
454
455
456
457 type LSym struct {
458 Name string
459 Type objabi.SymKind
460 Attribute
461
462 Size int64
463 Gotype *LSym
464 P []byte
465 R []Reloc
466
467 Extra *interface{}
468
469 Pkg string
470 PkgIdx int32
471 SymIdx int32
472 }
473
474
475 type FuncInfo struct {
476 Args int32
477 Locals int32
478 Align int32
479 FuncID abi.FuncID
480 FuncFlag abi.FuncFlag
481 StartLine int32
482 Text *Prog
483 Autot map[*LSym]struct{}
484 Pcln Pcln
485 InlMarks []InlMark
486 spills []RegSpill
487
488 dwarfInfoSym *LSym
489 dwarfLocSym *LSym
490 dwarfRangesSym *LSym
491 dwarfAbsFnSym *LSym
492 dwarfDebugLinesSym *LSym
493
494 GCArgs *LSym
495 GCLocals *LSym
496 StackObjects *LSym
497 OpenCodedDeferInfo *LSym
498 ArgInfo *LSym
499 ArgLiveInfo *LSym
500 WrapInfo *LSym
501 JumpTables []JumpTable
502
503 FuncInfoSym *LSym
504
505 WasmImport *WasmImport
506 WasmExport *WasmExport
507
508 sehUnwindInfoSym *LSym
509 }
510
511
512
513
514
515 type JumpTable struct {
516 Sym *LSym
517 Targets []*Prog
518 }
519
520
521 func (s *LSym) NewFuncInfo() *FuncInfo {
522 if s.Extra != nil {
523 panic(fmt.Sprintf("invalid use of LSym - NewFuncInfo with Extra of type %T", *s.Extra))
524 }
525 f := new(FuncInfo)
526 s.Extra = new(interface{})
527 *s.Extra = f
528 return f
529 }
530
531
532 func (s *LSym) Func() *FuncInfo {
533 if s.Extra == nil {
534 return nil
535 }
536 f, _ := (*s.Extra).(*FuncInfo)
537 return f
538 }
539
540 type VarInfo struct {
541 dwarfInfoSym *LSym
542 }
543
544
545 func (s *LSym) NewVarInfo() *VarInfo {
546 if s.Extra != nil {
547 panic(fmt.Sprintf("invalid use of LSym - NewVarInfo with Extra of type %T", *s.Extra))
548 }
549 f := new(VarInfo)
550 s.Extra = new(interface{})
551 *s.Extra = f
552 return f
553 }
554
555
556 func (s *LSym) VarInfo() *VarInfo {
557 if s.Extra == nil {
558 return nil
559 }
560 f, _ := (*s.Extra).(*VarInfo)
561 return f
562 }
563
564
565
566 type FileInfo struct {
567 Name string
568 Size int64
569 }
570
571
572 func (s *LSym) NewFileInfo() *FileInfo {
573 if s.Extra != nil {
574 panic(fmt.Sprintf("invalid use of LSym - NewFileInfo with Extra of type %T", *s.Extra))
575 }
576 f := new(FileInfo)
577 s.Extra = new(interface{})
578 *s.Extra = f
579 return f
580 }
581
582
583 func (s *LSym) File() *FileInfo {
584 if s.Extra == nil {
585 return nil
586 }
587 f, _ := (*s.Extra).(*FileInfo)
588 return f
589 }
590
591
592
593 type TypeInfo struct {
594 Type interface{}
595 }
596
597 func (s *LSym) NewTypeInfo() *TypeInfo {
598 if s.Extra != nil {
599 panic(fmt.Sprintf("invalid use of LSym - NewTypeInfo with Extra of type %T", *s.Extra))
600 }
601 t := new(TypeInfo)
602 s.Extra = new(interface{})
603 *s.Extra = t
604 return t
605 }
606
607
608 func (s *LSym) TypeInfo() *TypeInfo {
609 if s.Extra == nil {
610 return nil
611 }
612 t, _ := (*s.Extra).(*TypeInfo)
613 return t
614 }
615
616
617
618 type ItabInfo struct {
619 Type interface{}
620 }
621
622 func (s *LSym) NewItabInfo() *ItabInfo {
623 if s.Extra != nil {
624 panic(fmt.Sprintf("invalid use of LSym - NewItabInfo with Extra of type %T", *s.Extra))
625 }
626 t := new(ItabInfo)
627 s.Extra = new(interface{})
628 *s.Extra = t
629 return t
630 }
631
632
633 func (s *LSym) ItabInfo() *ItabInfo {
634 if s.Extra == nil {
635 return nil
636 }
637 i, _ := (*s.Extra).(*ItabInfo)
638 return i
639 }
640
641
642
643
644 type WasmImport struct {
645
646
647 Module string
648
649
650 Name string
651
652 WasmFuncType
653
654
655
656 AuxSym *LSym
657 }
658
659 func (wi *WasmImport) CreateAuxSym() {
660 var b bytes.Buffer
661 wi.Write(&b)
662 p := b.Bytes()
663 wi.AuxSym = &LSym{
664 Type: objabi.SDATA,
665 P: append([]byte(nil), p...),
666 Size: int64(len(p)),
667 }
668 }
669
670 func (wi *WasmImport) Write(w *bytes.Buffer) {
671 var b [8]byte
672 writeUint32 := func(x uint32) {
673 binary.LittleEndian.PutUint32(b[:], x)
674 w.Write(b[:4])
675 }
676 writeString := func(s string) {
677 writeUint32(uint32(len(s)))
678 w.WriteString(s)
679 }
680 writeString(wi.Module)
681 writeString(wi.Name)
682 wi.WasmFuncType.Write(w)
683 }
684
685 func (wi *WasmImport) Read(b []byte) {
686 readUint32 := func() uint32 {
687 x := binary.LittleEndian.Uint32(b)
688 b = b[4:]
689 return x
690 }
691 readString := func() string {
692 n := readUint32()
693 s := string(b[:n])
694 b = b[n:]
695 return s
696 }
697 wi.Module = readString()
698 wi.Name = readString()
699 wi.WasmFuncType.Read(b)
700 }
701
702
703
704
705 type WasmFuncType struct {
706
707 Params []WasmField
708
709 Results []WasmField
710 }
711
712 func (ft *WasmFuncType) Write(w *bytes.Buffer) {
713 var b [8]byte
714 writeByte := func(x byte) {
715 w.WriteByte(x)
716 }
717 writeUint32 := func(x uint32) {
718 binary.LittleEndian.PutUint32(b[:], x)
719 w.Write(b[:4])
720 }
721 writeInt64 := func(x int64) {
722 binary.LittleEndian.PutUint64(b[:], uint64(x))
723 w.Write(b[:])
724 }
725 writeUint32(uint32(len(ft.Params)))
726 for _, f := range ft.Params {
727 writeByte(byte(f.Type))
728 writeInt64(f.Offset)
729 }
730 writeUint32(uint32(len(ft.Results)))
731 for _, f := range ft.Results {
732 writeByte(byte(f.Type))
733 writeInt64(f.Offset)
734 }
735 }
736
737 func (ft *WasmFuncType) Read(b []byte) {
738 readByte := func() byte {
739 x := b[0]
740 b = b[1:]
741 return x
742 }
743 readUint32 := func() uint32 {
744 x := binary.LittleEndian.Uint32(b)
745 b = b[4:]
746 return x
747 }
748 readInt64 := func() int64 {
749 x := binary.LittleEndian.Uint64(b)
750 b = b[8:]
751 return int64(x)
752 }
753 ft.Params = make([]WasmField, readUint32())
754 for i := range ft.Params {
755 ft.Params[i].Type = WasmFieldType(readByte())
756 ft.Params[i].Offset = int64(readInt64())
757 }
758 ft.Results = make([]WasmField, readUint32())
759 for i := range ft.Results {
760 ft.Results[i].Type = WasmFieldType(readByte())
761 ft.Results[i].Offset = int64(readInt64())
762 }
763 }
764
765
766
767
768 type WasmExport struct {
769 WasmFuncType
770
771 WrappedSym *LSym
772 AuxSym *LSym
773 }
774
775 func (we *WasmExport) CreateAuxSym() {
776 var b bytes.Buffer
777 we.WasmFuncType.Write(&b)
778 p := b.Bytes()
779 we.AuxSym = &LSym{
780 Type: objabi.SDATA,
781 P: append([]byte(nil), p...),
782 Size: int64(len(p)),
783 }
784 }
785
786 type WasmField struct {
787 Type WasmFieldType
788
789
790
791 Offset int64
792 }
793
794 type WasmFieldType byte
795
796 const (
797 WasmI32 WasmFieldType = iota
798 WasmI64
799 WasmF32
800 WasmF64
801 WasmPtr
802
803
804
805 WasmBool
806 )
807
808 type InlMark struct {
809
810
811
812
813 p *Prog
814 id int32
815 }
816
817
818
819
820
821 func (fi *FuncInfo) AddInlMark(p *Prog, id int32) {
822 fi.InlMarks = append(fi.InlMarks, InlMark{p: p, id: id})
823 }
824
825
826 func (fi *FuncInfo) AddSpill(s RegSpill) {
827 fi.spills = append(fi.spills, s)
828 }
829
830
831
832 func (fi *FuncInfo) RecordAutoType(gotype *LSym) {
833 if fi.Autot == nil {
834 fi.Autot = make(map[*LSym]struct{})
835 }
836 fi.Autot[gotype] = struct{}{}
837 }
838
839
840
841
842 type ABI uint8
843
844 const (
845
846
847
848
849
850 ABI0 ABI = iota
851
852
853
854
855
856 ABIInternal
857
858 ABICount
859 )
860
861
862
863
864 func ParseABI(abistr string) (ABI, bool) {
865 switch abistr {
866 default:
867 return ABI0, false
868 case "ABI0":
869 return ABI0, true
870 case "ABIInternal":
871 return ABIInternal, true
872 }
873 }
874
875
876 type ABISet uint8
877
878 const (
879
880
881 ABISetCallable ABISet = (1 << ABI0) | (1 << ABIInternal)
882 )
883
884
885 var _ ABISet = 1 << (ABICount - 1)
886
887 func ABISetOf(abi ABI) ABISet {
888 return 1 << abi
889 }
890
891 func (a *ABISet) Set(abi ABI, value bool) {
892 if value {
893 *a |= 1 << abi
894 } else {
895 *a &^= 1 << abi
896 }
897 }
898
899 func (a *ABISet) Get(abi ABI) bool {
900 return (*a>>abi)&1 != 0
901 }
902
903 func (a ABISet) String() string {
904 s := "{"
905 for i := ABI(0); a != 0; i++ {
906 if a&(1<<i) != 0 {
907 if s != "{" {
908 s += ","
909 }
910 s += i.String()
911 a &^= 1 << i
912 }
913 }
914 return s + "}"
915 }
916
917
918 type Attribute uint32
919
920 const (
921 AttrDuplicateOK Attribute = 1 << iota
922 AttrCFunc
923 AttrNoSplit
924 AttrLeaf
925 AttrWrapper
926 AttrNeedCtxt
927 AttrNoFrame
928 AttrOnList
929 AttrStatic
930
931
932 AttrMakeTypelink
933
934
935
936
937
938
939
940 AttrReflectMethod
941
942
943
944
945
946
947
948 AttrLocal
949
950
951
952 AttrWasInlined
953
954
955
956 AttrIndexed
957
958
959
960
961
962 AttrUsedInIface
963
964
965 AttrContentAddressable
966
967
968
969 AttrABIWrapper
970
971
972 AttrPcdata
973
974
975 AttrPkgInit
976
977
978 AttrLinkname
979
980
981
982
983
984
985 attrABIBase
986 )
987
988 func (a *Attribute) load() Attribute { return Attribute(atomic.LoadUint32((*uint32)(a))) }
989
990 func (a *Attribute) DuplicateOK() bool { return a.load()&AttrDuplicateOK != 0 }
991 func (a *Attribute) MakeTypelink() bool { return a.load()&AttrMakeTypelink != 0 }
992 func (a *Attribute) CFunc() bool { return a.load()&AttrCFunc != 0 }
993 func (a *Attribute) NoSplit() bool { return a.load()&AttrNoSplit != 0 }
994 func (a *Attribute) Leaf() bool { return a.load()&AttrLeaf != 0 }
995 func (a *Attribute) OnList() bool { return a.load()&AttrOnList != 0 }
996 func (a *Attribute) ReflectMethod() bool { return a.load()&AttrReflectMethod != 0 }
997 func (a *Attribute) Local() bool { return a.load()&AttrLocal != 0 }
998 func (a *Attribute) Wrapper() bool { return a.load()&AttrWrapper != 0 }
999 func (a *Attribute) NeedCtxt() bool { return a.load()&AttrNeedCtxt != 0 }
1000 func (a *Attribute) NoFrame() bool { return a.load()&AttrNoFrame != 0 }
1001 func (a *Attribute) Static() bool { return a.load()&AttrStatic != 0 }
1002 func (a *Attribute) WasInlined() bool { return a.load()&AttrWasInlined != 0 }
1003 func (a *Attribute) Indexed() bool { return a.load()&AttrIndexed != 0 }
1004 func (a *Attribute) UsedInIface() bool { return a.load()&AttrUsedInIface != 0 }
1005 func (a *Attribute) ContentAddressable() bool { return a.load()&AttrContentAddressable != 0 }
1006 func (a *Attribute) ABIWrapper() bool { return a.load()&AttrABIWrapper != 0 }
1007 func (a *Attribute) IsPcdata() bool { return a.load()&AttrPcdata != 0 }
1008 func (a *Attribute) IsPkgInit() bool { return a.load()&AttrPkgInit != 0 }
1009 func (a *Attribute) IsLinkname() bool { return a.load()&AttrLinkname != 0 }
1010
1011 func (a *Attribute) Set(flag Attribute, value bool) {
1012 for {
1013 v0 := a.load()
1014 v := v0
1015 if value {
1016 v |= flag
1017 } else {
1018 v &^= flag
1019 }
1020 if atomic.CompareAndSwapUint32((*uint32)(a), uint32(v0), uint32(v)) {
1021 break
1022 }
1023 }
1024 }
1025
1026 func (a *Attribute) ABI() ABI { return ABI(a.load() / attrABIBase) }
1027 func (a *Attribute) SetABI(abi ABI) {
1028 const mask = 1
1029 for {
1030 v0 := a.load()
1031 v := (v0 &^ (mask * attrABIBase)) | Attribute(abi)*attrABIBase
1032 if atomic.CompareAndSwapUint32((*uint32)(a), uint32(v0), uint32(v)) {
1033 break
1034 }
1035 }
1036 }
1037
1038 var textAttrStrings = [...]struct {
1039 bit Attribute
1040 s string
1041 }{
1042 {bit: AttrDuplicateOK, s: "DUPOK"},
1043 {bit: AttrMakeTypelink, s: ""},
1044 {bit: AttrCFunc, s: "CFUNC"},
1045 {bit: AttrNoSplit, s: "NOSPLIT"},
1046 {bit: AttrLeaf, s: "LEAF"},
1047 {bit: AttrOnList, s: ""},
1048 {bit: AttrReflectMethod, s: "REFLECTMETHOD"},
1049 {bit: AttrLocal, s: "LOCAL"},
1050 {bit: AttrWrapper, s: "WRAPPER"},
1051 {bit: AttrNeedCtxt, s: "NEEDCTXT"},
1052 {bit: AttrNoFrame, s: "NOFRAME"},
1053 {bit: AttrStatic, s: "STATIC"},
1054 {bit: AttrWasInlined, s: ""},
1055 {bit: AttrIndexed, s: ""},
1056 {bit: AttrContentAddressable, s: ""},
1057 {bit: AttrABIWrapper, s: "ABIWRAPPER"},
1058 {bit: AttrPkgInit, s: "PKGINIT"},
1059 {bit: AttrLinkname, s: "LINKNAME"},
1060 }
1061
1062
1063 func (a Attribute) String() string {
1064 var s string
1065 for _, x := range textAttrStrings {
1066 if a&x.bit != 0 {
1067 if x.s != "" {
1068 s += x.s + "|"
1069 }
1070 a &^= x.bit
1071 }
1072 }
1073 switch a.ABI() {
1074 case ABI0:
1075 case ABIInternal:
1076 s += "ABIInternal|"
1077 a.SetABI(0)
1078 }
1079 if a != 0 {
1080 s += fmt.Sprintf("UnknownAttribute(%d)|", a)
1081 }
1082
1083 if len(s) > 0 {
1084 s = s[:len(s)-1]
1085 }
1086 return s
1087 }
1088
1089
1090 func (s *LSym) TextAttrString() string {
1091 attr := s.Attribute.String()
1092 if s.Func().FuncFlag&abi.FuncFlagTopFrame != 0 {
1093 if attr != "" {
1094 attr += "|"
1095 }
1096 attr += "TOPFRAME"
1097 }
1098 return attr
1099 }
1100
1101 func (s *LSym) String() string {
1102 return s.Name
1103 }
1104
1105
1106 func (*LSym) CanBeAnSSASym() {}
1107 func (*LSym) CanBeAnSSAAux() {}
1108
1109 type Pcln struct {
1110
1111 Pcsp *LSym
1112 Pcfile *LSym
1113 Pcline *LSym
1114 Pcinline *LSym
1115 Pcdata []*LSym
1116 Funcdata []*LSym
1117 UsedFiles map[goobj.CUFileIndex]struct{}
1118 InlTree InlTree
1119 }
1120
1121 type Reloc struct {
1122 Off int32
1123 Siz uint8
1124 Type objabi.RelocType
1125 Add int64
1126 Sym *LSym
1127 }
1128
1129 type Auto struct {
1130 Asym *LSym
1131 Aoffset int32
1132 Name AddrName
1133 Gotype *LSym
1134 }
1135
1136
1137
1138
1139
1140
1141 type RegSpill struct {
1142 Addr Addr
1143 Reg int16
1144 Reg2 int16
1145 Spill, Unspill As
1146 }
1147
1148
1149 type Func interface {
1150 Pos() src.XPos
1151 }
1152
1153
1154
1155 type Link struct {
1156 Headtype objabi.HeadType
1157 Arch *LinkArch
1158 Debugasm int
1159 Debugvlog bool
1160 Debugpcln string
1161 Flag_shared bool
1162 Flag_dynlink bool
1163 Flag_linkshared bool
1164 Flag_optimize bool
1165 Flag_locationlists bool
1166 Flag_noRefName bool
1167 Retpoline bool
1168 Flag_maymorestack string
1169 Bso *bufio.Writer
1170 Pathname string
1171 Pkgpath string
1172 hashmu sync.Mutex
1173 hash map[string]*LSym
1174 funchash map[string]*LSym
1175 statichash map[string]*LSym
1176 PosTable src.PosTable
1177 InlTree InlTree
1178 DwFixups *DwarfFixupTable
1179 DwTextCount int
1180 Imports []goobj.ImportedPkg
1181 DiagFunc func(string, ...interface{})
1182 DiagFlush func()
1183 DebugInfo func(ctxt *Link, fn *LSym, info *LSym, curfn Func) ([]dwarf.Scope, dwarf.InlCalls)
1184 GenAbstractFunc func(fn *LSym)
1185 Errors int
1186
1187 InParallel bool
1188 UseBASEntries bool
1189 IsAsm bool
1190 Std bool
1191
1192
1193 Text []*LSym
1194 Data []*LSym
1195
1196
1197
1198
1199
1200 constSyms []*LSym
1201
1202
1203
1204 SEHSyms []*LSym
1205
1206
1207
1208 pkgIdx map[string]int32
1209
1210 defs []*LSym
1211 hashed64defs []*LSym
1212 hasheddefs []*LSym
1213 nonpkgdefs []*LSym
1214 nonpkgrefs []*LSym
1215
1216 Fingerprint goobj.FingerprintType
1217 }
1218
1219
1220 func _(ctxt *Link) {
1221 ctxt.DiagFunc = func(format string, args ...any) {
1222 _ = fmt.Sprintf(format, args...)
1223 }
1224 }
1225
1226 func (ctxt *Link) Diag(format string, args ...interface{}) {
1227 ctxt.Errors++
1228 ctxt.DiagFunc(format, args...)
1229 }
1230
1231 func (ctxt *Link) Logf(format string, args ...interface{}) {
1232 fmt.Fprintf(ctxt.Bso, format, args...)
1233 ctxt.Bso.Flush()
1234 }
1235
1236
1237
1238 func (fi *FuncInfo) SpillRegisterArgs(last *Prog, pa ProgAlloc) *Prog {
1239
1240 for _, ra := range fi.spills {
1241 spill := Appendp(last, pa)
1242 spill.As = ra.Spill
1243 spill.From.Type = TYPE_REG
1244 spill.From.Reg = ra.Reg
1245 if ra.Reg2 != 0 {
1246 spill.From.Type = TYPE_REGREG
1247 spill.From.Offset = int64(ra.Reg2)
1248 }
1249 spill.To = ra.Addr
1250 last = spill
1251 }
1252 return last
1253 }
1254
1255
1256
1257 func (fi *FuncInfo) UnspillRegisterArgs(last *Prog, pa ProgAlloc) *Prog {
1258
1259 for _, ra := range fi.spills {
1260 unspill := Appendp(last, pa)
1261 unspill.As = ra.Unspill
1262 unspill.From = ra.Addr
1263 unspill.To.Type = TYPE_REG
1264 unspill.To.Reg = ra.Reg
1265 if ra.Reg2 != 0 {
1266 unspill.To.Type = TYPE_REGREG
1267 unspill.To.Offset = int64(ra.Reg2)
1268 }
1269 last = unspill
1270 }
1271 return last
1272 }
1273
1274
1275 type LinkArch struct {
1276 *sys.Arch
1277 Init func(*Link)
1278 ErrorCheck func(*Link, *LSym)
1279 Preprocess func(*Link, *LSym, ProgAlloc)
1280 Assemble func(*Link, *LSym, ProgAlloc)
1281 Progedit func(*Link, *Prog, ProgAlloc)
1282 SEH func(*Link, *LSym) *LSym
1283 UnaryDst map[As]bool
1284 DWARFRegisters map[int16]int16
1285 }
1286
View as plain text