1 #ifndef _DBI_ASM_ARM_KPROBES_H
2 #define _DBI_ASM_ARM_KPROBES_H
5 * Dynamic Binary Instrumentation Module based on KProbes
6 * modules/kprobe/arch/asm-arm/dbi_kprobes.h
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.
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.
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.
22 * Copyright (C) Samsung Electronics, 2006-2010
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
29 * 2010-2011 Alexander Shirshikov <a.shirshikov@samsung.com>: initial implementation for Thumb
32 #include <linux/sched.h>
33 #include <linux/compiler.h>
35 typedef unsigned long kprobe_opcode_t;
37 #ifdef CONFIG_CPU_S3C2443
38 #define BREAKPOINT_INSTRUCTION 0xe1200070
40 #define BREAKPOINT_INSTRUCTION 0xffffdeff
41 #endif /* CONFIG_CPU_S3C2443 */
43 #ifndef KPROBES_RET_PROBE_TRAMP
45 #ifdef CONFIG_CPU_S3C2443
46 #define UNDEF_INSTRUCTION 0xe1200071
48 #define UNDEF_INSTRUCTION 0xfffffffe
49 #endif /* CONFIG_CPU_S3C2443 */
51 #endif /* KPROBES_RET_PROBE_TRAMP */
53 #define MAX_INSN_SIZE 1
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
63 /* TODO: remove (not needed for kprobe) */
64 # define KPROBES_TRAMP_RET_BREAK_IDX UPROBES_TRAMP_RET_BREAK_IDX
66 #define UREGS_OFFSET 8
73 static inline unsigned long arch_get_task_pc(struct task_struct *p)
75 return task_thread_info(p)->cpu_context.pc;
78 static inline void arch_set_task_pc(struct task_struct *p, unsigned long val)
80 task_thread_info(p)->cpu_context.pc = val;
83 static inline struct pt_regs *dbi_get_syscall_uregs(unsigned long sp)
85 return (struct pt_regs *)(sp + UREGS_OFFSET);
88 static inline unsigned long dbi_get_stack_ptr(struct pt_regs *regs)
93 static inline unsigned long dbi_get_instr_ptr(struct pt_regs *regs)
98 static inline void dbi_set_instr_ptr(struct pt_regs *regs, unsigned long val)
103 static inline unsigned long dbi_get_ret_addr(struct pt_regs *regs)
108 static inline void dbi_set_ret_addr(struct pt_regs *regs, unsigned long val)
113 static inline unsigned long dbi_get_arg(struct pt_regs *regs, int num)
115 return regs->uregs[num];
118 static inline void dbi_set_arg(struct pt_regs *regs, int num, unsigned long val)
120 regs->uregs[num] = val;
124 # define MASK_ARM_INSN_UNDEF 0x0FF00000 // xxxx1111 1111xxxx xxxxxxxx xxxxxxxx
125 # define PTRN_ARM_INSN_UNDEF 0x03000000 // cccc0011 0000xxxx xxxxxxxx xxxxxxxx
127 # define MASK_THUMB_INSN_UNDEF 0xFE00 // 11111111xxxxxxxx
128 # define PTRN_THUMB_INSN_UNDEF 0xDE00 // 11011110xxxxxxxx
130 // architecturally undefined
131 # define MASK_ARM_INSN_AUNDEF 0x0FF000F0
132 # define PTRN_ARM_INSN_AUNDEF 0x07F000F0
135 # define MASK_ARM_INSN_B 0x0F000000 // xxxx1111xxxxxxxxxxxxxxxxxxxxxxxx
136 # define PTRN_ARM_INSN_B 0x0A000000 // cccc1010xxxxxxxxxxxxxxxxxxxxxxxx
138 # define MASK_THUMB_INSN_B1 0xF000 // 1111xxxxxxxxxxxx
139 # define PTRN_THUMB_INSN_B1 0xD000 // 1101xxxxxxxxxxxx // b<cond> label
141 # define MASK_THUMB_INSN_B2 0xF800 // 11111xxxxxxxxxxx
142 # define PTRN_THUMB_INSN_B2 0xE000 // 11100xxxxxxxxxxx // b label
144 # define MASK_THUMB_INSN_CBZ 0xF500 // 1111x1x1xxxxxxxx
145 # define PTRN_THUMB_INSN_CBZ 0xB100 // 1011x0x1xxxxxxxx // CBZ/CBNZ
147 # define MASK_THUMB2_INSN_B1 0xD000F800 // 11x1xxxxxxxxxxxx 11111xxxxxxxxxxx // swapped
148 # define PTRN_THUMB2_INSN_B1 0x8000F000 // 10x0xxxxxxxxxxxx 11110xxxxxxxxxxx // swapped
150 # define MASK_THUMB2_INSN_B2 0xD000F800 // 11x1xxxxxxxxxxxx 11111xxxxxxxxxxx // swapped
151 # define PTRN_THUMB2_INSN_B2 0x9000F000 // 10x1xxxxxxxxxxxx 11110xxxxxxxxxxx // swapped
153 # define MASK_ARM_INSN_BL 0x0F000000 // xxxx1111xxxxxxxxxxxxxxxxxxxxxxxx
154 # define PTRN_ARM_INSN_BL 0x0B000000 // cccc1011xxxxxxxxxxxxxxxxxxxxxxxx
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
160 # define MASK_THUMB2_INSN_BL 0xD000F800 // 11x1xxxxxxxxxxxx 11111xxxxxxxxxxx // swapped
161 # define PTRN_THUMB2_INSN_BL 0xD000F000 // 11x1xxxxxxxxxxxx 11110xxxxxxxxxxx // bl imm swapped
163 # define MASK_ARM_INSN_BLX1 0xFE000000 // 1111111axxxxxxxxxxxxxxxxxxxxxxxx
164 # define PTRN_ARM_INSN_BLX1 0xFA000000 // 1111101axxxxxxxxxxxxxxxxxxxxxxxx
166 //# define MASK_THUMB_INSN_BLX1 0xF800 // 11111xxxxxxxxxxx / blx imm
167 //# define PTRN_THUMB_INSN_BLX1 0xF000 // 11101xxxxxxxxxxx
169 # define MASK_THUMB2_INSN_BLX1 0xD001F800 // 11x1xxxxxxxxxxx1 11111xxxxxxxxxxx // swapped
170 # define PTRN_THUMB2_INSN_BLX1 0xC000F000 // 11x0xxxxxxxxxxx0 11110xxxxxxxxxxx // swapped
172 # define MASK_ARM_INSN_BLX2 0x0FF000F0 // xxxx11111111xxxxxxxxxxxx1111xxxx
173 # define PTRN_ARM_INSN_BLX2 0x01200030 // cccc00010010xxxxxxxxxxxx0011xxxx
175 # define MASK_THUMB_INSN_BLX2 0xFF80 // 111111111xxxxxxx / blx reg
176 # define PTRN_THUMB_INSN_BLX2 0x4780 // 010001111xxxxxxx
178 # define MASK_ARM_INSN_BX 0x0FF000F0 // cccc11111111xxxxxxxxxxxx1111xxxx
179 # define PTRN_ARM_INSN_BX 0x01200010 // cccc00010010xxxxxxxxxxxx0001xxxx
181 # define MASK_THUMB_INSN_BX 0xFF80 // 111111111xxxxxxx
182 # define PTRN_THUMB_INSN_BX 0x4700 // 010001110xxxxxxx
184 # define MASK_ARM_INSN_BXJ 0x0FF000F0 // xxxx11111111xxxxxxxxxxxx1111xxxx
185 # define PTRN_ARM_INSN_BXJ 0x01200020 // cccc00010010xxxxxxxxxxxx0010xxxx
187 # define MASK_THUMB2_INSN_BXJ 0xD000FFF0 // 11x1xxxxxxxxxxxx 111111111111xxxx // swapped
188 # define PTRN_THUMB2_INSN_BXJ 0x8000F3C0 // 10x0xxxxxxxxxxxx 111100111100xxxx // swapped
191 // software interrupts
192 # define MASK_ARM_INSN_SWI 0x0F000000 // cccc1111xxxxxxxxxxxxxxxxxxxxxxxx
193 # define PTRN_ARM_INSN_SWI 0x0F000000 // cccc1111xxxxxxxxxxxxxxxxxxxxxxxx
195 # define MASK_THUMB_INSN_SWI 0xFF00 // 11111111xxxxxxxx
196 # define PTRN_THUMB_INSN_SWI 0xDF00 // 11011111xxxxxxxx
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;
202 # define MASK_THUMB_INSN_BREAK 0xFF00 // 11111111xxxxxxxx
203 # define PTRN_THUMB_INSN_BREAK 0xBE00 // 10111110xxxxxxxx
205 // Data processing immediate shift
206 # define MASK_ARM_INSN_DPIS 0x0E000010
207 # define PTRN_ARM_INSN_DPIS 0x00000000
208 // Data processing register shift
209 # define MASK_ARM_INSN_DPRS 0x0E000090
210 # define PTRN_ARM_INSN_DPRS 0x00000010
212 # define MASK_THUMB2_INSN_DPRS 0xFFE00000 // 11111111111xxxxxxxxxxxxxxxxxxxxx
213 # define PTRN_THUMB2_INSN_DPRS 0xEA000000 // 1110101xxxxxxxxxxxxxxxxxxxxxxxxx
215 // Data processing immediate
216 # define MASK_ARM_INSN_DPI 0x0E000000
217 # define PTRN_ARM_INSN_DPI 0x02000000
219 # define MASK_THUMB_INSN_DP 0xFC00 // 111111xxxxxxxxxx
220 # define PTRN_THUMB_INSN_DP 0x4000 // 010000xxxxxxxxxx
222 # define MASK_THUMB_INSN_APC 0xF800 // 11111xxxxxxxxxxx
223 # define PTRN_THUMB_INSN_APC 0xA000 // 10100xxxxxxxxxxx ADD Rd, [PC, #<imm8> * 4]
225 # define MASK_THUMB2_INSN_DPI 0xFBE08000 // 11111x11111xxxxx 1xxxxxxxxxxxxxxx
226 //# define PTRN_THUMB2_INSN_DPI 0xF0000000 // 11110x0xxxxxxxxx 0xxxxxxxxxxxxxxx /? A6-19 ARM DDI 0406B
227 # define PTRN_THUMB2_INSN_DPI 0xF2000000 // 11110x1xxxxxxxxx 0xxxxxxxxxxxxxxx /? A6-19 ARM DDI 0406B
229 # define MASK_THUMB_INSN_MOV3 0xFF00 // 11111111xxxxxxxx
230 # define PTRN_THUMB_INSN_MOV3 0x4600 // 01000110xxxxxxxx MOV Rd, PC
232 # define MASK_THUMB2_INSN_RSBW 0x8000fbe0 // 1xxxxxxxxxxxxxxx 11111x11111xxxxx // swapped
233 # define PTRN_THUMB2_INSN_RSBW 0x0000f1c0 // 0xxxxxxxxxxxxxxx 11110x01110xxxxx RSB{S}.W Rd, Rn, #<const> // swapped
235 # define MASK_THUMB2_INSN_RORW 0xf0f0ffe0 // 1111xxxx1111xxxx 11111111111xxxxx // swapped
236 # define PTRN_THUMB2_INSN_RORW 0xf000fa60 // 1111xxxx0000xxxx 11111010011xxxxx ROR{S}.W Rd, Rn, Rm // swapped
238 # define MASK_THUMB2_INSN_ROR 0x0030ffef // xxxxxxxxxx11xxxx 11111111111x1111 // swapped
239 # define PTRN_THUMB2_INSN_ROR 0x0030ea4f // xxxxxxxxxx11xxxx 11101010010x1111 ROR{S} Rd, Rm, #<imm> // swapped
241 # define MASK_THUMB2_INSN_LSLW1 0xf0f0ffe0 // 1111xxxx1111xxxx 11111111111xxxxx // swapped
242 # define PTRN_THUMB2_INSN_LSLW1 0xf000fa00 // 1111xxxx0000xxxx 11111010000xxxxx LSL{S}.W Rd, Rn, Rm // swapped
244 # define MASK_THUMB2_INSN_LSLW2 0x0030ffef // xxxxxxxxxx11xxxx 11111111111x1111 // swapped
245 # define PTRN_THUMB2_INSN_LSLW2 0x0000ea4f // xxxxxxxxxx00xxxx 11101010010x1111 LSL{S}.W Rd, Rm, #<imm5> // swapped
247 # define MASK_THUMB2_INSN_LSRW1 0xf0f0ffe0 // 1111xxxx1111xxxx 11111111111xxxxx // swapped
248 # define PTRN_THUMB2_INSN_LSRW1 0xf000fa20 // 1111xxxx0000xxxx 11111010001xxxxx LSR{S}.W Rd, Rn, Rm // swapped
250 # define MASK_THUMB2_INSN_LSRW2 0x0030ffef // xxxxxxxxxx11xxxx 11111111111x1111 // swapped
251 # define PTRN_THUMB2_INSN_LSRW2 0x0010ea4f // xxxxxxxxxx01xxxx 11101010010x1111 LSR{S}.W Rd, Rm, #<imm5> // swapped
253 # define MASK_THUMB2_INSN_TEQ1 0x8f00fbf0 // 1xxx1111xxxxxxxx 11111x111111xxxx // swapped
254 # define PTRN_THUMB2_INSN_TEQ1 0x0f00f090 // 0xxx1111xxxxxxxx 11110x001001xxxx TEQ Rn, #<const> // swapped
256 # define MASK_THUMB2_INSN_TEQ2 0x0f00fff0 // xxxx1111xxxxxxxx 111111111111xxxx // swapped
257 # define PTRN_THUMB2_INSN_TEQ2 0x0f00ea90 // xxxx1111xxxxxxxx 111010101001xxxx TEQ Rn, Rm{,<shift>} // swapped
259 # define MASK_THUMB2_INSN_TST1 0x8f00fbf0 // 1xxx1111xxxxxxxx 11111x111111xxxx // swapped
260 # define PTRN_THUMB2_INSN_TST1 0x0f00f010 // 0xxx1111xxxxxxxx 11110x000001xxxx TST Rn, #<const> // swapped
262 # define MASK_THUMB2_INSN_TST2 0x0f00fff0 // xxxx1111xxxxxxxx 111111111111xxxx // swapped
263 # define PTRN_THUMB2_INSN_TST2 0x0f00ea10 // xxxx1111xxxxxxxx 111010100001xxxx TST Rn, Rm{,<shift>} // swapped
266 // Load immediate offset
267 # define MASK_ARM_INSN_LIO 0x0E100000
268 # define PTRN_ARM_INSN_LIO 0x04100000
270 # define MASK_THUMB_INSN_LIO1 0xF800 // 11111xxxxxxxxxxx
271 # define PTRN_THUMB_INSN_LIO1 0x6800 // 01101xxxxxxxxxxx LDR
273 # define MASK_THUMB_INSN_LIO2 MASK_THUMB_INSN_LIO1
274 # define PTRN_THUMB_INSN_LIO2 0x7800 // 01111xxxxxxxxxxx LDRB
276 # define MASK_THUMB_INSN_LIO3 MASK_THUMB_INSN_LIO1
277 # define PTRN_THUMB_INSN_LIO3 0x8800 // 10001xxxxxxxxxxx LDRH
279 # define MASK_THUMB_INSN_LIO4 MASK_THUMB_INSN_LIO1
280 # define PTRN_THUMB_INSN_LIO4 0x9800 // 10011xxxxxxxxxxx LDR SP relative
282 # define MASK_THUMB2_INSN_LDRW 0x0000fff0 // xxxxxxxxxxxxxxxx 111111111111xxxx // swapped
283 # define PTRN_THUMB2_INSN_LDRW 0x0000f850 // xxxxxxxxxxxxxxxx 111110000101xxxx LDR.W Rt, [Rn, #-<imm12>]// swapped
285 # define MASK_THUMB2_INSN_LDRW1 MASK_THUMB2_INSN_LDRW
286 # define PTRN_THUMB2_INSN_LDRW1 0x0000f8d0 // xxxxxxxxxxxxxxxx 111110001101xxxx LDR.W Rt, [Rn, #<imm12>]// swapped
288 # define MASK_THUMB2_INSN_LDRBW MASK_THUMB2_INSN_LDRW
289 # define PTRN_THUMB2_INSN_LDRBW 0x0000f810 // xxxxxxxxxxxxxxxx 111110000001xxxx LDRB.W Rt, [Rn, #-<imm8>]// swapped
291 # define MASK_THUMB2_INSN_LDRBW1 MASK_THUMB2_INSN_LDRW
292 # define PTRN_THUMB2_INSN_LDRBW1 0x0000f890 // xxxxxxxxxxxxxxxx 111110001001xxxx LDRB.W Rt, [Rn, #<imm12>]// swapped
294 # define MASK_THUMB2_INSN_LDRHW MASK_THUMB2_INSN_LDRW
295 # define PTRN_THUMB2_INSN_LDRHW 0x0000f830 // xxxxxxxxxxxxxxxx 111110000011xxxx LDRH.W Rt, [Rn, #-<imm8>]// swapped
297 # define MASK_THUMB2_INSN_LDRHW1 MASK_THUMB2_INSN_LDRW
298 # define PTRN_THUMB2_INSN_LDRHW1 0x0000f8b0 // xxxxxxxxxxxxxxxx 111110001011xxxx LDRH.W Rt, [Rn, #<imm12>]// swapped
300 # define MASK_THUMB2_INSN_LDRD 0x0000fed0 // xxxxxxxxxxxxxxxx 1111111x11x1xxxx // swapped
301 # define PTRN_THUMB2_INSN_LDRD 0x0000e850 // xxxxxxxxxxxxxxxx 1110100x01x1xxxx LDRD Rt, Rt2, [Rn, #-<imm8>]// swapped
303 # define MASK_THUMB2_INSN_LDRD1 MASK_THUMB2_INSN_LDRD
304 # define PTRN_THUMB2_INSN_LDRD1 0x0000e8d0 // xxxxxxxxxxxxxxxx 1110100x11x1xxxx LDRD Rt, Rt2, [Rn, #<imm8>]// swapped
306 # define MASK_THUMB2_INSN_LDRWL 0x0fc0fff0 // xxxx111111xxxxxx 111111111111xxxx // swapped
307 # define PTRN_THUMB2_INSN_LDRWL 0x0000f850 // xxxxxxxxxxxxxxxx 111110000101xxxx LDR.W Rt, [Rn, Rm, LSL #<imm2>]// swapped
309 # define MASK_THUMB2_INSN_LDREX 0x0f00ffff // xxxx1111xxxxxxxx 1111111111111111 // swapped
310 # define PTRN_THUMB2_INSN_LDREX 0x0f00e85f // xxxx1111xxxxxxxx 1110100001011111 LDREX Rt, [PC, #<imm8>]// swapped
312 # define MASK_THUMB2_INSN_MUL 0xf0f0fff0 // 1111xxxx1111xxxx 111111111111xxxx // swapped
313 # define PTRN_THUMB2_INSN_MUL 0xf000fb00 // 1111xxxx0000xxxx 111110110000xxxx MUL Rd, Rn, Rm// swapped
315 # define MASK_THUMB2_INSN_DP 0x0000ff00 // xxxxxxxxxxxxxxxx 11111111xxxxxxxx // swapped
316 # define PTRN_THUMB2_INSN_DP 0x0000eb00 // xxxxxxxxxxxxxxxx 11101011xxxxxxxx // swapped ADD/SUB/SBC/...Rd, Rn, Rm{,<shift>}
321 // Store immediate offset
322 # define MASK_ARM_INSN_SIO MASK_ARM_INSN_LIO
323 # define PTRN_ARM_INSN_SIO 0x04000000
325 # define MASK_THUMB_INSN_SIO1 MASK_THUMB_INSN_LIO1
326 # define PTRN_THUMB_INSN_SIO1 0x6000 // 01100xxxxxxxxxxx STR
328 # define MASK_THUMB_INSN_SIO2 MASK_THUMB_INSN_LIO1
329 # define PTRN_THUMB_INSN_SIO2 0x7000 // 01110xxxxxxxxxxx STRB
331 # define MASK_THUMB_INSN_SIO3 MASK_THUMB_INSN_LIO1
332 # define PTRN_THUMB_INSN_SIO3 0x8000 // 10000xxxxxxxxxxx STRH
334 # define MASK_THUMB_INSN_SIO4 MASK_THUMB_INSN_LIO1
335 # define PTRN_THUMB_INSN_SIO4 0x9000 // 10010xxxxxxxxxxx STR SP relative
337 # define MASK_THUMB2_INSN_STRW 0x0fc0fff0 // xxxx111111xxxxxx 111111111111xxxx // swapped
338 # define PTRN_THUMB2_INSN_STRW 0x0000f840 // xxxx000000xxxxxx 111110000100xxxx STR.W Rt, [Rn, Rm, {LSL #<imm2>}]// swapped
340 # define MASK_THUMB2_INSN_STRW1 0x0000fff0 // xxxxxxxxxxxxxxxx 111111111111xxxx // swapped
341 # 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
343 # define MASK_THUMB2_INSN_STRHW MASK_THUMB2_INSN_STRW
344 # define PTRN_THUMB2_INSN_STRHW 0x0000f820 // xxxx000000xxxxxx 111110000010xxxx STRH.W Rt, [Rn, Rm, {LSL #<imm2>}]// swapped
346 # define MASK_THUMB2_INSN_STRHW1 0x0000fff0 // xxxxxxxxxxxxxxxx 111111111111xxxx // swapped
347 # define PTRN_THUMB2_INSN_STRHW1 0x0000f8a0 // xxxxxxxxxxxxxxxx 111110001010xxxx STRH.W Rt, [Rn, #<imm12>]// swapped
349 # define MASK_THUMB2_INSN_STRHT 0x0f00fff0 // xxxx1111xxxxxxxx 111111111111xxxx // swapped // strht r1, [pc, #imm] illegal instruction on Tegra. WTF
350 # define PTRN_THUMB2_INSN_STRHT 0x0e00f820 // xxxx1110xxxxxxxx 111110000010xxxx STRHT Rt, [Rn, #<imm8>]// swapped
352 # define MASK_THUMB2_INSN_STRT 0x0f00fff0 // xxxx1111xxxxxxxx 111111111111xxxx // swapped
353 # define PTRN_THUMB2_INSN_STRT 0x0e00f840 // xxxx1110xxxxxxxx 111110000100xxxx STRT Rt, [Rn, #<imm8>]// swapped
355 # define MASK_THUMB2_INSN_STRBW MASK_THUMB2_INSN_STRW // xxxx111111xxxxxx 111111111111xxxx // swapped
356 # define PTRN_THUMB2_INSN_STRBW 0x0000f800 // xxxx000000xxxxxx 111110000100xxxx STRB.W Rt, [Rn, Rm, {LSL #<imm2>}]// swapped
358 # define MASK_THUMB2_INSN_STRBW1 0x0000fff0 // xxxxxxxxxxxxxxxx 111111111111xxxx // swapped
359 # 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
361 # define MASK_THUMB2_INSN_STRBT 0x0f00fff0 // xxxx1111xxxxxxxx 111111111111xxxx // swapped
362 # define PTRN_THUMB2_INSN_STRBT 0x0e00f800 // xxxx1110xxxxxxxx 111110000000xxxx STRBT Rt, [Rn, #<imm8>}]// swapped
364 # define MASK_THUMB2_INSN_STRD 0x0000fe50 // xxxxxxxxxxxxxxxx 1111111xx1x1xxxx // swapped
365 # define PTRN_THUMB2_INSN_STRD 0x0000e840 // xxxxxxxxxxxxxxxx 1110100xx1x0xxxx STR{D, EX, EXB, EXH, EXD} Rt, Rt2, [Rn, #<imm8>]// swapped
368 // Load register offset
369 # define MASK_ARM_INSN_LRO 0x0E100010
370 # define PTRN_ARM_INSN_LRO 0x06100000
372 # define MASK_THUMB_INSN_LRO1 0xFE00 // 1111111xxxxxxxxx
373 # define PTRN_THUMB_INSN_LRO1 0x5600 // 0101011xxxxxxxxx LDRSB
375 # define MASK_THUMB_INSN_LRO2 MASK_THUMB_INSN_LRO1
376 # define PTRN_THUMB_INSN_LRO2 0x5800 // 0101100xxxxxxxxx LDR
378 # define MASK_THUMB_INSN_LRO3 0xf800 // 11111xxxxxxxxxxx
379 # define PTRN_THUMB_INSN_LRO3 0x4800 // 01001xxxxxxxxxxx LDR Rd, [PC, #<imm8> * 4]
381 # define MASK_THUMB_INSN_LRO4 MASK_THUMB_INSN_LRO1
382 # define PTRN_THUMB_INSN_LRO4 0x5A00 // 0101101xxxxxxxxx LDRH
384 # define MASK_THUMB_INSN_LRO5 MASK_THUMB_INSN_LRO1
385 # define PTRN_THUMB_INSN_LRO5 0x5C00 // 0101110xxxxxxxxx LDRB
387 # define MASK_THUMB_INSN_LRO6 MASK_THUMB_INSN_LRO1
388 # define PTRN_THUMB_INSN_LRO6 0x5E00 // 0101111xxxxxxxxx LDRSH
390 # define MASK_THUMB2_INSN_ADR 0x8000fa1f // 1xxxxxxxxxxxxxxx 11111x1xxxx11111 // swapped
391 # define PTRN_THUMB2_INSN_ADR 0x0000f20f // 0xxxxxxxxxxxxxxx 11110x1xxxx01111 // swapped
395 // Store register offset
396 # define MASK_ARM_INSN_SRO MASK_ARM_INSN_LRO
397 # define PTRN_ARM_INSN_SRO 0x06000000
399 # define MASK_THUMB_INSN_SRO1 MASK_THUMB_INSN_LRO1
400 # define PTRN_THUMB_INSN_SRO1 0x5000 // 0101000xxxxxxxxx STR
402 # define MASK_THUMB_INSN_SRO2 MASK_THUMB_INSN_LRO1
403 # define PTRN_THUMB_INSN_SRO2 0x5200 // 0101001xxxxxxxxx STRH
405 # define MASK_THUMB_INSN_SRO3 MASK_THUMB_INSN_LRO1
406 # define PTRN_THUMB_INSN_SRO3 0x5400 // 0101010xxxxxxxxx STRB
409 # define MASK_ARM_INSN_LM 0x0E100000
410 # define PTRN_ARM_INSN_LM 0x08100000
412 # define MASK_THUMB2_INSN_LDMIA 0x8000ffd0 // 1xxxxxxxxxxxxxxx 1111111111x1xxxx // swapped
413 # define PTRN_THUMB2_INSN_LDMIA 0x8000e890 // 1xxxxxxxxxxxxxxx 1110100010x1xxxx LDMIA(.W) Rn(!), {Rx, ..., PC}// swapped
415 # define MASK_THUMB2_INSN_LDMDB 0x8000ffd0 // 1xxxxxxxxxxxxxxx 1111111111x1xxxx // swapped
416 # define PTRN_THUMB2_INSN_LDMDB 0x8000e910 // 1xxxxxxxxxxxxxxx 1110100100x1xxxx LDMDB(.W) Rn(!), {Rx, ..., PC}// swapped
419 # define MASK_ARM_INSN_SM MASK_ARM_INSN_LM
420 # define PTRN_ARM_INSN_SM 0x08000000
423 // Coprocessor load/store and double register transfers
424 # define MASK_ARM_INSN_CLS 0x0E000000
425 # define PTRN_ARM_INSN_CLS 0x0C000000
426 // Coprocessor register transfers
427 # define MASK_ARM_INSN_CRT 0x0F000010
428 # define PTRN_ARM_INSN_CRT 0x0E000010
430 # define ARM_INSN_MATCH(name, insn) ((insn & MASK_ARM_INSN_##name) == PTRN_ARM_INSN_##name)
431 # define THUMB_INSN_MATCH(name, insn) (((insn & 0x0000FFFF) & MASK_THUMB_INSN_##name) == PTRN_THUMB_INSN_##name)
432 # define THUMB2_INSN_MATCH(name, insn) ((insn & MASK_THUMB2_INSN_##name) == PTRN_THUMB2_INSN_##name)
434 # define ARM_INSN_REG_RN(insn) ((insn & 0x000F0000)>>16)
436 # define ARM_INSN_REG_SET_RN(insn, nreg) {insn &= ~0x000F0000; insn |= nreg<<16;}
438 # define ARM_INSN_REG_RD(insn) ((insn & 0x0000F000)>>12)
440 # define ARM_INSN_REG_SET_RD(insn, nreg) {insn &= ~0x0000F000; insn |= nreg<<12;}
442 # define ARM_INSN_REG_RS(insn) ((insn & 0x00000F00)>>8)
444 # define ARM_INSN_REG_SET_RS(insn, nreg) {insn &= ~0x00000F00; insn |= nreg<<8;}
446 # define ARM_INSN_REG_RM(insn) (insn & 0x0000000F)
448 # define ARM_INSN_REG_SET_RM(insn, nreg) {insn &= ~0x0000000F; insn |= nreg;}
450 # define ARM_INSN_REG_MR(insn, nreg) (insn & (1 << nreg))
452 # define ARM_INSN_REG_SET_MR(insn, nreg) {insn |= (1 << nreg);}
454 # define ARM_INSN_REG_CLEAR_MR(insn, nreg) {insn &= ~(1 << nreg);}
456 # define THUMB2_INSN_REG_RT(insn) ((insn & 0xf0000000) >> 28)
457 # define THUMB2_INSN_REG_RT2(insn) ((insn & 0x0f000000) >> 24)
458 # define THUMB2_INSN_REG_RN(insn) (insn & 0x0000000f)
459 # define THUMB2_INSN_REG_RD(insn) ((insn & 0x0f000000) >> 24)
460 # define THUMB2_INSN_REG_RM(insn) ((insn & 0x000f0000) >> 16)
463 /* per-cpu kprobe control block */
464 struct kprobe_ctlblk {
465 unsigned long kprobe_status;
466 struct prev_kprobe prev_kprobe;
469 /* Architecture specific copy of original instruction */
470 struct arch_specific_insn {
471 /* copy of the original instruction */
472 kprobe_opcode_t *insn;
475 typedef kprobe_opcode_t (*entry_point_t) (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
479 void swap_register_undef_hook(struct undef_hook *hook);
480 void swap_unregister_undef_hook(struct undef_hook *hook);
482 static inline int arch_init_module_deps(void)
487 int arch_make_trampoline_arm(unsigned long addr, unsigned long insn,
488 unsigned long *tramp);
492 struct kretprobe_instance;
493 int arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm);
494 void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs);
496 void arch_arm_kprobe(struct kprobe *p);
497 void arch_disarm_kprobe(struct kprobe *p);
499 int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs);
500 int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs);
502 void save_previous_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *cur_p);
503 void restore_previous_kprobe(struct kprobe_ctlblk *kcb);
504 void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb);
506 void __naked kretprobe_trampoline(void);
508 static inline unsigned long swap_get_karg(struct pt_regs *regs, unsigned long n)
521 return *((unsigned long *)regs->ARM_sp + n - 4);
524 static inline unsigned long swap_get_sarg(struct pt_regs *regs, unsigned long n)
526 return swap_get_karg(regs, n);
529 int arch_init_kprobes(void);
530 void arch_exit_kprobes(void);
532 //void gen_insn_execbuf (void);
533 //void pc_dep_insn_execbuf (void);
534 //void gen_insn_execbuf_holder (void);
535 //void pc_dep_insn_execbuf_holder (void);
537 #endif /* _DBI_ASM_ARM_KPROBES_H */