aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-06-10 06:36:36 -0400
committerTixy <tixy@medhuaa1.miniserver.com>2011-07-13 13:32:50 -0400
commite9a92859e91acaa67337b4a820040a820906ea4c (patch)
tree2cef55373048feb968c511875201a808fbcadbf1 /arch/arm/kernel
parent0d32e7d11b5ce8b3ab11fd74123b46b88f26b3e2 (diff)
ARM: kprobes: Migrate remaining instruction decoding functions to tables
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-arm.c170
1 files changed, 90 insertions, 80 deletions
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index b2fd2c87ffee..f271212a7cd5 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1209,27 +1209,6 @@ static const union decode_item arm_cccc_000x_table[] = {
1209 DECODE_END 1209 DECODE_END
1210}; 1210};
1211 1211
1212static enum kprobe_insn __kprobes
1213space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1214{
1215 if ((insn & 0x0f900080) == 0x01000000)
1216 return kprobe_decode_insn(insn, asi, arm_cccc_0001_0xx0____0xxx_table, false);
1217
1218 if ((insn & 0x0f900090) == 0x01000080)
1219 return kprobe_decode_insn(insn, asi, arm_cccc_0001_0xx0____1xx0_table, false);
1220
1221 if ((insn & 0x0f0000f0) == 0x00000090)
1222 return kprobe_decode_insn(insn, asi, arm_cccc_0000_____1001_table, false);
1223
1224 if ((insn & 0x0f0000f0) == 0x01000090)
1225 return kprobe_decode_insn(insn, asi, arm_cccc_0001_____1001_table, false);
1226
1227 if ((insn & 0x0e000090) == 0x00000090)
1228 return kprobe_decode_insn(insn, asi, arm_cccc_000x_____1xx1_table, false);
1229
1230 return kprobe_decode_insn(insn, asi, arm_cccc_000x_table, false);
1231}
1232
1233static const union decode_item arm_cccc_001x_table[] = { 1212static const union decode_item arm_cccc_001x_table[] = {
1234 /* Data-processing (immediate) */ 1213 /* Data-processing (immediate) */
1235 1214
@@ -1447,31 +1426,96 @@ static const union decode_item arm_cccc_100x_table[] = {
1447 DECODE_END 1426 DECODE_END
1448}; 1427};
1449 1428
1450static enum kprobe_insn __kprobes 1429const union decode_item kprobe_decode_arm_table[] = {
1451space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1430 /*
1452{ 1431 * Unconditional instructions
1453 /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ 1432 * 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx
1454 /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ 1433 */
1455 asi->insn_handler = simulate_bbl; 1434 DECODE_TABLE (0xf0000000, 0xf0000000, arm_1111_table),
1456 return INSN_GOOD_NO_SLOT; 1435
1457} 1436 /*
1437 * Miscellaneous instructions
1438 * cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx
1439 */
1440 DECODE_TABLE (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table),
1441
1442 /*
1443 * Halfword multiply and multiply-accumulate
1444 * cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx
1445 */
1446 DECODE_TABLE (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table),
1447
1448 /*
1449 * Multiply and multiply-accumulate
1450 * cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx
1451 */
1452 DECODE_TABLE (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table),
1453
1454 /*
1455 * Synchronization primitives
1456 * cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx
1457 */
1458 DECODE_TABLE (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table),
1459
1460 /*
1461 * Extra load/store instructions
1462 * cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx
1463 */
1464 DECODE_TABLE (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table),
1465
1466 /*
1467 * Data-processing (register)
1468 * cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx
1469 * Data-processing (register-shifted register)
1470 * cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx
1471 */
1472 DECODE_TABLE (0x0e000000, 0x00000000, arm_cccc_000x_table),
1473
1474 /*
1475 * Data-processing (immediate)
1476 * cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
1477 */
1478 DECODE_TABLE (0x0e000000, 0x02000000, arm_cccc_001x_table),
1479
1480 /*
1481 * Media instructions
1482 * cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx
1483 */
1484 DECODE_TABLE (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table),
1485 DECODE_TABLE (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table),
1486
1487 /*
1488 * Load/store word and unsigned byte
1489 * cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx
1490 */
1491 DECODE_TABLE (0x0c000000, 0x04000000, arm_cccc_01xx_table),
1492
1493 /*
1494 * Block data transfer instructions
1495 * cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx
1496 */
1497 DECODE_TABLE (0x0e000000, 0x08000000, arm_cccc_100x_table),
1498
1499 /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
1500 /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
1501 DECODE_SIMULATE (0x0e000000, 0x0a000000, simulate_bbl),
1502
1503 /*
1504 * Supervisor Call, and coprocessor instructions
1505 */
1506
1507 /* MCRR cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */
1508 /* MRRC cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */
1509 /* LDC cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
1510 /* STC cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
1511 /* CDP cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
1512 /* MCR cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
1513 /* MRC cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
1514 /* SVC cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
1515 DECODE_REJECT (0x0c000000, 0x0c000000),
1458 1516
1459static enum kprobe_insn __kprobes 1517 DECODE_END
1460space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1518};
1461{
1462 /* Coprocessor instructions... */
1463 /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1464 /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1465 /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
1466 /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
1467 /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
1468 /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
1469 /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
1470
1471 /* SVC : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
1472
1473 return INSN_REJECTED;
1474}
1475 1519
1476static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs) 1520static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs)
1477{ 1521{
@@ -1496,39 +1540,5 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1496{ 1540{
1497 asi->insn_singlestep = arm_singlestep; 1541 asi->insn_singlestep = arm_singlestep;
1498 asi->insn_check_cc = kprobe_condition_checks[insn>>28]; 1542 asi->insn_check_cc = kprobe_condition_checks[insn>>28];
1499 asi->insn[1] = KPROBE_RETURN_INSTRUCTION; 1543 return kprobe_decode_insn(insn, asi, kprobe_decode_arm_table, false);
1500
1501 if ((insn & 0xf0000000) == 0xf0000000)
1502
1503 return kprobe_decode_insn(insn, asi, arm_1111_table, false);
1504
1505 else if ((insn & 0x0e000000) == 0x00000000)
1506
1507 return space_cccc_000x(insn, asi);
1508
1509 else if ((insn & 0x0e000000) == 0x02000000)
1510
1511 return kprobe_decode_insn(insn, asi, arm_cccc_001x_table, false);
1512
1513 else if ((insn & 0x0f000010) == 0x06000010)
1514
1515 return kprobe_decode_insn(insn, asi, arm_cccc_0110_____xxx1_table, false);
1516
1517 else if ((insn & 0x0f000010) == 0x07000010)
1518
1519 return kprobe_decode_insn(insn, asi, arm_cccc_0111_____xxx1_table, false);
1520
1521 else if ((insn & 0x0c000000) == 0x04000000)
1522
1523 return kprobe_decode_insn(insn, asi, arm_cccc_01xx_table, false);
1524
1525 else if ((insn & 0x0e000000) == 0x08000000)
1526
1527 return kprobe_decode_insn(insn, asi, arm_cccc_100x_table, false);
1528
1529 else if ((insn & 0x0e000000) == 0x0a000000)
1530
1531 return space_cccc_101x(insn, asi);
1532
1533 return space_cccc_11xx(insn, asi);
1534} 1544}