Source file
src/runtime/export_debug_loong64_test.go
1
2
3
4
5
6
7 package runtime
8
9 import (
10 "internal/abi"
11 "internal/goarch"
12 "unsafe"
13 )
14
15 type sigContext struct {
16 savedRegs sigcontext
17 }
18
19 func sigctxtSetContextRegister(ctxt *sigctxt, x uint64) {
20 ctxt.regs().sc_regs[29] = x
21 }
22
23 func sigctxtAtTrapInstruction(ctxt *sigctxt) bool {
24 return *(*uint32)(unsafe.Pointer(ctxt.sigpc())) == 0x002a0000
25 }
26
27 func sigctxtStatus(ctxt *sigctxt) uint64 {
28 return ctxt.r19()
29 }
30
31 func (h *debugCallHandler) saveSigContext(ctxt *sigctxt) {
32 sp := ctxt.sp()
33 sp -= goarch.PtrSize
34 ctxt.set_sp(sp)
35 *(*uint64)(unsafe.Pointer(uintptr(sp))) = ctxt.link()
36 ctxt.set_link(ctxt.pc())
37
38 *(*uintptr)(unsafe.Pointer(uintptr(sp - 8))) = h.argSize
39
40 h.sigCtxt.savedRegs = *ctxt.regs()
41 }
42
43
44 func (h *debugCallHandler) debugCallRun(ctxt *sigctxt) {
45 sp := ctxt.sp()
46 memmove(unsafe.Pointer(uintptr(sp)+8), h.argp, h.argSize)
47 if h.regArgs != nil {
48 storeRegArgs(ctxt.regs(), h.regArgs)
49 }
50
51
52 ctxt.set_link(ctxt.pc() + 4)
53
54 ctxt.set_pc(uint64(h.fv.fn))
55 sigctxtSetContextRegister(ctxt, uint64(uintptr(unsafe.Pointer(h.fv))))
56 }
57
58
59 func (h *debugCallHandler) debugCallReturn(ctxt *sigctxt) {
60 sp := ctxt.sp()
61 memmove(h.argp, unsafe.Pointer(uintptr(sp)+8), h.argSize)
62 if h.regArgs != nil {
63 loadRegArgs(h.regArgs, ctxt.regs())
64 }
65
66 olr := *(*uint64)(unsafe.Pointer(uintptr(sp)))
67 ctxt.set_link(olr)
68 pc := ctxt.pc()
69 ctxt.set_pc(pc + 4)
70 }
71
72
73 func (h *debugCallHandler) debugCallPanicOut(ctxt *sigctxt) {
74 sp := ctxt.sp()
75 memmove(unsafe.Pointer(&h.panic), unsafe.Pointer(uintptr(sp)+8), 2*goarch.PtrSize)
76 ctxt.set_pc(ctxt.pc() + 4)
77 }
78
79
80 func (h *debugCallHandler) debugCallUnsafe(ctxt *sigctxt) {
81 sp := ctxt.sp()
82 reason := *(*string)(unsafe.Pointer(uintptr(sp) + 8))
83 h.err = plainError(reason)
84 ctxt.set_pc(ctxt.pc() + 4)
85 }
86
87
88 func (h *debugCallHandler) restoreSigContext(ctxt *sigctxt) {
89
90 pc, sp := ctxt.pc(), ctxt.sp()
91 *ctxt.regs() = h.sigCtxt.savedRegs
92 ctxt.set_pc(pc + 4)
93 ctxt.set_sp(sp)
94 }
95
96 func getVal32(base uintptr, off uintptr) uint32 {
97 return *(*uint32)(unsafe.Pointer(base + off))
98 }
99
100 func getVal64(base uintptr, off uintptr) uint64 {
101 return *(*uint64)(unsafe.Pointer(base + off))
102 }
103
104 func setVal64(base uintptr, off uintptr, val uint64) {
105 *(*uint64)(unsafe.Pointer(base + off)) = val
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119 const (
120 INVALID_MAGIC uint32 = 0
121 FPU_CTX_MAGIC = 0x46505501
122 LSX_CTX_MAGIC = 0x53580001
123 LASX_CTX_MAGIC = 0x41535801
124 LBT_CTX_MAGIC = 0x42540001
125 )
126
127 const (
128 SCTX_INFO_SIZE = 4 + 4 + 8
129 FPU_CTX_SIZE = 8*32 + 8 + 4
130 LSX_CTX_SIZE = 8*64 + 8 + 4
131 LASX_CTX_SIZE = 8*128 + 8 + 4
132 LBT_CTX_SIZE = 8*4 + 4 + 4
133 )
134
135
136
137
138
139 func storeRegArgs(dst *sigcontext, src *abi.RegArgs) {
140
141 for i := 0; i < abi.IntArgRegs; i++ {
142 dst.sc_regs[i+4] = (uint64)(src.Ints[i])
143 }
144
145
146 offset := (uintptr)(0)
147 baseAddr := (uintptr)(unsafe.Pointer(&dst.sc_extcontext))
148
149 for {
150 magic := getVal32(baseAddr, offset)
151 size := getVal32(baseAddr, offset+4)
152
153 switch magic {
154 case INVALID_MAGIC:
155 return
156
157 case FPU_CTX_MAGIC:
158 offset += SCTX_INFO_SIZE
159 for i := 0; i < abi.FloatArgRegs; i++ {
160 setVal64(baseAddr, ((uintptr)(i*8) + offset), src.Floats[i])
161 }
162 return
163
164 case LSX_CTX_MAGIC:
165 offset += SCTX_INFO_SIZE
166 for i := 0; i < abi.FloatArgRegs; i++ {
167 setVal64(baseAddr, ((uintptr)(i*16) + offset), src.Floats[i])
168 }
169 return
170
171 case LASX_CTX_MAGIC:
172 offset += SCTX_INFO_SIZE
173 for i := 0; i < abi.FloatArgRegs; i++ {
174 setVal64(baseAddr, ((uintptr)(i*32) + offset), src.Floats[i])
175 }
176 return
177
178 case LBT_CTX_MAGIC:
179 offset += uintptr(size)
180 }
181 }
182 }
183
184 func loadRegArgs(dst *abi.RegArgs, src *sigcontext) {
185
186 for i := 0; i < abi.IntArgRegs; i++ {
187 dst.Ints[i] = uintptr(src.sc_regs[i+4])
188 }
189
190
191 offset := (uintptr)(0)
192 baseAddr := (uintptr)(unsafe.Pointer(&src.sc_extcontext))
193
194 for {
195 magic := getVal32(baseAddr, offset)
196 size := getVal32(baseAddr, (offset + 4))
197
198 switch magic {
199 case INVALID_MAGIC:
200 return
201
202 case FPU_CTX_MAGIC:
203 offset += SCTX_INFO_SIZE
204 for i := 0; i < abi.FloatArgRegs; i++ {
205 dst.Floats[i] = getVal64(baseAddr, (uintptr(i*8) + offset))
206 }
207 return
208
209 case LSX_CTX_MAGIC:
210 offset += SCTX_INFO_SIZE
211 for i := 0; i < abi.FloatArgRegs; i++ {
212 dst.Floats[i] = getVal64(baseAddr, (uintptr(i*16) + offset))
213 }
214 return
215
216 case LASX_CTX_MAGIC:
217 offset += SCTX_INFO_SIZE
218 for i := 0; i < abi.FloatArgRegs; i++ {
219 dst.Floats[i] = getVal64(baseAddr, (uintptr(i*32) + offset))
220 }
221 return
222
223 case LBT_CTX_MAGIC:
224 offset += uintptr(size)
225 }
226 }
227 }
228
View as plain text