1 // SPDX-License-Identifier: GPL-2.0
6 #include "../../perf.h"
7 #include "../../util/util.h"
8 #include "../../util/perf_regs.h"
9 #include "../../util/debug.h"
11 const struct sample_reg sample_reg_masks
[] = {
12 SMPL_REG(r0
, PERF_REG_POWERPC_R0
),
13 SMPL_REG(r1
, PERF_REG_POWERPC_R1
),
14 SMPL_REG(r2
, PERF_REG_POWERPC_R2
),
15 SMPL_REG(r3
, PERF_REG_POWERPC_R3
),
16 SMPL_REG(r4
, PERF_REG_POWERPC_R4
),
17 SMPL_REG(r5
, PERF_REG_POWERPC_R5
),
18 SMPL_REG(r6
, PERF_REG_POWERPC_R6
),
19 SMPL_REG(r7
, PERF_REG_POWERPC_R7
),
20 SMPL_REG(r8
, PERF_REG_POWERPC_R8
),
21 SMPL_REG(r9
, PERF_REG_POWERPC_R9
),
22 SMPL_REG(r10
, PERF_REG_POWERPC_R10
),
23 SMPL_REG(r11
, PERF_REG_POWERPC_R11
),
24 SMPL_REG(r12
, PERF_REG_POWERPC_R12
),
25 SMPL_REG(r13
, PERF_REG_POWERPC_R13
),
26 SMPL_REG(r14
, PERF_REG_POWERPC_R14
),
27 SMPL_REG(r15
, PERF_REG_POWERPC_R15
),
28 SMPL_REG(r16
, PERF_REG_POWERPC_R16
),
29 SMPL_REG(r17
, PERF_REG_POWERPC_R17
),
30 SMPL_REG(r18
, PERF_REG_POWERPC_R18
),
31 SMPL_REG(r19
, PERF_REG_POWERPC_R19
),
32 SMPL_REG(r20
, PERF_REG_POWERPC_R20
),
33 SMPL_REG(r21
, PERF_REG_POWERPC_R21
),
34 SMPL_REG(r22
, PERF_REG_POWERPC_R22
),
35 SMPL_REG(r23
, PERF_REG_POWERPC_R23
),
36 SMPL_REG(r24
, PERF_REG_POWERPC_R24
),
37 SMPL_REG(r25
, PERF_REG_POWERPC_R25
),
38 SMPL_REG(r26
, PERF_REG_POWERPC_R26
),
39 SMPL_REG(r27
, PERF_REG_POWERPC_R27
),
40 SMPL_REG(r28
, PERF_REG_POWERPC_R28
),
41 SMPL_REG(r29
, PERF_REG_POWERPC_R29
),
42 SMPL_REG(r30
, PERF_REG_POWERPC_R30
),
43 SMPL_REG(r31
, PERF_REG_POWERPC_R31
),
44 SMPL_REG(nip
, PERF_REG_POWERPC_NIP
),
45 SMPL_REG(msr
, PERF_REG_POWERPC_MSR
),
46 SMPL_REG(orig_r3
, PERF_REG_POWERPC_ORIG_R3
),
47 SMPL_REG(ctr
, PERF_REG_POWERPC_CTR
),
48 SMPL_REG(link
, PERF_REG_POWERPC_LINK
),
49 SMPL_REG(xer
, PERF_REG_POWERPC_XER
),
50 SMPL_REG(ccr
, PERF_REG_POWERPC_CCR
),
51 SMPL_REG(softe
, PERF_REG_POWERPC_SOFTE
),
52 SMPL_REG(trap
, PERF_REG_POWERPC_TRAP
),
53 SMPL_REG(dar
, PERF_REG_POWERPC_DAR
),
54 SMPL_REG(dsisr
, PERF_REG_POWERPC_DSISR
),
55 SMPL_REG(sier
, PERF_REG_POWERPC_SIER
),
56 SMPL_REG(mmcra
, PERF_REG_POWERPC_MMCRA
),
61 #define SDT_OP_REGEX1 "^(%r)?([1-2]?[0-9]|3[0-1])$"
63 /* -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) */
64 #define SDT_OP_REGEX2 "^(\\-)?([0-9]+)\\((%r)?([1-2]?[0-9]|3[0-1])\\)$"
66 static regex_t sdt_op_regex1
, sdt_op_regex2
;
68 static int sdt_init_op_regex(void)
70 static int initialized
;
76 ret
= regcomp(&sdt_op_regex1
, SDT_OP_REGEX1
, REG_EXTENDED
);
80 ret
= regcomp(&sdt_op_regex2
, SDT_OP_REGEX2
, REG_EXTENDED
);
88 regfree(&sdt_op_regex1
);
90 pr_debug4("Regex compilation error.\n");
95 * Parse OP and convert it into uprobe format, which is, +/-NUM(%gprREG).
96 * Possible variants of OP are:
98 * -------------------------
101 * NUM(%rREG) 48(%r18)
102 * -NUM(%rREG) -48(%r18)
108 * SDT marker arguments on Powerpc uses %rREG form with -mregnames flag
109 * and REG form with -mno-regnames. Here REG is general purpose register,
110 * which is in 0 to 31 range.
112 int arch_sdt_arg_parse_op(char *old_op
, char **new_op
)
118 /* Constant argument. Uprobe does not support it */
119 if (old_op
[0] == 'i') {
120 pr_debug4("Skipping unsupported SDT argument: %s\n", old_op
);
124 ret
= sdt_init_op_regex();
128 if (!regexec(&sdt_op_regex1
, old_op
, 3, rm
, 0)) {
129 /* REG or %rREG --> %gprREG */
131 new_len
= 5; /* % g p r NULL */
132 new_len
+= (int)(rm
[2].rm_eo
- rm
[2].rm_so
);
134 *new_op
= zalloc(new_len
);
138 scnprintf(*new_op
, new_len
, "%%gpr%.*s",
139 (int)(rm
[2].rm_eo
- rm
[2].rm_so
), old_op
+ rm
[2].rm_so
);
140 } else if (!regexec(&sdt_op_regex2
, old_op
, 5, rm
, 0)) {
142 * -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) -->
145 prefix
= (rm
[1].rm_so
== -1) ? '+' : '-';
147 new_len
= 8; /* +/- ( % g p r ) NULL */
148 new_len
+= (int)(rm
[2].rm_eo
- rm
[2].rm_so
);
149 new_len
+= (int)(rm
[4].rm_eo
- rm
[4].rm_so
);
151 *new_op
= zalloc(new_len
);
155 scnprintf(*new_op
, new_len
, "%c%.*s(%%gpr%.*s)", prefix
,
156 (int)(rm
[2].rm_eo
- rm
[2].rm_so
), old_op
+ rm
[2].rm_so
,
157 (int)(rm
[4].rm_eo
- rm
[4].rm_so
), old_op
+ rm
[4].rm_so
);
159 pr_debug4("Skipping unsupported SDT argument: %s\n", old_op
);
163 return SDT_ARG_VALID
;