Redesign KProbe module (separating core and arch parts).
[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
30  */
31
32 #include "../dbi_kprobes.h"
33
34 typedef unsigned long kprobe_opcode_t;
35
36 #ifdef CONFIG_CPU_S3C2443
37 #define BREAKPOINT_INSTRUCTION          0xe1200070
38 #else 
39 #define BREAKPOINT_INSTRUCTION          0xffffffff
40 #endif /* CONFIG_CPU_S3C2443 */
41
42 #ifndef KPROBES_RET_PROBE_TRAMP
43
44 #ifdef CONFIG_CPU_S3C2443
45 #define UNDEF_INSTRUCTION               0xe1200071
46 #else 
47 #define UNDEF_INSTRUCTION               0xfffffffe
48 #endif /* CONFIG_CPU_S3C2443 */
49
50 #endif /* KPROBES_RET_PROBE_TRAMP */
51
52 #define MAX_INSN_SIZE                   1
53
54 # define UPROBES_TRAMP_LEN              8
55 # define UPROBES_TRAMP_INSN_IDX         2
56 # define UPROBES_TRAMP_SS_BREAK_IDX     4
57 # define UPROBES_TRAMP_RET_BREAK_IDX    5
58 # define KPROBES_TRAMP_LEN              8
59 # define KPROBES_TRAMP_INSN_IDX         UPROBES_TRAMP_INSN_IDX
60 # define KPROBES_TRAMP_SS_BREAK_IDX     UPROBES_TRAMP_SS_BREAK_IDX
61 # define KPROBES_TRAMP_RET_BREAK_IDX    UPROBES_TRAMP_RET_BREAK_IDX
62
63 #define NOTIFIER_CALL_CHAIN_INDEX       3
64
65 // undefined
66 # define MASK_ARM_INSN_UNDEF            0x0FF00000
67 # define PTRN_ARM_INSN_UNDEF            0x03000000
68 // architecturally undefined
69 # define MASK_ARM_INSN_AUNDEF           0x0FF000F0
70 # define PTRN_ARM_INSN_AUNDEF           0x07F000F0
71 // branches
72 # define MASK_ARM_INSN_B                0x0E000000
73 # define PTRN_ARM_INSN_B                0x0A000000
74 # define MASK_ARM_INSN_BL               0x0E000000
75 # define PTRN_ARM_INSN_BL               0x0B000000
76 # define MASK_ARM_INSN_BLX1             0xFF000000
77 # define PTRN_ARM_INSN_BLX1             0xFA000000
78 # define MASK_ARM_INSN_BLX2             0x0FF000F0
79 # define PTRN_ARM_INSN_BLX2             0x01200030
80 # define MASK_ARM_INSN_BX               0x0FF000F0
81 # define PTRN_ARM_INSN_BX               0x01200010
82 # define MASK_ARM_INSN_BXJ              0x0FF000F0
83 # define PTRN_ARM_INSN_BXJ              0x01200020
84 // software interrupts
85 # define MASK_ARM_INSN_SWI              0x0F000000
86 # define PTRN_ARM_INSN_SWI              0x0F000000
87 // break
88 # define MASK_ARM_INSN_BREAK            0xFFF000F0
89 # define PTRN_ARM_INSN_BREAK            0xE1200070
90 // Data processing immediate shift
91 # define MASK_ARM_INSN_DPIS             0x0E000010
92 # define PTRN_ARM_INSN_DPIS             0x00000000
93 // Data processing register shift
94 # define MASK_ARM_INSN_DPRS             0x0E000090
95 # define PTRN_ARM_INSN_DPRS             0x00000010
96 // Data processing immediate
97 # define MASK_ARM_INSN_DPI              0x0E000000
98 # define PTRN_ARM_INSN_DPI              0x02000000
99 // Load immediate offset
100 # define MASK_ARM_INSN_LIO              0x0E100000
101 # define PTRN_ARM_INSN_LIO              0x04100000
102 // Store immediate offset
103 # define MASK_ARM_INSN_SIO              MASK_ARM_INSN_LIO
104 # define PTRN_ARM_INSN_SIO              0x04000000
105 // Load register offset
106 # define MASK_ARM_INSN_LRO              0x0E100010
107 # define PTRN_ARM_INSN_LRO              0x06100000
108 // Store register offset
109 # define MASK_ARM_INSN_SRO              MASK_ARM_INSN_LRO
110 # define PTRN_ARM_INSN_SRO              0x06000000
111 // Load multiple
112 # define MASK_ARM_INSN_LM               0x0E100000
113 # define PTRN_ARM_INSN_LM               0x08100000
114 // Store multiple
115 # define MASK_ARM_INSN_SM               MASK_ARM_INSN_LM
116 # define PTRN_ARM_INSN_SM               0x08000000
117 // Coprocessor load/store and double register transfers
118 # define MASK_ARM_INSN_CLS              0x0E000000
119 # define PTRN_ARM_INSN_CLS              0x0C000000
120 // Coprocessor register transfers
121 # define MASK_ARM_INSN_CRT              0x0F000010
122 # define PTRN_ARM_INSN_CRT              0x0E000010
123
124 # define ARM_INSN_MATCH(name, insn)             ((insn & MASK_ARM_INSN_##name) == PTRN_ARM_INSN_##name)
125 # define ARM_INSN_REG_RN(insn)                   ((insn & 0x000F0000)>>16)
126 # define ARM_INSN_REG_SET_RN(insn, nreg)                {insn &= ~0x000F0000; insn |= nreg<<16;}
127 # define ARM_INSN_REG_RD(insn)                  ((insn & 0x0000F000)>>12)
128 # define ARM_INSN_REG_SET_RD(insn, nreg)                {insn &= ~0x0000F000; insn |= nreg<<12;}
129 # define ARM_INSN_REG_RS(insn)                  ((insn & 0x00000F00)>>8)
130 # define ARM_INSN_REG_SET_RS(insn, nreg)                {insn &= ~0x00000F00; insn |= nreg<<8;}
131 # define ARM_INSN_REG_RM(insn)                  (insn & 0x0000000F)
132 # define ARM_INSN_REG_SET_RM(insn, nreg)                {insn &= ~0x0000000F; insn |= nreg;}
133 # define ARM_INSN_REG_MR(insn, nreg)            (insn & (1 << nreg))
134 # define ARM_INSN_REG_SET_MR(insn, nreg)         {insn |= (1 << nreg);}
135 # define ARM_INSN_REG_CLEAR_MR(insn, nreg)      {insn &= ~(1 << nreg);}
136
137 /* per-cpu kprobe control block */
138 struct kprobe_ctlblk {
139         unsigned long kprobe_status;
140         struct prev_kprobe prev_kprobe;
141 };
142
143 /* Architecture specific copy of original instruction */
144 struct arch_specific_insn {
145         /* copy of the original instruction */
146         kprobe_opcode_t *insn;
147         /*
148          * If this flag is not 0, this kprobe can be boost when its
149          * post_handler and break_handler is not set.
150          */
151         int boostable;
152 };
153
154 typedef kprobe_opcode_t (*entry_point_t) (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
155
156 void gen_insn_execbuf (void);
157 void pc_dep_insn_execbuf (void);
158 void gen_insn_execbuf_holder (void);
159 void pc_dep_insn_execbuf_holder (void);
160
161 void patch_suspended_task_ret_addr(struct task_struct *p, struct kretprobe *rp);
162
163
164 #endif /* _DBI_ASM_ARM_KPROBES_H */