Skip to content

Commit feab999

Browse files
Leo Yanacmel
authored andcommitted
perf arm64: Add argument support for SDT
Now the two OP formats are used for SDT marker argument in Arm64 ELF, one format is general register xNUM (e.g. x1, x2, etc), another is for using stack pointer to access local variables (e.g. [sp], [sp, 8]). This patch adds support SDT marker argument for Arm64, it parses OP and converts to uprobe compatible format. Signed-off-by: Leo Yan <[email protected]> Acked-by: Masami Hiramatsu <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Alexandre Truong <[email protected]> Cc: Alexis Berlemont <[email protected]> Cc: He Zhe <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: John Garry <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mathieu Poirier <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Sumanth Korikkar <[email protected]> Cc: Thomas Richter <[email protected]> Cc: Will Deacon <[email protected]> Cc: [email protected] Link: http://lore.kernel.org/lkml/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent f19b587 commit feab999

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

tools/perf/arch/arm64/util/perf_regs.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
// SPDX-License-Identifier: GPL-2.0
2+
#include <errno.h>
3+
#include <regex.h>
4+
#include <string.h>
5+
#include <linux/kernel.h>
6+
#include <linux/zalloc.h>
7+
8+
#include "../../../util/debug.h"
9+
#include "../../../util/event.h"
210
#include "../../../util/perf_regs.h"
311

412
const struct sample_reg sample_reg_masks[] = {
@@ -37,3 +45,89 @@ const struct sample_reg sample_reg_masks[] = {
3745
SMPL_REG(pc, PERF_REG_ARM64_PC),
3846
SMPL_REG_END
3947
};
48+
49+
/* %xNUM */
50+
#define SDT_OP_REGEX1 "^(x[1-2]?[0-9]|3[0-1])$"
51+
52+
/* [sp], [sp, NUM] */
53+
#define SDT_OP_REGEX2 "^\\[sp(, )?([0-9]+)?\\]$"
54+
55+
static regex_t sdt_op_regex1, sdt_op_regex2;
56+
57+
static int sdt_init_op_regex(void)
58+
{
59+
static int initialized;
60+
int ret = 0;
61+
62+
if (initialized)
63+
return 0;
64+
65+
ret = regcomp(&sdt_op_regex1, SDT_OP_REGEX1, REG_EXTENDED);
66+
if (ret)
67+
goto error;
68+
69+
ret = regcomp(&sdt_op_regex2, SDT_OP_REGEX2, REG_EXTENDED);
70+
if (ret)
71+
goto free_regex1;
72+
73+
initialized = 1;
74+
return 0;
75+
76+
free_regex1:
77+
regfree(&sdt_op_regex1);
78+
error:
79+
pr_debug4("Regex compilation error.\n");
80+
return ret;
81+
}
82+
83+
/*
84+
* SDT marker arguments on Arm64 uses %xREG or [sp, NUM], currently
85+
* support these two formats.
86+
*/
87+
int arch_sdt_arg_parse_op(char *old_op, char **new_op)
88+
{
89+
int ret, new_len;
90+
regmatch_t rm[5];
91+
92+
ret = sdt_init_op_regex();
93+
if (ret < 0)
94+
return ret;
95+
96+
if (!regexec(&sdt_op_regex1, old_op, 3, rm, 0)) {
97+
/* Extract xNUM */
98+
new_len = 2; /* % NULL */
99+
new_len += (int)(rm[1].rm_eo - rm[1].rm_so);
100+
101+
*new_op = zalloc(new_len);
102+
if (!*new_op)
103+
return -ENOMEM;
104+
105+
scnprintf(*new_op, new_len, "%%%.*s",
106+
(int)(rm[1].rm_eo - rm[1].rm_so), old_op + rm[1].rm_so);
107+
} else if (!regexec(&sdt_op_regex2, old_op, 5, rm, 0)) {
108+
/* [sp], [sp, NUM] or [sp,NUM] */
109+
new_len = 7; /* + ( % s p ) NULL */
110+
111+
/* If the arugment is [sp], need to fill offset '0' */
112+
if (rm[2].rm_so == -1)
113+
new_len += 1;
114+
else
115+
new_len += (int)(rm[2].rm_eo - rm[2].rm_so);
116+
117+
*new_op = zalloc(new_len);
118+
if (!*new_op)
119+
return -ENOMEM;
120+
121+
if (rm[2].rm_so == -1)
122+
scnprintf(*new_op, new_len, "+0(%%sp)");
123+
else
124+
scnprintf(*new_op, new_len, "+%.*s(%%sp)",
125+
(int)(rm[2].rm_eo - rm[2].rm_so),
126+
old_op + rm[2].rm_so);
127+
} else {
128+
pr_debug4("Skipping unsupported SDT argument: %s\n", old_op);
129+
return SDT_ARG_SKIP;
130+
}
131+
132+
return SDT_ARG_VALID;
133+
}

0 commit comments

Comments
 (0)