aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/kprobes-arm.c57
-rw-r--r--arch/arm/kernel/kprobes-common.c3
-rw-r--r--arch/arm/kernel/kprobes-thumb.c149
-rw-r--r--arch/arm/kernel/kprobes.c9
-rw-r--r--arch/arm/kernel/kprobes.h15
-rw-r--r--arch/arm/kernel/probes-arm.c114
-rw-r--r--arch/arm/kernel/probes-arm.h52
-rw-r--r--arch/arm/kernel/probes-thumb.c145
-rw-r--r--arch/arm/kernel/probes-thumb.h104
-rw-r--r--arch/arm/kernel/probes.c9
-rw-r--r--arch/arm/kernel/probes.h55
11 files changed, 441 insertions, 271 deletions
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index a1d0a8f00f9e..8ebd84c48867 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -73,7 +73,7 @@
73#endif 73#endif
74 74
75 75
76void __kprobes 76static void __kprobes
77emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) 77emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
78{ 78{
79 kprobe_opcode_t insn = p->opcode; 79 kprobe_opcode_t insn = p->opcode;
@@ -102,7 +102,7 @@ emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
102 regs->uregs[rn] = rnv; 102 regs->uregs[rn] = rnv;
103} 103}
104 104
105void __kprobes 105static void __kprobes
106emulate_ldr(struct kprobe *p, struct pt_regs *regs) 106emulate_ldr(struct kprobe *p, struct pt_regs *regs)
107{ 107{
108 kprobe_opcode_t insn = p->opcode; 108 kprobe_opcode_t insn = p->opcode;
@@ -132,7 +132,7 @@ emulate_ldr(struct kprobe *p, struct pt_regs *regs)
132 regs->uregs[rn] = rnv; 132 regs->uregs[rn] = rnv;
133} 133}
134 134
135void __kprobes 135static void __kprobes
136emulate_str(struct kprobe *p, struct pt_regs *regs) 136emulate_str(struct kprobe *p, struct pt_regs *regs)
137{ 137{
138 kprobe_opcode_t insn = p->opcode; 138 kprobe_opcode_t insn = p->opcode;
@@ -159,7 +159,7 @@ emulate_str(struct kprobe *p, struct pt_regs *regs)
159 regs->uregs[rn] = rnv; 159 regs->uregs[rn] = rnv;
160} 160}
161 161
162void __kprobes 162static void __kprobes
163emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs) 163emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
164{ 164{
165 kprobe_opcode_t insn = p->opcode; 165 kprobe_opcode_t insn = p->opcode;
@@ -194,7 +194,7 @@ emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
194 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 194 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
195} 195}
196 196
197void __kprobes 197static void __kprobes
198emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) 198emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
199{ 199{
200 kprobe_opcode_t insn = p->opcode; 200 kprobe_opcode_t insn = p->opcode;
@@ -221,7 +221,7 @@ emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
221 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 221 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
222} 222}
223 223
224void __kprobes 224static void __kprobes
225emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) 225emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
226{ 226{
227 kprobe_opcode_t insn = p->opcode; 227 kprobe_opcode_t insn = p->opcode;
@@ -250,7 +250,7 @@ emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
250 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 250 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
251} 251}
252 252
253void __kprobes 253static void __kprobes
254emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs) 254emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
255{ 255{
256 kprobe_opcode_t insn = p->opcode; 256 kprobe_opcode_t insn = p->opcode;
@@ -270,7 +270,7 @@ emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
270 regs->uregs[rd] = rdv; 270 regs->uregs[rd] = rdv;
271} 271}
272 272
273void __kprobes 273static void __kprobes
274emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) 274emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
275{ 275{
276 kprobe_opcode_t insn = p->opcode; 276 kprobe_opcode_t insn = p->opcode;
@@ -299,3 +299,44 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
299 regs->uregs[rdhi] = rdhiv; 299 regs->uregs[rdhi] = rdhiv;
300 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 300 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
301} 301}
302
303const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
304 [PROBES_EMULATE_NONE] = {.handler = kprobe_emulate_none},
305 [PROBES_SIMULATE_NOP] = {.handler = kprobe_simulate_nop},
306 [PROBES_PRELOAD_IMM] = {.handler = kprobe_simulate_nop},
307 [PROBES_PRELOAD_REG] = {.handler = kprobe_simulate_nop},
308 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
309 [PROBES_MRS] = {.handler = simulate_mrs},
310 [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
311 [PROBES_CLZ] = {.handler = emulate_rd12rm0_noflags_nopc},
312 [PROBES_SATURATING_ARITHMETIC] = {
313 .handler = emulate_rd12rn16rm0_rwflags_nopc},
314 [PROBES_MUL1] = {.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
315 [PROBES_MUL2] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
316 [PROBES_SWP] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
317 [PROBES_LDRSTRD] = {.handler = emulate_ldrdstrd},
318 [PROBES_LOAD_EXTRA] = {.handler = emulate_ldr},
319 [PROBES_LOAD] = {.handler = emulate_ldr},
320 [PROBES_STORE_EXTRA] = {.handler = emulate_str},
321 [PROBES_STORE] = {.handler = emulate_str},
322 [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
323 [PROBES_DATA_PROCESSING_REG] = {
324 .handler = emulate_rd12rn16rm0rs8_rwflags},
325 [PROBES_DATA_PROCESSING_IMM] = {
326 .handler = emulate_rd12rn16rm0rs8_rwflags},
327 [PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc},
328 [PROBES_SEV] = {.handler = kprobe_emulate_none},
329 [PROBES_WFE] = {.handler = kprobe_simulate_nop},
330 [PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
331 [PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc},
332 [PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
333 [PROBES_PACK] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
334 [PROBES_EXTEND] = {.handler = emulate_rd12rm0_noflags_nopc},
335 [PROBES_EXTEND_ADD] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
336 [PROBES_MUL_ADD_LONG] = {
337 .handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
338 [PROBES_MUL_ADD] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
339 [PROBES_BITFIELD] = {.handler = emulate_rd12rm0_noflags_nopc},
340 [PROBES_BRANCH] = {.handler = simulate_bbl},
341 [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
342};
diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/kernel/kprobes-common.c
index f02c038059c3..029b79c6face 100644
--- a/arch/arm/kernel/kprobes-common.c
+++ b/arch/arm/kernel/kprobes-common.c
@@ -112,7 +112,8 @@ emulate_ldm_r3_15(struct kprobe *p, struct pt_regs *regs)
112} 112}
113 113
114enum kprobe_insn __kprobes 114enum kprobe_insn __kprobes
115kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) 115kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi,
116 const struct decode_header *h)
116{ 117{
117 kprobe_insn_handler_t *handler = 0; 118 kprobe_insn_handler_t *handler = 0;
118 unsigned reglist = insn & 0xffff; 119 unsigned reglist = insn & 0xffff;
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c
index 977f21723a9c..d83f6092920a 100644
--- a/arch/arm/kernel/kprobes-thumb.c
+++ b/arch/arm/kernel/kprobes-thumb.c
@@ -16,6 +16,10 @@
16#include "kprobes.h" 16#include "kprobes.h"
17#include "probes-thumb.h" 17#include "probes-thumb.h"
18 18
19/* These emulation encodings are functionally equivalent... */
20#define t32_emulate_rd8rn16rm0ra12_noflags \
21 t32_emulate_rdlo12rdhi8rn16rm0_noflags
22
19/* 23/*
20 * Return the PC value for a probe in thumb code. 24 * Return the PC value for a probe in thumb code.
21 * This is the address of the probed instruction plus 4. 25 * This is the address of the probed instruction plus 4.
@@ -29,7 +33,7 @@ static inline unsigned long __kprobes thumb_probe_pc(struct kprobe *p)
29 33
30/* t32 thumb actions */ 34/* t32 thumb actions */
31 35
32void __kprobes 36static void __kprobes
33t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs) 37t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs)
34{ 38{
35 kprobe_opcode_t insn = p->opcode; 39 kprobe_opcode_t insn = p->opcode;
@@ -49,7 +53,7 @@ t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs)
49 regs->ARM_pc = pc + 2 * halfwords; 53 regs->ARM_pc = pc + 2 * halfword