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 any
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 Attribute
460 Type objabi.SymKind
461
462 Align int16
463 Size int64
464 Gotype *LSym
465 P []byte
466 R []Reloc
467
468 Extra *any
469
470 Pkg string
471 PkgIdx int32
472 SymIdx int32
473 }
474
475
476 type FuncInfo struct {
477 Args int32
478 Locals 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(any)
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(any)
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(any)
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 any
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(any)
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 any
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(any)
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 = 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 = 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 WasmV128
803
804
805
806 WasmBool
807 )
808
809 type InlMark struct {
810
811
812
813
814 p *Prog
815 id int32
816 }
817
818
819
820
821
822 func (fi *FuncInfo) AddInlMark(p *Prog, id int32) {
823 fi.InlMarks = append(fi.InlMarks, InlMark{p: p, id: id})
824 }
825
826
827 func (fi *FuncInfo) AddSpill(s RegSpill) {
828 fi.spills = append(fi.spills, s)
829 }
830
831
832
833 func (fi *FuncInfo) RecordAutoType(gotype *LSym) {
834 if fi.Autot == nil {
835 fi.Autot = make(map[*LSym]struct{})
836 }
837 fi.Autot[gotype] = struct{}{}
838 }
839
840
841
842
843 type ABI uint8
844
845 const (
846
847
848
849
850
851 ABI0 ABI = iota
852
853
854
855
856
857 ABIInternal
858
859 ABICount
860 )
861
862
863
864
865 func ParseABI(abistr string) (ABI, bool) {
866 switch abistr {
867 default:
868 return ABI0, false
869 case "ABI0":
870 return ABI0, true
871 case "ABIInternal":
872 return ABIInternal, true
873 }
874 }
875
876
877 type ABISet uint8
878
879 const (
880
881
882 ABISetCallable ABISet = (1 << ABI0) | (1 << ABIInternal)
883 )
884
885
886 var _ ABISet = 1 << (ABICount - 1)
887
888 func ABISetOf(abi ABI) ABISet {
889 return 1 << abi
890 }
891
892 func (a *ABISet) Set(abi ABI, value bool) {
893 if value {
894 *a |= 1 << abi
895 } else {
896 *a &^= 1 << abi
897 }
898 }
899
900 func (a *ABISet) Get(abi ABI) bool {
901 return (*a>>abi)&1 != 0
902 }
903
904 func (a ABISet) String() string {
905 s := "{"
906 for i := ABI(0); a != 0; i++ {
907 if a&(1<<i) != 0 {
908 if s != "{" {
909 s += ","
910 }
911 s += i.String()
912 a &^= 1 << i
913 }
914 }
915 return s + "}"
916 }
917
918
919 type Attribute uint32
920
921 const (
922 AttrDuplicateOK Attribute = 1 << iota
923 AttrCFunc
924 AttrNoSplit
925 AttrLeaf
926 AttrWrapper
927 AttrNeedCtxt
928 AttrNoFrame
929 AttrOnList
930 AttrStatic
931
932
933 AttrMakeTypelink
934
935
936
937
938
939
940
941 AttrReflectMethod
942
943
944
945
946
947
948
949 AttrLocal
950
951
952
953 AttrWasInlined
954
955
956
957 AttrIndexed
958
959
960
961
962
963 AttrUsedInIface
964
965
966 AttrContentAddressable
967
968
969
970 AttrABIWrapper
971
972
973 AttrPcdata
974
975
976 AttrPkgInit
977
978
979 AttrLinkname
980
981
982 AttrLinknameStd
983
984
985
986
987
988
989 attrABIBase
990 )
991
992 func (a *Attribute) load() Attribute { return Attribute(atomic.LoadUint32((*uint32)(a))) }
993
994 func (a *Attribute) DuplicateOK() bool { return a.load()&AttrDuplicateOK != 0 }
995 func (a *Attribute) MakeTypelink() bool { return a.load()&AttrMakeTypelink != 0 }
996 func (a *Attribute) CFunc() bool { return a.load()&AttrCFunc != 0 }
997 func (a *Attribute) NoSplit() bool { return a.load()&AttrNoSplit != 0 }
998 func (a *Attribute) Leaf() bool { return a.load()&AttrLeaf != 0 }
999 func (a *Attribute) OnList() bool { return a.load()&AttrOnList != 0 }
1000 func (a *Attribute) ReflectMethod() bool { return a.load()&AttrReflectMethod != 0 }
1001 func (a *Attribute) Local() bool { return a.load()&AttrLocal != 0 }
1002 func (a *Attribute) Wrapper() bool { return a.load()&AttrWrapper != 0 }
1003 func (a *Attribute) NeedCtxt() bool { return a.load()&AttrNeedCtxt != 0 }
1004 func (a *Attribute) NoFrame() bool { return a.load()&AttrNoFrame != 0 }
1005 func (a *Attribute) Static() bool { return a.load()&AttrStatic != 0 }
1006 func (a *Attribute) WasInlined() bool { return a.load()&AttrWasInlined != 0 }
1007 func (a *Attribute) Indexed() bool { return a.load()&AttrIndexed != 0 }
1008 func (a *Attribute) UsedInIface() bool { return a.load()&AttrUsedInIface != 0 }
1009 func (a *Attribute) ContentAddressable() bool { return a.load()&AttrContentAddressable != 0 }
1010 func (a *Attribute) ABIWrapper() bool { return a.load()&AttrABIWrapper != 0 }
1011 func (a *Attribute) IsPcdata() bool { return a.load()&AttrPcdata != 0 }
1012 func (a *Attribute) IsPkgInit() bool { return a.load()&AttrPkgInit != 0 }
1013 func (a *Attribute) IsLinkname() bool { return a.load()&AttrLinkname != 0 }
1014 func (a *Attribute) IsLinknameStd() bool { return a.load()&AttrLinknameStd != 0 }
1015
1016 func (a *Attribute) Set(flag Attribute, value bool) {
1017 for {
1018 v0 := a.load()
1019 v := v0
1020 if value {
1021 v |= flag
1022 } else {
1023 v &^= flag
1024 }
1025 if atomic.CompareAndSwapUint32((*uint32)(a), uint32(v0), uint32(v)) {
1026 break
1027 }
1028 }
1029 }
1030
1031 func (a *Attribute) ABI() ABI { return ABI(a.load() / attrABIBase) }
1032 func (a *Attribute) SetABI(abi ABI) {
1033 const mask = 1
1034 for {
1035 v0 := a.load()
1036 v := (v0 &^ (mask * attrABIBase)) | Attribute(abi)*attrABIBase
1037 if atomic.CompareAndSwapUint32((*uint32)(a), uint32(v0), uint32(v)) {
1038 break
1039 }
1040 }
1041 }
1042
1043 var textAttrStrings = [...]struct {
1044 bit Attribute
1045 s string
1046 }{
1047 {bit: AttrDuplicateOK, s: "DUPOK"},
1048 {bit: AttrMakeTypelink, s: ""},
1049 {bit: AttrCFunc, s: "CFUNC"},
1050 {bit: AttrNoSplit, s: "NOSPLIT"},
1051 {bit: AttrLeaf, s: "LEAF"},
1052 {bit: AttrOnList, s: ""},
1053 {bit: AttrReflectMethod, s: "REFLECTMETHOD"},
1054 {bit: AttrLocal, s: "LOCAL"},
1055 {bit: AttrWrapper, s: "WRAPPER"},
1056 {bit: AttrNeedCtxt, s: "NEEDCTXT"},
1057 {bit: AttrNoFrame, s: "NOFRAME"},
1058 {bit: AttrStatic, s: "STATIC"},
1059 {bit: AttrWasInlined, s: ""},
1060 {bit: AttrIndexed, s: ""},
1061 {bit: AttrContentAddressable, s: ""},
1062 {bit: AttrABIWrapper, s: "ABIWRAPPER"},
1063 {bit: AttrPkgInit, s: "PKGINIT"},
1064 {bit: AttrLinkname, s: "LINKNAME"},
1065 {bit: AttrLinknameStd, s: "LINKNAMESTD"},
1066 }
1067
1068
1069 func (a Attribute) String() string {
1070 var s string
1071 for _, x := range textAttrStrings {
1072 if a&x.bit != 0 {
1073 if x.s != "" {
1074 s += x.s + "|"
1075 }
1076 a &^= x.bit
1077 }
1078 }
1079 switch a.ABI() {
1080 case ABI0:
1081 case ABIInternal:
1082 s += "ABIInternal|"
1083 a.SetABI(0)
1084 }
1085 if a != 0 {
1086 s += fmt.Sprintf("UnknownAttribute(%d)|", a)
1087 }
1088
1089 if len(s) > 0 {
1090 s = s[:len(s)-1]
1091 }
1092 return s
1093 }
1094
1095
1096 func (s *LSym) TextAttrString() string {
1097 attr := s.Attribute.String()
1098 if s.Func().FuncFlag&abi.FuncFlagTopFrame != 0 {
1099 if attr != "" {
1100 attr += "|"
1101 }
1102 attr += "TOPFRAME"
1103 }
1104 return attr
1105 }
1106
1107 func (s *LSym) String() string {
1108 return s.Name
1109 }
1110
1111
1112 func (*LSym) CanBeAnSSASym() {}
1113 func (*LSym) CanBeAnSSAAux() {}
1114
1115 type Pcln struct {
1116
1117 Pcsp *LSym
1118 Pcfile *LSym
1119 Pcline *LSym
1120 Pcinline *LSym
1121 Pcdata []*LSym
1122 Funcdata []*LSym
1123 UsedFiles map[goobj.CUFileIndex]struct{}
1124 InlTree InlTree
1125 }
1126
1127 type Reloc struct {
1128 Off int32
1129 Siz uint8
1130 Type objabi.RelocType
1131 Add int64
1132 Sym *LSym
1133 }
1134
1135 type Auto struct {
1136 Asym *LSym
1137 Aoffset int32
1138 Name AddrName
1139 Gotype *LSym
1140 }
1141
1142
1143
1144
1145
1146
1147 type RegSpill struct {
1148 Addr Addr
1149 Reg int16
1150 Reg2 int16
1151 Spill, Unspill As
1152 }
1153
1154
1155 type Func interface {
1156 Pos() src.XPos
1157 }
1158
1159
1160
1161 type Link struct {
1162 Headtype objabi.HeadType
1163 Arch *LinkArch
1164 CompressInstructions bool
1165 Debugasm int
1166 Debugvlog bool
1167 Debugpcln string
1168 Flag_shared bool
1169 Flag_dynlink bool
1170 Flag_linkshared bool
1171 Flag_optimize bool
1172 Flag_locationlists bool
1173 Flag_noRefName bool
1174 Retpoline bool
1175 Flag_maymorestack string
1176 Bso *bufio.Writer
1177 Pathname string
1178 Pkgpath string
1179
1180 hashmu sync.Mutex
1181 hash sync.Map
1182 funchash sync.Map
1183 statichash map[string]*LSym
1184 PosTable src.PosTable
1185 InlTree InlTree
1186 DwFixups *DwarfFixupTable
1187 DwTextCount int
1188 Imports []goobj.ImportedPkg
1189 DiagFunc func(string, ...any)
1190 DiagFlush func()
1191 DebugInfo func(ctxt *Link, fn *LSym, info *LSym, curfn Func) ([]dwarf.Scope, dwarf.InlCalls)
1192 GenAbstractFunc func(fn *LSym)
1193 Errors int
1194
1195 InParallel bool
1196 UseBASEntries bool
1197 IsAsm bool
1198 Std bool
1199
1200
1201 Text []*LSym
1202 Data []*LSym
1203
1204
1205
1206
1207
1208 constSyms []*LSym
1209
1210
1211
1212 SEHSyms []*LSym
1213
1214
1215
1216 pkgIdx map[string]int32
1217
1218 defs []*LSym
1219 hashed64defs []*LSym
1220 hasheddefs []*LSym
1221 nonpkgdefs []*LSym
1222 nonpkgrefs []*LSym
1223
1224 Fingerprint goobj.FingerprintType
1225 }
1226
1227
1228
1229 type symOnce struct {
1230 sym LSym
1231 inited atomic.Bool
1232 }
1233
1234
1235 func _(ctxt *Link) {
1236 ctxt.DiagFunc = func(format string, args ...any) {
1237 _ = fmt.Sprintf(format, args...)
1238 }
1239 }
1240
1241 func (ctxt *Link) Diag(format string, args ...any) {
1242 ctxt.Errors++
1243 ctxt.DiagFunc(format, args...)
1244 }
1245
1246 func (ctxt *Link) Logf(format string, args ...any) {
1247 fmt.Fprintf(ctxt.Bso, format, args...)
1248 ctxt.Bso.Flush()
1249 }
1250
1251
1252
1253 func (fi *FuncInfo) SpillRegisterArgs(last *Prog, pa ProgAlloc) *Prog {
1254
1255 for _, ra := range fi.spills {
1256 spill := Appendp(last, pa)
1257 spill.As = ra.Spill
1258 spill.From.Type = TYPE_REG
1259 spill.From.Reg = ra.Reg
1260 if ra.Reg2 != 0 {
1261 spill.From.Type = TYPE_REGREG
1262 spill.From.Offset = int64(ra.Reg2)
1263 }
1264 spill.To = ra.Addr
1265 last = spill
1266 }
1267 return last
1268 }
1269
1270
1271
1272 func (fi *FuncInfo) UnspillRegisterArgs(last *Prog, pa ProgAlloc) *Prog {
1273
1274 for _, ra := range fi.spills {
1275 unspill := Appendp(last, pa)
1276 unspill.As = ra.Unspill
1277 unspill.From = ra.Addr
1278 unspill.To.Type = TYPE_REG
1279 unspill.To.Reg = ra.Reg
1280 if ra.Reg2 != 0 {
1281 unspill.To.Type = TYPE_REGREG
1282 unspill.To.Offset = int64(ra.Reg2)
1283 }
1284 last = unspill
1285 }
1286 return last
1287 }
1288
1289
1290 type LinkArch struct {
1291 *sys.Arch
1292 Init func(*Link)
1293 ErrorCheck func(*Link, *LSym)
1294 Preprocess func(*Link, *LSym, ProgAlloc)
1295 Assemble func(*Link, *LSym, ProgAlloc)
1296 Progedit func(*Link, *Prog, ProgAlloc)
1297 SEH func(*Link, *LSym) *LSym
1298 UnaryDst map[As]bool
1299 DWARFRegisters map[int16]int16
1300 }
1301
View as plain text