diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-06-10 06:36:36 -0400 |
---|---|---|
committer | Tixy <tixy@medhuaa1.miniserver.com> | 2011-07-13 13:32:50 -0400 |
commit | e9a92859e91acaa67337b4a820040a820906ea4c (patch) | |
tree | 2cef55373048feb968c511875201a808fbcadbf1 /arch/arm/kernel | |
parent | 0d32e7d11b5ce8b3ab11fd74123b46b88f26b3e2 (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.c | 170 |
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 | ||
1212 | static enum kprobe_insn __kprobes | ||
1213 | space_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 | |||
1233 | static const union decode_item arm_cccc_001x_table[] = { | 1212 | static 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 | ||
1450 | static enum kprobe_insn __kprobes | 1429 | const union decode_item kprobe_decode_arm_table[] = { |
1451 | space_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 | ||
1459 | static enum kprobe_insn __kprobes | 1517 | DECODE_END |
1460 | space_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 | ||
1476 | static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs) | 1520 | static 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 | } |