...
Source file
src/runtime/export_debug_amd64_test.go
Documentation: runtime
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 savedFP fpstate1
20 }
21
22 func sigctxtSetContextRegister(ctxt *sigctxt, x uint64) {
23 ctxt.regs().rdx = x
24 }
25
26 func sigctxtAtTrapInstruction(ctxt *sigctxt) bool {
27 return *(*byte)(unsafe.Pointer(uintptr(ctxt.rip() - 1))) == 0xcc
28 }
29
30 func sigctxtStatus(ctxt *sigctxt) uint64 {
31 return ctxt.r12()
32 }
33
34 func (h *debugCallHandler) saveSigContext(ctxt *sigctxt) {
35
36 rsp := ctxt.rsp() - goarch.PtrSize
37 *(*uint64)(unsafe.Pointer(uintptr(rsp))) = ctxt.rip()
38 ctxt.set_rsp(rsp)
39
40 *(*uintptr)(unsafe.Pointer(uintptr(rsp - 16))) = h.argSize
41
42 h.sigCtxt.savedRegs = *ctxt.regs()
43 h.sigCtxt.savedFP = *h.sigCtxt.savedRegs.fpstate
44 h.sigCtxt.savedRegs.fpstate = nil
45 }
46
47
48 func (h *debugCallHandler) debugCallRun(ctxt *sigctxt) {
49 rsp := ctxt.rsp()
50 memmove(unsafe.Pointer(uintptr(rsp)), h.argp, h.argSize)
51 if h.regArgs != nil {
52 storeRegArgs(ctxt.regs(), h.regArgs)
53 }
54
55 rsp -= goarch.PtrSize
56 ctxt.set_rsp(rsp)
57
58 *(*uint64)(unsafe.Pointer(uintptr(rsp))) = ctxt.rip()
59
60 ctxt.set_rip(uint64(h.fv.fn))
61 sigctxtSetContextRegister(ctxt, uint64(uintptr(unsafe.Pointer(h.fv))))
62 }
63
64
65 func (h *debugCallHandler) debugCallReturn(ctxt *sigctxt) {
66 rsp := ctxt.rsp()
67 memmove(h.argp, unsafe.Pointer(uintptr(rsp)), h.argSize)
68 if h.regArgs != nil {
69 loadRegArgs(h.regArgs, ctxt.regs())
70 }
71 }
72
73
74 func (h *debugCallHandler) debugCallPanicOut(ctxt *sigctxt) {
75 rsp := ctxt.rsp()
76 memmove(unsafe.Pointer(&h.panic), unsafe.Pointer(uintptr(rsp)), 2*goarch.PtrSize)
77 }
78
79
80 func (h *debugCallHandler) debugCallUnsafe(ctxt *sigctxt) {
81 rsp := ctxt.rsp()
82 reason := *(*string)(unsafe.Pointer(uintptr(rsp)))
83 h.err = plainError(reason)
84 }
85
86
87 func (h *debugCallHandler) restoreSigContext(ctxt *sigctxt) {
88
89 rip, rsp := ctxt.rip(), ctxt.rsp()
90 fp := ctxt.regs().fpstate
91 *ctxt.regs() = h.sigCtxt.savedRegs
92 ctxt.regs().fpstate = fp
93 *fp = h.sigCtxt.savedFP
94 ctxt.set_rip(rip)
95 ctxt.set_rsp(rsp)
96 }
97
98
99
100
101
102 func storeRegArgs(dst *sigcontext, src *abi.RegArgs) {
103 dst.rax = uint64(src.Ints[0])
104 dst.rbx = uint64(src.Ints[1])
105 dst.rcx = uint64(src.Ints[2])
106 dst.rdi = uint64(src.Ints[3])
107 dst.rsi = uint64(src.Ints[4])
108 dst.r8 = uint64(src.Ints[5])
109 dst.r9 = uint64(src.Ints[6])
110 dst.r10 = uint64(src.Ints[7])
111 dst.r11 = uint64(src.Ints[8])
112 for i := range src.Floats {
113 dst.fpstate._xmm[i].element[0] = uint32(src.Floats[i] >> 0)
114 dst.fpstate._xmm[i].element[1] = uint32(src.Floats[i] >> 32)
115 }
116 }
117
118 func loadRegArgs(dst *abi.RegArgs, src *sigcontext) {
119 dst.Ints[0] = uintptr(src.rax)
120 dst.Ints[1] = uintptr(src.rbx)
121 dst.Ints[2] = uintptr(src.rcx)
122 dst.Ints[3] = uintptr(src.rdi)
123 dst.Ints[4] = uintptr(src.rsi)
124 dst.Ints[5] = uintptr(src.r8)
125 dst.Ints[6] = uintptr(src.r9)
126 dst.Ints[7] = uintptr(src.r10)
127 dst.Ints[8] = uintptr(src.r11)
128 for i := range dst.Floats {
129 dst.Floats[i] = uint64(src.fpstate._xmm[i].element[0]) << 0
130 dst.Floats[i] |= uint64(src.fpstate._xmm[i].element[1]) << 32
131 }
132 }
133
View as plain text