diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-04-26 10:15:56 -0400 |
---|---|---|
committer | Tixy <tixy@medhuaa1.miniserver.com> | 2011-07-13 13:32:43 -0400 |
commit | 0d1a095aa1e6e2a233bfb1729e15233e77f69d54 (patch) | |
tree | eb4d2415cf599c42bd425edf7557611abbd0bd4e /arch/arm/kernel | |
parent | e2960317d4581689bf80dbad4d75e7a59f11a3f7 (diff) |
ARM: kprobes: Infrastructure for table driven decoding of CPU instructions
The existing ARM instruction decoding functions are a mass of if/else
code. Rather than follow this pattern for Thumb instruction decoding
this patch implements an infrastructure for a new table driven scheme.
This has several advantages:
- Reduces the kernel size by approx 2kB. (The ARM instruction decoding
will eventually have -3.1kB code, +1.3kB data; with similar or better
estimated savings for Thumb decoding.)
- Allows programmatic checking of decoding consistency and test case
coverage.
- Provides more uniform source code and is therefore, arguably, clearer.
For a detailed explanation of how decoding tables work see the in-source
documentation in kprobes.h, and also for kprobe_decode_insn().
Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/kprobes-common.c | 258 | ||||
-rw-r--r-- | arch/arm/kernel/kprobes.h | 248 |
2 files changed, 505 insertions, 1 deletions
diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/kernel/kprobes-common.c index 87e91ce4d495..1cb6a82a5e24 100644 --- a/arch/arm/kernel/kprobes-common.c +++ b/arch/arm/kernel/kprobes-common.c | |||
@@ -140,3 +140,261 @@ kprobe_check_cc * const kprobe_condition_checks[16] = { | |||
140 | &__check_hi, &__check_ls, &__check_ge, &__check_lt, | 140 | &__check_hi, &__check_ls, &__check_ge, &__check_lt, |
141 | &__check_gt, &__check_le, &__check_al, &__check_al | 141 | &__check_gt, &__check_le, &__check_al, &__check_al |
142 | }; | 142 | }; |
143 | |||
144 | |||
145 | /* | ||
146 | * Prepare an instruction slot to receive an instruction for emulating. | ||
147 | * This is done by placing a subroutine return after the location where the | ||
148 | * instruction will be placed. We also modify ARM instructions to be | ||
149 | * unconditional as the condition code will already be checked before any | ||
150 | * emulation handler is called. | ||
151 | */ | ||
152 | static kprobe_opcode_t __kprobes | ||
153 | prepare_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, | ||
154 | bool thumb) | ||
155 | { | ||
156 | #ifdef CONFIG_THUMB2_KERNEL | ||
157 | if (thumb) { | ||
158 | u16 *thumb_insn = (u16 *)asi->insn; | ||
159 | thumb_insn[1] = 0x4770; /* Thumb bx lr */ | ||
160 | thumb_insn[2] = 0x4770; /* Thumb bx lr */ | ||
161 | return insn; | ||
162 | } | ||
163 | asi->insn[1] = 0xe12fff1e; /* ARM bx lr */ | ||
164 | #else | ||
165 | asi->insn[1] = 0xe1a0f00e; /* mov pc, lr */ | ||
166 | #endif | ||
167 | /* Make an ARM instruction unconditional */ | ||
168 | if (insn < 0xe0000000) | ||
169 | insn = (insn | 0xe0000000) & ~0x10000000; | ||
170 | return insn; | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * Write a (probably modified) instruction into the slot previously prepared by | ||
175 | * prepare_emulated_insn | ||
176 | */ | ||
177 | static void __kprobes | ||
178 | set_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, | ||
179 | bool thumb) | ||
180 | { | ||
181 | #ifdef CONFIG_THUMB2_KERNEL | ||
182 | if (thumb) { | ||
183 | u16 *ip = (u16 *)asi->insn; | ||
184 | if (is_wide_instruction(insn)) | ||
185 | *ip++ = insn >> 16; | ||
186 | *ip++ = insn; | ||
187 | return; | ||
188 | } | ||
189 | #endif | ||
190 | asi->insn[0] = insn; | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * When we modify the register numbers encoded in an instruction to be emulated, | ||
195 | * the new values come from this define. For ARM and 32-bit Thumb instructions | ||
196 | * this gives... | ||
197 | * | ||
198 | * bit position 16 12 8 4 0 | ||
199 | * ---------------+---+---+---+---+---+ | ||
200 | * register r2 r0 r1 -- r3 | ||
201 | */ | ||
202 | #define INSN_NEW_BITS 0x00020103 | ||
203 | |||
204 | /* Each nibble has same value as that at INSN_NEW_BITS bit 16 */ | ||
205 | #define INSN_SAMEAS16_BITS 0x22222222 | ||
206 | |||
207 | /* | ||
208 | * Validate and modify each of the registers encoded in an instruction. | ||
209 | * | ||
210 | * Each nibble in regs contains a value from enum decode_reg_type. For each | ||
211 | * non-zero value, the corresponding nibble in pinsn is validated and modified | ||
212 | * according to the type. | ||
213 | */ | ||
214 | static bool __kprobes decode_regs(kprobe_opcode_t* pinsn, u32 regs) | ||
215 | { | ||
216 | kprobe_opcode_t insn = *pinsn; | ||
217 | kprobe_opcode_t mask = 0xf; /* Start at least significant nibble */ | ||
218 | |||
219 | for (; regs != 0; regs >>= 4, mask <<= 4) { | ||
220 | |||
221 | kprobe_opcode_t new_bits = INSN_NEW_BITS; | ||
222 | |||
223 | switch (regs & 0xf) { | ||
224 | |||
225 | case REG_TYPE_NONE: | ||
226 | /* Nibble not a register, skip to next */ | ||
227 | continue; | ||
228 | |||
229 | case REG_TYPE_ANY: | ||
230 | /* Any register is allowed */ | ||
231 | break; | ||
232 | |||
233 | case REG_TYPE_SAMEAS16: | ||
234 | /* Replace register with same as at bit position 16 */ | ||
235 | new_bits = INSN_SAMEAS16_BITS; | ||
236 | break; | ||
237 | |||
238 | case REG_TYPE_SP: | ||
239 | /* Only allow SP (R13) */ | ||
240 | if ((insn ^ 0xdddddddd) & mask) | ||
241 | goto reject; | ||
242 | break; | ||
243 | |||
244 | case REG_TYPE_PC: | ||
245 | /* Only allow PC (R15) */ | ||
246 | if ((insn ^ 0xffffffff) & mask) | ||
247 | goto reject; | ||
248 | break; | ||
249 | |||
250 | case REG_TYPE_NOSP: | ||
251 | /* Reject SP (R13) */ | ||
252 | if (((insn ^ 0xdddddddd) & mask) == 0) | ||
253 | goto reject; | ||
254 | break; | ||
255 | |||
256 | case REG_TYPE_NOSPPC: | ||
257 | case REG_TYPE_NOSPPCX: | ||
258 | /* Reject SP and PC (R13 and R15) */ | ||
259 | if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0) | ||
260 | goto reject; | ||
261 | break; | ||
262 | |||
263 | case REG_TYPE_NOPCWB: | ||
264 | if (!is_writeback(insn)) | ||
265 | break; /* No writeback, so any register is OK */ | ||
266 | /* fall through... */ | ||
267 | case REG_TYPE_NOPC: | ||
268 | case REG_TYPE_NOPCX: | ||
269 | /* Reject PC (R15) */ | ||
270 | if (((insn ^ 0xffffffff) & mask) == 0) | ||
271 | goto reject; | ||
272 | break; | ||
273 | } | ||
274 | |||
275 | /* Replace value of nibble with new register number... */ | ||
276 | insn &= ~mask; | ||
277 | insn |= new_bits & mask; | ||
278 | } | ||
279 | |||
280 | *pinsn = insn; | ||
281 | return true; | ||
282 | |||
283 | reject: | ||
284 | return false; | ||
285 | } | ||
286 | |||
287 | static const int decode_struct_sizes[NUM_DECODE_TYPES] = { | ||
288 | [DECODE_TYPE_TABLE] = sizeof(struct decode_table), | ||
289 | [DECODE_TYPE_CUSTOM] = sizeof(struct decode_custom), | ||
290 | [DECODE_TYPE_SIMULATE] = sizeof(struct decode_simulate), | ||
291 | [DECODE_TYPE_EMULATE] = sizeof(struct decode_emulate), | ||
292 | [DECODE_TYPE_OR] = sizeof(struct decode_or), | ||
293 | [DECODE_TYPE_REJECT] = sizeof(struct decode_reject) | ||
294 | }; | ||
295 | |||
296 | /* | ||
297 | * kprobe_decode_insn operates on data tables in order to decode an ARM | ||
298 | * architecture instruction onto which a kprobe has been placed. | ||
299 | * | ||
300 | * These instruction decoding tables are a concatenation of entries each | ||
301 | * of which consist of one of the following structs: | ||
302 | * | ||
303 | * decode_table | ||
304 | * decode_custom | ||
305 | * decode_simulate | ||
306 | * decode_emulate | ||
307 | * decode_or | ||
308 | * decode_reject | ||
309 | * | ||
310 | * Each of these starts with a struct decode_header which has the following | ||
311 | * fields: | ||
312 | * | ||
313 | * type_regs | ||
314 | * mask | ||
315 | * value | ||
316 | * | ||
317 | * The least significant DECODE_TYPE_BITS of type_regs contains a value | ||
318 | * from enum decode_type, this indicates which of the decode_* structs | ||
319 | * the entry contains. The value DECODE_TYPE_END indicates the end of the | ||
320 | * table. | ||
321 | * | ||
322 | * When the table is parsed, each entry is checked in turn to see if it | ||
323 | * matches the instruction to be decoded using the test: | ||
324 | * | ||
325 | * (insn & mask) == value | ||
326 | * | ||
327 | * If no match is found before the end of the table is reached then decoding | ||
328 | * fails with INSN_REJECTED. | ||
329 | * | ||
330 | * When a match is found, decode_regs() is called to validate and modify each | ||
331 | * of the registers encoded in the instruction; the data it uses to do this | ||
332 | * is (type_regs >> DECODE_TYPE_BITS). A validation failure will cause decoding | ||
333 | * to fail with INSN_REJECTED. | ||
334 | * | ||
335 | * Once the instruction has passed the above tests, further processing | ||
336 | * depends on the type of the table entry's decode struct. | ||
337 | * | ||
338 | */ | ||
339 | int __kprobes | ||
340 | kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, | ||
341 | const union decode_item *table, bool thumb) | ||
342 | { | ||
343 | const struct decode_header *h = (struct decode_header *)table; | ||
344 | const struct decode_header *next; | ||
345 | bool matched = false; | ||
346 | |||
347 | insn = prepare_emulated_insn(insn, asi, thumb); | ||
348 | |||
349 | for (;; h = next) { | ||
350 | enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; | ||
351 | u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS; | ||
352 | |||
353 | if (type == DECODE_TYPE_END) | ||
354 | return INSN_REJECTED; | ||
355 | |||
356 | next = (struct decode_header *) | ||
357 | ((uintptr_t)h + decode_struct_sizes[type]); | ||
358 | |||
359 | if (!matched && (insn & h->mask.bits) != h->value.bits) | ||
360 | continue; | ||
361 | |||
362 | if (!decode_regs(&insn, regs)) | ||
363 | return INSN_REJECTED; | ||
364 | |||
365 | switch (type) { | ||
366 | |||
367 | case DECODE_TYPE_TABLE: { | ||
368 | struct decode_table *d = (struct decode_table *)h; | ||
369 | next = (struct decode_header *)d->table.table; | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | case DECODE_TYPE_CUSTOM: { | ||
374 | struct decode_custom *d = (struct decode_custom *)h; | ||
375 | return (*d->decoder.decoder)(insn, asi); | ||
376 | } | ||
377 | |||
378 | case DECODE_TYPE_SIMULATE: { | ||
379 | struct decode_simulate *d = (struct decode_simulate *)h; | ||
380 | asi->insn_handler = d->handler.handler; | ||
381 | return INSN_GOOD_NO_SLOT; | ||
382 | } | ||
383 | |||
384 | case DECODE_TYPE_EMULATE: { | ||
385 | struct decode_emulate *d = (struct decode_emulate *)h; | ||
386 | asi->insn_handler = d->handler.handler; | ||
387 | set_emulated_insn(insn, asi, thumb); | ||
388 | return INSN_GOOD; | ||
389 | } | ||
390 | |||
391 | case DECODE_TYPE_OR: | ||
392 | matched = true; | ||
393 | break; | ||
394 | |||
395 | case DECODE_TYPE_REJECT: | ||
396 | default: | ||
397 | return INSN_REJECTED; | ||
398 | } | ||
399 | } | ||
400 | } | ||
diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/kernel/kprobes.h index e3803c65c4be..c00681ce5cce 100644 --- a/arch/arm/kernel/kprobes.h +++ b/arch/arm/kernel/kprobes.h | |||
@@ -1,7 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/kernel/kprobes.h | 2 | * arch/arm/kernel/kprobes.h |
3 | * | 3 | * |
4 | * Contents moved from arch/arm/include/asm/kprobes.h which is | 4 | * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. |
5 | * | ||
6 | * Some contents moved here from arch/arm/include/asm/kprobes.h which is | ||
5 | * Copyright (C) 2006, 2007 Motorola Inc. | 7 | * Copyright (C) 2006, 2007 Motorola Inc. |
6 | * | 8 | * |
7 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
@@ -99,4 +101,248 @@ static inline unsigned long it_advance(unsigned long cpsr) | |||
99 | */ | 101 | */ |
100 | #define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000) | 102 | #define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000) |
101 | 103 | ||
104 | /* | ||
105 | * The following definitions and macros are used to build instruction | ||
106 | * decoding tables for use by kprobe_decode_insn. | ||
107 | * | ||
108 | * These tables are a concatenation of entries each of which consist of one of | ||
109 | * the decode_* structs. All of the fields in every type of decode structure | ||
110 | * are of the union type decode_item, therefore the entire decode table can be | ||
111 | * viewed as an array of these and declared like: | ||
112 | * | ||
113 | * static const union decode_item table_name[] = {}; | ||
114 | * | ||
115 | * In order to construct each entry in the table, macros are used to | ||
116 | * initialise a number of sequential decode_item values in a layout which | ||
117 | * matches the relevant struct. E.g. DECODE_SIMULATE initialise a struct | ||
118 | * decode_simulate by initialising four decode_item objects like this... | ||
119 | * | ||
120 | * {.bits = _type}, | ||
121 | * {.bits = _mask}, | ||
122 | * {.bits = _value}, | ||
123 | * {.handler = _handler}, | ||
124 | * | ||
125 | * Initialising a specified member of the union means that the compiler | ||
126 | * will produce a warning if the argument is of an incorrect type. | ||
127 | * | ||
128 | * Below is a list of each of the macros used to initialise entries and a | ||
129 | * description of the action performed when that entry is matched to an | ||
130 | * instruction. A match is found when (instruction & mask) == value. | ||
131 | * | ||
132 | * DECODE_TABLE(mask, value, table) | ||
133 | * Instruction decoding jumps to parsing the new sub-table 'table'. | ||
134 | * | ||
135 | * DECODE_CUSTOM(mask, value, decoder) | ||
136 | * The custom function 'decoder' is called to the complete decoding | ||
137 | * of an instruction. | ||
138 | * | ||
139 | * DECODE_SIMULATE(mask, value, handler) | ||
140 | * Set the probes instruction handler to 'handler', this will be used | ||
141 | * to simulate the instruction when the probe is hit. Decoding returns | ||
142 | * with INSN_GOOD_NO_SLOT. | ||
143 | * | ||
144 | * DECODE_EMULATE(mask, value, handler) | ||
145 | * Set the probes instruction handler to 'handler', this will be used | ||
146 | * to emulate the instruction when the probe is hit. The modified | ||
147 | * instruction (see below) is placed in the probes instruction slot so it | ||
148 | * may be called by the emulation code. Decoding returns with INSN_GOOD. | ||
149 | * | ||
150 | * DECODE_REJECT(mask, value) | ||
151 | * Instruction decoding fails with INSN_REJECTED | ||
152 | * | ||
153 | * DECODE_OR(mask, value) | ||
154 | * This allows the mask/value test of multiple table entries to be | ||
155 | * logically ORed. Once an 'or' entry is matched the decoding action to | ||
156 | * be performed is that of the next entry which isn't an 'or'. E.g. | ||
157 | * | ||
158 | * DECODE_OR (mask1, value1) | ||
159 | * DECODE_OR (mask2, value2) | ||
160 | * DECODE_SIMULATE (mask3, value3, simulation_handler) | ||
161 | * | ||
162 | * This means that if any of the three mask/value pairs match the | ||
163 | * instruction being decoded, then 'simulation_handler' will be used | ||
164 | * for it. | ||
165 | * | ||
166 | * Both the SIMULATE and EMULATE macros have a second form which take an | ||
167 | * additional 'regs' argument. | ||
168 | * | ||
169 | * DECODE_SIMULATEX(mask, value, handler, regs) | ||
170 | * DECODE_EMULATEX (mask, value, handler, regs) | ||
171 | * | ||
172 | * These are used to specify what kind of CPU register is encoded in each of the | ||
173 | * least significant 5 nibbles of the instruction being decoded. The regs value | ||
174 | * is specified using the REGS macro, this takes any of the REG_TYPE_* values | ||
175 | * from enum decode_reg_type as arguments; only the '*' part of the name is | ||
176 | * given. E.g. | ||
177 | * | ||
178 | * REGS(0, ANY, NOPC, 0, ANY) | ||
179 | * | ||
180 | * This indicates an instruction is encoded like: | ||
181 | * | ||
182 | * bits 19..16 ignore | ||
183 | * bits 15..12 any register allowed here | ||
184 | * bits 11.. 8 any register except PC allowed here | ||
185 | * bits 7.. 4 ignore | ||
186 | * bits 3.. 0 any register allowed here | ||
187 | * | ||
188 | * This register specification is checked after a decode table entry is found to | ||
189 | * match an instruction (through the mask/value test). Any invalid register then | ||
190 | * found in the instruction will cause decoding to fail with INSN_REJECTED. In | ||
191 | * the above example this would happen if bits 11..8 of the instruction were | ||
192 | * 1111, indicating R15 or PC. | ||
193 | * | ||
194 | * As well as checking for legal combinations of registers, this data is also | ||
195 | * used to modify the registers encoded in the instructions so that an | ||
196 | * emulation routines can use it. (See decode_regs() and INSN_NEW_BITS.) | ||
197 | * | ||
198 | * Here is a real example which matches ARM instructions of the form | ||
199 | * "AND <Rd>,<Rn>,<Rm>,<shift> <Rs>" | ||
200 | * | ||
201 | * DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags, | ||
202 | * REGS(ANY, ANY, NOPC, 0, ANY)), | ||
203 | * ^ ^ ^ ^ | ||
204 | * Rn Rd Rs Rm | ||
205 | * | ||
206 | * Decoding the instruction "AND R4, R5, R6, ASL R15" will be rejected because | ||
207 | * Rs == R15 | ||
208 | * | ||
209 | * Decoding the instruction "AND R4, R5, R6, ASL R7" will be accepted and the | ||
210 | * instruction will be modified to "AND R0, R2, R3, ASL R1" and then placed into | ||
211 | * the kprobes instruction slot. This can then be called later by the handler | ||
212 | * function emulate_rd12rn16rm0rs8_rwflags in order to simulate the instruction. | ||
213 | */ | ||
214 | |||
215 | enum decode_type { | ||
216 | DECODE_TYPE_END, | ||
217 | DECODE_TYPE_TABLE, | ||
218 | DECODE_TYPE_CUSTOM, | ||
219 | DECODE_TYPE_SIMULATE, | ||
220 | DECODE_TYPE_EMULATE, | ||
221 | DECODE_TYPE_OR, | ||
222 | DECODE_TYPE_REJECT, | ||
223 | NUM_DECODE_TYPES /* Must be last enum */ | ||
224 | }; | ||
225 | |||
226 | #define DECODE_TYPE_BITS 4 | ||
227 | #define DECODE_TYPE_MASK ((1 << DECODE_TYPE_BITS) - 1) | ||
228 | |||
229 | enum decode_reg_type { | ||
230 | REG_TYPE_NONE = 0, /* Not a register, ignore */ | ||
231 | REG_TYPE_ANY, /* Any register allowed */ | ||
232 | REG_TYPE_SAMEAS16, /* Register should be same as that at bits 19..16 */ | ||
233 | REG_TYPE_SP, /* Register must be SP */ | ||
234 | REG_TYPE_PC, /* Register must be PC */ | ||
235 | REG_TYPE_NOSP, /* Register must not be SP */ | ||
236 | REG_TYPE_NOSPPC, /* Register must not be SP or PC */ | ||
237 | REG_TYPE_NOPC, /* Register must not be PC */ | ||
238 | REG_TYPE_NOPCWB, /* No PC if load/store write-back flag also set */ | ||
239 | |||
240 | /* The following types are used when the encoding for PC indicates | ||
241 | * another instruction form. This distiction only matters for test | ||
242 | * case coverage checks. | ||
243 | */ | ||
244 | REG_TYPE_NOPCX, /* Register must not be PC */ | ||
245 | REG_TYPE_NOSPPCX, /* Register must not be SP or PC */ | ||
246 | |||
247 | /* Alias to allow '0' arg to be used in REGS macro. */ | ||
248 | REG_TYPE_0 = REG_TYPE_NONE | ||
249 | }; | ||
250 | |||
251 | #define REGS(r16, r12, r8, r4, r0) \ | ||
252 | ((REG_TYPE_##r16) << 16) + \ | ||
253 | ((REG_TYPE_##r12) << 12) + \ | ||
254 | ((REG_TYPE_##r8) << 8) + \ | ||
255 | ((REG_TYPE_##r4) << 4) + \ | ||
256 | (REG_TYPE_##r0) | ||
257 | |||
258 | union decode_item { | ||
259 | u32 bits; | ||
260 | const union decode_item *table; | ||
261 | kprobe_insn_handler_t *handler; | ||
262 | kprobe_decode_insn_t *decoder; | ||
263 | }; | ||
264 | |||
265 | |||
266 | #define DECODE_END \ | ||
267 | {.bits = DECODE_TYPE_END} | ||
268 | |||
269 | |||
270 | struct decode_header { | ||
271 | union decode_item type_regs; | ||
272 | union decode_item mask; | ||
273 | union decode_item value; | ||
274 | }; | ||
275 | |||
276 | #define DECODE_HEADER(_type, _mask, _value, _regs) \ | ||
277 | {.bits = (_type) | ((_regs) << DECODE_TYPE_BITS)}, \ | ||
278 | {.bits = (_mask)}, \ | ||
279 | {.bits = (_value)} | ||
280 | |||
281 | |||
282 | struct decode_table { | ||
283 | struct decode_header header; | ||
284 | union decode_item table; | ||
285 | }; | ||
286 | |||
287 | #define DECODE_TABLE(_mask, _value, _table) \ | ||
288 | DECODE_HEADER(DECODE_TYPE_TABLE, _mask, _value, 0), \ | ||
289 | {.table = (_table)} | ||
290 | |||
291 | |||
292 | struct decode_custom { | ||
293 | struct decode_header header; | ||
294 | union decode_item decoder; | ||
295 | }; | ||
296 | |||
297 | #define DECODE_CUSTOM(_mask, _value, _decoder) \ | ||
298 | DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0), \ | ||
299 | {.decoder = (_decoder)} | ||
300 | |||
301 | |||
302 | struct decode_simulate { | ||
303 | struct decode_header header; | ||
304 | union decode_item handler; | ||
305 | }; | ||
306 | |||
307 | #define DECODE_SIMULATEX(_mask, _value, _handler, _regs) \ | ||
308 | DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs), \ | ||
309 | {.handler = (_handler)} | ||
310 | |||
311 | #define DECODE_SIMULATE(_mask, _value, _handler) \ | ||
312 | DECODE_SIMULATEX(_mask, _value, _handler, 0) | ||
313 | |||
314 | |||
315 | struct decode_emulate { | ||
316 | struct decode_header header; | ||
317 | union decode_item handler; | ||
318 | }; | ||
319 | |||
320 | #define DECODE_EMULATEX(_mask, _value, _handler, _regs) \ | ||
321 | DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs), \ | ||
322 | {.handler = (_handler)} | ||
323 | |||
324 | #define DECODE_EMULATE(_mask, _value, _handler) \ | ||
325 | DECODE_EMULATEX(_mask, _value, _handler, 0) | ||
326 | |||
327 | |||
328 | struct decode_or { | ||
329 | struct decode_header header; | ||
330 | }; | ||
331 | |||
332 | #define DECODE_OR(_mask, _value) \ | ||
333 | DECODE_HEADER(DECODE_TYPE_OR, _mask, _value, 0) | ||
334 | |||
335 | |||
336 | struct decode_reject { | ||
337 | struct decode_header header; | ||
338 | }; | ||
339 | |||
340 | #define DECODE_REJECT(_mask, _value) \ | ||
341 | DECODE_HEADER(DECODE_TYPE_REJECT, _mask, _value, 0) | ||
342 | |||
343 | |||
344 | int kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, | ||
345 | const union decode_item *table, bool thumb16); | ||
346 | |||
347 | |||
102 | #endif /* _ARM_KERNEL_KPROBES_H */ | 348 | #endif /* _ARM_KERNEL_KPROBES_H */ |