aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/kprobes-decode.c
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-04-19 05:52:20 -0400
committerNicolas Pitre <nicolas.pitre@linaro.org>2011-04-28 23:41:01 -0400
commitcdc253611582f08036ccb6e10efe95b8e760a7e2 (patch)
treec2c1345ef27c642f02023c475f9fa94aeef72124 /arch/arm/kernel/kprobes-decode.c
parent94254930786216106100e9a28c9a244df58be61f (diff)
ARM: kprobes: Tidy-up kprobes-decode.c
- Remove coding standard violations reported by checkpatch.pl - Delete comment about handling of conditional branches which is no longer true. - Delete comment at end of file which lists all ARM instructions. This duplicates data available in the ARM ARM and seems like an unnecessary maintenance burden to keep this up to date and accurate. Signed-off-by: Jon Medhurst <tixy@yxit.co.uk> Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch/arm/kernel/kprobes-decode.c')
-rw-r--r--arch/arm/kernel/kprobes-decode.c131
1 files changed, 23 insertions, 108 deletions
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index 03b85ad525ab..15eeff6aea0e 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -34,9 +34,6 @@
34 * 34 *
35 * *) If the PC is written to by the instruction, the 35 * *) If the PC is written to by the instruction, the
36 * instruction must be fully simulated in software. 36 * instruction must be fully simulated in software.
37 * If it is a conditional instruction, the handler
38 * will use insn[0] to copy its condition code to
39 * set r0 to 1 and insn[1] to "mov pc, lr" to return.
40 * 37 *
41 * *) Otherwise, a modified form of the instruction is 38 * *) Otherwise, a modified form of the instruction is
42 * directly executed. Its handler calls the 39 * directly executed. Its handler calls the
@@ -1026,7 +1023,8 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1026 1023
1027 /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */ 1024 /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
1028 if ((insn & 0x0ff00090) == 0x01400080) 1025 if ((insn & 0x0ff00090) == 0x01400080)
1029 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); 1026 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
1027 asi);
1030 1028
1031 /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */ 1029 /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
1032 /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */ 1030 /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
@@ -1097,15 +1095,15 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1097 /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */ 1095 /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */
1098 /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */ 1096 /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */
1099 /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */ 1097 /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */
1100 if ((insn & 0x00d00000) == 0x00500000) { 1098 if ((insn & 0x00d00000) == 0x00500000)
1101 return INSN_REJECTED; 1099 return INSN_REJECTED;
1102 } else if ((insn & 0x00e00000) == 0x00000000) { 1100 else if ((insn & 0x00e00000) == 0x00000000)
1103 return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1101 return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1104 } else if ((insn & 0x00a00000) == 0x00200000) { 1102 else if ((insn & 0x00a00000) == 0x00200000)
1105 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1103 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1106 } else { 1104 else
1107 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); 1105 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
1108 } 1106 asi);
1109 } 1107 }
1110 1108
1111 /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */ 1109 /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */
@@ -1171,7 +1169,7 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1171 1169
1172 /* 1170 /*
1173 * ALU op with S bit and Rd == 15 : 1171 * ALU op with S bit and Rd == 15 :
1174 * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx 1172 * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx
1175 */ 1173 */
1176 if ((insn & 0x0e10f000) == 0x0010f000) 1174 if ((insn & 0x0e10f000) == 0x0010f000)
1177 return INSN_REJECTED; 1175 return INSN_REJECTED;
@@ -1401,11 +1399,10 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1401 if ((insn & 0x00300000) == 0x00100000) 1399 if ((insn & 0x00300000) == 0x00100000)
1402 return INSN_REJECTED; /* Unallocated space */ 1400 return INSN_REJECTED; /* Unallocated space */
1403 1401
1404 if ((insn & 0x000f0000) == 0x000f0000) { 1402 if ((insn & 0x000f0000) == 0x000f0000)
1405 return prep_emulate_rd12rm0(insn, asi); 1403 return prep_emulate_rd12rm0(insn, asi);
1406 } else { 1404 else
1407 return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1405 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1408 }
1409 } 1406 }
1410 1407
1411 /* Other instruction encodings aren't yet defined */ 1408 /* Other instruction encodings aren't yet defined */
@@ -1436,11 +1433,10 @@ space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1436 (insn & 0x0ff000d0) == 0x07500010 || 1433 (insn & 0x0ff000d0) == 0x07500010 ||
1437 (insn & 0x0ff000f0) == 0x07800010) { 1434 (insn & 0x0ff000f0) == 0x07800010) {
1438 1435
1439 if ((insn & 0x0000f000) == 0x0000f000) { 1436 if ((insn & 0x0000f000) == 0x0000f000)
1440 return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1437 return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1441 } else { 1438 else
1442 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1439 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1443 }
1444 } 1440 }
1445 1441
1446 /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */ 1442 /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */
@@ -1633,40 +1629,38 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1633 asi->insn_check_cc = condition_checks[insn>>28]; 1629 asi->insn_check_cc = condition_checks[insn>>28];
1634 asi->insn[1] = KPROBE_RETURN_INSTRUCTION; 1630 asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
1635 1631
1636 if ((insn & 0xf0000000) == 0xf0000000) { 1632 if ((insn & 0xf0000000) == 0xf0000000)
1637 1633
1638 return space_1111(insn, asi); 1634 return space_1111(insn, asi);
1639 1635
1640 } else if ((insn & 0x0e000000) == 0x00000000) { 1636 else if ((insn & 0x0e000000) == 0x00000000)
1641 1637
1642 return space_cccc_000x(insn, asi); 1638 return space_cccc_000x(insn, asi);
1643 1639
1644 } else if ((insn & 0x0e000000) == 0x02000000) { 1640 else if ((insn & 0x0e000000) == 0x02000000)
1645 1641
1646 return space_cccc_001x(insn, asi); 1642 return space_cccc_001x(insn, asi);
1647 1643
1648 } else if ((insn & 0x0f000010) == 0x06000010) { 1644 else if ((insn & 0x0f000010) == 0x06000010)
1649 1645
1650 return space_cccc_0110__1(insn, asi); 1646 return space_cccc_0110__1(insn, asi);
1651 1647
1652 } else if ((insn & 0x0f000010) == 0x07000010) { 1648 else if ((insn & 0x0f000010) == 0x07000010)
1653 1649
1654 return space_cccc_0111__1(insn, asi); 1650 return space_cccc_0111__1(insn, asi);
1655 1651
1656 } else if ((insn & 0x0c000000) == 0x04000000) { 1652 else if ((insn & 0x0c000000) == 0x04000000)
1657 1653
1658 return space_cccc_01xx(insn, asi); 1654 return space_cccc_01xx(insn, asi);
1659 1655
1660 } else if ((insn & 0x0e000000) == 0x08000000) { 1656 else if ((insn & 0x0e000000) == 0x08000000)
1661 1657
1662 return space_cccc_100x(insn, asi); 1658 return space_cccc_100x(insn, asi);
1663 1659
1664 } else if ((insn & 0x0e000000) == 0x0a000000) { 1660 else if ((insn & 0x0e000000) == 0x0a000000)
1665 1661
1666 return space_cccc_101x(insn, asi); 1662 return space_cccc_101x(insn, asi);
1667 1663
1668 }
1669
1670 return space_cccc_11xx(insn, asi); 1664 return space_cccc_11xx(insn, asi);
1671} 1665}
1672 1666
@@ -1674,82 +1668,3 @@ void __init arm_kprobe_decode_init(void)
1674{ 1668{
1675 find_str_pc_offset(); 1669 find_str_pc_offset();
1676} 1670}
1677
1678
1679/*
1680 * All ARM instructions listed below.
1681 *
1682 * Instructions and their general purpose registers are given.
1683 * If a particular register may not use R15, it is prefixed with a "!".
1684 * If marked with a "*" means the value returned by reading R15
1685 * is implementation defined.
1686 *
1687 * ADC/ADD/AND/BIC/CMN/CMP/EOR/MOV/MVN/ORR/RSB/RSC/SBC/SUB/TEQ
1688 * TST: Rd, Rn, Rm, !Rs
1689 * BX: Rm
1690 * BLX(2): !Rm
1691 * BX: Rm (R15 legal, but discouraged)
1692 * BXJ: !Rm,
1693 * CLZ: !Rd, !Rm
1694 * CPY: Rd, Rm
1695 * LDC/2,STC/2 immediate offset & unindex: Rn
1696 * LDC/2,STC/2 immediate pre/post-indexed: !Rn
1697 * LDM(1/3): !Rn, register_list
1698 * LDM(2): !Rn, !register_list
1699 * LDR,STR,PLD immediate offset: Rd, Rn
1700 * LDR,STR,PLD register offset: Rd, Rn, !Rm
1701 * LDR,STR,PLD scaled register offset: Rd, !Rn, !Rm
1702 * LDR,STR immediate pre/post-indexed: Rd, !Rn
1703 * LDR,STR register pre/post-indexed: Rd, !Rn, !Rm
1704 * LDR,STR scaled register pre/post-indexed: Rd, !Rn, !Rm
1705 * LDRB,STRB immediate offset: !Rd, Rn
1706 * LDRB,STRB register offset: !Rd, Rn, !Rm
1707 * LDRB,STRB scaled register offset: !Rd, !Rn, !Rm
1708 * LDRB,STRB immediate pre/post-indexed: !Rd, !Rn
1709 * LDRB,STRB register pre/post-indexed: !Rd, !Rn, !Rm
1710 * LDRB,STRB scaled register pre/post-indexed: !Rd, !Rn, !Rm
1711 * LDRT,LDRBT,STRBT immediate pre/post-indexed: !Rd, !Rn
1712 * LDRT,LDRBT,STRBT register pre/post-indexed: !Rd, !Rn, !Rm
1713 * LDRT,LDRBT,STRBT scaled register pre/post-indexed: !Rd, !Rn, !Rm
1714 * LDRH/SH/SB/D,STRH/SH/SB/D immediate offset: !Rd, Rn
1715 * LDRH/SH/SB/D,STRH/SH/SB/D register offset: !Rd, Rn, !Rm
1716 * LDRH/SH/SB/D,STRH/SH/SB/D immediate pre/post-indexed: !Rd, !Rn
1717 * LDRH/SH/SB/D,STRH/SH/SB/D register pre/post-indexed: !Rd, !Rn, !Rm
1718 * LDREX: !Rd, !Rn
1719 * MCR/2: !Rd
1720 * MCRR/2,MRRC/2: !Rd, !Rn
1721 * MLA: !Rd, !Rn, !Rm, !Rs
1722 * MOV: Rd
1723 * MRC/2: !Rd (if Rd==15, only changes cond codes, not the register)
1724 * MRS,MSR: !Rd
1725 * MUL: !Rd, !Rm, !Rs
1726 * PKH{BT,TB}: !Rd, !Rn, !Rm
1727 * QDADD,[U]QADD/16/8/SUBX: !Rd, !Rm, !Rn
1728 * QDSUB,[U]QSUB/16/8/ADDX: !Rd, !Rm, !Rn
1729 * REV/16/SH: !Rd, !Rm
1730 * RFE: !Rn
1731 * {S,U}[H]ADD{16,8,SUBX},{S,U}[H]SUB{16,8,ADDX}: !Rd, !Rn, !Rm
1732 * SEL: !Rd, !Rn, !Rm
1733 * SMLA<x><y>,SMLA{D,W<y>},SMLSD,SMML{A,S}: !Rd, !Rn, !Rm, !Rs
1734 * SMLAL<x><y>,SMLA{D,LD},SMLSLD,SMMULL,SMULW<y>: !RdHi, !RdLo, !Rm, !Rs
1735 * SMMUL,SMUAD,SMUL<x><y>,SMUSD: !Rd, !Rm, !Rs
1736 * SSAT/16: !Rd, !Rm
1737 * STM(1/2): !Rn, register_list* (R15 in reg list not recommended)
1738 * STRT immediate pre/post-indexed: Rd*, !Rn
1739 * STRT register pre/post-indexed: Rd*, !Rn, !Rm
1740 * STRT scaled register pre/post-indexed: Rd*, !Rn, !Rm
1741 * STREX: !Rd, !Rn, !Rm
1742 * SWP/B: !Rd, !Rn, !Rm
1743 * {S,U}XTA{B,B16,H}: !Rd, !Rn, !Rm
1744 * {S,U}XT{B,B16,H}: !Rd, !Rm
1745 * UM{AA,LA,UL}L: !RdHi, !RdLo, !Rm, !Rs
1746 * USA{D8,A8,T,T16}: !Rd, !Rm, !Rs
1747 *
1748 * May transfer control by writing R15 (possible mode changes or alternate
1749 * mode accesses marked by "*"):
1750 * ALU op (* with s-bit), B, BL, BKPT, BLX(1/2), BX, BXJ, CPS*, CPY,
1751 * LDM(1), LDM(2/3)*, LDR, MOV, RFE*, SWI*
1752 *
1753 * Instructions that do not take general registers, nor transfer control:
1754 * CDP/2, SETEND, SRS*
1755 */