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/kprobes.h | |
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/kprobes.h')
-rw-r--r-- | arch/arm/kernel/kprobes.h | 248 |
1 files changed, 247 insertions, 1 deletions
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 */ |