From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C93EFF9D0CA for ; Tue, 14 Apr 2026 12:47:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=S7jcapWIR3C+wE++D1FdOVCvl9lr0EETS5Qkcg9xuK8=; b=xwp6Tfo5hVkD/V 57/1Kqd4TICk6ltX0RnBSTHKgpcOofswkp1LTdpjBuq+WaH+6nvPHSRHdDkwkJAYXo0XrmRmmm/37 nJnec3m8p0HmfbYpqbboq9NYY1vrJF59uroNWlSXHxdWitAgjTJyMwun2WJC1s1R2lF2MJILxmK5x WUL/qS040jNg98JLsFZmI/NR3pFHx9Z51PLVpwGqxf/rjrXvbxTXQ7IEMBCXbbd4OoJUfQOPCZ58v GbmIrTmCmQ19VCRlv6azuON2EY9KJ+1NvubRUr27X9SwVFzo8lHGSRQ/nCwqYrFWU5XVkqnD1OHaY yeyIW1VOG1MK0fPeWkdw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1wCdAp-0000000HJkL-44pP; Tue, 14 Apr 2026 12:47:24 +0000 Received: from out30-119.freemail.mail.aliyun.com ([115.124.30.119]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1wCdAl-0000000HJio-1blg for linux-riscv@lists.infradead.org; Tue, 14 Apr 2026 12:47:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1776170829; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=YqK86tN+5CwSiapRk+YDENrvDUQ4S2Gqqvz2QGp5ER4=; b=xd7j/+H4k8b1tOovjG7RduDvbAez+bXRRxXZIxd0eG3pGh42C4CChDHVtfSjrZTxQdcVfMbKNr81WOU5wG3ExJo/AqQxjka1Kq8dyQlR2djboXr8QilEK5JCLKv1L7YvJeXlEPbt2UxgDD5D/kyE1q3o1GNVOtz7pVCEcxcOqOM= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R191e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033045098064;MF=cp0613@linux.alibaba.com;NM=1;PH=DS;RN=13;SR=0;TI=SMTPD_---0X11UUgK_1776170820; Received: from DESKTOP-S9E58SO.localdomain(mailfrom:cp0613@linux.alibaba.com fp:SMTPD_---0X11UUgK_1776170820 cluster:ay36) by smtp.aliyun-inc.com; Tue, 14 Apr 2026 20:47:06 +0800 From: cp0613@linux.alibaba.com To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org, namhyung@kernel.org, irogers@google.com, dapeng1.mi@linux.intel.com, pjw@kernel.org, alex@ghiti.fr, guoren@kernel.org Cc: linux-perf-users@vger.kernel.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Chen Pei Subject: [PATCH] perf riscv: Add SDT argument parsing for RISC-V Date: Tue, 14 Apr 2026 20:46:55 +0800 Message-ID: <20260414124655.129463-1-cp0613@linux.alibaba.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260414_054720_373944_FF1703BB X-CRM114-Status: GOOD ( 12.83 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org From: Chen Pei Implement __perf_sdt_arg_parse_op_riscv() to convert RISC-V GCC-generated SDT probe operands into uprobe-compatible format, and register it in the perf_sdt_arg_parse_op() dispatcher for EM_RISCV. RISC-V GCC uses the 'nor' constraint for SDT arguments, producing operands in the following formats: Format Example Uprobe format ----------- ----------- ------------- register a0 %a0 memory (+) 8(a0) +8(%a0) memory (-) -20(s0) -20(%s0) constant 99 (skip, not supported by uprobe) Key differences from other architectures: - Register names use ABI aliases (a0-a7, t0-t6, s0-s11, sp, ra, etc.) without any '%' prefix, unlike x86 (%rax) or arm64 (x0). - Memory operands use OFFSET(REG) syntax where OFFSET may be negative, unlike arm64's [sp, NUM] or powerpc's NUM(%rREG). Two regexes are used: - SDT_OP_REGEX1: matches all RISC-V ABI register names - SDT_OP_REGEX2: matches [-]NUM(REG) memory operands Signed-off-by: Chen Pei --- Tested on RISC-V QEMU(rv64gc) with GCC-generated SDT probes. Requires systemtap-sdt-dev (provides ) on the target system. # cat sdt_test.c #include #include void my_func(int a, long b) { DTRACE_PROBE2(myapp, my_probe, a, b); printf("a=%d b=%ld\n", a, b); } int main() { my_func(42, -100); return 0; } # gcc -O0 -Wl,--build-id -o sdt_test_O0 sdt_test.c # stack args: -20(s0) # gcc -O2 -Wl,--build-id -o sdt_test_O2 sdt_test.c # reg args: a0 # perf buildid-cache --add sdt_test_O0 # perf buildid-cache --add sdt_test_O2 # find ~/.debug -name "probes" | xargs cat p:sdt_myapp/my_probe .../sdt_test_O0:0x... arg1=-20(%s0):s32 arg2=-32(%s0):s64 p:sdt_myapp/my_probe .../sdt_test_O2:0x... arg1=%a0:s32 arg2=%a1:s64 .../util/perf-regs-arch/perf_regs_riscv.c | 126 ++++++++++++++++++ tools/perf/util/perf_regs.c | 3 + tools/perf/util/perf_regs.h | 1 + 3 files changed, 130 insertions(+) diff --git a/tools/perf/util/perf-regs-arch/perf_regs_riscv.c b/tools/perf/util/perf-regs-arch/perf_regs_riscv.c index 5b5f21fcba8c..51b43e68e0e3 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_riscv.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_riscv.c @@ -1,8 +1,134 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include + +#include "../debug.h" #include "../perf_regs.h" #include "../../arch/riscv/include/perf_regs.h" +/* + * RISC-V SDT argument formats (GCC 'nor' constraint): + * + * Register: REG e.g. a0, t1, s0, sp + * Memory: NUM(REG) e.g. 8(a0), -20(s0) + * Constant: NUM e.g. 99 (not supported by uprobe, skip) + * + * Uprobe target format: + * Register: %REG e.g. %a0 + * Memory: +NUM(%REG) or -NUM(%REG) + */ + +/* RISC-V register ABI names: zero, ra, sp, gp, tp, t0-t6, s0-s11, a0-a7 */ +#define SDT_OP_REGEX1 "^(zero|ra|sp|gp|tp|t[0-6]|s[0-9]|s1[01]|a[0-7])$" + +/* RISC-V memory operand: [-]NUM(REG) */ +#define SDT_OP_REGEX2 "^(\\-)?([0-9]+)\\((zero|ra|sp|gp|tp|t[0-6]|s[0-9]|s1[01]|a[0-7])\\)$" + +static regex_t sdt_op_regex1, sdt_op_regex2; + +static int sdt_init_op_regex(void) +{ + static int initialized; + int ret = 0; + + if (initialized) + return 0; + + ret = regcomp(&sdt_op_regex1, SDT_OP_REGEX1, REG_EXTENDED); + if (ret) + goto error; + + ret = regcomp(&sdt_op_regex2, SDT_OP_REGEX2, REG_EXTENDED); + if (ret) + goto free_regex1; + + initialized = 1; + return 0; + +free_regex1: + regfree(&sdt_op_regex1); +error: + pr_debug4("Regex compilation error.\n"); + return ret; +} + +/* + * Parse OP and convert it into uprobe format. + * Possible variants of OP (RISC-V, GCC 'nor' constraint): + * + * Format Example Uprobe + * ---------------------------------------- + * REG a0 %a0 + * NUM(REG) 8(a0) +8(%a0) + * -NUM(REG) -20(s0) -20(%s0) + * NUM 99 (skip, constant not supported) + */ +int __perf_sdt_arg_parse_op_riscv(char *old_op, char **new_op) +{ + int ret, new_len; + regmatch_t rm[4]; + char prefix; + + /* + * Constant argument: pure integer with no trailing '(' (e.g. "99", "-1"). + * uprobe does not support immediate values, so skip them. + * Memory operands like "8(a0)" or "-20(s0)" contain '(' so are NOT + * treated as constants here; they will be matched by REGEX2 below. + */ + if (strchr(old_op, '(') == NULL && + ((*old_op >= '0' && *old_op <= '9') || + (*old_op == '-' && old_op[1] >= '0' && old_op[1] <= '9'))) { + pr_debug4("Skipping unsupported SDT argument: %s\n", old_op); + return SDT_ARG_SKIP; + } + + ret = sdt_init_op_regex(); + if (ret < 0) + return ret; + + if (!regexec(&sdt_op_regex1, old_op, 2, rm, 0)) { + /* REG --> %REG */ + new_len = 2; /* % NULL */ + new_len += (int)(rm[1].rm_eo - rm[1].rm_so); + + *new_op = zalloc(new_len); + if (!*new_op) + return -ENOMEM; + + scnprintf(*new_op, new_len, "%%%.*s", + (int)(rm[1].rm_eo - rm[1].rm_so), old_op + rm[1].rm_so); + } else if (!regexec(&sdt_op_regex2, old_op, 4, rm, 0)) { + /* + * NUM(REG) or -NUM(REG) --> +NUM(%REG) or -NUM(%REG) + * rm[1]: optional '-' + * rm[2]: decimal offset + * rm[3]: register name + */ + prefix = (rm[1].rm_so == -1) ? '+' : '-'; + + new_len = 5; /* sign ( % ) NULL */ + new_len += (int)(rm[2].rm_eo - rm[2].rm_so); + new_len += (int)(rm[3].rm_eo - rm[3].rm_so); + + *new_op = zalloc(new_len); + if (!*new_op) + return -ENOMEM; + + scnprintf(*new_op, new_len, "%c%.*s(%%%.*s)", prefix, + (int)(rm[2].rm_eo - rm[2].rm_so), old_op + rm[2].rm_so, + (int)(rm[3].rm_eo - rm[3].rm_so), old_op + rm[3].rm_so); + } else { + pr_debug4("Skipping unsupported SDT argument: %s\n", old_op); + return SDT_ARG_SKIP; + } + + return SDT_ARG_VALID; +} + uint64_t __perf_reg_mask_riscv(bool intr __maybe_unused) { return PERF_REGS_MASK; diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index 5b8f34beb24e..57a1d227d1b2 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -19,6 +19,9 @@ int perf_sdt_arg_parse_op(uint16_t e_machine, char *old_op, char **new_op) case EM_PPC64: ret = __perf_sdt_arg_parse_op_powerpc(old_op, new_op); break; + case EM_RISCV: + ret = __perf_sdt_arg_parse_op_riscv(old_op, new_op); + break; case EM_386: case EM_X86_64: ret = __perf_sdt_arg_parse_op_x86(old_op, new_op); diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 7c04700bf837..e0b51b514ee0 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -53,6 +53,7 @@ const char *__perf_reg_name_powerpc(int id); uint64_t __perf_reg_ip_powerpc(void); uint64_t __perf_reg_sp_powerpc(void); +int __perf_sdt_arg_parse_op_riscv(char *old_op, char **new_op); uint64_t __perf_reg_mask_riscv(bool intr); const char *__perf_reg_name_riscv(int id); uint64_t __perf_reg_ip_riscv(void); -- 2.50.1 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv