Messages in this thread Patch in this message | | | From | Ravi Bangoria <> | Subject | [PATCH 4/5] perf/sdt/powerpc: Add argument support | Date | Thu, 2 Feb 2017 16:41:42 +0530 |
| |
SDT marker argument is in N@OP format. Here OP is arch dependent component. Add powerpc logic to parse OP and convert it to uprobe compatible format.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> --- tools/perf/arch/powerpc/util/perf_regs.c | 115 +++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+)
diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/powerpc/util/perf_regs.c index a3c3e1c..bbd6f91 100644 --- a/tools/perf/arch/powerpc/util/perf_regs.c +++ b/tools/perf/arch/powerpc/util/perf_regs.c @@ -1,5 +1,10 @@ +#include <string.h> +#include <regex.h> + #include "../../perf.h" +#include "../../util/util.h" #include "../../util/perf_regs.h" +#include "../../util/debug.h" const struct sample_reg sample_reg_masks[] = { SMPL_REG(r0, PERF_REG_POWERPC_R0), @@ -47,3 +52,113 @@ const struct sample_reg sample_reg_masks[] = { SMPL_REG(dsisr, PERF_REG_POWERPC_DSISR), SMPL_REG_END }; + +bool arch_sdt_probe_arg_supp(void) +{ + return true; +} + +static regex_t regex1, regex2; + +static int init_op_regex(void) +{ + static int initialized; + + if (initialized) + return 0; + + /* REG or %rREG */ + if (regcomp(®ex1, "^(%r)?([1-2]?[0-9]|3[0-1])$", REG_EXTENDED)) + goto error; + + /* -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) */ + if (regcomp(®ex2, "^(\\-)?([0-9]+)\\((%r)?([1-2]?[0-9]|3[0-1])\\)$", + REG_EXTENDED)) + goto free_regex1; + + initialized = 1; + return 0; + +free_regex1: + regfree(®ex1); +error: + pr_debug4("Regex compilation error.\n"); + return -1; +} + +/* + * Parse OP and convert it into uprobe format, which is, +/-NUM(%gprREG). + * Possible variants of OP are: + * Format Example + * ------------------------- + * NUM(REG) 48(18) + * -NUM(REG) -48(18) + * NUM(%rREG) 48(%r18) + * -NUM(%rREG) -48(%r18) + * REG 18 + * %rREG %r18 + * iNUM i0 + * i-NUM i-1 + * + * SDT marker arguments on Powerpc uses %rREG form with -mregnames flag + * and REG form with -mno-regnames. Here REG is general purpose register, + * which is in 0 to 31 range. + * + * return value of the function: + * <0 : error + * 0 : success + * >0 : skip + */ +int arch_sdt_probe_parse_op(char **desc, const char **prefix) +{ + char *tmp = NULL; + size_t new_len; + regmatch_t rm[5]; + + /* Constant argument. Uprobe does not support it */ + if (*desc[0] == 'i') { + pr_debug4("Skipping unsupported SDT argument: %s\n", *desc); + return 1; + } + + if (init_op_regex() < 0) + return -1; + + if (!regexec(®ex1, *desc, 3, rm, 0)) { + /* REG or %rREG --> %gprREG */ + new_len = 5; + new_len += (int)(rm[2].rm_eo - rm[2].rm_so); + + tmp = zalloc(new_len); + if (!tmp) + return -1; + + scnprintf(tmp, new_len, "%%gpr%.*s", + (int)(rm[2].rm_eo - rm[2].rm_so), *desc + rm[2].rm_so); + } else if (!regexec(®ex2, *desc, 5, rm, 0)) { + /* + * -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) --> + * +/-NUM(%gprREG) + */ + *prefix = (rm[1].rm_so == -1) ? "+" : "-"; + + new_len = 7; + new_len += (int)(rm[2].rm_eo - rm[2].rm_so); + new_len += (int)(rm[4].rm_eo - rm[4].rm_so); + + tmp = zalloc(new_len); + if (!tmp) + return -1; + + scnprintf(tmp, new_len, "%.*s(%%gpr%.*s)", + (int)(rm[2].rm_eo - rm[2].rm_so), *desc + rm[2].rm_so, + (int)(rm[4].rm_eo - rm[4].rm_so), *desc + rm[4].rm_so); + } else { + pr_debug4("Skipping unsupported SDT argument: %s\n", *desc); + return 1; + } + + free(*desc); + *desc = tmp; + return 0; +} -- 2.9.3
| |