linux/arch/arm/probes/kprobes/checkers-common.c
<<
>>
Prefs
   1/*
   2 * arch/arm/probes/kprobes/checkers-common.c
   3 *
   4 * Copyright (C) 2014 Huawei 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#include <linux/kernel.h>
  17#include "../decode.h"
  18#include "../decode-arm.h"
  19#include "checkers.h"
  20
  21enum probes_insn checker_stack_use_none(probes_opcode_t insn,
  22                struct arch_probes_insn *asi,
  23                const struct decode_header *h)
  24{
  25        asi->stack_space = 0;
  26        return INSN_GOOD_NO_SLOT;
  27}
  28
  29enum probes_insn checker_stack_use_unknown(probes_opcode_t insn,
  30                struct arch_probes_insn *asi,
  31                const struct decode_header *h)
  32{
  33        asi->stack_space = -1;
  34        return INSN_GOOD_NO_SLOT;
  35}
  36
  37#ifdef CONFIG_THUMB2_KERNEL
  38enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn,
  39                struct arch_probes_insn *asi,
  40                const struct decode_header *h)
  41{
  42        int imm = insn & 0xff;
  43        asi->stack_space = imm;
  44        return INSN_GOOD_NO_SLOT;
  45}
  46
  47/*
  48 * Different from other insn uses imm8, the real addressing offset of
  49 * STRD in T32 encoding should be imm8 * 4. See ARMARM description.
  50 */
  51enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
  52                struct arch_probes_insn *asi,
  53                const struct decode_header *h)
  54{
  55        int imm = insn & 0xff;
  56        asi->stack_space = imm << 2;
  57        return INSN_GOOD_NO_SLOT;
  58}
  59#else
  60enum probes_insn checker_stack_use_imm_x0x(probes_opcode_t insn,
  61                struct arch_probes_insn *asi,
  62                const struct decode_header *h)
  63{
  64        int imm = ((insn & 0xf00) >> 4) + (insn & 0xf);
  65        asi->stack_space = imm;
  66        return INSN_GOOD_NO_SLOT;
  67}
  68#endif
  69
  70enum probes_insn checker_stack_use_imm_xxx(probes_opcode_t insn,
  71                struct arch_probes_insn *asi,
  72                const struct decode_header *h)
  73{
  74        int imm = insn & 0xfff;
  75        asi->stack_space = imm;
  76        return INSN_GOOD_NO_SLOT;
  77}
  78
  79enum probes_insn checker_stack_use_stmdx(probes_opcode_t insn,
  80                struct arch_probes_insn *asi,
  81                const struct decode_header *h)
  82{
  83        unsigned int reglist = insn & 0xffff;
  84        int pbit = insn & (1 << 24);
  85        asi->stack_space = (hweight32(reglist) - (!pbit ? 1 : 0)) * 4;
  86
  87        return INSN_GOOD_NO_SLOT;
  88}
  89
  90const union decode_action stack_check_actions[] = {
  91        [STACK_USE_NONE] = {.decoder = checker_stack_use_none},
  92        [STACK_USE_UNKNOWN] = {.decoder = checker_stack_use_unknown},
  93#ifdef CONFIG_THUMB2_KERNEL
  94        [STACK_USE_FIXED_0XX] = {.decoder = checker_stack_use_imm_0xx},
  95        [STACK_USE_T32STRD] = {.decoder = checker_stack_use_t32strd},
  96#else
  97        [STACK_USE_FIXED_X0X] = {.decoder = checker_stack_use_imm_x0x},
  98#endif
  99        [STACK_USE_FIXED_XXX] = {.decoder = checker_stack_use_imm_xxx},
 100        [STACK_USE_STMDX] = {.decoder = checker_stack_use_stmdx},
 101};
 102