diff options
author | David A. Long <dave.long@linaro.org> | 2014-03-07 00:06:43 +0100 |
---|---|---|
committer | David A. Long <dave.long@linaro.org> | 2014-03-18 21:39:36 +0100 |
commit | 3e6cd394bb10c2d65322e5f5d2ff0a9074d903a1 (patch) | |
tree | 0bbc61744e1a60d9a3a823a44ae5a7c279347eda /arch/arm/kernel/kprobes.c | |
parent | ARM: move generic thumb instruction parsing code to new files for use by othe... (diff) | |
download | linux-3e6cd394bb10c2d65322e5f5d2ff0a9074d903a1.tar.xz linux-3e6cd394bb10c2d65322e5f5d2ff0a9074d903a1.zip |
ARM: use a function table for determining instruction interpreter action
Make the instruction interpreter call back to semantic action functions
through a function pointer array provided by the invoker. The interpreter
decodes the instructions into groups and uses the group number to index
into the supplied array. kprobes and uprobes code will each supply their
own array of functions.
Signed-off-by: David A. Long <dave.long@linaro.org>
Acked-by: Jon Medhurst <tixy@linaro.org>
Diffstat (limited to 'arch/arm/kernel/kprobes.c')
-rw-r--r-- | arch/arm/kernel/kprobes.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index 54e7b46a3295..a757c3c22381 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -56,6 +56,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) unsigned long addr = (unsigned long)p->addr; bool thumb; kprobe_decode_insn_t *decode_insn; + const union decode_action *actions; int is; if (in_exception_text(addr)) @@ -69,20 +70,24 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) insn <<= 16; insn |= ((u16 *)addr)[1]; decode_insn = thumb32_kprobe_decode_insn; - } else + actions = kprobes_t32_actions; + } else { decode_insn = thumb16_kprobe_decode_insn; + actions = kprobes_t16_actions; + } #else /* !CONFIG_THUMB2_KERNEL */ thumb = false; if (addr & 0x3) return -EINVAL; insn = *p->addr; decode_insn = arm_kprobe_decode_insn; + actions = kprobes_arm_actions; #endif p->opcode = insn; p->ainsn.insn = tmp_insn; - switch ((*decode_insn)(insn, &p->ainsn)) { + switch ((*decode_insn)(insn, &p->ainsn, actions)) { case INSN_REJECTED: /* not supported */ return -EINVAL; |