#include <linux/types.h>
#include <linux/stddef.h>
-#include <linux/kprobes.h>
+#include <asm/probes.h>
+
+void __init arm_probes_decode_init(void);
+
+extern probes_check_cc * const probes_condition_checks[16];
#if __LINUX_ARM_ARCH__ >= 7
}
-void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs);
-void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs);
-
-enum kprobe_insn __kprobes
-kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi);
-
/*
* Test if load/store instructions writeback the address register.
* if P (bit 24) == 0 or W (bit 21) == 1
/*
* The following definitions and macros are used to build instruction
- * decoding tables for use by kprobe_decode_insn.
+ * decoding tables for use by probes_decode_insn.
*
* These tables are a concatenation of entries each of which consist of one of
* the decode_* structs. All of the fields in every type of decode structure
* {.bits = _type},
* {.bits = _mask},
* {.bits = _value},
- * {.handler = _handler},
+ * {.action = _handler},
*
* Initialising a specified member of the union means that the compiler
* will produce a warning if the argument is of an incorrect type.
* Instruction decoding jumps to parsing the new sub-table 'table'.
*
* DECODE_CUSTOM(mask, value, decoder)
- * The custom function 'decoder' is called to the complete decoding
- * of an instruction.
+ * The value of 'decoder' is used as an index into the array of
+ * action functions, and the retrieved decoder function is invoked
+ * to complete decoding of the instruction.
*
* DECODE_SIMULATE(mask, value, handler)
- * Set the probes instruction handler to 'handler', this will be used
- * to simulate the instruction when the probe is hit. Decoding returns
- * with INSN_GOOD_NO_SLOT.
+ * The probes instruction handler is set to the value found by
+ * indexing into the action array using the value of 'handler'. This
+ * will be used to simulate the instruction when the probe is hit.
+ * Decoding returns with INSN_GOOD_NO_SLOT.
*
* DECODE_EMULATE(mask, value, handler)
- * Set the probes instruction handler to 'handler', this will be used
- * to emulate the instruction when the probe is hit. The modified
- * instruction (see below) is placed in the probes instruction slot so it
- * may be called by the emulation code. Decoding returns with INSN_GOOD.
+ * The probes instruction handler is set to the value found by
+ * indexing into the action array using the value of 'handler'. This
+ * will be used to emulate the instruction when the probe is hit. The
+ * modified instruction (see below) is placed in the probes instruction
+ * slot so it may be called by the emulation code. Decoding returns
+ * with INSN_GOOD.
*
* DECODE_REJECT(mask, value)
* Instruction decoding fails with INSN_REJECTED
* Here is a real example which matches ARM instructions of the form
* "AND <Rd>,<Rn>,<Rm>,<shift> <Rs>"
*
- * DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags,
+ * DECODE_EMULATEX (0x0e000090, 0x00000010, PROBES_DATA_PROCESSING_REG,
* REGS(ANY, ANY, NOPC, 0, ANY)),
* ^ ^ ^ ^
* Rn Rd Rs Rm
* Decoding the instruction "AND R4, R5, R6, ASL R7" will be accepted and the
* instruction will be modified to "AND R0, R2, R3, ASL R1" and then placed into
* the kprobes instruction slot. This can then be called later by the handler
- * function emulate_rd12rn16rm0rs8_rwflags in order to simulate the instruction.
+ * function emulate_rd12rn16rm0rs8_rwflags (a pointer to which is retrieved from
+ * the indicated slot in the action array), in order to simulate the instruction.
*/
enum decode_type {
union decode_item {
u32 bits;
const union decode_item *table;
- kprobe_insn_handler_t *handler;
- kprobe_decode_insn_t *decoder;
+ int action;
};
+struct decode_header;
+typedef enum probes_insn (probes_custom_decode_t)(probes_opcode_t,
+ struct arch_probes_insn *,
+ const struct decode_header *);
+
+union decode_action {
+ probes_insn_handler_t *handler;
+ probes_custom_decode_t *decoder;
+};
#define DECODE_END \
{.bits = DECODE_TYPE_END}
#define DECODE_CUSTOM(_mask, _value, _decoder) \
DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0), \
- {.decoder = (_decoder)}
+ {.action = (_decoder)}
struct decode_simulate {
#define DECODE_SIMULATEX(_mask, _value, _handler, _regs) \
DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs), \
- {.handler = (_handler)}
+ {.action = (_handler)}
#define DECODE_SIMULATE(_mask, _value, _handler) \
DECODE_SIMULATEX(_mask, _value, _handler, 0)
#define DECODE_EMULATEX(_mask, _value, _handler, _regs) \
DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs), \
- {.handler = (_handler)}
+ {.action = (_handler)}
#define DECODE_EMULATE(_mask, _value, _handler) \
DECODE_EMULATEX(_mask, _value, _handler, 0)
#define DECODE_OR(_mask, _value) \
DECODE_HEADER(DECODE_TYPE_OR, _mask, _value, 0)
+enum probes_insn {
+ INSN_REJECTED,
+ INSN_GOOD,
+ INSN_GOOD_NO_SLOT
+};
struct decode_reject {
struct decode_header header;
#define DECODE_REJECT(_mask, _value) \
DECODE_HEADER(DECODE_TYPE_REJECT, _mask, _value, 0)
+probes_insn_handler_t probes_simulate_nop;
+probes_insn_handler_t probes_emulate_none;
-#ifdef CONFIG_THUMB2_KERNEL
-extern const union decode_item kprobe_decode_thumb16_table[];
-extern const union decode_item kprobe_decode_thumb32_table[];
-#else
-extern const union decode_item kprobe_decode_arm_table[];
-#endif
-
-extern kprobe_check_cc * const kprobe_condition_checks[16];
-
-
-int kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
- const union decode_item *table, bool thumb16);
+int __kprobes
+probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+ const union decode_item *table, bool thumb, bool emulate,
+ const union decode_action *actions);
#endif