aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-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 */