linux/arch/arm/kernel/kprobes-decode.c
<<
>>
Prefs
   1/*
   2 * arch/arm/kernel/kprobes-decode.c
   3 *
   4 * Copyright (C) 2006, 2007 Motorola Inc.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License for more details.
  14 */
  15
  16/*
  17 * We do not have hardware single-stepping on ARM, This
  18 * effort is further complicated by the ARM not having a
  19 * "next PC" register.  Instructions that change the PC
  20 * can't be safely single-stepped in a MP environment, so
  21 * we have a lot of work to do:
  22 *
  23 * In the prepare phase:
  24 *   *) If it is an instruction that does anything
  25 *      with the CPU mode, we reject it for a kprobe.
  26 *      (This is out of laziness rather than need.  The
  27 *      instructions could be simulated.)
  28 *
  29 *   *) Otherwise, decode the instruction rewriting its
  30 *      registers to take fixed, ordered registers and
  31 *      setting a handler for it to run the instruction.
  32 *
  33 * In the execution phase by an instruction's handler:
  34 *
  35 *   *) If the PC is written to by the instruction, the
  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 *
  41 *   *) Otherwise, a modified form of the instruction is
  42 *      directly executed.  Its handler calls the
  43 *      instruction in insn[0].  In insn[1] is a
  44 *      "mov pc, lr" to return.
  45 *
  46 *      Before calling, load up the reordered registers
  47 *      from the original instruction's registers.  If one
  48 *      of the original input registers is the PC, compute
  49 *      and adjust the appropriate input register.
  50 *
  51 *      After call completes, copy the output registers to
  52 *      the original instruction's original registers.
  53 *
  54 * We don't use a real breakpoint instruction since that
  55 * would have us in the kernel go from SVC mode to SVC
  56 * mode losing the link register.  Instead we use an
  57 * undefined instruction.  To simplify processing, the
  58 * undefined instruction used for kprobes must be reserved
  59 * exclusively for kprobes use.
  60 *
  61 * TODO: ifdef out some instruction decoding based on architecture.
  62 */
  63
  64#include <linux/kernel.h>
  65#include <linux/kprobes.h>
  66
  67#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
  68
  69#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
  70
  71#define PSR_fs  (PSR_f|PSR_s)
  72
  73#define KPROBE_RETURN_INSTRUCTION       0xe1a0f00e      /* mov pc, lr */
  74#define SET_R0_TRUE_INSTRUCTION         0xe3a00001      /* mov  r0, #1 */
  75
  76#define truecc_insn(insn)       (((insn) & 0xf0000000) | \
  77                                 (SET_R0_TRUE_INSTRUCTION & 0x0fffffff))
  78
  79typedef long (insn_0arg_fn_t)(void);
  80typedef long (insn_1arg_fn_t)(long);
  81typedef long (insn_2arg_fn_t)(long, long);
  82typedef long (insn_3arg_fn_t)(long, long, long);
  83typedef long (insn_4arg_fn_t)(long, long, long, long);
  84typedef long long (insn_llret_0arg_fn_t)(void);
  85typedef long long (insn_llret_3arg_fn_t)(long, long, long);
  86typedef long long (insn_llret_4arg_fn_t)(long, long, long, long);
  87
  88union reg_pair {
  89        long long       dr;
  90#ifdef __LITTLE_ENDIAN
  91        struct { long   r0, r1; };
  92#else
  93        struct { long   r1, r0; };
  94#endif
  95};
  96
  97/*
  98 * For STR and STM instructions, an ARM core may choose to use either
  99 * a +8 or a +12 displacement from the current instruction's address.
 100 * Whichever value is chosen for a given core, it must be the same for
 101 * both instructions and may not change.  This function measures it.
 102 */
 103
 104static int str_pc_offset;
 105
 106static void __init find_str_pc_offset(void)
 107{
 108        int addr, scratch, ret;
 109
 110        __asm__ (
 111                "sub    %[ret], pc, #4          \n\t"
 112                "str    pc, %[addr]             \n\t"
 113                "ldr    %[scr], %[addr]         \n\t"
 114                "sub    %[ret], %[scr], %[ret]  \n\t"
 115                : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr));
 116
 117        str_pc_offset = ret;
 118}
 119
 120/*
 121 * The insnslot_?arg_r[w]flags() functions below are to keep the
 122 * msr -> *fn -> mrs instruction sequences indivisible so that
 123 * the state of the CPSR flags aren't inadvertently modified
 124 * just before or just after the call.
 125 */
 126
 127static inline long __kprobes
 128insnslot_0arg_rflags(long cpsr, insn_0arg_fn_t *fn)
 129{
 130        register long ret asm("r0");
 131
 132        __asm__ __volatile__ (
 133                "msr    cpsr_fs, %[cpsr]        \n\t"
 134                "mov    lr, pc                  \n\t"
 135                "mov    pc, %[fn]               \n\t"
 136                : "=r" (ret)
 137                : [cpsr] "r" (cpsr), [fn] "r" (fn)
 138                : "lr", "cc"
 139        );
 140        return ret;
 141}
 142
 143static inline long long __kprobes
 144insnslot_llret_0arg_rflags(long cpsr, insn_llret_0arg_fn_t *fn)
 145{
 146        register long ret0 asm("r0");
 147        register long ret1 asm("r1");
 148        union reg_pair fnr;
 149
 150        __asm__ __volatile__ (
 151                "msr    cpsr_fs, %[cpsr]        \n\t"
 152                "mov    lr, pc                  \n\t"
 153                "mov    pc, %[fn]               \n\t"
 154                : "=r" (ret0), "=r" (ret1)
 155                : [cpsr] "r" (cpsr), [fn] "r" (fn)
 156                : "lr", "cc"
 157        );
 158        fnr.r0 = ret0;
 159        fnr.r1 = ret1;
 160        return fnr.dr;
 161}
 162
 163static inline long __kprobes
 164insnslot_1arg_rflags(long r0, long cpsr, insn_1arg_fn_t *fn)
 165{
 166        register long rr0 asm("r0") = r0;
 167        register long ret asm("r0");
 168
 169        __asm__ __volatile__ (
 170                "msr    cpsr_fs, %[cpsr]        \n\t"
 171                "mov    lr, pc                  \n\t"
 172                "mov    pc, %[fn]               \n\t"
 173                : "=r" (ret)
 174                : "0" (rr0), [cpsr] "r" (cpsr), [fn] "r" (fn)
 175                : "lr", "cc"
 176        );
 177        return ret;
 178}
 179
 180static inline long __kprobes
 181insnslot_2arg_rflags(long r0, long r1, long cpsr, insn_2arg_fn_t *fn)
 182{
 183        register long rr0 asm("r0") = r0;
 184        register long rr1 asm("r1") = r1;
 185        register long ret asm("r0");
 186
 187        __asm__ __volatile__ (
 188                "msr    cpsr_fs, %[cpsr]        \n\t"
 189                "mov    lr, pc                  \n\t"
 190                "mov    pc, %[fn]               \n\t"
 191                : "=r" (ret)
 192                : "0" (rr0), "r" (rr1),
 193                  [cpsr] "r" (cpsr), [fn] "r" (fn)
 194                : "lr", "cc"
 195        );
 196        return ret;
 197}
 198
 199static inline long __kprobes
 200insnslot_3arg_rflags(long r0, long r1, long r2, long cpsr, insn_3arg_fn_t *fn)
 201{
 202        register long rr0 asm("r0") = r0;
 203        register long rr1 asm("r1") = r1;
 204        register long rr2 asm("r2") = r2;
 205        register long ret asm("r0");
 206
 207        __asm__ __volatile__ (
 208                "msr    cpsr_fs, %[cpsr]        \n\t"
 209                "mov    lr, pc                  \n\t"
 210                "mov    pc, %[fn]               \n\t"
 211                : "=r" (ret)
 212                : "0" (rr0), "r" (rr1), "r" (rr2),
 213                  [cpsr] "r" (cpsr), [fn] "r" (fn)
 214                : "lr", "cc"
 215        );
 216        return ret;
 217}
 218
 219static inline long long __kprobes
 220insnslot_llret_3arg_rflags(long r0, long r1, long r2, long cpsr,
 221                           insn_llret_3arg_fn_t *fn)
 222{
 223        register long rr0 asm("r0") = r0;
 224        register long rr1 asm("r1") = r1;
 225        register long rr2 asm("r2") = r2;
 226        register long ret0 asm("r0");
 227        register long ret1 asm("r1");
 228        union reg_pair fnr;
 229
 230        __asm__ __volatile__ (
 231                "msr    cpsr_fs, %[cpsr]        \n\t"
 232                "mov    lr, pc                  \n\t"
 233                "mov    pc, %[fn]               \n\t"
 234                : "=r" (ret0), "=r" (ret1)
 235                : "0" (rr0), "r" (rr1), "r" (rr2),
 236                  [cpsr] "r" (cpsr), [fn] "r" (fn)
 237                : "lr", "cc"
 238        );
 239        fnr.r0 = ret0;
 240        fnr.r1 = ret1;
 241        return fnr.dr;
 242}
 243
 244static inline long __kprobes
 245insnslot_4arg_rflags(long r0, long r1, long r2, long r3, long cpsr,
 246                     insn_4arg_fn_t *fn)
 247{
 248        register long rr0 asm("r0") = r0;
 249        register long rr1 asm("r1") = r1;
 250        register long rr2 asm("r2") = r2;
 251        register long rr3 asm("r3") = r3;
 252        register long ret asm("r0");
 253
 254        __asm__ __volatile__ (
 255                "msr    cpsr_fs, %[cpsr]        \n\t"
 256                "mov    lr, pc                  \n\t"
 257                "mov    pc, %[fn]               \n\t"
 258                : "=r" (ret)
 259                : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
 260                  [cpsr] "r" (cpsr), [fn] "r" (fn)
 261                : "lr", "cc"
 262        );
 263        return ret;
 264}
 265
 266static inline long __kprobes
 267insnslot_1arg_rwflags(long r0, long *cpsr, insn_1arg_fn_t *fn)
 268{
 269        register long rr0 asm("r0") = r0;
 270        register long ret asm("r0");
 271        long oldcpsr = *cpsr;
 272        long newcpsr;
 273
 274        __asm__ __volatile__ (
 275                "msr    cpsr_fs, %[oldcpsr]     \n\t"
 276                "mov    lr, pc                  \n\t"
 277                "mov    pc, %[fn]               \n\t"
 278                "mrs    %[newcpsr], cpsr        \n\t"
 279                : "=r" (ret), [newcpsr] "=r" (newcpsr)
 280                : "0" (rr0), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
 281                : "lr", "cc"
 282        );
 283        *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
 284        return ret;
 285}
 286
 287static inline long __kprobes
 288insnslot_2arg_rwflags(long r0, long r1, long *cpsr, insn_2arg_fn_t *fn)
 289{
 290        register long rr0 asm("r0") = r0;
 291        register long rr1 asm("r1") = r1;
 292        register long ret asm("r0");
 293        long oldcpsr = *cpsr;
 294        long newcpsr;
 295
 296        __asm__ __volatile__ (
 297                "msr    cpsr_fs, %[oldcpsr]     \n\t"
 298                "mov    lr, pc                  \n\t"
 299                "mov    pc, %[fn]               \n\t"
 300                "mrs    %[newcpsr], cpsr        \n\t"
 301                : "=r" (ret), [newcpsr] "=r" (newcpsr)
 302                : "0" (rr0), "r" (rr1), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
 303                : "lr", "cc"
 304        );
 305        *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
 306        return ret;
 307}
 308
 309static inline long __kprobes
 310insnslot_3arg_rwflags(long r0, long r1, long r2, long *cpsr,
 311                      insn_3arg_fn_t *fn)
 312{
 313        register long rr0 asm("r0") = r0;
 314        register long rr1 asm("r1") = r1;
 315        register long rr2 asm("r2") = r2;
 316        register long ret asm("r0");
 317        long oldcpsr = *cpsr;
 318        long newcpsr;
 319
 320        __asm__ __volatile__ (
 321                "msr    cpsr_fs, %[oldcpsr]     \n\t"
 322                "mov    lr, pc                  \n\t"
 323                "mov    pc, %[fn]               \n\t"
 324                "mrs    %[newcpsr], cpsr        \n\t"
 325                : "=r" (ret), [newcpsr] "=r" (newcpsr)
 326                : "0" (rr0), "r" (rr1), "r" (rr2),
 327                  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
 328                : "lr", "cc"
 329        );
 330        *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
 331        return ret;
 332}
 333
 334static inline long __kprobes
 335insnslot_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
 336                      insn_4arg_fn_t *fn)
 337{
 338        register long rr0 asm("r0") = r0;
 339        register long rr1 asm("r1") = r1;
 340        register long rr2 asm("r2") = r2;
 341        register long rr3 asm("r3") = r3;
 342        register long ret asm("r0");
 343        long oldcpsr = *cpsr;
 344        long newcpsr;
 345
 346        __asm__ __volatile__ (
 347                "msr    cpsr_fs, %[oldcpsr]     \n\t"
 348                "mov    lr, pc                  \n\t"
 349                "mov    pc, %[fn]               \n\t"
 350                "mrs    %[newcpsr], cpsr        \n\t"
 351                : "=r" (ret), [newcpsr] "=r" (newcpsr)
 352                : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
 353                  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
 354                : "lr", "cc"
 355        );
 356        *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
 357        return ret;
 358}
 359
 360static inline long long __kprobes
 361insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
 362                            insn_llret_4arg_fn_t *fn)
 363{
 364        register long rr0 asm("r0") = r0;
 365        register long rr1 asm("r1") = r1;
 366        register long rr2 asm("r2") = r2;
 367        register long rr3 asm("r3") = r3;
 368        register long ret0 asm("r0");
 369        register long ret1 asm("r1");
 370        long oldcpsr = *cpsr;
 371        long newcpsr;
 372        union reg_pair fnr;
 373
 374        __asm__ __volatile__ (
 375                "msr    cpsr_fs, %[oldcpsr]     \n\t"
 376                "mov    lr, pc                  \n\t"
 377                "mov    pc, %[fn]               \n\t"
 378                "mrs    %[newcpsr], cpsr        \n\t"
 379                : "=r" (ret0), "=r" (ret1), [newcpsr] "=r" (newcpsr)
 380                : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
 381                  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
 382                : "lr", "cc"
 383        );
 384        *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
 385        fnr.r0 = ret0;
 386        fnr.r1 = ret1;
 387        return fnr.dr;
 388}
 389
 390/*
 391 * To avoid the complications of mimicing single-stepping on a
 392 * processor without a Next-PC or a single-step mode, and to
 393 * avoid having to deal with the side-effects of boosting, we
 394 * simulate or emulate (almost) all ARM instructions.
 395 *
 396 * "Simulation" is where the instruction's behavior is duplicated in
 397 * C code.  "Emulation" is where the original instruction is rewritten
 398 * and executed, often by altering its registers.
 399 *
 400 * By having all behavior of the kprobe'd instruction completed before
 401 * returning from the kprobe_handler(), all locks (scheduler and
 402 * interrupt) can safely be released.  There is no need for secondary
 403 * breakpoints, no race with MP or preemptable kernels, nor having to
 404 * clean up resources counts at a later time impacting overall system
 405 * performance.  By rewriting the instruction, only the minimum registers
 406 * need to be loaded and saved back optimizing performance.
 407 *
 408 * Calling the insnslot_*_rwflags version of a function doesn't hurt
 409 * anything even when the CPSR flags aren't updated by the
 410 * instruction.  It's just a little slower in return for saving
 411 * a little space by not having a duplicate function that doesn't
 412 * update the flags.  (The same optimization can be said for
 413 * instructions that do or don't perform register writeback)
 414 * Also, instructions can either read the flags, only write the
 415 * flags, or read and write the flags.  To save combinations
 416 * rather than for sheer performance, flag functions just assume
 417 * read and write of flags.
 418 */
 419
 420static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
 421{
 422        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 423        kprobe_opcode_t insn = p->opcode;
 424        long iaddr = (long)p->addr;
 425        int disp  = branch_displacement(insn);
 426
 427        if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
 428                return;
 429
 430        if (insn & (1 << 24))
 431                regs->ARM_lr = iaddr + 4;
 432
 433        regs->ARM_pc = iaddr + 8 + disp;
 434}
 435
 436static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
 437{
 438        kprobe_opcode_t insn = p->opcode;
 439        long iaddr = (long)p->addr;
 440        int disp = branch_displacement(insn);
 441
 442        regs->ARM_lr = iaddr + 4;
 443        regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2);
 444        regs->ARM_cpsr |= PSR_T_BIT;
 445}
 446
 447static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
 448{
 449        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 450        kprobe_opcode_t insn = p->opcode;
 451        int rm = insn & 0xf;
 452        long rmv = regs->uregs[rm];
 453
 454        if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
 455                return;
 456
 457        if (insn & (1 << 5))
 458                regs->ARM_lr = (long)p->addr + 4;
 459
 460        regs->ARM_pc = rmv & ~0x1;
 461        regs->ARM_cpsr &= ~PSR_T_BIT;
 462        if (rmv & 0x1)
 463                regs->ARM_cpsr |= PSR_T_BIT;
 464}
 465
 466static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
 467{
 468        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 469        kprobe_opcode_t insn = p->opcode;
 470        int rn = (insn >> 16) & 0xf;
 471        int lbit = insn & (1 << 20);
 472        int wbit = insn & (1 << 21);
 473        int ubit = insn & (1 << 23);
 474        int pbit = insn & (1 << 24);
 475        long *addr = (long *)regs->uregs[rn];
 476        int reg_bit_vector;
 477        int reg_count;
 478
 479        if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
 480                return;
 481
 482        reg_count = 0;
 483        reg_bit_vector = insn & 0xffff;
 484        while (reg_bit_vector) {
 485                reg_bit_vector &= (reg_bit_vector - 1);
 486                ++reg_count;
 487        }
 488
 489        if (!ubit)
 490                addr -= reg_count;
 491        addr += (!pbit == !ubit);
 492
 493        reg_bit_vector = insn & 0xffff;
 494        while (reg_bit_vector) {
 495                int reg = __ffs(reg_bit_vector);
 496                reg_bit_vector &= (reg_bit_vector - 1);
 497                if (lbit)
 498                        regs->uregs[reg] = *addr++;
 499                else
 500                        *addr++ = regs->uregs[reg];
 501        }
 502
 503        if (wbit) {
 504                if (!ubit)
 505                        addr -= reg_count;
 506                addr -= (!pbit == !ubit);
 507                regs->uregs[rn] = (long)addr;
 508        }
 509}
 510
 511static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
 512{
 513        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 514
 515        if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
 516                return;
 517
 518        regs->ARM_pc = (long)p->addr + str_pc_offset;
 519        simulate_ldm1stm1(p, regs);
 520        regs->ARM_pc = (long)p->addr + 4;
 521}
 522
 523static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
 524{
 525        regs->uregs[12] = regs->uregs[13];
 526}
 527
 528static void __kprobes emulate_ldcstc(struct kprobe *p, struct pt_regs *regs)
 529{
 530        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 531        kprobe_opcode_t insn = p->opcode;
 532        int rn = (insn >> 16) & 0xf;
 533        long rnv = regs->uregs[rn];
 534
 535        /* Save Rn in case of writeback. */
 536        regs->uregs[rn] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
 537}
 538
 539static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
 540{
 541        insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
 542        kprobe_opcode_t insn = p->opcode;
 543        int rd = (insn >> 12) & 0xf;
 544        int rn = (insn >> 16) & 0xf;
 545        int rm = insn & 0xf;  /* rm may be invalid, don't care. */
 546
 547        /* Not following the C calling convention here, so need asm(). */
 548        __asm__ __volatile__ (
 549                "ldr    r0, %[rn]       \n\t"
 550                "ldr    r1, %[rm]       \n\t"
 551                "msr    cpsr_fs, %[cpsr]\n\t"
 552                "mov    lr, pc          \n\t"
 553                "mov    pc, %[i_fn]     \n\t"
 554                "str    r0, %[rn]       \n\t"   /* in case of writeback */
 555                "str    r2, %[rd0]      \n\t"
 556                "str    r3, %[rd1]      \n\t"
 557                : [rn]  "+m" (regs->uregs[rn]),
 558                  [rd0] "=m" (regs->uregs[rd]),
 559                  [rd1] "=m" (regs->uregs[rd+1])
 560                : [rm]   "m" (regs->uregs[rm]),
 561                  [cpsr] "r" (regs->ARM_cpsr),
 562                  [i_fn] "r" (i_fn)
 563                : "r0", "r1", "r2", "r3", "lr", "cc"
 564        );
 565}
 566
 567static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs)
 568{
 569        insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0];
 570        kprobe_opcode_t insn = p->opcode;
 571        int rd = (insn >> 12) & 0xf;
 572        int rn = (insn >> 16) & 0xf;
 573        int rm  = insn & 0xf;
 574        long rnv = regs->uregs[rn];
 575        long rmv = regs->uregs[rm];  /* rm/rmv may be invalid, don't care. */
 576
 577        regs->uregs[rn] = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd],
 578                                               regs->uregs[rd+1],
 579                                               regs->ARM_cpsr, i_fn);
 580}
 581
 582static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
 583{
 584        insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0];
 585        kprobe_opcode_t insn = p->opcode;
 586        long ppc = (long)p->addr + 8;
 587        union reg_pair fnr;
 588        int rd = (insn >> 12) & 0xf;
 589        int rn = (insn >> 16) & 0xf;
 590        int rm = insn & 0xf;
 591        long rdv;
 592        long rnv = (rn == 15) ? ppc : regs->uregs[rn];
 593        long rmv = (rm == 15) ? ppc : regs->uregs[rm];
 594        long cpsr = regs->ARM_cpsr;
 595
 596        fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
 597        regs->uregs[rn] = fnr.r0;  /* Save Rn in case of writeback. */
 598        rdv = fnr.r1;
 599
 600        if (rd == 15) {
 601#if __LINUX_ARM_ARCH__ >= 5
 602                cpsr &= ~PSR_T_BIT;
 603                if (rdv & 0x1)
 604                        cpsr |= PSR_T_BIT;
 605                regs->ARM_cpsr = cpsr;
 606                rdv &= ~0x1;
 607#else
 608                rdv &= ~0x2;
 609#endif
 610        }
 611        regs->uregs[rd] = rdv;
 612}
 613
 614static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
 615{
 616        insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
 617        kprobe_opcode_t insn = p->opcode;
 618        long iaddr = (long)p->addr;
 619        int rd = (insn >> 12) & 0xf;
 620        int rn = (insn >> 16) & 0xf;
 621        int rm = insn & 0xf;
 622        long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
 623        long rnv = (rn == 15) ? iaddr +  8 : regs->uregs[rn];
 624        long rmv = regs->uregs[rm];  /* rm/rmv may be invalid, don't care. */
 625
 626        /* Save Rn in case of writeback. */
 627        regs->uregs[rn] =
 628                insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
 629}
 630
 631static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs)
 632{
 633        insn_llret_0arg_fn_t *i_fn = (insn_llret_0arg_fn_t *)&p->ainsn.insn[0];
 634        kprobe_opcode_t insn = p->opcode;
 635        union reg_pair fnr;
 636        int rd = (insn >> 12) & 0xf;
 637        int rn = (insn >> 16) & 0xf;
 638
 639        fnr.dr = insnslot_llret_0arg_rflags(regs->ARM_cpsr, i_fn);
 640        regs->uregs[rn] = fnr.r0;
 641        regs->uregs[rd] = fnr.r1;
 642}
 643
 644static void __kprobes emulate_mcrr(struct kprobe *p, struct pt_regs *regs)
 645{
 646        insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
 647        kprobe_opcode_t insn = p->opcode;
 648        int rd = (insn >> 12) & 0xf;
 649        int rn = (insn >> 16) & 0xf;
 650        long rnv = regs->uregs[rn];
 651        long rdv = regs->uregs[rd];
 652
 653        insnslot_2arg_rflags(rnv, rdv, regs->ARM_cpsr, i_fn);
 654}
 655
 656static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs)
 657{
 658        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 659        kprobe_opcode_t insn = p->opcode;
 660        int rd = (insn >> 12) & 0xf;
 661        int rm = insn & 0xf;
 662        long rmv = regs->uregs[rm];
 663
 664        /* Writes Q flag */
 665        regs->uregs[rd] = insnslot_1arg_rwflags(rmv, &regs->ARM_cpsr, i_fn);
 666}
 667
 668static void __kprobes emulate_sel(struct kprobe *p, struct pt_regs *regs)
 669{
 670        insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
 671        kprobe_opcode_t insn = p->opcode;
 672        int rd = (insn >> 12) & 0xf;
 673        int rn = (insn >> 16) & 0xf;
 674        int rm = insn & 0xf;
 675        long rnv = regs->uregs[rn];
 676        long rmv = regs->uregs[rm];
 677
 678        /* Reads GE bits */
 679        regs->uregs[rd] = insnslot_2arg_rflags(rnv, rmv, regs->ARM_cpsr, i_fn);
 680}
 681
 682static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs)
 683{
 684        insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
 685
 686        insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
 687}
 688
 689static void __kprobes emulate_rd12(struct kprobe *p, struct pt_regs *regs)
 690{
 691        insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
 692        kprobe_opcode_t insn = p->opcode;
 693        int rd = (insn >> 12) & 0xf;
 694
 695        regs->uregs[rd] = insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
 696}
 697
 698static void __kprobes emulate_ird12(struct kprobe *p, struct pt_regs *regs)
 699{
 700        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 701        kprobe_opcode_t insn = p->opcode;
 702        int ird = (insn >> 12) & 0xf;
 703
 704        insnslot_1arg_rflags(regs->uregs[ird], regs->ARM_cpsr, i_fn);
 705}
 706
 707static void __kprobes emulate_rn16(struct kprobe *p, struct pt_regs *regs)
 708{
 709        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 710        kprobe_opcode_t insn = p->opcode;
 711        int rn = (insn >> 16) & 0xf;
 712        long rnv = regs->uregs[rn];
 713
 714        insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
 715}
 716
 717static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs)
 718{
 719        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 720        kprobe_opcode_t insn = p->opcode;
 721        int rd = (insn >> 12) & 0xf;
 722        int rm = insn & 0xf;
 723        long rmv = regs->uregs[rm];
 724
 725        regs->uregs[rd] = insnslot_1arg_rflags(rmv, regs->ARM_cpsr, i_fn);
 726}
 727
 728static void __kprobes
 729emulate_rd12rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
 730{
 731        insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
 732        kprobe_opcode_t insn = p->opcode;
 733        int rd = (insn >> 12) & 0xf;
 734        int rn = (insn >> 16) & 0xf;
 735        int rm = insn & 0xf;
 736        long rnv = regs->uregs[rn];
 737        long rmv = regs->uregs[rm];
 738
 739        regs->uregs[rd] =
 740                insnslot_2arg_rwflags(rnv, rmv, &regs->ARM_cpsr, i_fn);
 741}
 742
 743static void __kprobes
 744emulate_rd16rn12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
 745{
 746        insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
 747        kprobe_opcode_t insn = p->opcode;
 748        int rd = (insn >> 16) & 0xf;
 749        int rn = (insn >> 12) & 0xf;
 750        int rs = (insn >> 8) & 0xf;
 751        int rm = insn & 0xf;
 752        long rnv = regs->uregs[rn];
 753        long rsv = regs->uregs[rs];
 754        long rmv = regs->uregs[rm];
 755
 756        regs->uregs[rd] =
 757                insnslot_3arg_rwflags(rnv, rsv, rmv, &regs->ARM_cpsr, i_fn);
 758}
 759
 760static void __kprobes
 761emulate_rd16rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
 762{
 763        insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
 764        kprobe_opcode_t insn = p->opcode;
 765        int rd = (insn >> 16) & 0xf;
 766        int rs = (insn >> 8) & 0xf;
 767        int rm = insn & 0xf;
 768        long rsv = regs->uregs[rs];
 769        long rmv = regs->uregs[rm];
 770
 771        regs->uregs[rd] =
 772                insnslot_2arg_rwflags(rsv, rmv, &regs->ARM_cpsr, i_fn);
 773}
 774
 775static void __kprobes
 776emulate_rdhi16rdlo12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
 777{
 778        insn_llret_4arg_fn_t *i_fn = (insn_llret_4arg_fn_t *)&p->ainsn.insn[0];
 779        kprobe_opcode_t insn = p->opcode;
 780        union reg_pair fnr;
 781        int rdhi = (insn >> 16) & 0xf;
 782        int rdlo = (insn >> 12) & 0xf;
 783        int rs   = (insn >> 8) & 0xf;
 784        int rm   = insn & 0xf;
 785        long rsv = regs->uregs[rs];
 786        long rmv = regs->uregs[rm];
 787
 788        fnr.dr = insnslot_llret_4arg_rwflags(regs->uregs[rdhi],
 789                                             regs->uregs[rdlo], rsv, rmv,
 790                                             &regs->ARM_cpsr, i_fn);
 791        regs->uregs[rdhi] = fnr.r0;
 792        regs->uregs[rdlo] = fnr.r1;
 793}
 794
 795static void __kprobes
 796emulate_alu_imm_rflags(struct kprobe *p, struct pt_regs *regs)
 797{
 798        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 799        kprobe_opcode_t insn = p->opcode;
 800        int rd = (insn >> 12) & 0xf;
 801        int rn = (insn >> 16) & 0xf;
 802        long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
 803
 804        regs->uregs[rd] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
 805}
 806
 807static void __kprobes
 808emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs)
 809{
 810        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 811        kprobe_opcode_t insn = p->opcode;
 812        int rd = (insn >> 12) & 0xf;
 813        int rn = (insn >> 16) & 0xf;
 814        long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
 815
 816        regs->uregs[rd] = insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
 817}
 818
 819static void __kprobes
 820emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs)
 821{
 822        insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
 823        kprobe_opcode_t insn = p->opcode;
 824        long ppc = (long)p->addr + 8;
 825        int rd = (insn >> 12) & 0xf;
 826        int rn = (insn >> 16) & 0xf;    /* rn/rnv/rs/rsv may be */
 827        int rs = (insn >> 8) & 0xf;     /* invalid, don't care. */
 828        int rm = insn & 0xf;
 829        long rnv = (rn == 15) ? ppc : regs->uregs[rn];
 830        long rmv = (rm == 15) ? ppc : regs->uregs[rm];
 831        long rsv = regs->uregs[rs];
 832
 833        regs->uregs[rd] =
 834                insnslot_3arg_rflags(rnv, rmv, rsv, regs->ARM_cpsr, i_fn);
 835}
 836
 837static void __kprobes
 838emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs)
 839{
 840        insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
 841        kprobe_opcode_t insn = p->opcode;
 842        long ppc = (long)p->addr + 8;
 843        int rd = (insn >> 12) & 0xf;
 844        int rn = (insn >> 16) & 0xf;    /* rn/rnv/rs/rsv may be */
 845        int rs = (insn >> 8) & 0xf;     /* invalid, don't care. */
 846        int rm = insn & 0xf;
 847        long rnv = (rn == 15) ? ppc : regs->uregs[rn];
 848        long rmv = (rm == 15) ? ppc : regs->uregs[rm];
 849        long rsv = regs->uregs[rs];
 850
 851        regs->uregs[rd] =
 852                insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
 853}
 854
 855static enum kprobe_insn __kprobes
 856prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 857{
 858        int ibit = (insn & (1 << 26)) ? 25 : 22;
 859
 860        insn &= 0xfff00fff;
 861        insn |= 0x00001000;     /* Rn = r0, Rd = r1 */
 862        if (insn & (1 << ibit)) {
 863                insn &= ~0xf;
 864                insn |= 2;      /* Rm = r2 */
 865        }
 866        asi->insn[0] = insn;
 867        asi->insn_handler = (insn & (1 << 20)) ? emulate_ldr : emulate_str;
 868        return INSN_GOOD;
 869}
 870
 871static enum kprobe_insn __kprobes
 872prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 873{
 874        insn &= 0xffff0ff0;     /* Rd = r0, Rm = r0 */
 875        asi->insn[0] = insn;
 876        asi->insn_handler = emulate_rd12rm0;
 877        return INSN_GOOD;
 878}
 879
 880static enum kprobe_insn __kprobes
 881prep_emulate_rd12(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 882{
 883        insn &= 0xffff0fff;     /* Rd = r0 */
 884        asi->insn[0] = insn;
 885        asi->insn_handler = emulate_rd12;
 886        return INSN_GOOD;
 887}
 888
 889static enum kprobe_insn __kprobes
 890prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn,
 891                                struct arch_specific_insn *asi)
 892{
 893        insn &= 0xfff00ff0;     /* Rd = r0, Rn = r0 */
 894        insn |= 0x00000001;     /* Rm = r1 */
 895        asi->insn[0] = insn;
 896        asi->insn_handler = emulate_rd12rn16rm0_rwflags;
 897        return INSN_GOOD;
 898}
 899
 900static enum kprobe_insn __kprobes
 901prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn,
 902                               struct arch_specific_insn *asi)
 903{
 904        insn &= 0xfff0f0f0;     /* Rd = r0, Rs = r0 */
 905        insn |= 0x00000001;     /* Rm = r1          */
 906        asi->insn[0] = insn;
 907        asi->insn_handler = emulate_rd16rs8rm0_rwflags;
 908        return INSN_GOOD;
 909}
 910
 911static enum kprobe_insn __kprobes
 912prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn,
 913                                   struct arch_specific_insn *asi)
 914{
 915        insn &= 0xfff000f0;     /* Rd = r0, Rn = r0 */
 916        insn |= 0x00000102;     /* Rs = r1, Rm = r2 */
 917        asi->insn[0] = insn;
 918        asi->insn_handler = emulate_rd16rn12rs8rm0_rwflags;
 919        return INSN_GOOD;
 920}
 921
 922static enum kprobe_insn __kprobes
 923prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
 924                                       struct arch_specific_insn *asi)
 925{
 926        insn &= 0xfff000f0;     /* RdHi = r0, RdLo = r1 */
 927        insn |= 0x00001203;     /* Rs = r2, Rm = r3 */
 928        asi->insn[0] = insn;
 929        asi->insn_handler = emulate_rdhi16rdlo12rs8rm0_rwflags;
 930        return INSN_GOOD;
 931}
 932
 933/*
 934 * For the instruction masking and comparisons in all the "space_*"
 935 * functions below, Do _not_ rearrange the order of tests unless
 936 * you're very, very sure of what you are doing.  For the sake of
 937 * efficiency, the masks for some tests sometimes assume other test
 938 * have been done prior to them so the number of patterns to test
 939 * for an instruction set can be as broad as possible to reduce the
 940 * number of tests needed.
 941 */
 942
 943static enum kprobe_insn __kprobes
 944space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 945{
 946        /* CPS mmod == 1 : 1111 0001 0000 xx10 xxxx xxxx xx0x xxxx */
 947        /* RFE           : 1111 100x x0x1 xxxx xxxx 1010 xxxx xxxx */
 948        /* SRS           : 1111 100x x1x0 1101 xxxx 0101 xxxx xxxx */
 949        if ((insn & 0xfff30020) == 0xf1020000 ||
 950            (insn & 0xfe500f00) == 0xf8100a00 ||
 951            (insn & 0xfe5f0f00) == 0xf84d0500)
 952                return INSN_REJECTED;
 953
 954        /* PLD : 1111 01x1 x101 xxxx xxxx xxxx xxxx xxxx : */
 955        if ((insn & 0xfd700000) == 0xf4500000) {
 956                insn &= 0xfff0ffff;     /* Rn = r0 */
 957                asi->insn[0] = insn;
 958                asi->insn_handler = emulate_rn16;
 959                return INSN_GOOD;
 960        }
 961
 962        /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */
 963        if ((insn & 0xfe000000) == 0xfa000000) {
 964                asi->insn_handler = simulate_blx1;
 965                return INSN_GOOD_NO_SLOT;
 966        }
 967
 968        /* SETEND : 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
 969        /* CDP2   : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
 970        if ((insn & 0xffff00f0) == 0xf1010000 ||
 971            (insn & 0xff000010) == 0xfe000000) {
 972                asi->insn[0] = insn;
 973                asi->insn_handler = emulate_none;
 974                return INSN_GOOD;
 975        }
 976
 977        /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
 978        /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
 979        if ((insn & 0xffe00000) == 0xfc400000) {
 980                insn &= 0xfff00fff;     /* Rn = r0 */
 981                insn |= 0x00001000;     /* Rd = r1 */
 982                asi->insn[0] = insn;
 983                asi->insn_handler =
 984                        (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr;
 985                return INSN_GOOD;
 986        }
 987
 988        /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
 989        /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
 990        if ((insn & 0xfe000000) == 0xfc000000) {
 991                insn &= 0xfff0ffff;      /* Rn = r0 */
 992                asi->insn[0] = insn;
 993                asi->insn_handler = emulate_ldcstc;
 994                return INSN_GOOD;
 995        }
 996
 997        /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
 998        /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
 999        insn &= 0xffff0fff;     /* Rd = r0 */
1000        asi->insn[0]      = insn;
1001        asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12;
1002        return INSN_GOOD;
1003}
1004
1005static enum kprobe_insn __kprobes
1006space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1007{
1008        /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */
1009        if ((insn & 0x0f900010) == 0x01000000) {
1010
1011                /* BXJ  : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
1012                /* MSR  : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
1013                if ((insn & 0x0ff000f0) == 0x01200020 ||
1014                    (insn & 0x0fb000f0) == 0x01200000)
1015                        return INSN_REJECTED;
1016
1017                /* MRS : cccc 0001 0x00 xxxx xxxx xxxx 0000 xxxx */
1018                if ((insn & 0x0fb00010) == 0x01000000)
1019                        return prep_emulate_rd12(insn, asi);
1020
1021                /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
1022                if ((insn & 0x0ff00090) == 0x01400080)
1023                        return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
1024
1025                /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
1026                /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
1027                if ((insn & 0x0ff000b0) == 0x012000a0 ||
1028                    (insn & 0x0ff00090) == 0x01600080)
1029                        return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1030
1031                /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */
1032                /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 0x00 xxxx : Q */
1033                return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1034
1035        }
1036
1037        /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */
1038        else if ((insn & 0x0f900090) == 0x01000010) {
1039
1040                /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
1041                if ((insn & 0xfff000f0) == 0xe1200070)
1042                        return INSN_REJECTED;
1043
1044                /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
1045                /* BX     : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
1046                if ((insn & 0x0ff000d0) == 0x01200010) {
1047                        asi->insn[0] = truecc_insn(insn);
1048                        asi->insn_handler = simulate_blx2bx;
1049                        return INSN_GOOD;
1050                }
1051
1052                /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
1053                if ((insn & 0x0ff000f0) == 0x01600010)
1054                        return prep_emulate_rd12rm0(insn, asi);
1055
1056                /* QADD    : cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx :Q */
1057                /* QSUB    : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */
1058                /* QDADD   : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */
1059                /* QDSUB   : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */
1060                return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1061        }
1062
1063        /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */
1064        else if ((insn & 0x0f000090) == 0x00000090) {
1065
1066                /* MUL    : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx :   */
1067                /* MULS   : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */
1068                /* MLA    : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx :   */
1069                /* MLAS   : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */
1070                /* UMAAL  : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx :   */
1071                /* UMULL  : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx :   */
1072                /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */
1073                /* UMLAL  : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx :   */
1074                /* UMLALS : cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx :cc */
1075                /* SMULL  : cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx :   */
1076                /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */
1077                /* SMLAL  : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx :   */
1078                /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */
1079                if ((insn & 0x0fe000f0) == 0x00000090) {
1080                       return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1081                } else if  ((insn & 0x0fe000f0) == 0x00200090) {
1082                       return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1083                } else {
1084                       return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
1085                }
1086        }
1087
1088        /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */
1089        else if ((insn & 0x0e000090) == 0x00000090) {
1090
1091                /* SWP   : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */
1092                /* SWPB  : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */
1093                /* LDRD  : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */
1094                /* STRD  : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */
1095                /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */
1096                /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */
1097                /* LDRH  : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */
1098                /* STRH  : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */
1099                /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */
1100                /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */
1101                if ((insn & 0x0fb000f0) == 0x01000090) {
1102                        /* SWP/SWPB */
1103                        return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1104                } else if ((insn & 0x0e1000d0) == 0x00000d0) {
1105                        /* STRD/LDRD */
1106                        insn &= 0xfff00fff;
1107                        insn |= 0x00002000;     /* Rn = r0, Rd = r2 */
1108                        if (insn & (1 << 22)) {
1109                                /* I bit */
1110                                insn &= ~0xf;
1111                                insn |= 1;      /* Rm = r1 */
1112                        }
1113                        asi->insn[0] = insn;
1114                        asi->insn_handler =
1115                                (insn & (1 << 5)) ? emulate_strd : emulate_ldrd;
1116                        return INSN_GOOD;
1117                }
1118
1119                return prep_emulate_ldr_str(insn, asi);
1120        }
1121
1122        /* cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx xxxx */
1123
1124        /*
1125         * ALU op with S bit and Rd == 15 :
1126         *      cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx
1127         */
1128        if ((insn & 0x0e10f000) == 0x0010f000)
1129                return INSN_REJECTED;
1130
1131        /*
1132         * "mov ip, sp" is the most common kprobe'd instruction by far.
1133         * Check and optimize for it explicitly.
1134         */
1135        if (insn == 0xe1a0c00d) {
1136                asi->insn_handler = simulate_mov_ipsp;
1137                return INSN_GOOD_NO_SLOT;
1138        }
1139
1140        /*
1141         * Data processing: Immediate-shift / Register-shift
1142         * ALU op : cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx
1143         * CPY    : cccc 0001 1010 xxxx xxxx 0000 0000 xxxx
1144         * MOV    : cccc 0001 101x xxxx xxxx xxxx xxxx xxxx
1145         * *S (bit 20) updates condition codes
1146         * ADC/SBC/RSC reads the C flag
1147         */
1148        insn &= 0xfff00ff0;     /* Rn = r0, Rd = r0 */
1149        insn |= 0x00000001;     /* Rm = r1 */
1150        if (insn & 0x010) {
1151                insn &= 0xfffff0ff;     /* register shift */
1152                insn |= 0x00000200;     /* Rs = r2 */
1153        }
1154        asi->insn[0] = insn;
1155        asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
1156                                emulate_alu_rwflags : emulate_alu_rflags;
1157        return INSN_GOOD;
1158}
1159
1160static enum kprobe_insn __kprobes
1161space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1162{
1163        /*
1164         * MSR   : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx
1165         * Undef : cccc 0011 0x00 xxxx xxxx xxxx xxxx xxxx
1166         * ALU op with S bit and Rd == 15 :
1167         *         cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
1168         */
1169        if ((insn & 0x0f900000) == 0x03200000 ||        /* MSR & Undef */
1170            (insn & 0x0e10f000) == 0x0210f000)          /* ALU s-bit, R15  */
1171                return INSN_REJECTED;
1172
1173        /*
1174         * Data processing: 32-bit Immediate
1175         * ALU op : cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
1176         * MOV    : cccc 0011 101x xxxx xxxx xxxx xxxx xxxx
1177         * *S (bit 20) updates condition codes
1178         * ADC/SBC/RSC reads the C flag
1179         */
1180        insn &= 0xfff00fff;     /* Rn = r0, Rd = r0 */
1181        asi->insn[0] = insn;
1182        asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
1183                        emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
1184        return INSN_GOOD;
1185}
1186
1187static enum kprobe_insn __kprobes
1188space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1189{
1190        /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */
1191        if ((insn & 0x0ff000f0) == 0x068000b0) {
1192                insn &= 0xfff00ff0;     /* Rd = r0, Rn = r0 */
1193                insn |= 0x00000001;     /* Rm = r1 */
1194                asi->insn[0] = insn;
1195                asi->insn_handler = emulate_sel;
1196                return INSN_GOOD;
1197        }
1198
1199        /* SSAT   : cccc 0110 101x xxxx xxxx xxxx xx01 xxxx :Q */
1200        /* USAT   : cccc 0110 111x xxxx xxxx xxxx xx01 xxxx :Q */
1201        /* SSAT16 : cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx :Q */
1202        /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */
1203        if ((insn & 0x0fa00030) == 0x06a00010 ||
1204            (insn & 0x0fb000f0) == 0x06a00030) {
1205                insn &= 0xffff0ff0;     /* Rd = r0, Rm = r0 */
1206                asi->insn[0] = insn;
1207                asi->insn_handler = emulate_sat;
1208                return INSN_GOOD;
1209        }
1210
1211        /* REV    : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
1212        /* REV16  : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
1213        /* REVSH  : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
1214        if ((insn & 0x0ff00070) == 0x06b00030 ||
1215            (insn & 0x0ff000f0) == 0x06f000b0)
1216                return prep_emulate_rd12rm0(insn, asi);
1217
1218        /* SADD16    : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */
1219        /* SADDSUBX  : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */
1220        /* SSUBADDX  : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */
1221        /* SSUB16    : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */
1222        /* SADD8     : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */
1223        /* SSUB8     : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */
1224        /* QADD16    : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx :   */
1225        /* QADDSUBX  : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx :   */
1226        /* QSUBADDX  : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx :   */
1227        /* QSUB16    : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx :   */
1228        /* QADD8     : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx :   */
1229        /* QSUB8     : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx :   */
1230        /* SHADD16   : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx :   */
1231        /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx :   */
1232        /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx :   */
1233        /* SHSUB16   : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx :   */
1234        /* SHADD8    : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx :   */
1235        /* SHSUB8    : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx :   */
1236        /* UADD16    : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */
1237        /* UADDSUBX  : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */
1238        /* USUBADDX  : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */
1239        /* USUB16    : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */
1240        /* UADD8     : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */
1241        /* USUB8     : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */
1242        /* UQADD16   : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx :   */
1243        /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx :   */
1244        /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx :   */
1245        /* UQSUB16   : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx :   */
1246        /* UQADD8    : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx :   */
1247        /* UQSUB8    : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx :   */
1248        /* UHADD16   : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx :   */
1249        /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx :   */
1250        /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx :   */
1251        /* UHSUB16   : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx :   */
1252        /* UHADD8    : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx :   */
1253        /* UHSUB8    : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx :   */
1254        /* PKHBT     : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx :   */
1255        /* PKHTB     : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx :   */
1256        /* SXTAB16   : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx :   */
1257        /* SXTB      : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx :   */
1258        /* SXTAB     : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx :   */
1259        /* SXTAH     : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx :   */
1260        /* UXTAB16   : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx :   */
1261        /* UXTAB     : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx :   */
1262        /* UXTAH     : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx :   */
1263        return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1264}
1265
1266static enum kprobe_insn __kprobes
1267space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1268{
1269        /* Undef : cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
1270        if ((insn & 0x0ff000f0) == 0x03f000f0)
1271                return INSN_REJECTED;
1272
1273        /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
1274        /* USAD8  : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
1275        if ((insn & 0x0ff000f0) == 0x07800010)
1276                 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1277
1278        /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
1279        /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
1280        if ((insn & 0x0ff00090) == 0x07400010)
1281                return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
1282
1283        /* SMLAD  : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */
1284        /* SMLSD  : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */
1285        /* SMMLA  : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx :  */
1286        /* SMMLS  : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx :  */
1287        if ((insn & 0x0ff00090) == 0x07000010 ||
1288            (insn & 0x0ff000d0) == 0x07500010 ||
1289            (insn & 0x0ff000d0) == 0x075000d0)
1290                return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1291
1292        /* SMUSD  : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :  */
1293        /* SMUAD  : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */
1294        /* SMMUL  : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx :  */
1295        return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1296}
1297
1298static enum kprobe_insn __kprobes
1299space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1300{
1301        /* LDR   : cccc 01xx x0x1 xxxx xxxx xxxx xxxx xxxx */
1302        /* LDRB  : cccc 01xx x1x1 xxxx xxxx xxxx xxxx xxxx */
1303        /* LDRBT : cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
1304        /* LDRT  : cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
1305        /* STR   : cccc 01xx x0x0 xxxx xxxx xxxx xxxx xxxx */
1306        /* STRB  : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */
1307        /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
1308        /* STRT  : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
1309        return prep_emulate_ldr_str(insn, asi);
1310}
1311
1312static enum kprobe_insn __kprobes
1313space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1314{
1315        /* LDM(2) : cccc 100x x101 xxxx 0xxx xxxx xxxx xxxx */
1316        /* LDM(3) : cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
1317        if ((insn & 0x0e708000) == 0x85000000 ||
1318            (insn & 0x0e508000) == 0x85010000)
1319                return INSN_REJECTED;
1320
1321        /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
1322        /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
1323        asi->insn[0] = truecc_insn(insn);
1324        asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */
1325                                simulate_stm1_pc : simulate_ldm1stm1;
1326        return INSN_GOOD;
1327}
1328
1329static enum kprobe_insn __kprobes
1330space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1331{
1332        /* B  : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
1333        /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
1334        asi->insn[0] = truecc_insn(insn);
1335        asi->insn_handler = simulate_bbl;
1336        return INSN_GOOD;
1337}
1338
1339static enum kprobe_insn __kprobes
1340space_cccc_1100_010x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1341{
1342        /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1343        /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1344        insn &= 0xfff00fff;
1345        insn |= 0x00001000;     /* Rn = r0, Rd = r1 */
1346        asi->insn[0] = insn;
1347        asi->insn_handler = (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr;
1348        return INSN_GOOD;
1349}
1350
1351static enum kprobe_insn __kprobes
1352space_cccc_110x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1353{
1354        /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
1355        /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
1356        insn &= 0xfff0ffff;     /* Rn = r0 */
1357        asi->insn[0] = insn;
1358        asi->insn_handler = emulate_ldcstc;
1359        return INSN_GOOD;
1360}
1361
1362static enum kprobe_insn __kprobes
1363space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1364{
1365        /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
1366        /* SWI  : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
1367        if ((insn & 0xfff000f0) == 0xe1200070 ||
1368            (insn & 0x0f000000) == 0x0f000000)
1369                return INSN_REJECTED;
1370
1371        /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
1372        if ((insn & 0x0f000010) == 0x0e000000) {
1373                asi->insn[0] = insn;
1374                asi->insn_handler = emulate_none;
1375                return INSN_GOOD;
1376        }
1377
1378        /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
1379        /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
1380        insn &= 0xffff0fff;     /* Rd = r0 */
1381        asi->insn[0] = insn;
1382        asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12;
1383        return INSN_GOOD;
1384}
1385
1386/* Return:
1387 *   INSN_REJECTED     If instruction is one not allowed to kprobe,
1388 *   INSN_GOOD         If instruction is supported and uses instruction slot,
1389 *   INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
1390 *
1391 * For instructions we don't want to kprobe (INSN_REJECTED return result):
1392 *   These are generally ones that modify the processor state making
1393 *   them "hard" to simulate such as switches processor modes or
1394 *   make accesses in alternate modes.  Any of these could be simulated
1395 *   if the work was put into it, but low return considering they
1396 *   should also be very rare.
1397 */
1398enum kprobe_insn __kprobes
1399arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1400{
1401        asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
1402
1403        if ((insn & 0xf0000000) == 0xf0000000) {
1404
1405                return space_1111(insn, asi);
1406
1407        } else if ((insn & 0x0e000000) == 0x00000000) {
1408
1409                return space_cccc_000x(insn, asi);
1410
1411        } else if ((insn & 0x0e000000) == 0x02000000) {
1412
1413                return space_cccc_001x(insn, asi);
1414
1415        } else if ((insn & 0x0f000010) == 0x06000010) {
1416
1417                return space_cccc_0110__1(insn, asi);
1418
1419        } else if ((insn & 0x0f000010) == 0x07000010) {
1420
1421                return space_cccc_0111__1(insn, asi);
1422
1423        } else if ((insn & 0x0c000000) == 0x04000000) {
1424
1425                return space_cccc_01xx(insn, asi);
1426
1427        } else if ((insn & 0x0e000000) == 0x08000000) {
1428
1429                return space_cccc_100x(insn, asi);
1430
1431        } else if ((insn & 0x0e000000) == 0x0a000000) {
1432
1433                return space_cccc_101x(insn, asi);
1434
1435        } else if ((insn & 0x0fe00000) == 0x0c400000) {
1436
1437                return space_cccc_1100_010x(insn, asi);
1438
1439        } else if ((insn & 0x0e000000) == 0x0c400000) {
1440
1441                return space_cccc_110x(insn, asi);
1442
1443        }
1444
1445        return space_cccc_111x(insn, asi);
1446}
1447
1448void __init arm_kprobe_decode_init(void)
1449{
1450        find_str_pc_offset();
1451}
1452
1453
1454/*
1455 * All ARM instructions listed below.
1456 *
1457 * Instructions and their general purpose registers are given.
1458 * If a particular register may not use R15, it is prefixed with a "!".
1459 * If marked with a "*" means the value returned by reading R15
1460 * is implementation defined.
1461 *
1462 * ADC/ADD/AND/BIC/CMN/CMP/EOR/MOV/MVN/ORR/RSB/RSC/SBC/SUB/TEQ
1463 *     TST: Rd, Rn, Rm, !Rs
1464 * BX: Rm
1465 * BLX(2): !Rm
1466 * BX: Rm (R15 legal, but discouraged)
1467 * BXJ: !Rm,
1468 * CLZ: !Rd, !Rm
1469 * CPY: Rd, Rm
1470 * LDC/2,STC/2 immediate offset & unindex: Rn
1471 * LDC/2,STC/2 immediate pre/post-indexed: !Rn
1472 * LDM(1/3): !Rn, register_list
1473 * LDM(2): !Rn, !register_list
1474 * LDR,STR,PLD immediate offset: Rd, Rn
1475 * LDR,STR,PLD register offset: Rd, Rn, !Rm
1476 * LDR,STR,PLD scaled register offset: Rd, !Rn, !Rm
1477 * LDR,STR immediate pre/post-indexed: Rd, !Rn
1478 * LDR,STR register pre/post-indexed: Rd, !Rn, !Rm
1479 * LDR,STR scaled register pre/post-indexed: Rd, !Rn, !Rm
1480 * LDRB,STRB immediate offset: !Rd, Rn
1481 * LDRB,STRB register offset: !Rd, Rn, !Rm
1482 * LDRB,STRB scaled register offset: !Rd, !Rn, !Rm
1483 * LDRB,STRB immediate pre/post-indexed: !Rd, !Rn
1484 * LDRB,STRB register pre/post-indexed: !Rd, !Rn, !Rm
1485 * LDRB,STRB scaled register pre/post-indexed: !Rd, !Rn, !Rm
1486 * LDRT,LDRBT,STRBT immediate pre/post-indexed: !Rd, !Rn
1487 * LDRT,LDRBT,STRBT register pre/post-indexed: !Rd, !Rn, !Rm
1488 * LDRT,LDRBT,STRBT scaled register pre/post-indexed: !Rd, !Rn, !Rm
1489 * LDRH/SH/SB/D,STRH/SH/SB/D immediate offset: !Rd, Rn
1490 * LDRH/SH/SB/D,STRH/SH/SB/D register offset: !Rd, Rn, !Rm
1491 * LDRH/SH/SB/D,STRH/SH/SB/D immediate pre/post-indexed: !Rd, !Rn
1492 * LDRH/SH/SB/D,STRH/SH/SB/D register pre/post-indexed: !Rd, !Rn, !Rm
1493 * LDREX: !Rd, !Rn
1494 * MCR/2: !Rd
1495 * MCRR/2,MRRC/2: !Rd, !Rn
1496 * MLA: !Rd, !Rn, !Rm, !Rs
1497 * MOV: Rd
1498 * MRC/2: !Rd (if Rd==15, only changes cond codes, not the register)
1499 * MRS,MSR: !Rd
1500 * MUL: !Rd, !Rm, !Rs
1501 * PKH{BT,TB}: !Rd, !Rn, !Rm
1502 * QDADD,[U]QADD/16/8/SUBX: !Rd, !Rm, !Rn
1503 * QDSUB,[U]QSUB/16/8/ADDX: !Rd, !Rm, !Rn
1504 * REV/16/SH: !Rd, !Rm
1505 * RFE: !Rn
1506 * {S,U}[H]ADD{16,8,SUBX},{S,U}[H]SUB{16,8,ADDX}: !Rd, !Rn, !Rm
1507 * SEL: !Rd, !Rn, !Rm
1508 * SMLA<x><y>,SMLA{D,W<y>},SMLSD,SMML{A,S}: !Rd, !Rn, !Rm, !Rs
1509 * SMLAL<x><y>,SMLA{D,LD},SMLSLD,SMMULL,SMULW<y>: !RdHi, !RdLo, !Rm, !Rs
1510 * SMMUL,SMUAD,SMUL<x><y>,SMUSD: !Rd, !Rm, !Rs
1511 * SSAT/16: !Rd, !Rm
1512 * STM(1/2): !Rn, register_list* (R15 in reg list not recommended)
1513 * STRT immediate pre/post-indexed: Rd*, !Rn
1514 * STRT register pre/post-indexed: Rd*, !Rn, !Rm
1515 * STRT scaled register pre/post-indexed: Rd*, !Rn, !Rm
1516 * STREX: !Rd, !Rn, !Rm
1517 * SWP/B: !Rd, !Rn, !Rm
1518 * {S,U}XTA{B,B16,H}: !Rd, !Rn, !Rm
1519 * {S,U}XT{B,B16,H}: !Rd, !Rm
1520 * UM{AA,LA,UL}L: !RdHi, !RdLo, !Rm, !Rs
1521 * USA{D8,A8,T,T16}: !Rd, !Rm, !Rs
1522 *
1523 * May transfer control by writing R15 (possible mode changes or alternate
1524 * mode accesses marked by "*"):
1525 * ALU op (* with s-bit), B, BL, BKPT, BLX(1/2), BX, BXJ, CPS*, CPY,
1526 * LDM(1), LDM(2/3)*, LDR, MOV, RFE*, SWI*
1527 *
1528 * Instructions that do not take general registers, nor transfer control:
1529 * CDP/2, SETEND, SRS*
1530 */
1531
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.