Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * arch/arm/probes/kprobes/checkers-common.c
0004  *
0005  * Copyright (C) 2014 Huawei Inc.
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include "../decode.h"
0010 #include "../decode-arm.h"
0011 #include "checkers.h"
0012 
0013 enum probes_insn checker_stack_use_none(probes_opcode_t insn,
0014         struct arch_probes_insn *asi,
0015         const struct decode_header *h)
0016 {
0017     asi->stack_space = 0;
0018     return INSN_GOOD_NO_SLOT;
0019 }
0020 
0021 enum probes_insn checker_stack_use_unknown(probes_opcode_t insn,
0022         struct arch_probes_insn *asi,
0023         const struct decode_header *h)
0024 {
0025     asi->stack_space = -1;
0026     return INSN_GOOD_NO_SLOT;
0027 }
0028 
0029 #ifdef CONFIG_THUMB2_KERNEL
0030 enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn,
0031         struct arch_probes_insn *asi,
0032         const struct decode_header *h)
0033 {
0034     int imm = insn & 0xff;
0035     asi->stack_space = imm;
0036     return INSN_GOOD_NO_SLOT;
0037 }
0038 
0039 /*
0040  * Different from other insn uses imm8, the real addressing offset of
0041  * STRD in T32 encoding should be imm8 * 4. See ARMARM description.
0042  */
0043 enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
0044         struct arch_probes_insn *asi,
0045         const struct decode_header *h)
0046 {
0047     int imm = insn & 0xff;
0048     asi->stack_space = imm << 2;
0049     return INSN_GOOD_NO_SLOT;
0050 }
0051 #else
0052 enum probes_insn checker_stack_use_imm_x0x(probes_opcode_t insn,
0053         struct arch_probes_insn *asi,
0054         const struct decode_header *h)
0055 {
0056     int imm = ((insn & 0xf00) >> 4) + (insn & 0xf);
0057     asi->stack_space = imm;
0058     return INSN_GOOD_NO_SLOT;
0059 }
0060 #endif
0061 
0062 enum probes_insn checker_stack_use_imm_xxx(probes_opcode_t insn,
0063         struct arch_probes_insn *asi,
0064         const struct decode_header *h)
0065 {
0066     int imm = insn & 0xfff;
0067     asi->stack_space = imm;
0068     return INSN_GOOD_NO_SLOT;
0069 }
0070 
0071 enum probes_insn checker_stack_use_stmdx(probes_opcode_t insn,
0072         struct arch_probes_insn *asi,
0073         const struct decode_header *h)
0074 {
0075     unsigned int reglist = insn & 0xffff;
0076     int pbit = insn & (1 << 24);
0077     asi->stack_space = (hweight32(reglist) - (!pbit ? 1 : 0)) * 4;
0078 
0079     return INSN_GOOD_NO_SLOT;
0080 }
0081 
0082 const union decode_action stack_check_actions[] = {
0083     [STACK_USE_NONE] = {.decoder = checker_stack_use_none},
0084     [STACK_USE_UNKNOWN] = {.decoder = checker_stack_use_unknown},
0085 #ifdef CONFIG_THUMB2_KERNEL
0086     [STACK_USE_FIXED_0XX] = {.decoder = checker_stack_use_imm_0xx},
0087     [STACK_USE_T32STRD] = {.decoder = checker_stack_use_t32strd},
0088 #else
0089     [STACK_USE_FIXED_X0X] = {.decoder = checker_stack_use_imm_x0x},
0090 #endif
0091     [STACK_USE_FIXED_XXX] = {.decoder = checker_stack_use_imm_xxx},
0092     [STACK_USE_STMDX] = {.decoder = checker_stack_use_stmdx},
0093 };