aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/probes.h9
-rw-r--r--arch/arm/kernel/kprobes-arm.c61
-rw-r--r--arch/arm/kernel/kprobes-common.c40
-rw-r--r--arch/arm/kernel/kprobes-thumb.c175
-rw-r--r--arch/arm/kernel/kprobes.c2
-rw-r--r--arch/arm/kernel/probes-arm.c33
-rw-r--r--arch/arm/kernel/probes-arm.h15
-rw-r--r--arch/arm/kernel/probes-thumb.c15
-rw-r--r--arch/arm/kernel/probes.c13
-rw-r--r--arch/arm/kernel/probes.h8
10 files changed, 201 insertions, 170 deletions
diff --git a/arch/arm/include/asm/probes.h b/arch/arm/include/asm/probes.h
index 737a9b310efc..4d014c4aa1e7 100644
--- a/arch/arm/include/asm/probes.h
+++ b/arch/arm/include/asm/probes.h
@@ -21,9 +21,14 @@
21 21
22struct kprobe; 22struct kprobe;
23 23
24typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *); 24struct arch_specific_insn;
25typedef void (kprobe_insn_handler_t)(kprobe_opcode_t,
26 struct arch_specific_insn *,
27 struct pt_regs *);
25typedef unsigned long (kprobe_check_cc)(unsigned long); 28typedef unsigned long (kprobe_check_cc)(unsigned long);
26typedef void (kprobe_insn_singlestep_t)(struct kprobe *, struct pt_regs *); 29typedef void (kprobe_insn_singlestep_t)(kprobe_opcode_t,
30 struct arch_specific_insn *,
31 struct pt_regs *);
27typedef void (kprobe_insn_fn_t)(void); 32typedef void (kprobe_insn_fn_t)(void);
28 33
29/* Architecture specific copy of original instruction. */ 34/* Architecture specific copy of original instruction. */
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 8ebd84c48867..4a232e682e5a 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -72,12 +72,11 @@
72 "mov pc, "reg" \n\t" 72 "mov pc, "reg" \n\t"
73#endif 73#endif
74 74
75
76static void __kprobes 75static void __kprobes
77emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) 76emulate_ldrdstrd(kprobe_opcode_t insn,
77 struct arch_specific_insn *asi, struct pt_regs *regs)
78{ 78{
79 kprobe_opcode_t insn = p->opcode; 79 unsigned long pc = regs->ARM_pc + 4;
80 unsigned long pc = (unsigned long)p->addr + 8;
81 int rt = (insn >> 12) & 0xf; 80 int rt = (insn >> 12) & 0xf;
82 int rn = (insn >> 16) & 0xf; 81 int rn = (insn >> 16) & 0xf;
83 int rm = insn & 0xf; 82 int rm = insn & 0xf;
@@ -92,7 +91,7 @@ emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
92 BLX("%[fn]") 91 BLX("%[fn]")
93 : "=r" (rtv), "=r" (rt2v), "=r" (rnv) 92 : "=r" (rtv), "=r" (rt2v), "=r" (rnv)
94 : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv), 93 : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
95 [fn] "r" (p->ainsn.insn_fn) 94 [fn] "r" (asi->insn_fn)
96 : "lr", "memory", "cc" 95 : "lr", "memory", "cc"
97 ); 96 );
98 97
@@ -103,10 +102,10 @@ emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
103} 102}
104 103
105static void __kprobes 104static void __kprobes
106emulate_ldr(struct kprobe *p, struct pt_regs *regs) 105emulate_ldr(kprobe_opcode_t insn,
106 struct arch_specific_insn *asi, struct pt_regs *regs)
107{ 107{
108 kprobe_opcode_t insn = p->opcode; 108 unsigned long pc = regs->ARM_pc + 4;
109 unsigned long pc = (unsigned long)p->addr + 8;
110 int rt = (insn >> 12) & 0xf; 109 int rt = (insn >> 12) & 0xf;
111 int rn = (insn >> 16) & 0xf; 110 int rn = (insn >> 16) & 0xf;
112 int rm = insn & 0xf; 111 int rm = insn & 0xf;
@@ -119,7 +118,7 @@ emulate_ldr(struct kprobe *p, struct pt_regs *regs)
119 __asm__ __volatile__ ( 118 __asm__ __volatile__ (
120 BLX("%[fn]") 119 BLX("%[fn]")
121 : "=r" (rtv), "=r" (rnv) 120 : "=r" (rtv), "=r" (rnv)
122 : "1" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn) 121 : "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
123 : "lr", "memory", "cc" 122 : "lr", "memory", "cc"
124 ); 123 );
125 124
@@ -133,11 +132,11 @@ emulate_ldr(struct kprobe *p, struct pt_regs *regs)
133} 132}
134 133
135static void __kprobes 134static void __kprobes
136emulate_str(struct kprobe *p, struct pt_regs *regs) 135emulate_str(kprobe_opcode_t insn,
136 struct arch_specific_insn *asi, struct pt_regs *regs)
137{ 137{
138 kprobe_opcode_t insn = p->opcode; 138 unsigned long rtpc = regs->ARM_pc - 4 + str_pc_offset;
139 unsigned long rtpc = (unsigned long)p->addr + str_pc_offset; 139 unsigned long rnpc = regs->ARM_pc + 4;
140 unsigned long rnpc = (unsigned long)p->addr + 8;
141 int rt = (insn >> 12) & 0xf; 140 int rt = (insn >> 12) & 0xf;
142 int rn = (insn >> 16) & 0xf; 141 int rn = (insn >> 16) & 0xf;
143 int rm = insn & 0xf; 142 int rm = insn & 0xf;
@@ -151,7 +150,7 @@ emulate_str(struct kprobe *p, struct pt_regs *regs)
151 __asm__ __volatile__ ( 150 __asm__ __volatile__ (
152 BLX("%[fn]") 151 BLX("%[fn]")
153 : "=r" (rnv) 152 : "=r" (rnv)
154 : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn) 153 : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
155 : "lr", "memory", "cc" 154 : "lr", "memory", "cc"
156 ); 155 );
157 156
@@ -160,10 +159,10 @@ emulate_str(struct kprobe *p, struct pt_regs *regs)
160} 159}
161 160
162static void __kprobes 161static void __kprobes
163emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs) 162emulate_rd12rn16rm0rs8_rwflags(kprobe_opcode_t insn,
163 struct arch_specific_insn *asi, struct pt_regs *regs)
164{ 164{
165 kprobe_opcode_t insn = p->opcode; 165 unsigned long pc = regs->ARM_pc + 4;
166 unsigned long pc = (unsigned long)p->addr + 8;
167 int rd = (insn >> 12) & 0xf; 166 int rd = (insn >> 12) & 0xf;
168 int rn = (insn >> 16) & 0xf; 167 int rn = (insn >> 16) & 0xf;
169 int rm = insn & 0xf; 168 int rm = insn & 0xf;
@@ -183,7 +182,7 @@ emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
183 "mrs %[cpsr], cpsr \n\t" 182 "mrs %[cpsr], cpsr \n\t"
184 : "=r" (rdv), [cpsr] "=r" (cpsr) 183 : "=r" (rdv), [cpsr] "=r" (cpsr)
185 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv), 184 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
186 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) 185 "1" (cpsr), [fn] "r" (asi->insn_fn)
187 : "lr", "memory", "cc" 186 : "lr", "memory", "cc"
188 ); 187 );
189 188
@@ -195,9 +194,9 @@ emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
195} 194}
196 195
197static void __kprobes 196static void __kprobes
198emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) 197emulate_rd12rn16rm0_rwflags_nopc(kprobe_opcode_t insn,
198 struct arch_specific_insn *asi, struct pt_regs *regs)
199{ 199{
200 kprobe_opcode_t insn = p->opcode;
201 int rd = (insn >> 12) & 0xf; 200 int rd = (insn >> 12) & 0xf;
202 int rn = (insn >> 16) & 0xf; 201 int rn = (insn >> 16) & 0xf;
203 int rm = insn & 0xf; 202 int rm = insn & 0xf;
@@ -213,7 +212,7 @@ emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
213 "mrs %[cpsr], cpsr \n\t" 212 "mrs %[cpsr], cpsr \n\t"
214 : "=r" (rdv), [cpsr] "=r" (cpsr) 213 : "=r" (rdv), [cpsr] "=r" (cpsr)
215 : "0" (rdv), "r" (rnv), "r" (rmv), 214 : "0" (rdv), "r" (rnv), "r" (rmv),
216 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) 215 "1" (cpsr), [fn] "r" (asi->insn_fn)
217 : "lr", "memory", "cc" 216 : "lr", "memory", "cc"
218 ); 217 );
219 218
@@ -222,9 +221,10 @@ emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
222} 221}
223 222
224static void __kprobes 223static void __kprobes
225emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) 224emulate_rd16rn12rm0rs8_rwflags_nopc(kprobe_opcode_t insn,
225 struct arch_specific_insn *asi,
226 struct pt_regs *regs)
226{ 227{
227 kprobe_opcode_t insn = p->opcode;
228 int rd = (insn >> 16) & 0xf; 228 int rd = (insn >> 16) & 0xf;
229 int rn = (insn >> 12) & 0xf; 229 int rn = (insn >> 12) & 0xf;
230 int rm = insn & 0xf; 230 int rm = insn & 0xf;
@@ -242,7 +242,7 @@ emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
242 "mrs %[cpsr], cpsr \n\t" 242 "mrs %[cpsr], cpsr \n\t"