Linux Audio

Check our new training course

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