11 #include <linux/kernel.h>
13 #include <linux/module.h>
21 #define in_it_block(cpsr) ((cpsr & 0x06000c00) != 0x00000000)
28 #define current_cond(cpsr) ((cpsr >> 12) & 0xf)
38 return (
unsigned long)p->
addr - 1 + 4;
45 unsigned long pc = thumb_probe_pc(p);
46 int rn = (insn >> 16) & 0xf;
49 unsigned long rnv = (rn == 15) ? pc : regs->
uregs[rn];
50 unsigned long rmv = regs->
uregs[rm];
51 unsigned int halfwords;
54 halfwords = ((
u16 *)rnv)[rmv];
56 halfwords = ((
u8 *)rnv)[rmv];
58 regs->ARM_pc = pc + 2 * halfwords;
65 int rd = (insn >> 8) & 0xf;
66 unsigned long mask = 0xf8ff03df;
71 t32_simulate_cond_branch(
struct kprobe *p,
struct pt_regs *regs)
74 unsigned long pc = thumb_probe_pc(p);
76 long offset = insn & 0x7ff;
77 offset += (insn & 0x003f0000) >> 5;
78 offset += (insn & 0x00002000) << 4;
79 offset += (insn & 0x00000800) << 7;
80 offset -= (insn & 0x04000000) >> 7;
82 regs->ARM_pc = pc + (offset * 2);
88 int cc = (insn >> 22) & 0xf;
98 unsigned long pc = thumb_probe_pc(p);
100 long offset = insn & 0x7ff;
101 offset += (insn & 0x03ff0000) >> 5;
102 offset += (insn & 0x00002000) << 9;
103 offset += (insn & 0x00000800) << 10;
104 if (insn & 0x04000000)
105 offset -= 0x00800000;
107 offset ^= 0x00600000;
109 if (insn & (1 << 14)) {
111 regs->ARM_lr = (
unsigned long)p->
addr + 4;
112 if (!(insn & (1 << 12))) {
119 regs->ARM_pc = pc + (offset * 2);
123 t32_simulate_ldr_literal(
struct kprobe *p,
struct pt_regs *regs)
126 unsigned long addr = thumb_probe_pc(p) & ~3;
127 int rt = (insn >> 12) & 0xf;
130 long offset = insn & 0xfff;
131 if (insn & 0x00800000)
136 if (insn & 0x00400000) {
138 rtv = *(
unsigned long *)addr;
140 bx_write_pc(rtv, regs);
143 }
else if (insn & 0x00200000) {
145 if (insn & 0x01000000)
151 if (insn & 0x01000000)
157 regs->
uregs[rt] = rtv;
167 ((
u16 *)asi->
insn)[0] = insn >> 16;
168 ((
u16 *)asi->
insn)[1] = insn & 0xffff;
177 unsigned long pc = thumb_probe_pc(p) & ~3;
178 int rt1 = (insn >> 12) & 0xf;
179 int rt2 = (insn >> 8) & 0xf;
180 int rn = (insn >> 16) & 0xf;
182 register unsigned long rt1v
asm(
"r0") = regs->
uregs[rt1];
183 register unsigned long rt2v
asm(
"r1") = regs->
uregs[rt2];
184 register unsigned long rnv
asm(
"r2") = (rn == 15) ? pc
189 :
"=r" (rt1v),
"=r" (rt2v),
"=r" (rnv)
190 :
"0" (rt1v),
"1" (rt2v),
"2" (rnv), [
fn]
"r" (p->
ainsn.insn_fn)
191 :
"lr",
"memory",
"cc"
195 regs->
uregs[rn] = rnv;
196 regs->
uregs[rt1] = rt1v;
197 regs->
uregs[rt2] = rt2v;
204 int rt = (insn >> 12) & 0xf;
205 int rn = (insn >> 16) & 0xf;
208 register unsigned long rtv
asm(
"r0") = regs->
uregs[rt];
209 register unsigned long rnv
asm(
"r2") = regs->
uregs[rn];
210 register unsigned long rmv
asm(
"r3") = regs->
uregs[rm];
214 :
"=r" (rtv),
"=r" (rnv)
215 :
"0" (rtv),
"1" (rnv),
"r" (rmv), [
fn]
"r" (p->
ainsn.insn_fn)
216 :
"lr",
"memory",
"cc"
219 regs->
uregs[rn] = rnv;
221 bx_write_pc(rtv, regs);
223 regs->
uregs[rt] = rtv;
227 t32_emulate_rd8rn16rm0_rwflags(
struct kprobe *p,
struct pt_regs *regs)
230 int rd = (insn >> 8) & 0xf;
231 int rn = (insn >> 16) & 0xf;
234 register unsigned long rdv
asm(
"r1") = regs->
uregs[rd];
235 register unsigned long rnv
asm(
"r2") = regs->
uregs[rn];
236 register unsigned long rmv
asm(
"r3") = regs->
uregs[rm];
237 unsigned long cpsr = regs->ARM_cpsr;
240 "msr cpsr_fs, %[cpsr] \n\t"
242 "mrs %[cpsr], cpsr \n\t"
243 :
"=r" (rdv), [cpsr]
"=r" (cpsr)
244 :
"0" (rdv),
"r" (rnv),
"r" (rmv),
245 "1" (cpsr), [
fn]
"r" (p->
ainsn.insn_fn)
246 :
"lr",
"memory",
"cc"
254 t32_emulate_rd8pc16_noflags(
struct kprobe *p,
struct pt_regs *regs)
257 unsigned long pc = thumb_probe_pc(p);
258 int rd = (insn >> 8) & 0xf;
260 register unsigned long rdv
asm(
"r1") = regs->
uregs[rd];
261 register unsigned long rnv
asm(
"r2") = pc & ~3;
266 :
"0" (rdv),
"r" (rnv), [
fn]
"r" (p->
ainsn.insn_fn)
267 :
"lr",
"memory",
"cc"
274 t32_emulate_rd8rn16_noflags(
struct kprobe *p,
struct pt_regs *regs)
277 int rd = (insn >> 8) & 0xf;
278 int rn = (insn >> 16) & 0xf;
280 register unsigned long rdv
asm(
"r1") = regs->
uregs[rd];
281 register unsigned long rnv
asm(
"r2") = regs->
uregs[rn];
286 :
"0" (rdv),
"r" (rnv), [
fn]
"r" (p->
ainsn.insn_fn)
287 :
"lr",
"memory",
"cc"
294 t32_emulate_rdlo12rdhi8rn16rm0_noflags(
struct kprobe *p,
struct pt_regs *regs)
297 int rdlo = (insn >> 12) & 0xf;
298 int rdhi = (insn >> 8) & 0xf;
299 int rn = (insn >> 16) & 0xf;
302 register unsigned long rdlov
asm(
"r0") = regs->
uregs[rdlo];
303 register unsigned long rdhiv
asm(
"r1") = regs->
uregs[rdhi];
304 register unsigned long rnv
asm(
"r2") = regs->
uregs[rn];
305 register unsigned long rmv
asm(
"r3") = regs->
uregs[rm];
309 :
"=r" (rdlov),
"=r" (rdhiv)
310 :
"0" (rdlov),
"1" (rdhiv),
"r" (rnv),
"r" (rmv),
312 :
"lr",
"memory",
"cc"
315 regs->
uregs[rdlo] = rdlov;
316 regs->
uregs[rdhi] = rdhiv;
320 #define t32_emulate_rd8rn16rm0ra12_noflags \
321 t32_emulate_rdlo12rdhi8rn16rm0_noflags
323 static const union decode_item t32_table_1110_100x_x0xx[] = {
352 static const union decode_item t32_table_1110_100x_x1xx[] = {
361 REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)),
366 REGS(NOSP, 0, 0, 0, NOSPPC)),
380 static const union decode_item t32_table_1110_101x[] = {
385 DECODE_EMULATEX (0xff700f00, 0xea100f00, t32_emulate_rd8rn16rm0_rwflags,
386 REGS(NOSPPC, 0, 0, 0, NOSPPC)),
391 DECODE_EMULATEX (0xfff00f00, 0xebb00f00, t32_emulate_rd8rn16rm0_rwflags,
392 REGS(NOPC, 0, 0, 0, NOSPPC)),
396 DECODE_EMULATEX (0xffcf0000, 0xea4f0000, t32_emulate_rd8rn16rm0_rwflags,
397 REGS(0, 0, NOSPPC, 0, NOSPPC)),
411 DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, t32_emulate_rd8rn16rm0_rwflags,
420 DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, t32_emulate_rd8rn16rm0_rwflags,
421 REGS(
SP, 0, NOPC, 0, NOSPPC)),
434 DECODE_EMULATEX (0xfe000000, 0xea000000, t32_emulate_rd8rn16rm0_rwflags,
435 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
440 static const union decode_item t32_table_1111_0x0x___0[] = {
445 DECODE_EMULATEX (0xfb708f00, 0xf0100f00, t32_emulate_rd8rn16rm0_rwflags,
446 REGS(NOSPPC, 0, 0, 0, 0)),
451 DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, t32_emulate_rd8rn16rm0_rwflags,
452 REGS(NOPC, 0, 0, 0, 0)),
456 DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, t32_emulate_rd8rn16rm0_rwflags,
457 REGS(0, 0, NOSPPC, 0, 0)),
473 DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, t32_emulate_rd8rn16rm0_rwflags,
486 DECODE_EMULATEX (0xfa008000, 0xf0000000, t32_emulate_rd8rn16rm0_rwflags,
487 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
492 static const union decode_item t32_table_1111_0x1x___0[] = {
499 REGS(
PC, 0, NOSPPC, 0, 0)),
511 REGS(NOPCX, 0, NOSPPC, 0, 0)),
516 REGS(0, 0, NOSPPC, 0, 0)),
522 DECODE_EMULATEX (0xfb508000, 0xf3000000, t32_emulate_rd8rn16rm0_rwflags,
523 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
528 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
532 REGS(0, 0, NOSPPC, 0, 0)),
536 REGS(NOSPPCX, 0, NOSPPC, 0, 0)),
541 static const union decode_item t32_table_1111_0xxx___1[] = {
555 REGS(0, 0, NOSPPC, 0, 0)),
576 DECODE_CUSTOM (0xf800d000, 0xf0008000, t32_decode_cond_branch),
587 static const union decode_item t32_table_1111_100x_x0x1__1111[] = {
602 REGS(NOPCX, 0, 0, 0, 0)),
608 REGS(NOPCX, 0, 0, 0, NOSPPC)),
614 static const union decode_item t32_table_1111_100x[] = {
657 REGS(NOPCX,
ANY, 0, 0, NOSPPC)),
664 REGS(
PC, NOSPPCX, 0, 0, 0)),
680 REGS(NOPCX, NOSPPCX, 0, 0, 0)),
689 REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)),
695 static const union decode_item t32_table_1111_1010___1111[] = {
707 DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, t32_emulate_rd8rn16rm0_rwflags,
708 REGS(0, 0, NOSPPC, 0, NOSPPC)),
780 DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, t32_emulate_rd8rn16rm0_rwflags,
781 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
791 REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)),
797 static const union decode_item t32_table_1111_1011_0[] = {
813 DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, t32_emulate_rd8rn16rm0_rwflags,
814 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
830 REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)),
836 static const union decode_item t32_table_1111_1011_1[] = {
850 DECODE_EMULATEX (0xff9000f0, 0xfb800000, t32_emulate_rdlo12rdhi8rn16rm0_noflags,
851 REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)),
865 DECODE_TABLE (0xfe400000, 0xe8000000, t32_table_1110_100x_x0xx),
871 DECODE_TABLE (0xfe400000, 0xe8400000, t32_table_1110_100x_x1xx),
877 DECODE_TABLE (0xfe000000, 0xea000000, t32_table_1110_101x),
889 DECODE_TABLE (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0),
895 DECODE_TABLE (0xfa008000, 0xf2000000, t32_table_1111_0x1x___0),
901 DECODE_TABLE (0xf8008000, 0xf0008000, t32_table_1111_0xxx___1),
913 DECODE_TABLE (0xfe50f000, 0xf810f000, t32_table_1111_100x_x0x1__1111),
921 DECODE_TABLE (0xfe000000, 0xf8000000, t32_table_1111_100x),
927 DECODE_TABLE (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111),
933 DECODE_TABLE (0xff800000, 0xfb000000, t32_table_1111_1011_0),
939 DECODE_TABLE (0xff800000, 0xfb800000, t32_table_1111_1011_1),
947 #ifdef CONFIG_ARM_KPROBES_TEST_MODULE
955 unsigned long pc = thumb_probe_pc(p);
956 int rm = (insn >> 3) & 0xf;
957 unsigned long rmv = (rm == 15) ? pc : regs->
uregs[rm];
960 regs->ARM_lr = (
unsigned long)p->
addr + 2;
962 bx_write_pc(rmv, regs);
966 t16_simulate_ldr_literal(
struct kprobe *p,
struct pt_regs *regs)
969 unsigned long*
base = (
unsigned long *)(thumb_probe_pc(p) & ~3);
970 long index = insn & 0xff;
971 int rt = (insn >> 8) & 0x7;
976 t16_simulate_ldrstr_sp_relative(
struct kprobe *p,
struct pt_regs *regs)
979 unsigned long* base = (
unsigned long *)regs->ARM_sp;
980 long index = insn & 0xff;
981 int rt = (insn >> 8) & 0x7;
992 unsigned long base = (insn & 0x800) ? regs->ARM_sp
993 : (thumb_probe_pc(p) & ~3);
994 long offset = insn & 0xff;
995 int rt = (insn >> 8) & 0x7;
996 regs->
uregs[rt] = base + offset * 4;
1000 t16_simulate_add_sp_imm(
struct kprobe *p,
struct pt_regs *regs)
1003 long imm = insn & 0x7f;
1005 regs->ARM_sp -= imm * 4;
1007 regs->ARM_sp += imm * 4;
1014 int rn = insn & 0x7;
1016 if (nonzero & 0x800) {
1017 long i = insn & 0x200;
1018 long imm5 = insn & 0xf8;
1019 unsigned long pc = thumb_probe_pc(p);
1020 regs->ARM_pc = pc + (i >> 3) + (imm5 >> 2);
1034 unsigned long cpsr = regs->ARM_cpsr;
1036 cpsr |= (insn & 0xfc) << 8;
1037 cpsr |= (insn & 0x03) << 25;
1038 regs->ARM_cpsr = cpsr;
1045 t16_simulate_it(p, regs);
1056 t16_simulate_cond_branch(
struct kprobe *p,
struct pt_regs *regs)
1059 unsigned long pc = thumb_probe_pc(p);
1060 long offset = insn & 0x7f;
1061 offset -= insn & 0x80;
1062 regs->ARM_pc = pc + (offset * 2);
1068 int cc = (insn >> 8) & 0xf;
1078 unsigned long pc = thumb_probe_pc(p);
1079 long offset = insn & 0x3ff;
1080 offset -= insn & 0x400;
1081 regs->ARM_pc = pc + (offset * 2);
1087 unsigned long oldcpsr = regs->ARM_cpsr;
1088 unsigned long newcpsr;
1091 "msr cpsr_fs, %[oldcpsr] \n\t"
1092 "ldmia %[regs], {r0-r7} \n\t"
1094 "stmia %[regs], {r0-r7} \n\t"
1095 "mrs %[newcpsr], cpsr \n\t"
1096 : [newcpsr]
"=r" (newcpsr)
1097 : [oldcpsr]
"r" (oldcpsr), [regs]
"r" (regs),
1099 :
"r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
1100 "lr",
"memory",
"cc"
1107 t16_emulate_loregs_rwflags(
struct kprobe *p,
struct pt_regs *regs)
1109 regs->ARM_cpsr = t16_emulate_loregs(p, regs);
1113 t16_emulate_loregs_noitrwflags(
struct kprobe *p,
struct pt_regs *regs)
1115 unsigned long cpsr = t16_emulate_loregs(p, regs);
1117 regs->ARM_cpsr = cpsr;
1124 unsigned long pc = thumb_probe_pc(p);
1125 int rdn = (insn & 0x7) | ((insn & 0x80) >> 4);
1126 int rm = (insn >> 3) & 0xf;
1128 register unsigned long rdnv
asm(
"r1");
1129 register unsigned long rmv
asm(
"r0");
1130 unsigned long cpsr = regs->ARM_cpsr;
1132 rdnv = (rdn == 15) ? pc : regs->
uregs[rdn];
1133 rmv = (rm == 15) ? pc : regs->
uregs[rm];
1136 "msr cpsr_fs, %[cpsr] \n\t"
1138 "mrs %[cpsr], cpsr \n\t"
1139 :
"=r" (rdnv), [cpsr]
"=r" (cpsr)
1140 :
"0" (rdnv),
"r" (rmv),
"1" (cpsr), [
fn]
"r" (p->
ainsn.insn_fn)
1141 :
"lr",
"memory",
"cc"
1147 regs->
uregs[rdn] = rdnv;
1165 "ldr r9, [%[regs], #13*4] \n\t"
1166 "ldr r8, [%[regs], #14*4] \n\t"
1167 "ldmia %[regs], {r0-r7} \n\t"
1169 "str r9, [%[regs], #13*4] \n\t"
1171 : [regs]
"r" (regs), [
fn]
"r" (p->
ainsn.insn_fn)
1172 :
"r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
"r8",
"r9",
1173 "lr",
"memory",
"cc"
1185 ((
u16 *)asi->
insn)[0] = 0xe929;
1186 ((
u16 *)asi->
insn)[1] = insn & 0x1ff;
1192 t16_emulate_pop_nopc(
struct kprobe *p,
struct pt_regs *regs)
1195 "ldr r9, [%[regs], #13*4] \n\t"
1196 "ldmia %[regs], {r0-r7} \n\t"
1198 "stmia %[regs], {r0-r7} \n\t"
1199 "str r9, [%[regs], #13*4] \n\t"
1201 : [regs]
"r" (regs), [
fn]
"r" (p->
ainsn.insn_fn)
1202 :
"r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
"r9",
1203 "lr",
"memory",
"cc"
1210 register unsigned long pc
asm(
"r8");
1213 "ldr r9, [%[regs], #13*4] \n\t"
1214 "ldmia %[regs], {r0-r7} \n\t"
1216 "stmia %[regs], {r0-r7} \n\t"
1217 "str r9, [%[regs], #13*4] \n\t"
1219 : [regs]
"r" (regs), [
fn]
"r" (p->
ainsn.insn_fn)
1220 :
"r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
"r9",
1221 "lr",
"memory",
"cc"
1224 bx_write_pc(pc, regs);
1235 ((
u16 *)asi->
insn)[0] = 0xe8b9;
1236 ((
u16 *)asi->
insn)[1] = insn & 0x1ff;
1238 : t16_emulate_pop_nopc;
1242 static const union decode_item t16_table_1011[] = {
1430 #ifdef CONFIG_ARM_KPROBES_TEST_MODULE
1434 static unsigned long __kprobes thumb_check_cc(
unsigned long cpsr)
1444 p->
ainsn.insn_handler(p, regs);
1445 regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
1451 p->
ainsn.insn_handler(p, regs);
1452 regs->ARM_cpsr = it_advance(regs->ARM_cpsr);