704ad0450941a5eaed588b2b06092bbcf3f900d5
[kernel/swap-modules.git] / kprobe / arch / asm-arm / dbi_kprobes.h
1 #ifndef _DBI_ASM_ARM_KPROBES_H
2 #define _DBI_ASM_ARM_KPROBES_H
3
4 /*
5  *  Dynamic Binary Instrumentation Module based on KProbes
6  *  modules/kprobe/arch/asm-arm/dbi_kprobes.h
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  *
22  * Copyright (C) Samsung Electronics, 2006-2010
23  *
24  * 2006-2007    Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM/MIPS
25  * 2008-2009    Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
26  *              Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
27  * 2010         Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
28  *
29  * 2010-2011    Alexander Shirshikov <a.shirshikov@samsung.com>: initial implementation for Thumb
30  */
31
32 #include <linux/sched.h>
33 #include <linux/compiler.h>
34
35 typedef unsigned long kprobe_opcode_t;
36
37 #ifdef CONFIG_CPU_S3C2443
38 #define BREAKPOINT_INSTRUCTION          0xe1200070
39 #else
40 #define BREAKPOINT_INSTRUCTION          0xffffdeff
41 #endif /* CONFIG_CPU_S3C2443 */
42
43 #ifndef KPROBES_RET_PROBE_TRAMP
44
45 #ifdef CONFIG_CPU_S3C2443
46 #define UNDEF_INSTRUCTION               0xe1200071
47 #else
48 #define UNDEF_INSTRUCTION               0xfffffffe
49 #endif /* CONFIG_CPU_S3C2443 */
50
51 #endif /* KPROBES_RET_PROBE_TRAMP */
52
53 #define MAX_INSN_SIZE                   1
54
55 #define UPROBES_TRAMP_LEN              9 * 4
56 # define UPROBES_TRAMP_INSN_IDX         2
57 # define UPROBES_TRAMP_SS_BREAK_IDX     4
58 # define UPROBES_TRAMP_RET_BREAK_IDX    5
59 #define KPROBES_TRAMP_LEN              9 * 4
60 # define KPROBES_TRAMP_INSN_IDX         UPROBES_TRAMP_INSN_IDX
61 # define KPROBES_TRAMP_SS_BREAK_IDX     UPROBES_TRAMP_SS_BREAK_IDX
62
63 /* TODO: remove (not needed for kprobe) */
64 # define KPROBES_TRAMP_RET_BREAK_IDX    UPROBES_TRAMP_RET_BREAK_IDX
65
66 #define UREGS_OFFSET 8
67
68 struct prev_kprobe {
69         struct kprobe *kp;
70         unsigned long status;
71 };
72
73 static inline unsigned long arch_get_task_pc(struct task_struct *p)
74 {
75         return task_thread_info(p)->cpu_context.pc;
76 }
77
78 static inline void arch_set_task_pc(struct task_struct *p, unsigned long val)
79 {
80         task_thread_info(p)->cpu_context.pc = val;
81 }
82
83 static inline struct pt_regs *dbi_get_syscall_uregs(unsigned long sp)
84 {
85         return (struct pt_regs *)(sp + UREGS_OFFSET);
86 }
87
88 static inline unsigned long dbi_get_stack_ptr(struct pt_regs *regs)
89 {
90         return regs->ARM_sp;
91 }
92
93 static inline unsigned long dbi_get_instr_ptr(struct pt_regs *regs)
94 {
95         return regs->ARM_pc;
96 }
97
98 static inline void dbi_set_instr_ptr(struct pt_regs *regs, unsigned long val)
99 {
100         regs->ARM_pc = val;
101 }
102
103 static inline unsigned long dbi_get_ret_addr(struct pt_regs *regs)
104 {
105         return regs->ARM_lr;
106 }
107
108 static inline void dbi_set_ret_addr(struct pt_regs *regs, unsigned long val)
109 {
110         regs->ARM_lr = val;
111 }
112
113 static inline unsigned long dbi_get_arg(struct pt_regs *regs, int num)
114 {
115         return regs->uregs[num];
116 }
117
118 static inline void dbi_set_arg(struct pt_regs *regs, int num, unsigned long val)
119 {
120         regs->uregs[num] = val;
121 }
122
123 // undefined
124 # define MASK_ARM_INSN_UNDEF            0x0FF00000              // xxxx1111 1111xxxx xxxxxxxx xxxxxxxx
125 # define PTRN_ARM_INSN_UNDEF            0x03000000              // cccc0011 0000xxxx xxxxxxxx xxxxxxxx
126
127 # define MASK_THUMB_INSN_UNDEF          0xFE00                  // 11111111xxxxxxxx
128 # define PTRN_THUMB_INSN_UNDEF          0xDE00                  // 11011110xxxxxxxx
129
130 // architecturally undefined
131 # define MASK_ARM_INSN_AUNDEF           0x0FF000F0
132 # define PTRN_ARM_INSN_AUNDEF           0x07F000F0
133
134 // branches
135 # define MASK_ARM_INSN_B                0x0F000000              // xxxx1111xxxxxxxxxxxxxxxxxxxxxxxx
136 # define PTRN_ARM_INSN_B                0x0A000000              // cccc1010xxxxxxxxxxxxxxxxxxxxxxxx
137
138 # define MASK_THUMB_INSN_B1             0xF000                  // 1111xxxxxxxxxxxx
139 # define PTRN_THUMB_INSN_B1             0xD000                  // 1101xxxxxxxxxxxx                                             // b<cond> label
140
141 # define MASK_THUMB_INSN_B2             0xF800                  // 11111xxxxxxxxxxx
142 # define PTRN_THUMB_INSN_B2             0xE000                  // 11100xxxxxxxxxxx                                             // b label
143
144 # define MASK_THUMB_INSN_CBZ            0xF500                  // 1111x1x1xxxxxxxx
145 # define PTRN_THUMB_INSN_CBZ            0xB100                  // 1011x0x1xxxxxxxx                                             // CBZ/CBNZ
146
147 # define MASK_THUMB2_INSN_B1            0xD000F800              // 11x1xxxxxxxxxxxx 11111xxxxxxxxxxx                            // swapped
148 # define PTRN_THUMB2_INSN_B1            0x8000F000              // 10x0xxxxxxxxxxxx 11110xxxxxxxxxxx                            // swapped
149
150 # define MASK_THUMB2_INSN_B2            0xD000F800              // 11x1xxxxxxxxxxxx 11111xxxxxxxxxxx                            // swapped
151 # define PTRN_THUMB2_INSN_B2            0x9000F000              // 10x1xxxxxxxxxxxx 11110xxxxxxxxxxx                            // swapped
152
153 # define MASK_ARM_INSN_BL               0x0F000000              // xxxx1111xxxxxxxxxxxxxxxxxxxxxxxx
154 # define PTRN_ARM_INSN_BL               0x0B000000              // cccc1011xxxxxxxxxxxxxxxxxxxxxxxx
155
156 //# define MASK_THUMB_INSN_BL           0xF800                  // 11111xxxxxxxxxxx
157 //# define PTRN_THUMB_INSN_BL           0xF000                  // 11110xxxxxxxxxxx                                             // shared between BL and BLX
158 //# define PTRN_THUMB_INSN_BL           0xF800                  // 11111xxxxxxxxxxx
159
160 # define MASK_THUMB2_INSN_BL            0xD000F800              // 11x1xxxxxxxxxxxx 11111xxxxxxxxxxx                            // swapped
161 # define PTRN_THUMB2_INSN_BL            0xD000F000              // 11x1xxxxxxxxxxxx 11110xxxxxxxxxxx                            // bl imm  swapped
162
163 # define MASK_ARM_INSN_BLX1             0xFE000000              // 1111111axxxxxxxxxxxxxxxxxxxxxxxx
164 # define PTRN_ARM_INSN_BLX1             0xFA000000              // 1111101axxxxxxxxxxxxxxxxxxxxxxxx
165
166 //# define MASK_THUMB_INSN_BLX1         0xF800                  // 11111xxxxxxxxxxx                                             / blx imm
167 //# define PTRN_THUMB_INSN_BLX1         0xF000                  // 11101xxxxxxxxxxx
168
169 # define MASK_THUMB2_INSN_BLX1          0xD001F800              // 11x1xxxxxxxxxxx1 11111xxxxxxxxxxx                            // swapped
170 # define PTRN_THUMB2_INSN_BLX1          0xC000F000              // 11x0xxxxxxxxxxx0 11110xxxxxxxxxxx                            // swapped
171
172 # define MASK_ARM_INSN_BLX2             0x0FF000F0              // xxxx11111111xxxxxxxxxxxx1111xxxx
173 # define PTRN_ARM_INSN_BLX2             0x01200030              // cccc00010010xxxxxxxxxxxx0011xxxx
174
175 # define MASK_THUMB_INSN_BLX2           0xFF80                  // 111111111xxxxxxx                                             / blx reg
176 # define PTRN_THUMB_INSN_BLX2           0x4780                  // 010001111xxxxxxx
177
178 # define MASK_ARM_INSN_BX               0x0FF000F0              // cccc11111111xxxxxxxxxxxx1111xxxx
179 # define PTRN_ARM_INSN_BX               0x01200010              // cccc00010010xxxxxxxxxxxx0001xxxx
180
181 # define MASK_THUMB_INSN_BX             0xFF80                  // 111111111xxxxxxx
182 # define PTRN_THUMB_INSN_BX             0x4700                  // 010001110xxxxxxx
183
184 # define MASK_ARM_INSN_BXJ              0x0FF000F0              // xxxx11111111xxxxxxxxxxxx1111xxxx
185 # define PTRN_ARM_INSN_BXJ              0x01200020              // cccc00010010xxxxxxxxxxxx0010xxxx
186
187 # define MASK_THUMB2_INSN_BXJ           0xD000FFF0              // 11x1xxxxxxxxxxxx 111111111111xxxx                            // swapped
188 # define PTRN_THUMB2_INSN_BXJ           0x8000F3C0              // 10x0xxxxxxxxxxxx 111100111100xxxx                            // swapped
189
190
191 // software interrupts
192 # define MASK_ARM_INSN_SWI              0x0F000000              // cccc1111xxxxxxxxxxxxxxxxxxxxxxxx
193 # define PTRN_ARM_INSN_SWI              0x0F000000              // cccc1111xxxxxxxxxxxxxxxxxxxxxxxx
194
195 # define MASK_THUMB_INSN_SWI            0xFF00                  // 11111111xxxxxxxx
196 # define PTRN_THUMB_INSN_SWI            0xDF00                  // 11011111xxxxxxxx
197
198 // break
199 # define MASK_ARM_INSN_BREAK            0xFFF000F0              // 111111111111xxxxxxxxxxxx1111xxxx
200 # define PTRN_ARM_INSN_BREAK            0xE1200070              // 111000010010xxxxxxxxxxxx0111xxxx                             /? A8-56 ARM DDI 046B if cond != ‘1110’ then UNPREDICTABLE;
201
202 # define MASK_THUMB_INSN_BREAK          0xFF00                  // 11111111xxxxxxxx
203 # define PTRN_THUMB_INSN_BREAK          0xBE00                  // 10111110xxxxxxxx
204
205 // CLZ
206 # define MASK_ARM_INSN_CLZ              0x0FFF0FF0              // xxxx111111111111xxxx11111111xxxx
207 # define PTRN_ARM_INSN_CLZ              0x016F0F10              // cccc000101101111xxxx11110001xxxx
208
209 // Data processing immediate shift
210 # define MASK_ARM_INSN_DPIS             0x0E000010
211 # define PTRN_ARM_INSN_DPIS             0x00000000
212 // Data processing register shift
213 # define MASK_ARM_INSN_DPRS             0x0E000090
214 # define PTRN_ARM_INSN_DPRS             0x00000010
215
216 # define MASK_THUMB2_INSN_DPRS          0xFFE00000              // 11111111111xxxxxxxxxxxxxxxxxxxxx
217 # define PTRN_THUMB2_INSN_DPRS          0xEA000000              // 1110101xxxxxxxxxxxxxxxxxxxxxxxxx
218
219 // Data processing immediate
220 # define MASK_ARM_INSN_DPI              0x0E000000
221 # define PTRN_ARM_INSN_DPI              0x02000000
222
223 # define MASK_THUMB_INSN_DP             0xFC00                  // 111111xxxxxxxxxx
224 # define PTRN_THUMB_INSN_DP             0x4000                  // 010000xxxxxxxxxx
225
226 # define MASK_THUMB_INSN_APC            0xF800                  // 11111xxxxxxxxxxx
227 # define PTRN_THUMB_INSN_APC            0xA000                  // 10100xxxxxxxxxxx     ADD Rd, [PC, #<imm8> * 4]
228
229 # define MASK_THUMB2_INSN_DPI           0xFBE08000              // 11111x11111xxxxx 1xxxxxxxxxxxxxxx
230 //# define PTRN_THUMB2_INSN_DPI         0xF0000000              // 11110x0xxxxxxxxx 0xxxxxxxxxxxxxxx                            /? A6-19 ARM DDI 0406B
231 # define PTRN_THUMB2_INSN_DPI           0xF2000000              // 11110x1xxxxxxxxx 0xxxxxxxxxxxxxxx                            /? A6-19 ARM DDI 0406B
232
233 # define MASK_THUMB_INSN_MOV3           0xFF00                  // 11111111xxxxxxxx
234 # define PTRN_THUMB_INSN_MOV3           0x4600                  // 01000110xxxxxxxx     MOV Rd, PC
235
236 # define MASK_THUMB2_INSN_RSBW          0x8000fbe0              // 1xxxxxxxxxxxxxxx 11111x11111xxxxx    // swapped
237 # define PTRN_THUMB2_INSN_RSBW          0x0000f1c0              // 0xxxxxxxxxxxxxxx 11110x01110xxxxx    RSB{S}.W Rd, Rn, #<const> // swapped
238
239 # define MASK_THUMB2_INSN_RORW          0xf0f0ffe0              // 1111xxxx1111xxxx 11111111111xxxxx    // swapped
240 # define PTRN_THUMB2_INSN_RORW          0xf000fa60              // 1111xxxx0000xxxx 11111010011xxxxx    ROR{S}.W Rd, Rn, Rm // swapped
241
242 # define MASK_THUMB2_INSN_ROR           0x0030ffef              // xxxxxxxxxx11xxxx 11111111111x1111    // swapped
243 # define PTRN_THUMB2_INSN_ROR           0x0030ea4f              // xxxxxxxxxx11xxxx 11101010010x1111    ROR{S} Rd, Rm, #<imm> // swapped
244
245 # define MASK_THUMB2_INSN_LSLW1         0xf0f0ffe0              // 1111xxxx1111xxxx 11111111111xxxxx    // swapped
246 # define PTRN_THUMB2_INSN_LSLW1         0xf000fa00              // 1111xxxx0000xxxx 11111010000xxxxx    LSL{S}.W Rd, Rn, Rm // swapped
247
248 # define MASK_THUMB2_INSN_LSLW2         0x0030ffef              // xxxxxxxxxx11xxxx 11111111111x1111    // swapped
249 # define PTRN_THUMB2_INSN_LSLW2         0x0000ea4f              // xxxxxxxxxx00xxxx 11101010010x1111    LSL{S}.W Rd, Rm, #<imm5> // swapped
250
251 # define MASK_THUMB2_INSN_LSRW1         0xf0f0ffe0              // 1111xxxx1111xxxx 11111111111xxxxx    // swapped
252 # define PTRN_THUMB2_INSN_LSRW1         0xf000fa20              // 1111xxxx0000xxxx 11111010001xxxxx    LSR{S}.W Rd, Rn, Rm // swapped
253
254 # define MASK_THUMB2_INSN_LSRW2         0x0030ffef              // xxxxxxxxxx11xxxx 11111111111x1111    // swapped
255 # define PTRN_THUMB2_INSN_LSRW2         0x0010ea4f              // xxxxxxxxxx01xxxx 11101010010x1111    LSR{S}.W Rd, Rm, #<imm5> // swapped
256
257 # define MASK_THUMB2_INSN_TEQ1          0x8f00fbf0              // 1xxx1111xxxxxxxx 11111x111111xxxx    // swapped
258 # define PTRN_THUMB2_INSN_TEQ1          0x0f00f090              // 0xxx1111xxxxxxxx 11110x001001xxxx    TEQ Rn, #<const> // swapped
259
260 # define MASK_THUMB2_INSN_TEQ2          0x0f00fff0              // xxxx1111xxxxxxxx 111111111111xxxx    // swapped
261 # define PTRN_THUMB2_INSN_TEQ2          0x0f00ea90              // xxxx1111xxxxxxxx 111010101001xxxx    TEQ Rn, Rm{,<shift>} // swapped
262
263 # define MASK_THUMB2_INSN_TST1          0x8f00fbf0              // 1xxx1111xxxxxxxx 11111x111111xxxx    // swapped
264 # define PTRN_THUMB2_INSN_TST1          0x0f00f010              // 0xxx1111xxxxxxxx 11110x000001xxxx    TST Rn, #<const> // swapped
265
266 # define MASK_THUMB2_INSN_TST2          0x0f00fff0              // xxxx1111xxxxxxxx 111111111111xxxx    // swapped
267 # define PTRN_THUMB2_INSN_TST2          0x0f00ea10              // xxxx1111xxxxxxxx 111010100001xxxx    TST Rn, Rm{,<shift>} // swapped
268
269
270 // Load immediate offset
271 # define MASK_ARM_INSN_LIO              0x0E100000
272 # define PTRN_ARM_INSN_LIO              0x04100000
273
274 # define MASK_THUMB_INSN_LIO1           0xF800                  // 11111xxxxxxxxxxx
275 # define PTRN_THUMB_INSN_LIO1           0x6800                  // 01101xxxxxxxxxxx     LDR
276
277 # define MASK_THUMB_INSN_LIO2           MASK_THUMB_INSN_LIO1
278 # define PTRN_THUMB_INSN_LIO2           0x7800                  // 01111xxxxxxxxxxx     LDRB
279
280 # define MASK_THUMB_INSN_LIO3           MASK_THUMB_INSN_LIO1
281 # define PTRN_THUMB_INSN_LIO3           0x8800                  // 10001xxxxxxxxxxx     LDRH
282
283 # define MASK_THUMB_INSN_LIO4           MASK_THUMB_INSN_LIO1
284 # define PTRN_THUMB_INSN_LIO4           0x9800                  // 10011xxxxxxxxxxx     LDR SP relative
285
286 # define MASK_THUMB2_INSN_LDRW          0x0000fff0              // xxxxxxxxxxxxxxxx 111111111111xxxx    // swapped
287 # define PTRN_THUMB2_INSN_LDRW          0x0000f850              // xxxxxxxxxxxxxxxx 111110000101xxxx    LDR.W Rt, [Rn, #-<imm12>]// swapped
288
289 # define MASK_THUMB2_INSN_LDRW1         MASK_THUMB2_INSN_LDRW
290 # define PTRN_THUMB2_INSN_LDRW1         0x0000f8d0              // xxxxxxxxxxxxxxxx 111110001101xxxx    LDR.W Rt, [Rn, #<imm12>]// swapped
291
292 # define MASK_THUMB2_INSN_LDRBW         MASK_THUMB2_INSN_LDRW
293 # define PTRN_THUMB2_INSN_LDRBW         0x0000f810              // xxxxxxxxxxxxxxxx 111110000001xxxx    LDRB.W Rt, [Rn, #-<imm8>]// swapped
294
295 # define MASK_THUMB2_INSN_LDRBW1        MASK_THUMB2_INSN_LDRW
296 # define PTRN_THUMB2_INSN_LDRBW1        0x0000f890              // xxxxxxxxxxxxxxxx 111110001001xxxx    LDRB.W Rt, [Rn, #<imm12>]// swapped
297
298 # define MASK_THUMB2_INSN_LDRHW         MASK_THUMB2_INSN_LDRW
299 # define PTRN_THUMB2_INSN_LDRHW         0x0000f830              // xxxxxxxxxxxxxxxx 111110000011xxxx    LDRH.W Rt, [Rn, #-<imm8>]// swapped
300
301 # define MASK_THUMB2_INSN_LDRHW1        MASK_THUMB2_INSN_LDRW
302 # define PTRN_THUMB2_INSN_LDRHW1        0x0000f8b0              // xxxxxxxxxxxxxxxx 111110001011xxxx    LDRH.W Rt, [Rn, #<imm12>]// swapped
303
304 # define MASK_THUMB2_INSN_LDRD          0x0000fed0              // xxxxxxxxxxxxxxxx 1111111x11x1xxxx    // swapped
305 # define PTRN_THUMB2_INSN_LDRD          0x0000e850              // xxxxxxxxxxxxxxxx 1110100x01x1xxxx    LDRD Rt, Rt2, [Rn, #-<imm8>]// swapped
306
307 # define MASK_THUMB2_INSN_LDRD1         MASK_THUMB2_INSN_LDRD
308 # define PTRN_THUMB2_INSN_LDRD1         0x0000e8d0              // xxxxxxxxxxxxxxxx 1110100x11x1xxxx    LDRD Rt, Rt2, [Rn, #<imm8>]// swapped
309
310 # define MASK_THUMB2_INSN_LDRWL         0x0fc0fff0              // xxxx111111xxxxxx 111111111111xxxx    // swapped
311 # define PTRN_THUMB2_INSN_LDRWL         0x0000f850              // xxxxxxxxxxxxxxxx 111110000101xxxx    LDR.W Rt, [Rn, Rm, LSL #<imm2>]// swapped
312
313 # define MASK_THUMB2_INSN_LDREX         0x0f00ffff              // xxxx1111xxxxxxxx 1111111111111111    // swapped
314 # define PTRN_THUMB2_INSN_LDREX         0x0f00e85f              // xxxx1111xxxxxxxx 1110100001011111    LDREX Rt, [PC, #<imm8>]// swapped
315
316 # define MASK_THUMB2_INSN_MUL           0xf0f0fff0              // 1111xxxx1111xxxx 111111111111xxxx    // swapped
317 # define PTRN_THUMB2_INSN_MUL           0xf000fb00              // 1111xxxx0000xxxx 111110110000xxxx    MUL Rd, Rn, Rm// swapped
318
319 # define MASK_THUMB2_INSN_DP            0x0000ff00              // xxxxxxxxxxxxxxxx 11111111xxxxxxxx    // swapped
320 # define PTRN_THUMB2_INSN_DP            0x0000eb00              // xxxxxxxxxxxxxxxx 11101011xxxxxxxx    // swapped      ADD/SUB/SBC/...Rd, Rn, Rm{,<shift>}
321
322
323
324
325 // Store immediate offset
326 # define MASK_ARM_INSN_SIO              MASK_ARM_INSN_LIO
327 # define PTRN_ARM_INSN_SIO              0x04000000
328
329 # define MASK_THUMB_INSN_SIO1           MASK_THUMB_INSN_LIO1
330 # define PTRN_THUMB_INSN_SIO1           0x6000                  // 01100xxxxxxxxxxx     STR
331
332 # define MASK_THUMB_INSN_SIO2           MASK_THUMB_INSN_LIO1
333 # define PTRN_THUMB_INSN_SIO2           0x7000                  // 01110xxxxxxxxxxx     STRB
334
335 # define MASK_THUMB_INSN_SIO3           MASK_THUMB_INSN_LIO1
336 # define PTRN_THUMB_INSN_SIO3           0x8000                  // 10000xxxxxxxxxxx     STRH
337
338 # define MASK_THUMB_INSN_SIO4           MASK_THUMB_INSN_LIO1
339 # define PTRN_THUMB_INSN_SIO4           0x9000                  // 10010xxxxxxxxxxx     STR SP relative
340
341 # define MASK_THUMB2_INSN_STRW          0x0fc0fff0              // xxxx111111xxxxxx 111111111111xxxx    // swapped
342 # define PTRN_THUMB2_INSN_STRW          0x0000f840              // xxxx000000xxxxxx 111110000100xxxx    STR.W Rt, [Rn, Rm, {LSL #<imm2>}]// swapped
343
344 # define MASK_THUMB2_INSN_STRW1         0x0000fff0              // xxxxxxxxxxxxxxxx 111111111111xxxx    // swapped
345 # define PTRN_THUMB2_INSN_STRW1         0x0000f8c0              // xxxxxxxxxxxxxxxx 111110001100xxxx    STR.W Rt, [Rn, #imm12]// swapped                                // STR.W Rt, [PC, #imm12] shall be skipped, because it hangs on Tegra. WTF
346
347 # define MASK_THUMB2_INSN_STRHW         MASK_THUMB2_INSN_STRW
348 # define PTRN_THUMB2_INSN_STRHW         0x0000f820              // xxxx000000xxxxxx 111110000010xxxx    STRH.W Rt, [Rn, Rm, {LSL #<imm2>}]// swapped
349
350 # define MASK_THUMB2_INSN_STRHW1        0x0000fff0              // xxxxxxxxxxxxxxxx 111111111111xxxx    // swapped
351 # define PTRN_THUMB2_INSN_STRHW1        0x0000f8a0              // xxxxxxxxxxxxxxxx 111110001010xxxx    STRH.W Rt, [Rn, #<imm12>]// swapped
352
353 # define MASK_THUMB2_INSN_STRHT         0x0f00fff0              // xxxx1111xxxxxxxx 111111111111xxxx    // swapped                                                      // strht r1, [pc, #imm] illegal instruction on Tegra. WTF
354 # define PTRN_THUMB2_INSN_STRHT         0x0e00f820              // xxxx1110xxxxxxxx 111110000010xxxx    STRHT Rt, [Rn, #<imm8>]// swapped
355
356 # define MASK_THUMB2_INSN_STRT          0x0f00fff0              // xxxx1111xxxxxxxx 111111111111xxxx    // swapped
357 # define PTRN_THUMB2_INSN_STRT          0x0e00f840              // xxxx1110xxxxxxxx 111110000100xxxx    STRT Rt, [Rn, #<imm8>]// swapped
358
359 # define MASK_THUMB2_INSN_STRBW         MASK_THUMB2_INSN_STRW   // xxxx111111xxxxxx 111111111111xxxx    // swapped
360 # define PTRN_THUMB2_INSN_STRBW         0x0000f800              // xxxx000000xxxxxx 111110000100xxxx    STRB.W Rt, [Rn, Rm, {LSL #<imm2>}]// swapped
361
362 # define MASK_THUMB2_INSN_STRBW1        0x0000fff0              // xxxxxxxxxxxxxxxx 111111111111xxxx    // swapped
363 # define PTRN_THUMB2_INSN_STRBW1        0x0000f880              // xxxxxxxxxxxxxxxx 111110001000xxxx    STRB.W Rt, [Rn, #<imm12>]// swapped                             // STRB.W Rt, [PC, #imm12] shall be skipped, because it hangs on Tegra. WTF
364
365 # define MASK_THUMB2_INSN_STRBT         0x0f00fff0              // xxxx1111xxxxxxxx 111111111111xxxx    // swapped
366 # define PTRN_THUMB2_INSN_STRBT         0x0e00f800              // xxxx1110xxxxxxxx 111110000000xxxx    STRBT Rt, [Rn, #<imm8>}]// swapped
367
368 # define MASK_THUMB2_INSN_STRD          0x0000fe50              // xxxxxxxxxxxxxxxx 1111111xx1x1xxxx    // swapped
369 # define PTRN_THUMB2_INSN_STRD          0x0000e840              // xxxxxxxxxxxxxxxx 1110100xx1x0xxxx    STR{D, EX, EXB, EXH, EXD} Rt, Rt2, [Rn, #<imm8>]// swapped
370
371
372 // Load register offset
373 # define MASK_ARM_INSN_LRO              0x0E100010
374 # define PTRN_ARM_INSN_LRO              0x06100000
375
376 # define MASK_THUMB_INSN_LRO1           0xFE00                  // 1111111xxxxxxxxx
377 # define PTRN_THUMB_INSN_LRO1           0x5600                  // 0101011xxxxxxxxx     LDRSB
378
379 # define MASK_THUMB_INSN_LRO2           MASK_THUMB_INSN_LRO1
380 # define PTRN_THUMB_INSN_LRO2           0x5800                  // 0101100xxxxxxxxx     LDR
381
382 # define MASK_THUMB_INSN_LRO3           0xf800                  // 11111xxxxxxxxxxx
383 # define PTRN_THUMB_INSN_LRO3           0x4800                  // 01001xxxxxxxxxxx     LDR Rd, [PC, #<imm8> * 4]
384
385 # define MASK_THUMB_INSN_LRO4           MASK_THUMB_INSN_LRO1
386 # define PTRN_THUMB_INSN_LRO4           0x5A00                  // 0101101xxxxxxxxx     LDRH
387
388 # define MASK_THUMB_INSN_LRO5           MASK_THUMB_INSN_LRO1
389 # define PTRN_THUMB_INSN_LRO5           0x5C00                  // 0101110xxxxxxxxx     LDRB
390
391 # define MASK_THUMB_INSN_LRO6           MASK_THUMB_INSN_LRO1
392 # define PTRN_THUMB_INSN_LRO6           0x5E00                  // 0101111xxxxxxxxx     LDRSH
393
394 # define MASK_THUMB2_INSN_ADR           0x8000fa1f              // 1xxxxxxxxxxxxxxx 11111x1xxxx11111    // swapped
395 # define PTRN_THUMB2_INSN_ADR           0x0000f20f              // 0xxxxxxxxxxxxxxx 11110x1xxxx01111    // swapped
396
397
398
399 // Store register offset
400 # define MASK_ARM_INSN_SRO              MASK_ARM_INSN_LRO
401 # define PTRN_ARM_INSN_SRO              0x06000000
402
403 # define MASK_THUMB_INSN_SRO1           MASK_THUMB_INSN_LRO1
404 # define PTRN_THUMB_INSN_SRO1           0x5000                  // 0101000xxxxxxxxx     STR
405
406 # define MASK_THUMB_INSN_SRO2           MASK_THUMB_INSN_LRO1
407 # define PTRN_THUMB_INSN_SRO2           0x5200                  // 0101001xxxxxxxxx     STRH
408
409 # define MASK_THUMB_INSN_SRO3           MASK_THUMB_INSN_LRO1
410 # define PTRN_THUMB_INSN_SRO3           0x5400                  // 0101010xxxxxxxxx     STRB
411
412 // Load multiple
413 # define MASK_ARM_INSN_LM               0x0E100000
414 # define PTRN_ARM_INSN_LM               0x08100000
415
416 # define MASK_THUMB2_INSN_LDMIA         0x8000ffd0              // 1xxxxxxxxxxxxxxx 1111111111x1xxxx    // swapped
417 # define PTRN_THUMB2_INSN_LDMIA         0x8000e890              // 1xxxxxxxxxxxxxxx 1110100010x1xxxx    LDMIA(.W) Rn(!), {Rx, ..., PC}// swapped
418
419 # define MASK_THUMB2_INSN_LDMDB         0x8000ffd0              // 1xxxxxxxxxxxxxxx 1111111111x1xxxx    // swapped
420 # define PTRN_THUMB2_INSN_LDMDB         0x8000e910              // 1xxxxxxxxxxxxxxx 1110100100x1xxxx    LDMDB(.W) Rn(!), {Rx, ..., PC}// swapped
421
422 // Store multiple
423 # define MASK_ARM_INSN_SM               MASK_ARM_INSN_LM
424 # define PTRN_ARM_INSN_SM               0x08000000
425
426
427 // Coprocessor load/store and double register transfers
428 # define MASK_ARM_INSN_CLS              0x0E000000
429 # define PTRN_ARM_INSN_CLS              0x0C000000
430 // Coprocessor register transfers
431 # define MASK_ARM_INSN_CRT              0x0F000010
432 # define PTRN_ARM_INSN_CRT              0x0E000010
433
434 # define ARM_INSN_MATCH(name, insn)             ((insn & MASK_ARM_INSN_##name) == PTRN_ARM_INSN_##name)
435 # define THUMB_INSN_MATCH(name, insn)           (((insn & 0x0000FFFF) & MASK_THUMB_INSN_##name) == PTRN_THUMB_INSN_##name)
436 # define THUMB2_INSN_MATCH(name, insn)          ((insn & MASK_THUMB2_INSN_##name) == PTRN_THUMB2_INSN_##name)
437
438 # define ARM_INSN_REG_RN(insn)                  ((insn & 0x000F0000)>>16)
439
440 # define ARM_INSN_REG_SET_RN(insn, nreg)        {insn &= ~0x000F0000; insn |= nreg<<16;}
441
442 # define ARM_INSN_REG_RD(insn)                  ((insn & 0x0000F000)>>12)
443
444 # define ARM_INSN_REG_SET_RD(insn, nreg)        {insn &= ~0x0000F000; insn |= nreg<<12;}
445
446 # define ARM_INSN_REG_RS(insn)                  ((insn & 0x00000F00)>>8)
447
448 # define ARM_INSN_REG_SET_RS(insn, nreg)        {insn &= ~0x00000F00; insn |= nreg<<8;}
449
450 # define ARM_INSN_REG_RM(insn)                  (insn & 0x0000000F)
451
452 # define ARM_INSN_REG_SET_RM(insn, nreg)        {insn &= ~0x0000000F; insn |= nreg;}
453
454 # define ARM_INSN_REG_MR(insn, nreg)            (insn & (1 << nreg))
455
456 # define ARM_INSN_REG_SET_MR(insn, nreg)        {insn |= (1 << nreg);}
457
458 # define ARM_INSN_REG_CLEAR_MR(insn, nreg)      {insn &= ~(1 << nreg);}
459
460 # define THUMB2_INSN_REG_RT(insn)               ((insn & 0xf0000000) >> 28)
461 # define THUMB2_INSN_REG_RT2(insn)              ((insn & 0x0f000000) >> 24)
462 # define THUMB2_INSN_REG_RN(insn)               (insn & 0x0000000f)
463 # define THUMB2_INSN_REG_RD(insn)               ((insn & 0x0f000000) >> 24)
464 # define THUMB2_INSN_REG_RM(insn)               ((insn & 0x000f0000) >> 16)
465
466
467 /* per-cpu kprobe control block */
468 struct kprobe_ctlblk {
469         unsigned long kprobe_status;
470         struct prev_kprobe prev_kprobe;
471 };
472
473 /* Architecture specific copy of original instruction */
474 struct arch_specific_insn {
475         /* copy of the original instruction */
476         kprobe_opcode_t *insn;
477 };
478
479 typedef kprobe_opcode_t (*entry_point_t) (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
480
481 struct undef_hook;
482
483 void swap_register_undef_hook(struct undef_hook *hook);
484 void swap_unregister_undef_hook(struct undef_hook *hook);
485
486 static inline int arch_init_module_deps(void)
487 {
488         return 0;
489 }
490
491 int arch_make_trampoline_arm(unsigned long addr, unsigned long insn,
492                              unsigned long *tramp);
493
494 struct slot_manager;
495 struct kretprobe;
496 struct kretprobe_instance;
497 int arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm);
498 void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs);
499
500 void arch_arm_kprobe(struct kprobe *p);
501 void arch_disarm_kprobe(struct kprobe *p);
502
503 int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs);
504 int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs);
505
506 void save_previous_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *cur_p);
507 void restore_previous_kprobe(struct kprobe_ctlblk *kcb);
508 void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb);
509
510 void __naked kretprobe_trampoline(void);
511
512 static inline unsigned long swap_get_karg(struct pt_regs *regs, unsigned long n)
513 {
514         switch (n) {
515         case 0:
516                 return regs->ARM_r0;
517         case 1:
518                 return regs->ARM_r1;
519         case 2:
520                 return regs->ARM_r2;
521         case 3:
522                 return regs->ARM_r3;
523         }
524
525         return *((unsigned long *)regs->ARM_sp + n - 4);
526 }
527
528 static inline unsigned long swap_get_sarg(struct pt_regs *regs, unsigned long n)
529 {
530         return swap_get_karg(regs, n);
531 }
532
533 int arch_init_kprobes(void);
534 void arch_exit_kprobes(void);
535
536 //void gen_insn_execbuf (void);
537 //void pc_dep_insn_execbuf (void);
538 //void gen_insn_execbuf_holder (void);
539 //void pc_dep_insn_execbuf_holder (void);
540
541 #endif /* _DBI_ASM_ARM_KPROBES_H */