1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef DFX_REGS_GET_H
16 #define DFX_REGS_GET_H
17
18 #include <cstdint>
19 #include <string>
20 #include <memory>
21 #include <vector>
22 #include "dfx_define.h"
23
24 namespace OHOS {
25 namespace HiviewDFX {
26
27 #if defined(__arm__)
28
GetLocalRegs(void * regs)29 inline AT_ALWAYS_INLINE void GetLocalRegs(void* regs)
30 {
31 asm volatile(
32 ".align 2\n"
33 "bx pc\n"
34 "nop\n"
35 ".code 32\n"
36 "stmia %[base], {r0-r12}\n"
37 "add %[base], #52\n"
38 "mov r1, r13\n"
39 "mov r2, r14\n"
40 "mov r3, r15\n"
41 "stmia %[base], {r1-r3}\n"
42 "orr %[base], pc, #1\n"
43 "bx %[base]\n"
44 : [base] "+r"(regs)
45 :
46 : "memory");
47 }
48
49 // Only get 4 registers(r7/r11/sp/pc)
GetFramePointerMiniRegs(void * regs)50 inline AT_ALWAYS_INLINE void GetFramePointerMiniRegs(void *regs)
51 {
52 asm volatile(
53 ".align 2\n"
54 "bx pc\n"
55 "nop\n"
56 ".code 32\n"
57 "stmia %[base], {r7, r11}\n"
58 "add %[base], #8\n"
59 "mov r1, r13\n"
60 "mov r2, r15\n"
61 "stmia %[base], {r1, r2}\n"
62 "orr %[base], pc, #1\n"
63 "bx %[base]\n"
64 : [base] "+r"(regs)
65 :
66 : "r1", "r2", "memory");
67 }
68
69 // Fill regs[7] with [r4, r7, r10, r11, sp, pc, unset].
GetQuickenMiniRegsAsm(void * regs)70 inline AT_ALWAYS_INLINE void GetQuickenMiniRegsAsm(void *regs)
71 {
72 asm volatile(
73 ".align 2\n"
74 "bx pc\n"
75 "nop\n"
76 ".code 32\n"
77 "stmia %[base], {r4, r7, r10, r11}\n"
78 "add %[base], #16\n"
79 "mov r1, r13\n"
80 "mov r2, r15\n"
81 "stmia %[base], {r1, r2}\n"
82 "orr %[base], pc, #1\n"
83 "bx %[base]\n"
84 : [base] "+r"(regs)
85 :
86 : "r1", "r2", "memory");
87 }
88
89 #elif defined(__aarch64__)
90
91 inline AT_ALWAYS_INLINE void GetLocalRegs(void* regs)
92 {
93 asm volatile(
94 "1:\n"
95 "stp x0, x1, [%[base], #0]\n"
96 "stp x2, x3, [%[base], #16]\n"
97 "stp x4, x5, [%[base], #32]\n"
98 "stp x6, x7, [%[base], #48]\n"
99 "stp x8, x9, [%[base], #64]\n"
100 "stp x10, x11, [%[base], #80]\n"
101 "stp x12, x13, [%[base], #96]\n"
102 "stp x14, x15, [%[base], #112]\n"
103 "stp x16, x17, [%[base], #128]\n"
104 "stp x18, x19, [%[base], #144]\n"
105 "stp x20, x21, [%[base], #160]\n"
106 "stp x22, x23, [%[base], #176]\n"
107 "stp x24, x25, [%[base], #192]\n"
108 "stp x26, x27, [%[base], #208]\n"
109 "stp x28, x29, [%[base], #224]\n"
110 "str x30, [%[base], #240]\n"
111 "mov x12, sp\n"
112 "adr x13, 1b\n"
113 "stp x12, x13, [%[base], #248]\n"
114 : [base] "+r"(regs)
115 :
116 : "x12", "x13", "memory");
117 }
118
119 // Only get 4 registers from x29 to x32.
120 inline AT_ALWAYS_INLINE void GetFramePointerMiniRegs(void *regs)
121 {
122 asm volatile(
123 "1:\n"
124 "stp x29, x30, [%[base], #0]\n"
125 "mov x12, sp\n"
126 "adr x13, 1b\n"
127 "stp x12, x13, [%[base], #16]\n"
128 : [base] "+r"(regs)
129 :
130 : "x12", "x13", "memory");
131 }
132
133 // Fill regs[7] with [unuse, unset, x28, x29, sp, pc, unset].
134 inline AT_ALWAYS_INLINE void GetQuickenMiniRegsAsm(void *regs)
135 {
136 asm volatile(
137 "1:\n"
138 "stp x28, x29, [%[base], #16]\n"
139 "mov x12, sp\n"
140 "adr x13, 1b\n"
141 "stp x12, x13, [%[base], #32]\n"
142 : [base] "+r"(regs)
143 :
144 : "x12", "x13", "memory");
145 }
146
147 #elif defined(__x86_64__)
148
149 inline AT_ALWAYS_INLINE void GetLocalRegs(void* regs)
150 {
151 }
152
153 inline AT_ALWAYS_INLINE void GetFramePointerMiniRegs(void *regs)
154 {
155 }
156
157 inline AT_ALWAYS_INLINE void GetQuickenMiniRegsAsm(void *regs)
158 {
159 }
160
161 #elif defined(__riscv) && __riscv_xlen == 64
162
163 //future work
164 inline AT_ALWAYS_INLINE void GetLocalRegs(void* regs)
165 {
166 }
167
168 inline AT_ALWAYS_INLINE void GetFramePointerMiniRegs(void *regs)
169 {
170 }
171
172 inline AT_ALWAYS_INLINE void GetQuickenMiniRegsAsm(void *regs)
173 {
174 }
175
176 #endif
177 } // namespace HiviewDFX
178 } // namespace OHOS
179 #endif
180