Source file
src/runtime/export_debug_arm64_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().regs[26] = x
21 }
22
23 func sigctxtAtTrapInstruction(ctxt *sigctxt) bool {
24 return *(*uint32)(unsafe.Pointer(ctxt.sigpc())) == 0xd4200000
25 }
26
27 func sigctxtStatus(ctxt *sigctxt) uint64 {
28 return ctxt.r20()
29 }
30
31 func (h *debugCallHandler) saveSigContext(ctxt *sigctxt) {
32 sp := ctxt.sp()
33 sp -= 2 * goarch.PtrSize
34 ctxt.set_sp(sp)
35 *(*uint64)(unsafe.Pointer(uintptr(sp))) = ctxt.lr()
36 ctxt.set_lr(ctxt.pc())
37
38 *(*uintptr)(unsafe.Pointer(uintptr(sp - 16))) = 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_lr(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_lr(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
97
98
99
100 func storeRegArgs(dst *sigcontext, src *abi.RegArgs) {
101 for i, r := range src.Ints {
102 dst.regs[i] = uint64(r)
103 }
104 for i, r := range src.Floats {
105 *(fpRegAddr(dst, i)) = r
106 }
107 }
108
109 func loadRegArgs(dst *abi.RegArgs, src *sigcontext) {
110 for i := range dst.Ints {
111 dst.Ints[i] = uintptr(src.regs[i])
112 }
113 for i := range dst.Floats {
114 dst.Floats[i] = *(fpRegAddr(src, i))
115 }
116 }
117
118
119 func fpRegAddr(dst *sigcontext, i int) *uint64 {
120
134 return (*uint64)(unsafe.Pointer(&dst.__reserved[16+i*128]))
135 }
136
View as plain text