From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2236A397332; Wed, 16 Sep 2026 01:30:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522218; cv=none; b=X35eGHvPGppk+2AoArJ5OuFNnYHZNxWUANqFd1Air+Yt6A1EXqKvSHUpmZHqbioIRPACpVc+rLKOv9CUGpH/dbCMg2kLj3leNZIc6vzDxTdrDEwP8Uh3Lln/5R2SH6oS1bcpGFSvSejSGIYyPQxoxClJYapLjUZ1vQicfUAiPAE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522218; c=relaxed/simple; bh=KOyN1rGkVcithK48sZW7JTvMWZuGj5lrgQXex9dlbbE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=I3wI9wipx6ws2nmdY15Ubxx5sUXZOJuGZWoHDFXawhPQnVn9SR92+WywSB43tGmtFjOQm1/jc6+LMRf2Vt7a1F8ucm3vmfXaMTjvFqq7zkGa86lf8lybFK063VgF759zA07aZajLcLO4N6F34fgPDmanMChhaw1426zV0lmxnSY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XH4LbSzKHMRR; Wed, 16 Sep 2026 09:29:51 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 1AE904058C; Wed, 16 Sep 2026 09:30:05 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S3; Wed, 16 Sep 2026 09:30:04 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 01/26] perf capstone: Symbolize address operands to match objdump on arm64 Date: Wed, 16 Sep 2026 01:29:15 +0000 Message-Id: <6055eabaa63f43fffb67e7e5ca6f70d997a3faa9.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S3 X-Coremail-Antispam: 1UD129KBjvJXoW3Jr4fCF47JFyfuw4rXr4DCFg_yoWfAr48pa nrC345JFs5JF1xWws3Ja1kX34akws3XF4Yk3y7K3ySkrnxKrn3XayxKFya9F98GrWkGw17 tFs0kr45Wr93tr7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQKb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUGw A2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxS w2x7M28EF7xvwVC0I7IYx2IY67AKxVW8JVW5JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxV WxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVWxJr0_GcWle2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2 WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkE bVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxcIEc7 CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5MxAI w28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr 4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0EwIxG rwCI42IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJw CI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2 z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7sRNNVy3UUUUU== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Capstone currently outputs address-bearing instructions with a raw hex value prefixed by '#', without symbolic resolution. This differs from objdump output and leads to parse failures in jump__parse() and arm64_mov__parse() on arm64. Example of the mismatch: Current: b #0xffff8000800114c8 Objdump: b ffff8000800114c8 Current: adrp x18, #0xffff800081f5f000 Objdump: adrp x18, ffff800081f5f000 Fix this by extending symbol__disassemble_capstone() to: - Enable CS_OPT_DETAIL for arm64 to access instruction group info. - Detect instructions with address operands requiring symbolization (jump/call/branch/adr/adrp) via opcode or Capstone group ID. - Resolve target addresses to symbols via find_symbol_from_addr(). - Format output to match objdump's style (strip '#' prefix, add symbol and offset). Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers Reviewed-by: Namhyung Kim --- tools/perf/util/capstone.c | 186 ++++++++++++++++++++++++++++++------- tools/perf/util/disasm.c | 5 + tools/perf/util/disasm.h | 1 + 3 files changed, 157 insertions(+), 35 deletions(-) diff --git a/tools/perf/util/capstone.c b/tools/perf/util/capstone.c index 74213daf8786..95881f15324a 100644 --- a/tools/perf/util/capstone.c +++ b/tools/perf/util/capstone.c @@ -3,6 +3,7 @@ =20 #include #include +#include #include =20 #include @@ -31,6 +32,10 @@ #define CS_MODE_RISCVC 4 #endif =20 +#if CS_VERSION_MAJOR < 4 +#define ARM64_GRP_BRANCH_RELATIVE 7 /* =3D CS_GRP_BRANCH_RELATIVE */ +#endif + #ifdef LIBCAPSTONE_DLOPEN static void *perf_cs_dll_handle(void) { @@ -225,6 +230,12 @@ static int capstone_init(uint16_t e_machine, csh *cs_h= andle, bool is64, bool is_ * on x86 by investigating instruction details. */ perf_cs_option(*cs_handle, CS_OPT_DETAIL, CS_OPT_ON); + } else if (arch =3D=3D CS_ARCH_ARM64) { + /* + * Same as x86: arm64 needs instruction details to resolve + * symbolic addresses. + */ + perf_cs_option(*cs_handle, CS_OPT_DETAIL, CS_OPT_ON); } =20 return 0; @@ -292,6 +303,40 @@ ssize_t capstone__fprintf_insn_asm(struct machine *mac= hine, struct thread *threa return printed; } =20 +static struct symbol *find_symbol_from_addr(struct map *map, u64 addr, + struct map **found_map, u64 *sym_offset) +{ + struct symbol *sym; + u64 al_addr; + u64 ip =3D map__objdump_2mem(map, addr); + + *found_map =3D NULL; + if (dso__kernel(map__dso(map))) { + /* + * The kernel maps can be split into sections, let's + * find the map first and then search the symbol. + */ + *found_map =3D maps__find(map__kmaps(map), ip); + if (*found_map =3D=3D NULL) + return NULL; + map =3D *found_map; + } + + /* convert it to map-relative address for search */ + al_addr =3D map__map_ip(map, ip); + + sym =3D map__find_symbol(map, al_addr); + + if (sym =3D=3D NULL) { + map__put(*found_map); + *found_map =3D NULL; + return NULL; + } + + *sym_offset =3D al_addr - sym->start; + return sym; +} + static void print_capstone_detail(struct cs_insn *insn, char *buf, size_t = len, struct annotate_args *args, u64 addr) { @@ -299,17 +344,14 @@ static void print_capstone_detail(struct cs_insn *ins= n, char *buf, size_t len, struct map *map =3D args->ms->map; struct symbol *sym; =20 - /* TODO: support more architectures */ - if (!arch__is_x86(args->arch)) - return; - if (insn->detail =3D=3D NULL) return; =20 for (i =3D 0; i < insn->detail->x86.op_count; i++) { struct cs_x86_op *op =3D &insn->detail->x86.operands[i]; u64 orig_addr; - struct map *found_map =3D NULL; + struct map *found_map; + u64 sym_offset; =20 if (op->type !=3D X86_OP_MEM) continue; @@ -320,40 +362,119 @@ static void print_capstone_detail(struct cs_insn *in= sn, char *buf, size_t len, =20 /* get the target address */ orig_addr =3D addr + insn->size + op->mem.disp; - addr =3D map__objdump_2mem(map, orig_addr); - - if (dso__kernel(map__dso(map))) { - /* - * The kernel maps can be split into sections, let's - * find the map first and then search the symbol. - */ - found_map =3D maps__find(map__kmaps(map), addr); - if (found_map =3D=3D NULL) - continue; - map =3D found_map; - } - - /* convert it to map-relative address for search */ - addr =3D map__map_ip(map, addr); - - sym =3D map__find_symbol(map, addr); - if (sym =3D=3D NULL) { - map__put(found_map); + sym =3D find_symbol_from_addr(map, orig_addr, &found_map, &sym_offset); + if (sym =3D=3D NULL) continue; - } =20 - if (addr =3D=3D sym->start) { + if (sym_offset =3D=3D 0) { scnprintf(buf, len, "\t# %"PRIx64" <%s>", orig_addr, sym->name); } else { scnprintf(buf, len, "\t# %"PRIx64" <%s+%#"PRIx64">", - orig_addr, sym->name, addr - sym->start); + orig_addr, sym->name, sym_offset); } map__put(found_map); break; } } =20 +static int print_default_format(struct cs_insn *insn, char *buf, size_t le= n) +{ + return scnprintf(buf, len, " %-7s %s", + insn->mnemonic, insn->op_str); +} + +static void format_capstone_insn_x86(struct cs_insn *insn, char *buf, + size_t len, struct annotate_args *args, + u64 addr) +{ + int printed; + + printed =3D print_default_format(insn, buf, len); + buf +=3D printed; + len -=3D printed; + + print_capstone_detail(insn, buf, len, args, addr); +} + +static bool needs_symbolic_address(struct cs_insn *insn) +{ + int i; + + if (insn->id =3D=3D ARM64_INS_ADR || insn->id =3D=3D ARM64_INS_ADRP) + return true; + + if (insn->detail =3D=3D NULL) + return false; + + for (i =3D 0; i < insn->detail->groups_count; i++) { + if (insn->detail->groups[i] =3D=3D ARM64_GRP_JUMP || + insn->detail->groups[i] =3D=3D ARM64_GRP_CALL || + insn->detail->groups[i] =3D=3D ARM64_GRP_BRANCH_RELATIVE) + return true; + } + + return false; +} + +static void format_capstone_insn_arm64(struct cs_insn *insn, char *buf, + size_t len, struct annotate_args *args) +{ + struct map *map =3D args->ms->map; + char *last_imm, *endptr; + u64 addr; + + print_default_format(insn, buf, len); + /* + * Adjust instructions to keep the existing behavior with objdump. + * + * Example conversion: + * From: b #0xffff8000800114c8 + * To: b ffff8000800114c8 + */ + if (needs_symbolic_address(insn)) { + struct symbol *sym; + struct map *found_map; + u64 sym_offset; + + /* Extract last immediate value as address */ + last_imm =3D strrchr(buf, '#'); + if (!last_imm) + return; + + addr =3D strtoull(last_imm + 1, &endptr, 16); + if (endptr =3D=3D last_imm + 1) + return; + + sym =3D find_symbol_from_addr(map, addr, &found_map, &sym_offset); + if (sym =3D=3D NULL) + return; + + /* Symbolize the resolved address */ + len =3D len - (last_imm - buf); + if (sym_offset =3D=3D 0) { + scnprintf(last_imm, len, "%"PRIx64" <%s>", + addr, sym->name); + } else { + scnprintf(last_imm, len, "%"PRIx64" <%s+%#"PRIx64">", + addr, sym->name, sym_offset); + } + map__put(found_map); + } +} + +static void format_capstone_insn(struct cs_insn *insn, char *buf, size_t l= en, + struct annotate_args *args, u64 addr) +{ + /* TODO: support more architectures */ + if (arch__is_x86(args->arch)) + format_capstone_insn_x86(insn, buf, len, args, addr); + else if (arch__is_arm64(args->arch)) + format_capstone_insn_arm64(insn, buf, len, args); + else + print_default_format(insn, buf, len); +} + struct find_file_offset_data { u64 ip; u64 offset; @@ -446,14 +567,9 @@ int symbol__disassemble_capstone(const char *filename,= struct symbol *sym, =20 free_count =3D count =3D perf_cs_disasm(handle, buf, buf_len, start, buf_= len, &insn); for (i =3D 0, offset =3D 0; i < count; i++) { - int printed; - - printed =3D scnprintf(disasm_buf, sizeof(disasm_buf), - " %-7s %s", - insn[i].mnemonic, insn[i].op_str); - print_capstone_detail(&insn[i], disasm_buf + printed, - sizeof(disasm_buf) - printed, args, - start + offset); + format_capstone_insn(&insn[i], disasm_buf, + sizeof(disasm_buf), args, + start + offset); =20 args->offset =3D offset; args->line =3D disasm_buf; diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 49c206a88eec..b39636ec35c1 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -214,6 +214,11 @@ bool arch__is_powerpc(const struct arch *arch) return arch->id.e_machine =3D=3D EM_PPC || arch->id.e_machine =3D=3D EM_P= PC64; } =20 +bool arch__is_arm64(const struct arch *arch) +{ + return arch->id.e_machine =3D=3D EM_AARCH64; +} + static void ins_ops__delete(struct ins_operands *ops) { if (ops =3D=3D NULL) diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h index adbdbf8f1f35..3a42166f7f49 100644 --- a/tools/perf/util/disasm.h +++ b/tools/perf/util/disasm.h @@ -111,6 +111,7 @@ struct annotate_args { const struct arch *arch__find(uint16_t e_machine, uint32_t e_flags, const = char *cpuid); bool arch__is_x86(const struct arch *arch); bool arch__is_powerpc(const struct arch *arch); +bool arch__is_arm64(const struct arch *arch); =20 extern const struct ins_ops call_ops; extern const struct ins_ops dec_ops; --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 226B7399CF5; Wed, 16 Sep 2026 01:30:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522217; cv=none; b=CpM6VJsA7jAgBLaUPSIM/9BBzOaSikJJhczFqj/MqLS5G7Wkl6/X8dt8PBfHBYRFiBGPsQe+8RfNwVBg2HNfz3U6BOI6NVs5tS9MhU4W1OWNeEZHLXVv7AVkosIvH24qUYimbhaneo2vecu19qkG7xCV5AemTEe07GgDdCEG1V0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522217; c=relaxed/simple; bh=L43fAWvi1JW9a7ix+z5PjQrdj7t6r8ko5qEIQZt4YE0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BdIcO9k/LRmNMWFGbmRtJPJaSy7GkU/0mwClVqVOAVDTmy18+N9+1/fkZDnZHyzNg8EpA/6REHkHgzJVl2Myvz4IAa+fzNuX+IPHvgikEcOtE09YbII8SquYi53SwCQ7CxPSR/a/Pedmb8EpW0PmFnhakLkiPxq3F5dUtMw3qQk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XH4ktPzKHMRS; Wed, 16 Sep 2026 09:29:51 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 2CF0640592; Wed, 16 Sep 2026 09:30:05 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S4; Wed, 16 Sep 2026 09:30:04 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 02/26] perf llvm: Fix arm64 adrp instruction disassembly mismatch with objdump Date: Wed, 16 Sep 2026 01:29:16 +0000 Message-Id: <63d15af66450065329b08f41794738c2e8c811ab.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S4 X-Coremail-Antispam: 1UD129KBjvJXoWxWryxGryUCF1fWF1rWw1xZrb_yoW5uF43pr ZFkayrXryUAr1fZ39IkF47WFn8trZ2gF4Yg3y3A3yvkr4xtFyxC34xGF129F1UXryqq3y5 CrWqvFyUGF1kArJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUHjb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUXw A2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxS w2x7M28EF7xvwVC0I7IYx2IY67AKxVW8JVW5JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxV W8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Cr1j6rxdM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7 xfMcIj6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Y z7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6x kF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r4a6rW5MxkF7I0Ew4C26cxK6c8Ij28IcwCF 04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r 18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_GFv_WrylIxkGc2Ij64vI r41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr 1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY 6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjTRQL00DUUUU X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" The operands of 'adrp' instructions parsed by libllvm are currently represented as raw immediates rather than the "address " format used by objdump. This inconsistency causes arm64_mov__parse() to fail when parsing these instructions during post-processing. Example of the mismatch: Current: adrp x18, 8014 Objdump: adrp x18, ffff800081f5f000 Fix this by manually extracting the target address from the raw adrp instruction via symbol_lookup_callback(). The address is then converted to a specific symbol during symbol__disassemble_llvm() and formatted to match objdump's output, ensuring compatibility with existing parsers. Reviewed-by: Namhyung Kim Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- tools/perf/util/llvm.c | 52 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/llvm.c b/tools/perf/util/llvm.c index a0deb742a733..a78845689aa1 100644 --- a/tools/perf/util/llvm.c +++ b/tools/perf/util/llvm.c @@ -9,8 +9,10 @@ #include "symbol.h" #include #include +#include #include #include +#include =20 #ifdef HAVE_LIBLLVM_SUPPORT #include "llvm-c-helpers.h" @@ -108,6 +110,16 @@ symbol_lookup_callback(void *disinfo, uint64_t value, storage->branch_addr =3D value; else if (*ref_type =3D=3D LLVMDisassembler_ReferenceType_In_PCrel_Load) storage->pcrel_load_addr =3D value; + else if (*ref_type =3D=3D LLVMDisassembler_ReferenceType_In_ARM64_ADRP) { + uint64_t adrp_imm; + + /* immhi (bits 23:5) and immlo (bits 30:29) */ + adrp_imm =3D ((value & 0x00ffffe0) >> 3) | ((value >> 29) & 0x3); + adrp_imm =3D sign_extend64(adrp_imm, 20); + + /* Calculate the target page address */ + storage->pcrel_load_addr =3D (address & ~0xfffULL) + (adrp_imm << 12); + } *ref_type =3D LLVMDisassembler_ReferenceType_InOut_None; return NULL; } @@ -228,12 +240,42 @@ int symbol__disassemble_llvm(const char *filename, st= ruct symbol *sym, } } if (storage.pcrel_load_addr !=3D 0) { - char *name =3D llvm_name_for_data(dso, filename, + char *name; + + if (arch__is_arm64(args->arch)) { + /* + * For arm64, replace the immediate operand with + * the resolved address to match objdump's output. + * + * Example conversion: + * From: adrp x18, 8014 + * To: adrp x18, ffff800081f5f000 + */ + char *s =3D strchr(disasm_buf, ','); + + if (s =3D=3D NULL) + goto err; + + s++; + *s =3D '\0'; + disasm_len =3D strlen(disasm_buf); + disasm_len +=3D scnprintf(disasm_buf + disasm_len, + sizeof(disasm_buf) - disasm_len, + " %"PRIx64, storage.pcrel_load_addr); - disasm_len +=3D scnprintf(disasm_buf + disasm_len, - sizeof(disasm_buf) - disasm_len, - " # %#"PRIx64, - storage.pcrel_load_addr); + } else { + /* + * For other archs, append the resolved address + * as an inline comment. + */ + disasm_len +=3D scnprintf(disasm_buf + disasm_len, + sizeof(disasm_buf) - disasm_len, + " # %#"PRIx64, + storage.pcrel_load_addr); + } + + /* Append the resolved symbol name if available */ + name =3D llvm_name_for_data(dso, filename, storage.pcrel_load_addr); if (name) { disasm_len +=3D scnprintf(disasm_buf + disasm_len, sizeof(disasm_buf) - --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2242439768C; Wed, 16 Sep 2026 01:30:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522220; cv=none; b=s63w3NLVlzt/p3IE5X2EHm+viOv00r6z+mCcez6rwbo1Dj234smS/SBCzSrhKJ+bCTrDTe2Y9djAnBT/bJaccPaYHDI4Tfr1KnPMT61XcBmn5L12VjY/cie4kMk8vTaTqpgeljGkPOxlykPpLH377AGGq8iD2/qoDDEebZwVKTg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522220; c=relaxed/simple; bh=eORo/K7+bPCpN41r7RwUQOgsKgu3StmNKrQyK2JsQfE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cnaL9NUXxJ1F617OPcli6335dVi0iRP9dOpGBfuNOJ97l94o09fB9ZDHBcVyZNF4EL3VLTlwmRPc8S3qTPoKg5N1vRMvJxiLvLdMsObo9ZC6SJUIVKH8bOyNw913FPuOYqS91BzOTRF0xsogyAB9A29U1a+LGrQgHCUNEScBvZI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.170]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XH4f7TzKHMQL; Wed, 16 Sep 2026 09:29:51 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 47E8D4056B; Wed, 16 Sep 2026 09:30:05 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S5; Wed, 16 Sep 2026 09:30:04 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 03/26] perf annotate-arm64: Generalize arm64_mov__parse to support more instructions Date: Wed, 16 Sep 2026 01:29:17 +0000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S5 X-Coremail-Antispam: 1UD129KBjvJXoWxtr1xurWfZFyfCw1kXw48Crg_yoWxJFW5pa n2kw1rtr48Wr1Fgws3Jrs2vrn3Ww4fK343ua48tas3Awsa9ryrKan3KF1akF4rGry8urWU tFnYvryrGr4DJaUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUHjb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUWw A2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxS w2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxV W8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Cr1j6rxdM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7 xfMcIj6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Y z7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6x kF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r4a6rW5MxkF7I0Ew4C26cxK6c8Ij28IcwCF 04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r 18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_GFv_WrylIxkGc2Ij64vI r41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr 1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY 6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjTRHpBaDUUUU X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" As the default parser for arm64 instructions, arm64_mov__parse() currently only supports parsing instructions with the 'addr ' suffix. Other instructions are not supported, causing a lack of source and target information for most regular instructions. Generalize arm64_mov__parse to extend its parsing capabilities: 1. Parse 'ops->target.raw' and 'ops->source.raw' by default. 2. Utilize arm64__check_multi_regs() to identify if source and target contain multiple registers. 3. Maintain backward compatibility for instructions containing the 'addr ' suffix. Reviewed-by: Namhyung Kim Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 166 ++++++++++++++---- 1 file changed, 134 insertions(+), 32 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index 33080fdca125..151184210691 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include #include "../annotate.h" @@ -14,59 +16,158 @@ struct arch_arm64 { regex_t jump_insn; }; =20 -static int arm64_mov__parse(const struct arch *arch __maybe_unused, +static bool arm64__is_reg(const char *op) +{ + if (!op || !*op) + return false; + + /* + * General-purpose registers: x0-x30, w0-w30. + * Check for 'x' or 'w' prefix followed by a numeric index. + */ + if ((op[0] =3D=3D 'x' || op[0] =3D=3D 'w') && isdigit(op[1])) + return true; + + /* Special-purpose registers: sp, wzr, xzr. */ + if (!strncmp(op, "sp", 2) || !strncmp(op, "xzr", 3) || + !strncmp(op, "wzr", 3)) + return true; + + /* TODO: Support more registers. */ + return false; +} + +static bool arm64__check_multi_regs(const struct arch *arch, const char *o= p) +{ + const char *p =3D op; + int reg_count =3D 0; + + while (p && *p) { + p =3D skip_spaces(p); + if (*p =3D=3D arch->objdump.memory_ref_char) + p++; + + if (arm64__is_reg(p)) + reg_count++; + + if (reg_count >=3D 2) + return true; + + /* Move to next operand after comma */ + p =3D strchr(p, ','); + if (p) + p++; + } + + return false; +} + +/* + * Duplicate @insn, stripping the comment and trailing whitespace. + * Returns a newly allocated string which the caller must free(), + * or NULL on allocation failure or if @insn is NULL. + */ +static char *rstrip_space_and_comment(const char *insn, char comment_char) +{ + const char *end, *comment; + size_t len; + char *result; + + if (insn =3D=3D NULL) + return NULL; + + comment =3D strchr(insn, comment_char); + if (comment !=3D NULL) + end =3D comment; + else + end =3D insn + strlen(insn); + + while (end > insn && isspace(end[-1])) + --end; + + len =3D end - insn; + result =3D malloc(len + 1); + if (result =3D=3D NULL) + return NULL; + + memcpy(result, insn, len); + result[len] =3D '\0'; + + return result; +} + +static int arm64_mov__parse(const struct arch *arch, struct ins_operands *ops, struct map_symbol *ms __maybe_unused, struct disasm_line *dl __maybe_unused) { - char *s =3D strchr(ops->raw, ','), *target, *endptr; + char *s =3D strchr(ops->raw, ','), *source, *endptr; =20 if (s =3D=3D NULL) return -1; =20 + /* Parse target */ *s =3D '\0'; - ops->source.raw =3D strdup(ops->raw); + ops->target.raw =3D strdup(ops->raw); *s =3D ','; =20 - if (ops->source.raw =3D=3D NULL) - return -1; - - target =3D ++s; - ops->target.raw =3D strdup(target); if (ops->target.raw =3D=3D NULL) - goto out_free_source; + return -1; =20 - ops->target.addr =3D strtoull(target, &endptr, 16); - if (endptr =3D=3D target) - goto out_free_target; + ops->target.multi_regs =3D arm64__check_multi_regs(arch, ops->target.raw); =20 - s =3D strchr(endptr, '<'); - if (s =3D=3D NULL) - goto out_free_target; - endptr =3D strchr(s + 1, '>'); - if (endptr =3D=3D NULL) - goto out_free_target; - - *endptr =3D '\0'; - *s =3D ' '; - ops->target.name =3D strdup(s); - *s =3D '<'; - *endptr =3D '>'; - if (ops->target.name =3D=3D NULL) - goto out_free_target; + /* Parse source, stripping comment if present */ + source =3D skip_spaces(++s); + ops->source.raw =3D rstrip_space_and_comment(source, arch->objdump.commen= t_char); + if (ops->source.raw =3D=3D NULL) { + zfree(&ops->target.raw); + return -1; + } + + ops->source.multi_regs =3D arm64__check_multi_regs(arch, ops->source.raw); + + /* + * Parse 'addr ' from source (if any). + * + * A raw hex string may be a scalar immediate, not an address. + * Only validate 'source.addr' if accompanied by a '' tag, + * otherwise reset it to 0 to avoid false positive address tracking. + */ + ops->source.addr =3D strtoull(ops->source.raw, &endptr, 16); + if (endptr !=3D ops->source.raw) { + s =3D strchr(endptr, '<'); + if (s =3D=3D NULL) { + ops->source.addr =3D 0; + return 0; + } + endptr =3D strrchr(s + 1, '>'); + if (endptr =3D=3D NULL) { + ops->source.addr =3D 0; + return 0; + } + + *endptr =3D '\0'; + ops->source.name =3D strdup(s + 1); + *endptr =3D '>'; + if (ops->source.name =3D=3D NULL) { + ops->source.addr =3D 0; + return 0; + } + } =20 return 0; +} =20 -out_free_target: - zfree(&ops->target.raw); -out_free_source: - zfree(&ops->source.raw); - return -1; +static int arm64_mov__scnprintf(const struct ins *ins, char *bf, size_t si= ze, + struct ins_operands *ops, int max_ins_name) +{ + return scnprintf(bf, size, "%-*s %s, %s", max_ins_name, ins->name, + ops->target.raw, ops->source.name ?: ops->source.raw); } =20 static const struct ins_ops arm64_mov_ops =3D { .parse =3D arm64_mov__parse, - .scnprintf =3D mov__scnprintf, + .scnprintf =3D arm64_mov__scnprintf, }; =20 static const struct ins_ops *arm64__associate_instruction_ops(struct arch = *arch, const char *name) @@ -103,6 +204,7 @@ const struct arch *arch__new_arm64(const struct e_machi= ne_and_e_flags *id, arch->id =3D *id; arch->objdump.comment_char =3D '/'; arch->objdump.skip_functions_char =3D '+'; + arch->objdump.memory_ref_char =3D '['; arch->associate_instruction_ops =3D arm64__associate_instruction_ops; =20 /* bl, blr */ --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3094C396560; Wed, 16 Sep 2026 01:30:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522218; cv=none; b=J/cY0VMHMzB2h/4bg/O+XrOwATpjsut1/JkXW6U9yad8t5Js4jwD8qjg7OZsgIY9izrueqjx9ci2m55bSoIUqMFnqLIIqiWmD3bLBQNnVOFf4k29cloM4Iq+3Oe/QYD9lTtA8+rDRnPcVpySrsz5h9vsKNXllb9glU+mhyu3ViM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522218; c=relaxed/simple; bh=wI1r5lukNDX/+mrcclvo6bXateMUR8gdKy2BVAVQSrg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Fy5OSsAThrguLeqSzofAc7Wqg4HGEmSPMU4e3lg/ml+bj+X9QktHtZTmYQNwRW09hcjPkRutT2Pbp2hgDzwD+fX7dcRJrOo94AosThoJwQ9o1tGgj8EuinPcEF/gtFJDEaVT9mpdmpHy/S4DfPMmZQGF9N07OoR6CA5fxAwi0MQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.170]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XH4mPJzKHMRk; Wed, 16 Sep 2026 09:29:51 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 4C1394056F; Wed, 16 Sep 2026 09:30:05 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S6; Wed, 16 Sep 2026 09:30:04 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 04/26] perf annotate-arm64: Handle load and store instructions Date: Wed, 16 Sep 2026 01:29:18 +0000 Message-Id: <4f8af3313ac79cfe91132089ce1da8b8a69bd9f5.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S6 X-Coremail-Antispam: 1UD129KBjvJXoW3XF4rXr15Xr4xurW5Gry7GFg_yoWxXw18pa 92k345tr42qr4rW3WftF4kZ34fGa18Ja4a9ry8Jwn3Ca1avryxtFn5Kr12kFs8Grykur43 XFn0vry0vF98A3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUHIb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_Cr1j6rxdM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F4 0Ex7xfMcIj6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC 6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI 8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r4a6rW5MxkF7I0Ew4C26cxK6c8Ij28I cwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r 1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_GFv_WrylIxkGc2Ij 64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr 1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1l IxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0piPkusUUU UU= X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Add ldst_ops to handle load and store instructions in order to parse the data types and offsets associated with PMU events for memory access instructions. There are many variants of load and store instructions in arm64, making it difficult to match all of these instruction names completely. Therefore, only the instruction prefixes are matched. The prefix 'ld|st' covers most of the memory access instructions, 'cas|swp' matches atomic instructions, and 'prf' matches memory prefetch instructions. Reviewed-by: Namhyung Kim Signed-off-by: Li Huafei Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index 151184210691..a7595a954cfa 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -14,6 +14,7 @@ struct arch_arm64 { struct arch arch; regex_t call_insn; regex_t jump_insn; + regex_t ldst_insn; /* load and store instruction */ }; =20 static bool arm64__is_reg(const char *op) @@ -170,6 +171,130 @@ static const struct ins_ops arm64_mov_ops =3D { .scnprintf =3D arm64_mov__scnprintf, }; =20 +static bool arm64__insn_is_target_on_right(const char *ins_name) +{ + /* + * Store instructions write to the memory operand on the right, + * unlike standard syntax where the target is the left operand. + */ + return !strncmp(ins_name, "st", 2); +} + +/* + * This function is used to parse arm64 load/store instructions into + * instruction operands. + * + * Typical instructions and their parsing logic: + * + * 1. Immediate offset: + * ldr x2, [x0] -> target=3D"x2", source=3D"[x0]" + * ldr x2, [x0, #24] -> target=3D"x2", source=3D"[x0, #24]" + * ldp x19, x20, [sp, #16] -> target=3D"x19, x20", source=3D"[sp,= #16]" + * + * 2. Pre-index addressing: + * stp x29, x30, [sp, #-64]! -> target=3D"[sp, #-64]!", source=3D"x= 29, x30" + * + * 3. Post-index addressing: + * str x1, [x0], #8 -> target=3D"[x0], #8", source=3D"x1" + * ldr w1, [x21], #4 -> target=3D"w1", source=3D"[x21], #4" + * ldp x29, x30, [sp], #32 -> target=3D"x29, x30", source=3D"[sp]= , #32" + * + * 4. Register offset / extension: + * ldr x0, [x1, w0, sxtw #3] -> target=3D"x0", source=3D"[x1, w0, s= xtw #3]" + * ldr x0, [x1, x0, lsl #3] -> target=3D"x0", source=3D"[x1, x0, l= sl #3]" + * + * 5. Atomic operations: + * cas w3, w1, [x0] -> target=3D"w3, w1", source=3D"[x0]" + * swp x3, x0, [x2] -> target=3D"x3, x0", source=3D"[x2]" + * + * 6. Prefetch memory: + * prfm pstl1strm, [x4] -> target=3D"pstl1strm", source=3D"[x4= ]" + * + * 7. PC-relative loads (No bracket found): + * ldr x0, ffff800080f40c68 <__kvm_nvhe_$d> -> Fallback to default p= arser + * + * Parsing strategy: + * Use the '[' bracket as the boundary to split the operands into left + * and right sides. For non-store instructions, the left side is the + * target and the right side is the source. For store instructions, the + * roles are reversed. + */ +static int arm64_ldst__parse(const struct arch *arch, struct ins_operands = *ops, + struct map_symbol *ms, struct disasm_line *dl) +{ + char *raw, *s, *left, *right; + int ret =3D -1; + + raw =3D rstrip_space_and_comment(ops->raw, arch->objdump.comment_char); + if (!raw) + return -1; + + s =3D strchr(raw, arch->objdump.memory_ref_char); + if (!s) { + /* Fallback to default parser for PC-relative loads. */ + free(raw); + return arm64_mov__parse(arch, ops, ms, dl); + } + + right =3D strdup(s); + if (!right) + goto out_free_raw; + + while (s > raw && *s !=3D ',') + --s; + + if (s =3D=3D raw) + goto out_free_right; + + *s =3D '\0'; + left =3D strdup(raw); + *s =3D ','; + if (!left) + goto out_free_right; + + free(raw); + + if (arm64__insn_is_target_on_right(dl->ins.name)) { + ops->source.raw =3D left; + ops->source.mem_ref =3D false; + + ops->target.raw =3D right; + ops->target.mem_ref =3D true; + } else { + ops->source.raw =3D right; + ops->source.mem_ref =3D true; + + ops->target.raw =3D left; + ops->target.mem_ref =3D false; + } + + ops->source.multi_regs =3D arm64__check_multi_regs(arch, ops->source.raw); + ops->target.multi_regs =3D arm64__check_multi_regs(arch, ops->target.raw); + + return 0; + +out_free_right: + free(right); +out_free_raw: + free(raw); + return ret; +} + +static int arm64_ldst__scnprintf(const struct ins *ins, char *bf, size_t s= ize, + struct ins_operands *ops, int max_ins_name) +{ + if (arm64__insn_is_target_on_right(ins->name)) + return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->raw); + + return scnprintf(bf, size, "%-*s %s, %s", max_ins_name, ins->name, + ops->target.raw, ops->source.name ?: ops->source.raw); +} + +static struct ins_ops arm64_ldst_ops =3D { + .parse =3D arm64_ldst__parse, + .scnprintf =3D arm64_ldst__scnprintf, +}; + static const struct ins_ops *arm64__associate_instruction_ops(struct arch = *arch, const char *name) { struct arch_arm64 *arm =3D container_of(arch, struct arch_arm64, arch); @@ -180,6 +305,8 @@ static const struct ins_ops *arm64__associate_instructi= on_ops(struct arch *arch, ops =3D &jump_ops; else if (!regexec(&arm->call_insn, name, 2, match, 0)) ops =3D &call_ops; + else if (!regexec(&arm->ldst_insn, name, 2, match, 0)) + ops =3D &arm64_ldst_ops; else if (!strcmp(name, "ret")) ops =3D &ret_ops; else @@ -205,6 +332,7 @@ const struct arch *arch__new_arm64(const struct e_machi= ne_and_e_flags *id, arch->objdump.comment_char =3D '/'; arch->objdump.skip_functions_char =3D '+'; arch->objdump.memory_ref_char =3D '['; + arch->objdump.imm_char =3D '#'; arch->associate_instruction_ops =3D arm64__associate_instruction_ops; =20 /* bl, blr */ @@ -218,8 +346,20 @@ const struct arch *arch__new_arm64(const struct e_mach= ine_and_e_flags *id, if (err) goto out_free_call; =20 + /* + * The ARM64 architecture has many variants of load/store instructions. + * It is quite challenging to match all of them completely. Here, we + * only match the prefixes of these instructions. + */ + err =3D regcomp(&arm->ldst_insn, "^(ld|st|cas|prf|swp)", + REG_EXTENDED); + if (err) + goto out_free_jump; + return arch; =20 +out_free_jump: + regfree(&arm->jump_insn); out_free_call: regfree(&arm->call_insn); out_free_arm: --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 410A739A062; Wed, 16 Sep 2026 01:30:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522219; cv=none; b=sUB/IgxJuBgfIm7t9P3OEP/ANbYz6MY3J/Olpa7xMTxPRTZ/WGYnADXS7TtO4XMRszhOO+zNyLDU4fFAsqoYPbZhKt8Osl4dOMNpCcz8B/r00hyQNlG1zf+TozgxxfekLUz8e3MLEPMCortJ7jFMq/4q50fls9cERRZ2QbjtQwY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522219; c=relaxed/simple; bh=u6EvwHcWFSDjqpjAM3ITHpvzxG0l1AwAuTRpQH5rjsE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=I6k74xz20uGGtXlar+0L5iA3aWWIp1wzhTh3HtoQvK2JRyoqbF0osDj9xP5saK/di87ExfuZcQJZH1XumavCi1pdCjULTWuIp1v8yTs+s20+ng0RRPDagtZOOXUDY2Zg+jDA5pArri/p/0VDMKfP+VVmDXW4QCE/uLbN32uO+cI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XT2Qb4zYQtpK; Wed, 16 Sep 2026 09:30:01 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 7026B4057C; Wed, 16 Sep 2026 09:30:05 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S7; Wed, 16 Sep 2026 09:30:04 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 05/26] perf annotate: Normalize arch__dwarf_regnum() error return values Date: Wed, 16 Sep 2026 01:29:19 +0000 Message-Id: <0c35645aec74e08df0c64470f40e45647451b876.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S7 X-Coremail-Antispam: 1UD129KBjvdXoWrKw1rAr1kKw4xtryUtr4xWFg_yoWDZrc_u3 WIyF1Utr48ArZ2yas2kFWfuryfJFy5ArWxW34Uta13ua4fGr15tFWDArZYk3yrWa1UKr9I yw1kXr4xZr4UujkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT 9fnUUIcSsGvfJTRUUUblxYFVCjjxCrM7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20E Y4v20xvaj40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s 0DM28IrcIa0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r4UJVWxJr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x02 67AKxVWxJr0_GcWle2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" arch__dwarf_regnum() returns inconsistent error values: early path returns -1 while the main lookup returns -ENOENT/-EINVAL from get_dwarf_regnum(). Callers only check for -1, so genuine failures can slip through. Normalize all failures to -1 to match the callers' expectation. Suggested-by: Shuai Xue Reviewed-by: Ian Rogers Reviewed-by: Namhyung Kim Signed-off-by: Tengda Wu --- tools/perf/util/annotate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index fd789eb53e74..b0f8a8d37333 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2600,7 +2600,7 @@ static int arch__dwarf_regnum(const struct arch *arch= , const char *str) =20 reg =3D get_dwarf_regnum(regname, arch->id.e_machine, arch->id.e_flags); free(regname); - return reg; + return reg < 0 ? -1 : reg; } =20 /* --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4113339A079; Wed, 16 Sep 2026 01:30:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522221; cv=none; b=LIV9VbtN7hniDG1fMWfx8/QiNbhBMNbzcWYGJ53As9PJbKwzYZIoEWkxaS9k+ZkbAhglmF6xR9D0+6+0TNwMlD7kItKgvhaSHCUOJGMrSu94y2+w2+yVWpI2M8TfjIqtT0VTXgDEczrMr870PbiRpmNr5Fqagwn/hg1ZaMaFhvs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522221; c=relaxed/simple; bh=Dhx3hnjwKiiS2Yil9+J4DZRTudq9W0jw18hCA64LhIU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KfjFuKLgFrA4DwePBu4KaCBvxFVVY0MQG4EZMTTTEFDuAKm4s7745WYiE5047OL8p26iyZ9/zOZ8ihgQgtSXgfz3ZtdNLPacNky5w9XBJtmfLKIpkgAMcDKyjJxAWdxPmQdl2+6RUqgqKe6IA8PgfqWxp9Wki6kuS/0WVy3t+a0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XT3DSMzYQtmy; Wed, 16 Sep 2026 09:30:01 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 89D904057A; Wed, 16 Sep 2026 09:30:05 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S8; Wed, 16 Sep 2026 09:30:05 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 06/26] perf annotate: Introduce extract_op_location callback for arch-specific parsing Date: Wed, 16 Sep 2026 01:29:20 +0000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S8 X-Coremail-Antispam: 1UD129KBjvJXoWxtr13tF45uFy8Wr1kuw1xZrb_yoWfKF4xpw 4Du34YyF1rKr4YgwsxXFs5W3Wakw4rWF1Y9r17KwsrAFn2vrn5Jan2gF1ayF1rJrZ5ur1j vF4qvr48XryrGaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUHIb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_Cr1j6rxdM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F4 0Ex7xfMcIj6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC 6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI 8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r4a6rW5MxkF7I0Ew4C26cxK6c8Ij28I cwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r 1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_GFv_WrylIxkGc2Ij 64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr 1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1l IxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0piPkusUUU UU= X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Assembly syntax for operands varies significantly across different architectures, which prevents the operand location (op_loc) parsing logic in annotate_get_insn_location() from being directly reused. To simplify the core logic and improve maintainability, move the operand parsing inside the for_each_insn_op_loc loop into arch-specific extract_op_location callbacks. This refactoring is intended to be a cleanup with no functional changes. Reviewed-by: Namhyung Kim Signed-off-by: Li Huafei Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../util/annotate-arch/annotate-powerpc.c | 9 ++ tools/perf/util/annotate-arch/annotate-x86.c | 79 ++++++++++++++++ tools/perf/util/annotate.c | 94 +------------------ tools/perf/util/annotate.h | 2 + tools/perf/util/disasm.h | 4 + 5 files changed, 99 insertions(+), 89 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-powerpc.c b/tools/perf/= util/annotate-arch/annotate-powerpc.c index 218207b52581..00b93296fc94 100644 --- a/tools/perf/util/annotate-arch/annotate-powerpc.c +++ b/tools/perf/util/annotate-arch/annotate-powerpc.c @@ -390,6 +390,14 @@ static void update_insn_state_powerpc(struct type_stat= e *state, } #endif /* HAVE_LIBDW_SUPPORT */ =20 +static void extract_op_location_powerpc(const struct arch *arch __maybe_un= used, + struct disasm_line *dl, + const char *op_str __maybe_unused, int op_idx, + struct annotated_op_loc *op_loc) +{ + get_powerpc_regs(dl->raw.raw_insn, !op_idx, op_loc); +} + const struct arch *arch__new_powerpc(const struct e_machine_and_e_flags *i= d, const char *cpuid __maybe_unused) { @@ -406,5 +414,6 @@ const struct arch *arch__new_powerpc(const struct e_mac= hine_and_e_flags *id, #ifdef HAVE_LIBDW_SUPPORT arch->update_insn_state =3D update_insn_state_powerpc; #endif + arch->extract_op_location =3D extract_op_location_powerpc; return arch; } diff --git a/tools/perf/util/annotate-arch/annotate-x86.c b/tools/perf/util= /annotate-arch/annotate-x86.c index 7e6136536393..1acf31a2c759 100644 --- a/tools/perf/util/annotate-arch/annotate-x86.c +++ b/tools/perf/util/annotate-arch/annotate-x86.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include +#include #include #include #include @@ -809,6 +811,82 @@ static void update_insn_state_x86(struct type_state *s= tate, } #endif =20 +/* + * Get register number and access offset from the given instruction. + * It assumes AT&T x86 asm format like OFFSET(REG). + * Fills @reg and @offset when return 0. + */ +static int extract_reg_offset(const struct arch *arch, const char *str, + struct annotated_op_loc *op_loc) +{ + char *p; + + if (arch->objdump.register_char =3D=3D 0) + return -1; + + /* + * It should start from offset, but it's possible to skip 0 + * in the asm. So 0(%rax) should be same as (%rax). + * + * However, it also start with a segment select register like + * %gs:0x18(%rbx). In that case it should skip the part. + */ + if (*str =3D=3D arch->objdump.register_char) { + /* FIXME: Handle other segment registers */ + if (!strncmp(str, "%gs:", 4)) + op_loc->segment =3D INSN_SEG_X86_GS; + + while (*str && !isdigit(*str) && + *str !=3D arch->objdump.memory_ref_char) + str++; + } + + op_loc->offset =3D strtol(str, &p, 0); + op_loc->reg1 =3D arch__dwarf_regnum(arch, p); + if (op_loc->reg1 =3D=3D -1) + return -1; + + /* Get the second register */ + if (op_loc->multi_regs) + op_loc->reg2 =3D arch__dwarf_regnum(arch, p + 1); + + return 0; +} + +static void extract_op_location_x86(const struct arch *arch, + struct disasm_line *dl __maybe_unused, + const char *op_str, int op_idx __maybe_unused, + struct annotated_op_loc *op_loc) +{ + if (op_str =3D=3D NULL) + return; + + if (strchr(op_str, arch->objdump.memory_ref_char)) { + op_loc->mem_ref =3D true; + extract_reg_offset(arch, op_str, op_loc); + } else { + const char *s =3D op_str; + char *p =3D NULL; + + /* FIXME: Handle other segment registers */ + if (!strncmp(op_str, "%gs:", 4)) { + op_loc->segment =3D INSN_SEG_X86_GS; + op_loc->offset =3D strtol(op_str + 4, &p, 0); + if (p && p !=3D op_str + 4) + op_loc->imm =3D true; + return; + } + + if (*s =3D=3D arch->objdump.register_char) { + op_loc->reg1 =3D arch__dwarf_regnum(arch, s); + } else if (*s =3D=3D arch->objdump.imm_char) { + op_loc->offset =3D strtol(s + 1, &p, 0); + if (p && p !=3D s + 1) + op_loc->imm =3D true; + } + } +} + const struct arch *arch__new_x86(const struct e_machine_and_e_flags *id, c= onst char *cpuid) { struct arch *arch =3D zalloc(sizeof(*arch)); @@ -848,5 +926,6 @@ const struct arch *arch__new_x86(const struct e_machine= _and_e_flags *id, const c #ifdef HAVE_LIBDW_SUPPORT arch->update_insn_state =3D update_insn_state_x86; #endif + arch->extract_op_location =3D extract_op_location_x86; return arch; } diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index b0f8a8d37333..d3482eba9283 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2580,7 +2580,7 @@ int annotate_check_args(void) return 0; } =20 -static int arch__dwarf_regnum(const struct arch *arch, const char *str) +int arch__dwarf_regnum(const struct arch *arch, const char *str) { const char *p; char *regname, *q; @@ -2603,51 +2603,6 @@ static int arch__dwarf_regnum(const struct arch *arc= h, const char *str) return reg < 0 ? -1 : reg; } =20 -/* - * Get register number and access offset from the given instruction. - * It assumes AT&T x86 asm format like OFFSET(REG). Maybe it needs - * to revisit the format when it handles different architecture. - * Fills @reg and @offset when return 0. - */ -static int extract_reg_offset(const struct arch *arch, const char *str, - struct annotated_op_loc *op_loc) -{ - char *p; - - if (arch->objdump.register_char =3D=3D 0) - return -1; - - /* - * It should start from offset, but it's possible to skip 0 - * in the asm. So 0(%rax) should be same as (%rax). - * - * However, it also start with a segment select register like - * %gs:0x18(%rbx). In that case it should skip the part. - */ - if (*str =3D=3D arch->objdump.register_char) { - if (arch__is_x86(arch)) { - /* FIXME: Handle other segment registers */ - if (!strncmp(str, "%gs:", 4)) - op_loc->segment =3D INSN_SEG_X86_GS; - } - - while (*str && !isdigit(*str) && - *str !=3D arch->objdump.memory_ref_char) - str++; - } - - op_loc->offset =3D strtol(str, &p, 0); - op_loc->reg1 =3D arch__dwarf_regnum(arch, p); - if (op_loc->reg1 =3D=3D -1) - return -1; - - /* Get the second register */ - if (op_loc->multi_regs) - op_loc->reg2 =3D arch__dwarf_regnum(arch, p + 1); - - return 0; -} - /** * annotate_get_insn_location - Get location of instruction * @arch: the architecture info @@ -2703,50 +2658,11 @@ int annotate_get_insn_location(const struct arch *a= rch, struct disasm_line *dl, /* Invalidate the register by default */ op_loc->reg1 =3D -1; op_loc->reg2 =3D -1; + op_loc->mem_ref =3D mem_ref; + op_loc->multi_regs =3D multi_regs; =20 - if (insn_str =3D=3D NULL) { - if (!arch__is_powerpc(arch)) - continue; - } - - /* - * For powerpc, call get_powerpc_regs function which extracts the - * required fields for op_loc, ie reg1, reg2, offset from the - * raw instruction. - */ - if (arch__is_powerpc(arch)) { - op_loc->mem_ref =3D mem_ref; - op_loc->multi_regs =3D multi_regs; - get_powerpc_regs(dl->raw.raw_insn, !i, op_loc); - } else if (strchr(insn_str, arch->objdump.memory_ref_char)) { - op_loc->mem_ref =3D true; - op_loc->multi_regs =3D multi_regs; - extract_reg_offset(arch, insn_str, op_loc); - } else { - const char *s =3D insn_str; - char *p =3D NULL; - - if (arch__is_x86(arch)) { - /* FIXME: Handle other segment registers */ - if (!strncmp(insn_str, "%gs:", 4)) { - op_loc->segment =3D INSN_SEG_X86_GS; - op_loc->offset =3D strtol(insn_str + 4, - &p, 0); - if (p && p !=3D insn_str + 4) - op_loc->imm =3D true; - continue; - } - } - - if (*s =3D=3D arch->objdump.register_char) { - op_loc->reg1 =3D arch__dwarf_regnum(arch, s); - } - else if (*s =3D=3D arch->objdump.imm_char) { - op_loc->offset =3D strtol(s + 1, &p, 0); - if (p && p !=3D s + 1) - op_loc->imm =3D true; - } - } + if (arch->extract_op_location) + arch->extract_op_location(arch, dl, insn_str, i, op_loc); } =20 return 0; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 4c49d41e73a4..6cd3ef537564 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -524,6 +524,8 @@ int annotate_parse_percent_type(const struct option *op= t, const char *_str, =20 int annotate_check_args(void); =20 +int arch__dwarf_regnum(const struct arch *arch, const char *str); + /** * struct annotated_op_loc - Location info of instruction operand * @reg1: First register in the operand diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h index 3a42166f7f49..7a1c889f2c50 100644 --- a/tools/perf/util/disasm.h +++ b/tools/perf/util/disasm.h @@ -16,6 +16,7 @@ struct symbol; struct data_loc_info; struct type_state; struct disasm_line; +struct annotated_op_loc; =20 struct e_machine_and_e_flags { uint32_t e_flags; @@ -49,6 +50,9 @@ struct arch { struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl); #endif + void (*extract_op_location)(const struct arch *arch, struct disasm_line = *dl, + const char *op_str, int op_idx, + struct annotated_op_loc *op_loc); }; =20 struct ins { --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 22600399CE9; Wed, 16 Sep 2026 01:30:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522218; cv=none; b=MDtBglo/C5VY9dW8aWJDu6nLBRGrzNkgDpkV8vGkHMtU4GbHzRUmQhfRkqeTtzXDa5s522MwYgjd+yf9WeNyTkoytkXYn5vIGThFHMJ6ibzsaoZ/ft7XfMonVqrkXn6tyh50w8Wyz4nOjP4wbAPa56PKqQOrd5PAqHwbKopkwlk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522218; c=relaxed/simple; bh=cTQCXfNsJnQxRRt5wUQR669eMPsgS6g+fsbp+0Iwjw8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tDKOAZC36jFnZHWccgysB9szBNQl89WvakvQdmuELpOKhpSNC++TYE646N5jbeKmOHaxYMWE3jh9/+PVK5dyrLrdsHZXbO9QDXSYlx7qiroB1oJz+xr7QYtV3fOkn2ff5TDW/vdoQFnzijqzrJNKY93INEQNIWxvIfArwZLjmSE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XJ0fdpzKHMSc; Wed, 16 Sep 2026 09:29:52 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id A65CA4058F; Wed, 16 Sep 2026 09:30:05 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S9; Wed, 16 Sep 2026 09:30:05 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 07/26] perf dwarf-regs: Adapt get_dwarf_regnum() for arm64 Date: Wed, 16 Sep 2026 01:29:21 +0000 Message-Id: <3115e9c4253d6710aa995a2052e5b73da395726b.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S9 X-Coremail-Antispam: 1UD129KBjvJXoWxAFyrCFWDtw43ur18AFWUurg_yoW5urW8pF sxC347Jr4UW3WYkwnxJF1IgF1rXw4rZr40yry0yw47CrsruF1UXw4ftr1Y9F45J3yDJw10 kayDKr18Gr1rJFJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUHIb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_Cr1j6rxdM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F4 0Ex7xfMcIj6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC 6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI 8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r4a6rW5MxkF7I0Ew4C26cxK6c8Ij28I cwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r 1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_GFv_WrylIxkGc2Ij 64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr 1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1l IxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0piPkusUUU UU= X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" The current arm64 DWARF register lookup relies on 'aarch64_regstr_tbl', a static string table. While this works for kprobe-tracer where register names start with '%', it is insufficient for parsing register numbers directly from raw instructions (e.g., extracting '6' from 'x6' or 'w6') during annotation. Since get_dwarf_regnum() is currently used only by 'perf annotate' and does not affect kprobe-tracer, replace the limited table-based lookup with a programmatic implementation in __get_dwarf_regnum_arm64(). This allows resolving arm64 register names (x0-x30, w0-w30, sp, etc.) directly into their corresponding DWARF register numbers. Reviewed-by: Namhyung Kim Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../util/dwarf-regs-arch/dwarf-regs-arm64.c | 25 +++++++++++++++++++ tools/perf/util/dwarf-regs.c | 2 +- tools/perf/util/include/dwarf-regs.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm64.c b/tools/per= f/util/dwarf-regs-arch/dwarf-regs-arm64.c index 593ca7d4fccc..425c8aa2e984 100644 --- a/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm64.c +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm64.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include +#include #include #include "../../../arch/arm64/include/uapi/asm/perf_regs.h" =20 @@ -10,3 +12,26 @@ int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_re= gnum) =20 return perf_regnum; } + +int __get_dwarf_regnum_arm64(const char *name) +{ + int reg; + + if (!strcmp(name, "sp")) + return 31; + + if (*name !=3D 'x' && *name !=3D 'w') + return -ENOENT; + + name++; + if (!isdigit(name[0])) + return -ENOENT; + else if (isdigit(name[1]) && name[2] =3D=3D '\0') + reg =3D (name[0] - '0') * 10 + name[1] - '0'; + else if (name[1] =3D=3D '\0') + reg =3D name[0] - '0'; + else + return -ENOENT; + + return reg >=3D 0 && reg <=3D 30 ? reg : -ENOENT; +} diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c index 67f38342247e..09aca6304002 100644 --- a/tools/perf/util/dwarf-regs.c +++ b/tools/perf/util/dwarf-regs.c @@ -114,7 +114,7 @@ int get_dwarf_regnum(const char *name, unsigned int mac= hine, unsigned int flags) reg =3D _get_dwarf_regnum(arm_regstr_tbl, name); break; case EM_AARCH64: - reg =3D _get_dwarf_regnum(aarch64_regstr_tbl, name); + reg =3D __get_dwarf_regnum_arm64(name); break; case EM_CSKY: reg =3D __get_csky_regnum(name, flags); diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include= /dwarf-regs.h index 92cf0af93e9e..1da915c2683a 100644 --- a/tools/perf/util/include/dwarf-regs.h +++ b/tools/perf/util/include/dwarf-regs.h @@ -105,6 +105,7 @@ int __get_dwarf_regnum_x86_64(const char *name); int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum); int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum, int abi); =20 +int __get_dwarf_regnum_arm64(const char *name); int __get_dwarf_regnum_for_perf_regnum_arm(int perf_regnum); int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_regnum); =20 --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F0AE939184C; Wed, 16 Sep 2026 01:30:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522222; cv=none; b=Fb7tFUe5MJbbBJJrLsXP52sihDcGMOBFLIZZ6MikwXlh9O8cRa9ZFeDo+WYiU7qtbrNGuvusxLTfyGAV3nn6O6PgSMgb8Pv8I/f59mTeSorYv+a8Ckg1CscFVvPCZovsCW6FQ6yx8pfyfxIoAaXzDe8euqxDcvCVb/49dxTzJjI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522222; c=relaxed/simple; bh=mQOEnFNDPytHbQQT9IAXpz28luodl7krkuFVgcN+Mng=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=U5Dge5up9UiXLgfOmKSKOILcfn8LmaVDjrMS0mU6eixix97WTmgHXXIG0Qw7fKeyrtNjG9G8Q5fFYnSeaoVVFaxuZkjwFvEXSZi0Pd7FVYfnnc5qdPvXf1Xpytkq9YIjUI1MNmUFu6GMlmT8zDKc98gKFGw7EUV+t/ZYcqfiCg0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XT4JzMzYQtp4; Wed, 16 Sep 2026 09:30:01 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id B429940576; Wed, 16 Sep 2026 09:30:05 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S10; Wed, 16 Sep 2026 09:30:05 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 08/26] perf annotate: Adapt arch__dwarf_regnum() for arm64 Date: Wed, 16 Sep 2026 01:29:22 +0000 Message-Id: <1f03970d9efc5195283158362873d1e445b4afe5.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S10 X-Coremail-Antispam: 1UD129KBjvJXoW7ury3uw48Cr47ZF1DGF1Utrb_yoW8CF1fpw 4xC343Ar10kr4FqwsxXFs3WFy3G3WfAa13uF1ktwn7Can7WryrJw4SyF1F9a13Ars7Jr1Y yr4qqw18WFnxCaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Currently, arch__dwarf_regnum() assumes that all architectures use a register prefix character (e.g., '%' for x86) defined by arch->objdump.register_char, and uses it to match register names in objdump output. However, this assumption does not hold for arm64, where assembly syntax uses bare register names like 'x0', 'w1' without any prefix. As a result, arm64 builds may fail to correctly recognize register names from objdump disassembly, leading to incomplete or incorrect annotation output. To address this: - Make the register prefix check optional, allowing architectures without a prefix character to be parsed correctly. - Extend the delimiter set in strpbrk() to include the closing square bracket ']'. In arm64 assembly, memory operands often use bracketed syntax such as '[x1, #16]' or '[x2]'. Adding ']' ensures clean extraction of register names like 'x2' without trailing characters. Reviewed-by: Namhyung Kim Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- tools/perf/util/annotate.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index d3482eba9283..86a4beec6528 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2582,19 +2582,21 @@ int annotate_check_args(void) =20 int arch__dwarf_regnum(const struct arch *arch, const char *str) { - const char *p; + const char *p =3D str; char *regname, *q; int reg; =20 - p =3D strchr(str, arch->objdump.register_char); - if (p =3D=3D NULL) - return -1; + if (arch->objdump.register_char) { + p =3D strchr(str, arch->objdump.register_char); + if (p =3D=3D NULL) + return -1; + } =20 regname =3D strdup(p); if (regname =3D=3D NULL) return -1; =20 - q =3D strpbrk(regname, ",) "); + q =3D strpbrk(regname, ",)] "); if (q) *q =3D '\0'; =20 --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD5BB3ACEE0; Wed, 16 Sep 2026 01:30:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522222; cv=none; b=u0tSSVpUnRjz/E9wOdRx5spAVxV2uDYcLfgonKsFhyBizCukYUZ/0+Lii4Aam90wD7+1HjW0cNLVtMtJWhEwJ4wz0jas+ocTBBcwbLg4KmqaqFOfpT1qymSk9UfBskzI0z/GN+U49yrerbuz+bQKUhB3B+eGpNl0Mr5Tpx+DR+s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522222; c=relaxed/simple; bh=F+tb4jFPXVYucjTKi8or58Nt3w6Jxx47TwjlWNG0AlE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gHpfkg9lKuvBv285JbhIQ5//oYuGgkN1dn54/Ryh+oHThhosAfp11eWuhjR7c7RiLZFsaRPx1SXvG/TpWqCkoieMW6qya6GXdbX6f08wU9G0r/VFbVDpC0aYBMXicucpHJ4m8RRx366D4AR8FrK9IzPgGgky9EWCdGVv1uqrUPQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XJ1lcgzKHMTD; Wed, 16 Sep 2026 09:29:52 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id CEB9B40592; Wed, 16 Sep 2026 09:30:05 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S11; Wed, 16 Sep 2026 09:30:05 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 09/26] perf annotate-arm64: Implement extract_op_location() callback Date: Wed, 16 Sep 2026 01:29:23 +0000 Message-Id: <7d425a8afe73f5684cf7baaffd2d5398f89f32a3.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S11 X-Coremail-Antispam: 1UD129KBjvJXoWxKF1kXw17Jr1UAFW3Ww4xCrg_yoW3Zr45pr 4Uu345tr1UJwsIqw4Svrs8WF15Cw4Ika4qgry3C3sIyFsavF1fX3Wxta4avFyrJrZxX34j yrs0vr48Xr17CaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Implement the extract_op_location() callback for the arm64 architecture to handle its specific assembly syntax and addressing modes. The extractor handles: 1. Immediate operands (e.g., '#0x10' or '#0xc600, lsl #16'). 2. Memory references with diverse addressing modes: - Signed offset: [base{, #imm|reg}] - Pre-index: [base, #imm]! - Post-index: [base], #imm|reg 3. Multi-register operands and primary/secondary register extraction. 4. Register extension specifiers (e.g., uxtw, sxtx) and shift amounts for shifted/extended operands. With this callback in place, 'perf annotate' can now resolve memory locations and register types on arm64, marking the initial enablement of data type profiling for this architecture. Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 133 ++++++++++++++++++ tools/perf/util/annotate.h | 61 ++++++++ 2 files changed, 194 insertions(+) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index a7595a954cfa..508a95d0ad4b 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -316,6 +316,138 @@ static const struct ins_ops *arm64__associate_instruc= tion_ops(struct arch *arch, return ops; } =20 +static enum annotated_ext_type arm64__check_ext_type(const char *op) +{ + if (!strncmp(op, "uxtb", 4)) return PERF_EXT_UXTB; + if (!strncmp(op, "uxth", 4)) return PERF_EXT_UXTH; + if (!strncmp(op, "uxtw", 4)) return PERF_EXT_UXTW; + if (!strncmp(op, "uxtx", 4)) return PERF_EXT_UXTX; + if (!strncmp(op, "sxtb", 4)) return PERF_EXT_SXTB; + if (!strncmp(op, "sxth", 4)) return PERF_EXT_SXTH; + if (!strncmp(op, "sxtw", 4)) return PERF_EXT_SXTW; + if (!strncmp(op, "sxtx", 4)) return PERF_EXT_SXTX; + + return PERF_EXT_NONE; +} + +static enum annotated_shift_type arm64__check_shift_type(const char *op) +{ + if (!strncmp(op, "lsl", 3)) return PERF_SHIFT_LSL; + if (!strncmp(op, "lsr", 3)) return PERF_SHIFT_LSR; + if (!strncmp(op, "asr", 3)) return PERF_SHIFT_ASR; + if (!strncmp(op, "ror", 3)) return PERF_SHIFT_ROR; + + return PERF_SHIFT_NONE; +} + +static const char *next_operand_field(const char *s) +{ + s =3D strchr(s, ','); + return s ? skip_spaces(s + 1) : NULL; +} + +static void extract_op_location_arm64(const struct arch *arch, + struct disasm_line *dl __maybe_unused, + const char *op_str, int op_idx __maybe_unused, + struct annotated_op_loc *op_loc) +{ + const char *s =3D op_str; + char *p =3D NULL; + + if (op_str =3D=3D NULL) + return; + + /* + * Handle immediate operand. + * e.g., "#0xc600" -> offset =3D 0xc600, imm =3D true + * + * After parsing, check for post-modifiers like "lsl #16", which + * typically occur in instructions such as movk, movz, movn, etc. + */ + if (*s =3D=3D arch->objdump.imm_char) { + op_loc->offset =3D strtol(s + 1, &p, 0); + if (p && p !=3D s + 1) { + op_loc->imm =3D true; + s =3D p; + } + s =3D next_operand_field(s); + goto check_modifiers; + } + + /* + * Handle memory references, identify arm64 specific addressing modes. + * Reference: Arm Architecture Reference Manual + * (DDI 0487), Chapter C1.3.3: Load/store addressing modes. + */ + if (*s =3D=3D arch->objdump.memory_ref_char) { + op_loc->mem_ref =3D true; + + p =3D strchr(s, ']'); + if (p =3D=3D NULL) + return; + + /* Pre-index: [base, #imm]! */ + if (p[1] =3D=3D '!') + op_loc->addr_mode =3D PERF_AAM_PRE_INDEX; + /* Post-index: [base], #imm|reg */ + else if (p[1] =3D=3D ',' && + (strchr(p + 1, arch->objdump.imm_char) || + arm64__is_reg(skip_spaces(p + 2)))) + op_loc->addr_mode =3D PERF_AAM_POST_INDEX; + /* Signed offset: [base{, #imm|reg}] */ + else + op_loc->addr_mode =3D PERF_AAM_SIGNED_OFFSET; + + s++; + } + + /* Extract the primary register */ + op_loc->reg1 =3D arch__dwarf_regnum(arch, s); + if (op_loc->reg1 =3D=3D -1) + return; + + s =3D next_operand_field(s); + if (s =3D=3D NULL) + return; + + /* Extract secondary register or immediate offset */ + if (op_loc->multi_regs) { + op_loc->reg2 =3D arch__dwarf_regnum(arch, s); + s =3D next_operand_field(s); + } else if (*s =3D=3D arch->objdump.imm_char) { + op_loc->offset =3D strtol(s + 1, NULL, 0); + s =3D next_operand_field(s); + } + +check_modifiers: + /* + * Look for a following shift or extension modifier: + * "lsl #3" -> extend_type =3D PERF_EXT_NONE, + * shift_type =3D PERF_SHIFT_LSL, amount =3D 3 + * "uxtw #3" -> extend_type =3D PERF_EXT_UXTW, + * shift_type =3D PERF_SHIFT_LSL, amount =3D 3 + * "uxtw" -> extend_type =3D PERF_EXT_UXTW, + * shift_type =3D PERF_SHIFT_LSL, amount =3D 0 + */ + if (s =3D=3D NULL) + return; + + op_loc->extend_type =3D arm64__check_ext_type(s); + op_loc->shift_type =3D arm64__check_shift_type(s); + /* ARM64 extended operands are implicitly shifted by LSL. */ + if (op_loc->extend_type !=3D PERF_EXT_NONE) + op_loc->shift_type =3D PERF_SHIFT_LSL; + + /* Parse shift amount if present */ + op_loc->amount =3D 0; + if (op_loc->extend_type !=3D PERF_EXT_NONE || + op_loc->shift_type !=3D PERF_SHIFT_NONE) { + s =3D strchr(s, arch->objdump.imm_char); + if (s) + op_loc->amount =3D (u8)strtol(s + 1, NULL, 0); + } +} + const struct arch *arch__new_arm64(const struct e_machine_and_e_flags *id, const char *cpuid __maybe_unused) { @@ -334,6 +466,7 @@ const struct arch *arch__new_arm64(const struct e_machi= ne_and_e_flags *id, arch->objdump.memory_ref_char =3D '['; arch->objdump.imm_char =3D '#'; arch->associate_instruction_ops =3D arm64__associate_instruction_ops; + arch->extract_op_location =3D extract_op_location_arm64; =20 /* bl, blr */ err =3D regcomp(&arm->call_insn, "^blr?$", REG_EXTENDED); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 6cd3ef537564..c528fbef8b38 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -532,6 +532,10 @@ int arch__dwarf_regnum(const struct arch *arch, const = char *str); * @reg2: Second register in the operand * @offset: Memory access offset in the operand * @segment: Segment selector register + * @addr_mode: Addressing mode, only valid if @mem_ref is true + * @extend_type: Operand extension type (enum annotated_ext_type) + * @shift_type: Operand shift type (enum annotated_shift_type) + * @amount: Number of bits to shift * @mem_ref: Whether the operand accesses memory * @multi_regs: Whether the second register is used * @imm: Whether the operand is an immediate value (in offset) @@ -541,6 +545,10 @@ struct annotated_op_loc { int reg2; int offset; u8 segment; + u8 addr_mode; + u8 extend_type; + u8 shift_type; + u8 amount; bool mem_ref; bool multi_regs; bool imm; @@ -564,6 +572,59 @@ enum annotated_x86_segment { INSN_SEG_X86_SS, }; =20 +/* + * ARM64 addressing modes for memory operations. + * + * [Xn, #imm] -> SIGNED_OFFSET (base + offset, base unchanged) + * [Xn, #imm]! -> PRE_INDEX (base +=3D offset, then access) + * [Xn], #imm -> POST_INDEX (access, then base +=3D offset) + */ +enum annotated_addr_mode { + PERF_AAM_NONE =3D 0, + + PERF_AAM_SIGNED_OFFSET, + PERF_AAM_PRE_INDEX, + PERF_AAM_POST_INDEX, +}; + +/* + * ARM64 register extension types. + * UXT* =3D zero-extend, SXT* =3D sign-extend. + * B=3D8bit, H=3D16bit, W=3D32bit, X=3D64bit. + * + * Example: UXTW =3D zero-extend 32-bit Wn to 64-bit Xn + */ +enum annotated_ext_type { + PERF_EXT_NONE =3D 0, + + PERF_EXT_UXTB, + PERF_EXT_UXTH, + PERF_EXT_UXTW, + PERF_EXT_UXTX, + PERF_EXT_SXTB, + PERF_EXT_SXTH, + PERF_EXT_SXTW, + PERF_EXT_SXTX, +}; + +/* + * ARM64 operand shift types. + * LSL =3D logical shift left. + * LSR =3D logical shift right. + * ASR =3D arithmetic shift right. + * ROR =3D rotate right. + * + * Example: LSL #3 =3D shift the operand left by 3 bits. + */ +enum annotated_shift_type { + PERF_SHIFT_NONE =3D 0, + + PERF_SHIFT_LSL, + PERF_SHIFT_LSR, + PERF_SHIFT_ASR, + PERF_SHIFT_ROR, +}; + /** * struct annotated_insn_loc - Location info of instruction * @ops: Array of location info for source and target operands --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A76A93976BA; Wed, 16 Sep 2026 01:30:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522220; cv=none; b=HjYbfYamUMewJdQHjQ/3o1jjv9rZt8d7PYzIHsp8qUvKuS7n967Sopmz/gp6BTALeqgXn6yz5FsknrAZQLpb2Ed+poS338GLUJzSvpnmT7sQlUtqhonsPCbDuH2PQwXBk+0XQec+2YpkMG5xrZSEyHX11dg35xytvRI7kvYfJps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522220; c=relaxed/simple; bh=s9n095wSUCsRXSW/632bX+pY7fxYSqIcMHlvjqJeZTE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=elZ+ExPLf/qNwW8D5EGQQZZVd6xmxfTg+TTXbqodGVk2TGRfU4xQF++XJ1oV0fyE3oQ4kWcEBAIyG9leGxnq5DVRnR67PLmFiIpwTpS6gJYLBwfniKd844/gLojMWIuvkQj/GAE7LKWj8BcWrQid8amksaHztId2QUDVQDgYjTM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XT5dN0zYQtqn; Wed, 16 Sep 2026 09:30:01 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id E24D64057D; Wed, 16 Sep 2026 09:30:05 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S12; Wed, 16 Sep 2026 09:30:05 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 10/26] perf annotate: Default to --itrace=i1i for data type profiling Date: Wed, 16 Sep 2026 01:29:24 +0000 Message-Id: <3d2b93b84d7059024f40528153dc6b6a20461c77.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S12 X-Coremail-Antispam: 1UD129KBjvJXoW3JFy5ZrykXF4kZw1kXr4Utwb_yoW3ZFWDpr nxCr9rKwnxXr4rKwnIya1UZF1Yk34rXFyY9r10kF4rA3yxur9rtFyxtr15tFW3Xw1DC3sI vws09wn8Za1rZaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" ARM SPE-based sampling can synthesize multiple events on a single instruction, as shown below. This would affect data type profiling statistics: Available samples 0 arm_spe_0/ts_enable=3D1,pa_enable=3D1,load_filter=3D1,store_filter=3D1,= min_latency=3D30/ 0 dummy:u 84K l1d-miss 95K l1d-access 77K llc-miss 58K llc-access 9K tlb-miss 108K tlb-access 0 branch 13K remote-access 108K memory 108K instructions While 'perf report' provides an interactive menu for users to select a specific event to prevent duplicate counting, 'perf annotate' lacks such a mechanism. Consequently, it counts all instructions across these overlapping events, which inflates the profile and distorts the data type statistics. Although using the '--itrace' option can work around this issue (e.g.: perf annotate --data-type --stdio --itrace=3Di1i), it is inconvenient for users to specify this explicitly every time. To address this, introduce itrace_synth_opts.default_single_event_per_ip. Set this field to true when data type profiling is enabled and the user has not explicitly specified an itrace option. In itrace_synth_opts__set_de= fault(), use this flag to default to synthesizing at most one event per IP (equivale= nt to --itrace=3Di1i) to prevent duplicate sample counts. Reviewed-by: Adrian Hunter Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- tools/perf/builtin-annotate.c | 8 ++++++++ tools/perf/util/arm-spe.c | 5 ++++- tools/perf/util/auxtrace.c | 12 ++++++++++-- tools/perf/util/auxtrace.h | 7 ++++++- tools/perf/util/cs-etm.c | 2 +- tools/perf/util/intel-bts.c | 2 +- tools/perf/util/intel-pt.c | 3 ++- 7 files changed, 32 insertions(+), 7 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 850fc72fa75f..8863f3a570f6 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -885,6 +885,14 @@ int cmd_annotate(int argc, const char **argv) annotate.session =3D perf_session__new(&data, &annotate.tool); if (IS_ERR(annotate.session)) return PTR_ERR(annotate.session); + /* + * Hardware tracing (e.g., ARM SPE) may synthesize multiple events per + * instruction. When data type profiling is enabled, default to synthesiz= ing + * at most one event (equivalent to --itrace=3Di1i) to prevent skewed + * statistics. + */ + if (annotate.data_type && !itrace_synth_opts.set) + itrace_synth_opts.default_single_event_per_ip =3D true; =20 annotate.session->itrace_synth_opts =3D &itrace_synth_opts; =20 diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index 401aab529309..ae7a5e9c3892 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -2029,7 +2029,10 @@ int arm_spe_process_auxtrace_info(union perf_event *= event, if (session->itrace_synth_opts && session->itrace_synth_opts->set) { spe->synth_opts =3D *session->itrace_synth_opts; } else { - itrace_synth_opts__set_default(&spe->synth_opts, false); + struct itrace_synth_opts *opts =3D session->itrace_synth_opts; + bool single_event_per_ip =3D opts ? opts->default_single_event_per_ip : = false; + + itrace_synth_opts__set_default(&spe->synth_opts, false, single_event_per= _ip); /* Default nanoseconds period not supported */ spe->synth_opts.period_type =3D PERF_ITRACE_PERIOD_INSTRUCTIONS; spe->synth_opts.period =3D 1; diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index aa749e1c3036..ed2113190785 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -1478,8 +1478,15 @@ s64 perf_event__process_auxtrace(const struct perf_t= ool *tool __maybe_unused, #define PERF_ITRACE_MAX_LAST_BRANCH_SZ 1024 =20 void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts, - bool no_sample) + bool no_sample, bool single_event_per_ip) { + if (single_event_per_ip) { + synth_opts->instructions =3D true; + synth_opts->period_type =3D PERF_ITRACE_PERIOD_INSTRUCTIONS; + synth_opts->period =3D 1; + return; + } + synth_opts->branches =3D true; synth_opts->transactions =3D true; synth_opts->ptwrites =3D true; @@ -1582,7 +1589,8 @@ int itrace_do_parse_synth_opts(struct itrace_synth_op= ts *synth_opts, =20 if (!str) { itrace_synth_opts__set_default(synth_opts, - synth_opts->default_no_sample); + synth_opts->default_no_sample, + synth_opts->default_single_event_per_ip); return 0; } =20 diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index 6947f3f284c0..5012bead1b92 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -65,6 +65,10 @@ enum itrace_period_type { * struct itrace_synth_opts - AUX area tracing synthesis options. * @set: indicates whether or not options have been set * @default_no_sample: Default to no sampling. + * @default_single_event_per_ip: Default to synthesizing at most 1 event p= er IP + * (equivalent to --itrace=3Di1i). Used by c= ommands + * like 'perf annotate --data-type' to avoid= duplicate + * sample counts for a single instruction. * @inject: indicates the event (not just the sample) must be fully synthe= sized * because 'perf inject' will write it out * @instructions: whether to synthesize 'instructions' events @@ -117,6 +121,7 @@ enum itrace_period_type { struct itrace_synth_opts { bool set; bool default_no_sample; + bool default_single_event_per_ip; bool inject; bool instructions; bool cycles; @@ -622,7 +627,7 @@ int itrace_do_parse_synth_opts(struct itrace_synth_opts= *synth_opts, int itrace_parse_synth_opts(const struct option *opt, const char *str, int unset); void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts, - bool no_sample); + bool no_sample, bool single_event_per_ip); =20 size_t perf_event__fprintf_auxtrace_error(union perf_event *event, FILE *f= p); void perf_session__auxtrace_error_inc(struct perf_session *session, diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 114b3cd2da49..2d1ab34f7b6b 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -3626,7 +3626,7 @@ int cs_etm__process_auxtrace_info_full(union perf_eve= nt *event, etm->synth_opts =3D *session->itrace_synth_opts; } else { itrace_synth_opts__set_default(&etm->synth_opts, - session->itrace_synth_opts->default_no_sample); + session->itrace_synth_opts->default_no_sample, false); etm->synth_opts.callchain =3D false; etm->synth_opts.thread_stack =3D session->itrace_synth_opts->thread_stac= k; } diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 02df3e460489..4c9cca3acb6c 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -877,7 +877,7 @@ int intel_bts_process_auxtrace_info(union perf_event *e= vent, bts->synth_opts =3D *session->itrace_synth_opts; } else { itrace_synth_opts__set_default(&bts->synth_opts, - session->itrace_synth_opts->default_no_sample); + session->itrace_synth_opts->default_no_sample, false); bts->synth_opts.thread_stack =3D session->itrace_synth_opts->thread_stack; } diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 9d6628169fd9..8c21c9f52d57 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -4463,7 +4463,8 @@ int intel_pt_process_auxtrace_info(union perf_event *= event, } else { struct itrace_synth_opts *opts =3D session->itrace_synth_opts; =20 - itrace_synth_opts__set_default(&pt->synth_opts, opts->default_no_sample); + itrace_synth_opts__set_default(&pt->synth_opts, + opts->default_no_sample, false); if (!opts->default_no_sample && !opts->inject) { pt->synth_opts.branches =3D false; pt->synth_opts.callchain =3D true; --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD3BC3ACA7E; Wed, 16 Sep 2026 01:30:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522222; cv=none; b=YR9GIQY6tq9Y3am20cofRKULWNIramdoa5t98cR8i+kMDr2xTVmxwDcV+p0giQPRGxJvzlDKjqjOsqw+1xqW3axTUeysw9sZNNozJYuDfiad54xwQMgYvLJWZNZrbfkGgBienA+KDfP9lxyEVdbUd1tnT9fmbi1FrvY7lIJCauo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522222; c=relaxed/simple; bh=I8s3IRLIG6/0sh4VgQx4eFZKk5wCQhypjzz0IrTQSWc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=uOIrse6SxnAVWNwgRnA6qYNjUGMvCqsKM4N7sYCKEfTbfiwdv9VA5pCDHdghZTQEnmB1FI+5KdaQ/Qf/vWIg+kf/1wI3U5osDXJu80FGt2rD0DGOp8XZh+UQyNE9FwmG4WY0BhMyOxVGbV1d4K/rgISNTGH47dOoYPAnuAb4ycI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XJ2wZPzKHMRB; Wed, 16 Sep 2026 09:29:52 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 02D7E4058F; Wed, 16 Sep 2026 09:30:06 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S13; Wed, 16 Sep 2026 09:30:05 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 11/26] perf arm-spe: Set default synthesized event period to 1 Date: Wed, 16 Sep 2026 01:29:25 +0000 Message-Id: <40acb41b77fcb4aef1efe720c651563043800ff3.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S13 X-Coremail-Antispam: 1UD129KBjvJXoWxXFy7CFyxXFWkWw1kJryftFb_yoW5uw43pr nFga4ftr1kJry8Kw17Ar4UuFy3tw4FvF1fGF1xGrWUAw1UKry8tr17try5Cr4UWr1Fyr12 qFyqgw1UGr1Utr7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" When using --itrace=3DM for data type profiling on arm64, the 'Percent' values in perf annotate output are all zero: Annotate type: 'struct mmu_gather_batch' in [kernel.kallsyms] (15 samples): =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D Percent offset size field 0.00 0 0x10 struct mmu_gather_batch { 0.00 0 0x8 struct mmu_gather_batch* next; 0.00 0x8 0x4 unsigned int nr; 0.00 0xc 0x4 unsigned int max; 0.00 0x10 0 struct encoded_page*[] encoded_pag= es; }; However, adding the -n option (show-nr-samples) reveals non-zero sample cou= nts: Annotate type: 'struct mmu_gather_batch' in [kernel.kallsyms] (15 samples): =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D Samples offset size field 15 0 0x10 struct mmu_gather_batch { 13 0 0x8 struct mmu_gather_batch* next; 2 0x8 0x4 unsigned int nr; 0 0xc 0x4 unsigned int max; 0 0x10 0 struct encoded_page*[] encoded_pag= es; }; The root cause is that when --itrace is used with non-i/y options (e.g., --itrace=3DM), the period remains zero after parsing. During subsequent propagation, the final percentage calculation results in zero: arm_spe_prep_sample() sample->period =3D spe->synth_opts.period; __hists__add_entry() he.stat.period =3D sample->period; annotated_data_type__update_samples() h->period +=3D period; h->addr[offset].period +=3D period; print_annotated_data_value() double percent =3D h->period ? (100.0 * period / h->period) : 0; Fix this by defaulting the period to 1 in the ARM SPE auxtrace info processing path if it is not explicitly specified. This ensures that downstream tool components can correctly accumulate periods and compute event percentages for all synthesized SPE events. With this fix applied, the result is as follows: Annotate type: 'struct mmu_gather_batch' in [kernel.kallsyms] (15 samples): =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D Percent offset size field 100.00 0 0x10 struct mmu_gather_batch { 86.67 0 0x8 struct mmu_gather_batch* next; 13.33 0x8 0x4 unsigned int nr; 0.00 0xc 0x4 unsigned int max; 0.00 0x10 0 struct encoded_page*[] encoded_pag= es; }; Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- tools/perf/util/arm-spe.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index ae7a5e9c3892..7805a1a98a89 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -2043,6 +2043,17 @@ int arm_spe_process_auxtrace_info(union perf_event *= event, err =3D -EINVAL; goto err_free_queues; } + + /* + * When --itrace is used with non-i/y options (e.g., --itrace=3DM), + * the period remains 0 because the parser does not apply a default + * for those paths. However, synthesized SPE events such as memory + * accesses, TLB walks, and cache misses still require a valid + * sample->period to correctly accumulate periods and compute event + * percentages. Set it to 1 to ensure proper accounting. + */ + spe->synth_opts.period =3D spe->synth_opts.period ?: 1; + if (spe->synth_opts.period > 1) ui__warning("Arm SPE has a hardware-based sampling period.\n\n" "--itrace periods > 1i downsample by an interval of n SPE samples r= ather than n instructions.\n"); --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3010F3B14C1; Wed, 16 Sep 2026 01:30:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522226; cv=none; b=J7p3lRH75P6CrX2XcaUzG3dQj2Exzn0IwdE9FjWBZCULVhLCFb9d491skkggCCfRCXMVSdjYlGcUOVcSipDUXZhX4U/Fd7OGlj2lzrbht9pVSg2RnAxqjPI17dEQOnEidBNIOAIZPqlTJE3BIcgYZD8W0DvuIjZU7GYAEsbArUs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522226; c=relaxed/simple; bh=WYqUr/mqKlO1HaSBmbRolJ9/ErEUm5dWB2ZH8l5XqpQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=aLddM0JYRugIp4aoZWPYHnjByFW8NfrZrv8PQcgheIVsL52CBMch++Z9HiVVyYkVvLJAcydXJv0DMaOPB0CyyMuiTD4jMlhU1KRbW0MkA5QzmI8dTOOFiB90J9G3f2HBKFamSWQacE6VgKPLfbMnrwSMgI0gVYEBfjjIqbqlXwM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XT6xRfzYQtqt; Wed, 16 Sep 2026 09:30:01 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 1A62F40573; Wed, 16 Sep 2026 09:30:06 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S14; Wed, 16 Sep 2026 09:30:05 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 12/26] perf annotate-data: Extract invalidate_reg_state() as a common helper Date: Wed, 16 Sep 2026 01:29:26 +0000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S14 X-Coremail-Antispam: 1UD129KBjvJXoWxGr1rJry8CF1ktr17Kr4UJwb_yoW5XrW5p3 yDC347Gw43Gr4FgwnxJFW3XFyrur1fXa4Fk3sYy3Z2vFWIyrn3Jr92qFy5tFW7Xr93Gw12 yw1qgr4DJayxKaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" The invalidate_reg_state() function is currently static and only used within the x86 data type profiling implementation. To prepare for adding arm64 instruction tracking support, extract it as a common helper that can be shared across architectures. No functional change intended. Reviewed-by: Shuai Xue Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- tools/perf/util/annotate-arch/annotate-x86.c | 9 --------- tools/perf/util/annotate-data.c | 9 +++++++++ tools/perf/util/annotate-data.h | 1 + 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-x86.c b/tools/perf/util= /annotate-arch/annotate-x86.c index 1acf31a2c759..aa381d25a63b 100644 --- a/tools/perf/util/annotate-arch/annotate-x86.c +++ b/tools/perf/util/annotate-arch/annotate-x86.c @@ -207,15 +207,6 @@ static int x86__cpuid_parse(struct arch *arch, const c= har *cpuid) } =20 #ifdef HAVE_LIBDW_SUPPORT -static void invalidate_reg_state(struct type_state_reg *reg) -{ - reg->kind =3D TSR_KIND_INVALID; - reg->ok =3D false; - reg->lifetime_active =3D false; - reg->lifetime_end =3D 0; - reg->copied_from =3D -1; -} - static void update_insn_state_x86(struct type_state *state, struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index aff60a630fd0..82003d2c240d 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -638,6 +638,15 @@ struct type_state_stack *findnew_stack_state(struct ty= pe_state *state, return stack; } =20 +void invalidate_reg_state(struct type_state_reg *reg) +{ + reg->kind =3D TSR_KIND_INVALID; + reg->ok =3D false; + reg->lifetime_active =3D false; + reg->lifetime_end =3D 0; + reg->copied_from =3D -1; +} + /* Maintain a cache for quick global variable lookup */ struct global_var_entry { struct rb_node node; diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index ca2096a9ee62..2af70e3cf73f 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -258,6 +258,7 @@ void set_stack_state(struct type_state_stack *stack, in= t offset, u8 kind, Dwarf_Die *type_die, int ptr_offset); struct type_state_stack *find_stack_state(struct type_state *state, int offset); +void invalidate_reg_state(struct type_state_reg *reg); bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc, u64 ip, u64 var_addr, int *var_offset, Dwarf_Die *type_die); --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31BFF3B14CC; Wed, 16 Sep 2026 01:30:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522227; cv=none; b=l+vHcD+Gbsppj9Su0pfwEgqEhayV20AOfQdXwjoVyQyxPmgi5TusLNC9X6J4/eydhRpALLrLesHV2UrYASzJyENU2GxxjvNzVBFzS4CIsX3Yt0yPBDJDVs6xu8InNDoPTMwy/UdSux3ivmtoqsH3mCcHxCkDV8+HP7RkD21x2hc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522227; c=relaxed/simple; bh=Wh+a4mIPAKLjd+zZpUbjKlGSrWozbQN/Pik1BBtXSBg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=d9x2H6DOx9e/XaiqC5DE9e0CUyIrB6l3DwI8GteadZgPyMfyy3qpN4R4vAXMrg/42QfIkAHqd7b7xQk4s3aT1OkcZAoWbvvvmuux0ODNTf9dMEPwNeOcyZAG4XWVmWYSWMJqqr8Vu3yFngq4ehtjxamJwffwsH6Ri7YoQiKGxmo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XV0GbtzYQts0; Wed, 16 Sep 2026 09:30:02 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 2DE8F4057E; Wed, 16 Sep 2026 09:30:06 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S15; Wed, 16 Sep 2026 09:30:05 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 13/26] perf annotate-arm64: Enable instruction tracking support Date: Wed, 16 Sep 2026 01:29:27 +0000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S15 X-Coremail-Antispam: 1UD129KBjvJXoW3WFy7Wr48tF1UZr1DAryfCrg_yoWxGFy8pa yDC34rKF4UJr42gwnxJF4UXry3Gw4fW34Y9ryqgw4SyFsFyryrtF4kKFWayFWrGrZ3Cr42 qa1qyFWUXw4UCaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Enable basic instruction tracking for arm64 by implementing three essential functions in the find_data_type_block() call path: find_data_type_block -> arch_supports_insn_tracking (1) -> find_data_type_insn -> init_type_state (2) -> update_var_state -> update_insn_state (3) Changes: * arch_supports_insn_tracking(): add arm64 to the list of supported architectures, allowing find_data_type_block() to proceed with data type analysis. * init_type_state(): correctly identify ret_reg, stack_reg, and caller-saved registers for arm64 during type state initialization. * update_insn_state(): add the update_insn_state_arm64() callback with conservative register invalidation for call instructions and those with destination register(s), preventing stale type propagation. Full instruction-level analysis support will be added incrementally in later patches. With these changes, arm64 gains support for basic variable type inference during instruction tracking. Signed-off-by: Li Huafei Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 78 +++++++++++++++++++ tools/perf/util/annotate-data.c | 15 +++- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index 508a95d0ad4b..cd369fcd7dc0 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -9,6 +9,10 @@ #include #include "../annotate.h" #include "../disasm.h" +#include "../annotate-data.h" +#include "../debug.h" +#include "../map.h" +#include "../symbol.h" =20 struct arch_arm64 { struct arch arch; @@ -448,6 +452,77 @@ static void extract_op_location_arm64(const struct arc= h *arch, } } =20 +#ifdef HAVE_LIBDW_SUPPORT +static bool is_readonly_branch_or_cmp(const char *name) +{ + return !strncmp(name, "cb", 2) || !strncmp(name, "tb", 2) || + !strcmp(name, "tst") || !strcmp(name, "teq") || + !strcmp(name, "cmp") || !strcmp(name, "cmn") || + !strcmp(name, "ccmp") || !strcmp(name, "ccmn"); +} + +static void update_insn_state_arm64(struct type_state *state, + struct data_loc_info *dloc, Dwarf_Die *cu_die __maybe_unused, + struct disasm_line *dl) +{ + struct annotated_insn_loc loc; + struct annotated_op_loc *dst =3D &loc.ops[INSN_OP_TARGET]; + u32 insn_offset =3D dl->al.offset; + + /* Skip read-only instructions that do not affect register type state */ + if (is_readonly_branch_or_cmp(dl->ins.name)) + return; + + if (annotate_get_insn_location(dloc->arch, dl, &loc) < 0) + return; + + /* + * Invalidate caller-saved registers on function calls per ARM64 AAPCS64 + * ABI, unless DWARF location info indicates the register remains valid + * beyond the call address. + */ + if (ins__is_call(&dl->ins)) { + struct symbol *func =3D dl->ops.target.sym; + const char *call_name; + u64 call_addr; + + call_name =3D func ? func->name : dl->ops.target.name; + pr_debug_dtp("call [%x] %s\n", insn_offset, call_name ?: ""); + + /* Invalidate caller-saved registers after call */ + call_addr =3D map__rip_2objdump(dloc->ms->map, + dloc->ms->sym->start + dl->al.offset); + for (unsigned int i =3D 0; i < ARRAY_SIZE(state->regs); i++) { + struct type_state_reg *reg =3D &state->regs[i]; + + if (!reg->caller_saved) + continue; + /* Keep register valid within DWARF location lifetime */ + if (reg->lifetime_active && call_addr < reg->lifetime_end) + continue; + invalidate_reg_state(reg); + } + return; + } + + /* + * Invalidate destination register(s) for unsupported instructions to + * prevent stale type info from propagating to subsequent instructions. + */ + if (has_reg_type(state, dst->reg1) && !dst->mem_ref) { + pr_debug_dtp("%s [%x] invalidate reg%d", + dl->ins.name, insn_offset, dst->reg1); + invalidate_reg_state(&state->regs[dst->reg1]); + if (dst->multi_regs && has_reg_type(state, dst->reg2)) { + pr_debug_dtp(" and reg%d", dst->reg2); + invalidate_reg_state(&state->regs[dst->reg2]); + } + pr_debug_dtp("\n"); + return; + } +} +#endif + const struct arch *arch__new_arm64(const struct e_machine_and_e_flags *id, const char *cpuid __maybe_unused) { @@ -467,6 +542,9 @@ const struct arch *arch__new_arm64(const struct e_machi= ne_and_e_flags *id, arch->objdump.imm_char =3D '#'; arch->associate_instruction_ops =3D arm64__associate_instruction_ops; arch->extract_op_location =3D extract_op_location_arm64; +#ifdef HAVE_LIBDW_SUPPORT + arch->update_insn_state =3D update_insn_state_arm64; +#endif =20 /* bl, blr */ err =3D regcomp(&arm->call_insn, "^blr?$", REG_EXTENDED); diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 82003d2c240d..9196f54b7297 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -28,6 +28,7 @@ =20 /* register number of the stack pointer */ #define X86_REG_SP 7 +#define ARM64_REG_SP 31 =20 static void delete_var_types(struct die_var_type *var_types); =20 @@ -178,6 +179,17 @@ static void init_type_state(struct type_state *state, = const struct arch *arch) state->regs[11].caller_saved =3D true; state->ret_reg =3D 0; state->stack_reg =3D X86_REG_SP; + } else if (arch__is_arm64(arch)) { + /* + * Mark x0..x18 as caller-saved. x30 (LR) is intentionally + * omitted from the caller_saved set: it is clobbered by + * calls, but holds only the return address and is not used + * to carry data type information. + */ + for (int i =3D 0; i < 19; i++) + state->regs[i].caller_saved =3D true; + state->ret_reg =3D 0; + state->stack_reg =3D ARM64_REG_SP; } } =20 @@ -1437,7 +1449,8 @@ static enum type_match_result find_data_type_insn(str= uct data_loc_info *dloc, =20 static int arch_supports_insn_tracking(struct data_loc_info *dloc) { - if ((arch__is_x86(dloc->arch)) || (arch__is_powerpc(dloc->arch))) + if (arch__is_x86(dloc->arch) || arch__is_powerpc(dloc->arch) || + arch__is_arm64(dloc->arch)) return 1; return 0; } --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D8243B19B6; Wed, 16 Sep 2026 01:30:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522227; cv=none; b=UlEYbEegvpkpNEAwGP422EcB0AI8SJjGQKazmekFmIyDNonKJXueptqePmu7EbImALzHCRFwXBSP4XLl6goyHNvBDLheln1sCajLbZx5z0wCdim8gXcRKFGm9gONlzOpe/HR4Zwcs51ady5fSpWj2cHcDxs9M6z3KTQGfwF3QR4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522227; c=relaxed/simple; bh=ctMIgjR5Un14E+eIFJElBQe/il1/i+7Wb6QgNq/U6/k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EZ9yusimYCIRLZdoCPa/WrtsJb+4fk/yWhF2d+psge8XwIHJlh8of7pGX7RR6HH+jdWbuceBEuhtB3SUwiwJK3PYnAt+GOV8o+qsSakYCzvW0PpSHeEbNnFUPDEvKoV6ojurdyppXwTD+Pj7YmV+Hy4GGkjMNCAILXKcI3PHa4o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XV0zv3zYQtqt; Wed, 16 Sep 2026 09:30:02 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 448C340579; Wed, 16 Sep 2026 09:30:06 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S16; Wed, 16 Sep 2026 09:30:05 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 14/26] perf annotate-data: Add arch_get_reg_offset helper Date: Wed, 16 Sep 2026 01:29:28 +0000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S16 X-Coremail-Antispam: 1UD129KBjvJXoW3AF1rZryUAF1fJw4rJFy3XFb_yoWfWrWkpa 98GFyfGr47Wr4SgrsrXF98Xr9Y9ws7Gr93Cryq93sIyFyaqr18Ka1vyryYk3yUJrZYyw17 G3W5tr47Xw47GaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Add a helper to compute the effective offset from a base register for instruction operands. Currently handles arm64 addressing modes including post-indexed, single-register, SIB-style indexed with shift/extension, and constant-offset register pairs. Fallback to instruction's raw offset for other architectures. Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- tools/perf/util/annotate-data.c | 115 ++++++++++++++++++++++++++------ tools/perf/util/annotate-data.h | 4 +- 2 files changed, 98 insertions(+), 21 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 9196f54b7297..d9f0bfd3f0a7 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -1122,6 +1122,74 @@ static void setup_stack_canary(struct data_loc_info = *dloc) } } =20 +int arch_get_reg_offset(const struct arch *arch, struct annotated_op_loc *= op_loc, + int breg, struct type_state *state, bool apply_index, + int *offset) +{ + if (arch__is_arm64(arch)) { + int reg2; + + /* Post-indexed addressing: offset is 0 when not applying index */ + if (op_loc->addr_mode =3D=3D PERF_AAM_POST_INDEX && !apply_index) { + *offset =3D 0; + return 0; + } + + /* Single-register addressing: return the stored offset directly */ + if (!op_loc->multi_regs) { + *offset =3D op_loc->offset; + return 0; + } + + /* + * SIB (Scale-Index-Base) style indexed addressing, e.g.: + * Array element load: ldr dst, [base, index, lsl #3] + * Array element load: ldr dst, [base, index, uxtw #3] + * Array address calc: add dst, base, index lsl #3 + * + * The index reg only computes element offset without modifying + * the underlying data type; the dst type is inherited from base. + * Therefore, the base reg offset can be treated as 0. + */ + if (op_loc->extend_type || op_loc->shift_type) { + /* Memory references use the breg as the address base. */ + if (op_loc->mem_ref) { + *offset =3D 0; + return 0; + } + /* + * Otherwise, require breg to be a known pointer type to + * avoid treating integer operations as address calculations. + */ + if (has_reg_type(state, breg) && state->regs[breg].ok && + (state->regs[breg].kind =3D=3D TSR_KIND_POINTER || + (state->regs[breg].kind =3D=3D TSR_KIND_TYPE && + dwarf_tag(&state->regs[breg].type) =3D=3D DW_TAG_pointer_type))) { + *offset =3D 0; + return 0; + } + return -1; + } + + /* + * For register-based addressing without shift/extension, + * reg2 may be a constant offset. Use its value as the offset + * from the base register. + */ + reg2 =3D op_loc->reg1 =3D=3D breg ? op_loc->reg2 : op_loc->reg1; + if (has_reg_type(state, reg2) && state->regs[reg2].ok && + state->regs[reg2].kind =3D=3D TSR_KIND_CONST) { + *offset =3D (s64)state->regs[reg2].imm_value; + return 0; + } + + return -1; + } + + *offset =3D op_loc->offset; + return 0; +} + /* * It's at the target address, check if it has a matching type. * It returns PERF_TMR_BAIL_OUT when it looks up per-cpu variables which @@ -1136,18 +1204,25 @@ static enum type_match_result check_matching_type(s= truct type_state *state, Dwarf_Word size; u32 insn_offset =3D dl->al.offset; int reg =3D dloc->op->reg1; - int offset =3D dloc->op->offset; - const char *offset_sign =3D ""; + int offset; + const char *offset_sign; bool retry =3D true; =20 - if (offset < 0) { - offset =3D -offset; - offset_sign =3D "-"; +again: + if (arch_get_reg_offset(dloc->arch, dloc->op, reg, state, false, &offset)= ) { + /* + * Fall back to the instruction's offset. This prevents the + * register type of the instruction from being completely lost. + * Compared to dropping this type inference entirely, providing + * a rough type hint is likely more useful. + */ + offset =3D dloc->op->offset; } =20 -again: + offset_sign =3D offset < 0 ? "-" : ""; + pr_debug_dtp("chk [%x] reg%d offset=3D%s%#x ok=3D%d kind=3D%d ", - insn_offset, reg, offset_sign, offset, + insn_offset, reg, offset_sign, abs(offset), state->regs[reg].ok, state->regs[reg].kind); =20 if (!state->regs[reg].ok) @@ -1170,7 +1245,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, */ ptr_type =3D die_get_pointer_type(&state->regs[reg].type, &ptr_die); if (!ptr_type) { - if (dloc->op->offset < 0 && reg !=3D state->stack_reg) + if (offset < 0 && reg !=3D state->stack_reg) goto check_kernel; =20 return PERF_TMR_NO_POINTER; @@ -1180,7 +1255,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, if (__die_get_real_type(ptr_type, type_die) =3D=3D NULL) return PERF_TMR_NO_POINTER; =20 - dloc->type_offset =3D dloc->op->offset + state->regs[reg].offset; + dloc->type_offset =3D offset + state->regs[reg].offset; =20 if (dwarf_tag(type_die) =3D=3D DW_TAG_typedef) die_get_real_type(type_die, &sized_type); @@ -1209,7 +1284,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, */ *type_die =3D state->regs[reg].type; =20 - dloc->type_offset =3D dloc->op->offset + state->regs[reg].offset; + dloc->type_offset =3D offset + state->regs[reg].offset; =20 /* Get the size of the actual type */ if (dwarf_aggregate_size(type_die, &size) < 0 || @@ -1228,7 +1303,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, */ *type_die =3D state->regs[reg].type; =20 - dloc->type_offset =3D dloc->op->offset; + dloc->type_offset =3D offset; =20 /* Get the size of the actual type */ if (dwarf_aggregate_size(type_die, &size) < 0 || @@ -1252,7 +1327,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, } =20 if (state->regs[reg].kind =3D=3D TSR_KIND_PERCPU_BASE) { - u64 var_addr =3D dloc->op->offset; + u64 var_addr =3D (s64) offset; int var_offset; =20 pr_debug_dtp("percpu var"); @@ -1279,7 +1354,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, =20 if (state->regs[reg].kind =3D=3D TSR_KIND_CONST && dso__kernel(map__dso(dloc->ms->map))) { - if (dloc->op->offset < 0 && reg !=3D state->stack_reg && reg !=3D dloc->= fbreg) + if (offset < 0 && reg !=3D state->stack_reg && reg !=3D dloc->fbreg) goto check_kernel; } check_non_register: @@ -1288,7 +1363,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, =20 pr_debug_dtp("%s", reg =3D=3D dloc->fbreg ? "fbreg" : "stack"); =20 - stack =3D find_stack_state(state, dloc->type_offset); + stack =3D find_stack_state(state, offset); if (stack =3D=3D NULL) { if (retry) { pr_debug_dtp(" : retry\n"); @@ -1311,7 +1386,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, =20 *type_die =3D stack->type; /* Update the type offset from the start of slot */ - dloc->type_offset -=3D stack->offset; + dloc->type_offset =3D offset - stack->offset; =20 return PERF_TMR_OK; } @@ -1329,7 +1404,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, if (reg !=3D fbreg) return PERF_TMR_NO_TYPE; =20 - stack =3D find_stack_state(state, dloc->type_offset - fboff); + stack =3D find_stack_state(state, offset - fboff); if (stack =3D=3D NULL) { if (retry) { pr_debug_dtp(" : retry\n"); @@ -1352,7 +1427,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, =20 *type_die =3D stack->type; /* Update the type offset from the start of slot */ - dloc->type_offset -=3D fboff + stack->offset; + dloc->type_offset =3D offset - fboff - stack->offset; =20 return PERF_TMR_OK; } @@ -1366,7 +1441,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, arch__is_x86(dloc->arch)) { pr_debug_dtp("this-cpu var"); =20 - addr =3D dloc->op->offset; + addr =3D (s64) offset; =20 if (get_global_var_type(cu_die, dloc, dloc->ip, addr, &offset, type_die)) { @@ -1377,8 +1452,8 @@ static enum type_match_result check_matching_type(str= uct type_state *state, } =20 /* Access to global variable like "-0x7dcf0500(,%rdx,8)" */ - if (dloc->op->offset < 0 && reg !=3D state->stack_reg) { - addr =3D (s64) dloc->op->offset; + if (offset < 0 && reg !=3D state->stack_reg) { + addr =3D (s64) offset; =20 if (get_global_var_type(cu_die, dloc, dloc->ip, addr, &offset, type_die)) { diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index 2af70e3cf73f..68e3feda2eda 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -265,7 +265,9 @@ bool get_global_var_type(Dwarf_Die *cu_die, struct data= _loc_info *dloc, bool get_global_var_info(struct data_loc_info *dloc, u64 addr, const char **var_name, int *var_offset); void pr_debug_type_name(Dwarf_Die *die, enum type_state_kind kind); - +int arch_get_reg_offset(const struct arch *arch, struct annotated_op_loc *= op_loc, + int breg, struct type_state *state, bool apply_index, + int *offset); #else /* HAVE_LIBDW_SUPPORT */ =20 static inline struct annotated_data_type * --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 865CB3B1ED1; Wed, 16 Sep 2026 01:30:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522228; cv=none; b=okQu//x8OqK9l69D0iCZvgGNojfjK7eX37PWZMyRhO2yG+6HgSBzaozL9JFjKdzs41uHhoCWHRIrnzXn+ExMTmT7YAa7CC3ag+9J9z86CnOaTchOG/1BrmN8p5qJoZeAZw3aYlyelZjjOL9fRYTiOeJGC4OHy3arELblANn0/v4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522228; c=relaxed/simple; bh=5cenqpQBsJKSzPGP23ZNodOBWN/bw6yIFMxX+C4bJ98=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=A0Xb6DIO4dCEGJX5A7zMlqSU+VmquQJrE/UR9ojLcMI/RSEudIEa8SJPYO1pVpSeW2+VFUUZeeF5DqFf9PG/EVasocqQHyA3RSvY9hSvhram8iUJ8vyJb2EzGpPVfBjpgzvaMi6eaz1sJ+Wi+++mwWTi9sxUY6J/aK9abx/k/Jk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XV2939zYQtsS; Wed, 16 Sep 2026 09:30:02 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 6748740577; Wed, 16 Sep 2026 09:30:06 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S17; Wed, 16 Sep 2026 09:30:05 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 15/26] perf annotate-arm64: Track return type after call instructions Date: Wed, 16 Sep 2026 01:29:29 +0000 Message-Id: <4cc79c0f84c37c27c2c82edd75498d6ccc27fe51.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S17 X-Coremail-Antispam: 1UD129KBjvJXoW7tFy3ZFykGF13Xw4kuFWDCFg_yoW8CFWrp3 WDuryUKr1UGr47KrnxJrWfXryrCrW7W34jkw17twnavFW2yr4fJFZ7KFyaqa1rXr9xCw48 AwsFkr45Cw4xCaUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Enable data type profiling to track function return values in arm64 annotations by looking up the DWARF return type of called functions. Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- tools/perf/util/annotate-arch/annotate-arm64.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index cd369fcd7dc0..d3d994a22cf9 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -462,7 +462,7 @@ static bool is_readonly_branch_or_cmp(const char *name) } =20 static void update_insn_state_arm64(struct type_state *state, - struct data_loc_info *dloc, Dwarf_Die *cu_die __maybe_unused, + struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) { struct annotated_insn_loc loc; @@ -485,6 +485,8 @@ static void update_insn_state_arm64(struct type_state *= state, struct symbol *func =3D dl->ops.target.sym; const char *call_name; u64 call_addr; + struct type_state_reg *tsr; + Dwarf_Die type_die; =20 call_name =3D func ? func->name : dl->ops.target.name; pr_debug_dtp("call [%x] %s\n", insn_offset, call_name ?: ""); @@ -502,6 +504,20 @@ static void update_insn_state_arm64(struct type_state = *state, continue; invalidate_reg_state(reg); } + + /* Update register with the return type (if any) */ + if (call_name && die_find_func_rettype(cu_die, call_name, &type_die)) { + tsr =3D &state->regs[state->ret_reg]; + invalidate_reg_state(tsr); + tsr->type =3D type_die; + tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; + tsr->ok =3D true; + + pr_debug_dtp("call [%x] return -> reg%d", + insn_offset, state->ret_reg); + pr_debug_type_name(&type_die, tsr->kind); + } return; } =20 --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 565873AA4EB; Wed, 16 Sep 2026 01:30:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522229; cv=none; b=JxOtaP+dUvZ6RpdrEy5bJJk2FMkeDbV0Pt9J2AQJULqxBWkkTed5CJlKyBxbqSw5lO27nWT5dr3kWsuwagWuhVj8CdHSizEhU2mZ08v/ra17eWLEOHJpnc3jUfSsd4/v7iKV2n7iP42w2ALSPFJp5qTSWWM4qjKXKZMyDE6duw0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522229; c=relaxed/simple; bh=CYAWsgGfQzpw61WJo1udQTT4iUZ56p41ZSuuO/R4r3Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=unamXiJNGvInG1iyIR6RftDni/F2TOLOby/X5uAdek6snN6VHJZ0bdSwyDo5rRKtcOX9I9c6AEf5TBGq5zBHDI3n0YESGdfzK2x5RJ/Rm0atXpaSVcMjXqsi/ao6mCawJm4drZqJ9zT6AVhSMen/muizvRcNv/8HAU/J9Nva5eA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XV2r5YzYQts3; Wed, 16 Sep 2026 09:30:02 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 7EE484057B; Wed, 16 Sep 2026 09:30:06 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S18; Wed, 16 Sep 2026 09:30:06 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 16/26] perf annotate-arm64: Support load instruction tracking Date: Wed, 16 Sep 2026 01:29:30 +0000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S18 X-Coremail-Antispam: 1UD129KBjvJXoW3Xw1fWr13Kry7ZF4DWr43trb_yoWDJF1fpF WDC345Kw47Ar4SgrsIqF48Wr9xuw4xWr15Cr98Za9FyF47trn5Ka93tay2vF45GrZruw13 Jw4Dtr98Xw42yaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Extend update_insn_state_arm64() to handle load instructions, tracking register state changes when data is loaded from memory to registers. Two main categories are considered: standard load (e.g, ldr variants) and load pair (ldp), for example: ldr dst, [src, #imm] ldp dst1, dst2, [src, #imm] For data type propagation, a load pair can be treated as two standard loads combined, first loading dst1 and then dst2. The difference is that when loading dst2, an additional memory spacing 'mem_spacing' after the first load must be added. This mem_spacing can be derived from the instruction mnemonic and the size of the dst register. Each load operation is handled by introducing propagate_load_reg_state(). When processing a load pair, the case where dst and src registers are the same (e.g., ldp x0, x1, [x0]) also needs to be considered. Therefore, before propagating data types, a snapshot of the src register's state must be saved and then passed to propagate_load_reg_state(). Finally, handle the side effects of pre-index and post-index addressing via adjust_reg_index_state(). A real-world example is shown below: ffff80008011f5b0 : ffff80008011f5b8: ldr x0, [x0, #2712] // x0: struct rq* -> task_struct* * ffff80008011f5c0: ldr w1, [x0, #104] Before this commit, the type of x0 was incorrectly inferred as 'struct rq': find data type for 0x68(reg0) at pick_task_stop+0x10 var [8] reg0 offset 0 type=3D'struct rq*' chk [10] reg0 offset=3D0x68 ok=3D1 kind=3D1 (struct rq*) : Good! final result: type=3D'struct rq' After this commit, the type of x0 is correctly inferred as 'struct task_str= uct': find data type for 0x68(reg0) at pick_task_stop+0x10 var [8] reg0 offset 0 type=3D'struct rq*' ldr [8] 0xa98(reg0) -> reg0 type=3D'struct task_struct*' chk [10] reg0 offset=3D0x68 ok=3D1 kind=3D1 (struct task_struct*) : Good! final result: type=3D'struct task_struct' Signed-off-by: Li Huafei Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 206 +++++++++++++++++- 1 file changed, 205 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index d3d994a22cf9..11b2bdceaacb 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -461,11 +461,210 @@ static bool is_readonly_branch_or_cmp(const char *na= me) !strcmp(name, "ccmp") || !strcmp(name, "ccmn"); } =20 +static int arm64__reg_size(const char *reg) +{ + if (!reg || !*reg || !arm64__is_reg(reg)) + return -1; + + if (reg[0] =3D=3D 'w') + return 4; + + if (reg[0] =3D=3D 'x' || !strncmp(reg, "sp", 2)) + return 8; + + return -1; +} + +/* Apply addressing mode (pre-index, post-index) to register state */ +static void adjust_reg_index_state(struct type_state *state, + struct data_loc_info *dloc, + struct disasm_line *dl, + struct annotated_op_loc *op_loc) +{ + struct type_state_reg *tsr; + int reg =3D op_loc->reg1; + int offset; + + if (op_loc->addr_mode !=3D PERF_AAM_PRE_INDEX && + op_loc->addr_mode !=3D PERF_AAM_POST_INDEX) + return; + + if (!has_reg_type(state, reg) || !state->regs[reg].ok) + return; + + tsr =3D &state->regs[reg]; + tsr->copied_from =3D -1; + + if (arch_get_reg_offset(dloc->arch, op_loc, reg, state, true, &offset)) { + invalidate_reg_state(tsr); + return; + } + + tsr->offset +=3D offset; + + pr_debug_dtp("%s [%x] %s-index %#x(reg%d) -> reg%d", dl->ins.name, + (u32) dl->al.offset, op_loc->addr_mode =3D=3D PERF_AAM_PRE_INDEX ? + "pre" : "post", offset, reg, reg); + pr_debug_type_name(&tsr->type, tsr->kind); +} + +/* + * Match standard load variants (ldr, ldur, ldar, ldp) that follow + * straightforward load semantics: memory source on the right + * and target registers on the left (written). Excludes exclusive loads + * (ldxr, ldxp, etc.) and acquire/exclusive combination variants. + */ +static bool is_standard_load_insn(const char *name) +{ + return !strncmp(name, "ldr", 3) || /* ldr, ldrb, ldrh, ldrsb, ldrsh, ld= rsw */ + !strncmp(name, "ldur", 4) || /* ldur, ldurb, ldurh, ldursb, ldurs= h, ldursw */ + !strncmp(name, "ldar", 4) || /* ldar, ldarb, ldarh */ + !strncmp(name, "ldp", 3); /* ldp, ldpsw */ +} + +/* + * For load insns: propagate type from source reg state @src_states to @dr= eg. + * + * @mem_spacing accounts for the additional in-memory spacing between the = two + * loads when handling multi-reg loads (e.g. the second target reg in 'ldp= '), + * which is added to the reg offset. + */ +static int propagate_load_reg_state(struct type_state *state, + struct data_loc_info *dloc, + struct disasm_line *dl, int dreg, + struct annotated_op_loc *src, + struct type_state_reg **src_states, + int mem_spacing) +{ + struct type_state_reg *tsr; + struct type_state_reg *src_tsr =3D src_states[0]; + Dwarf_Die type_die; + u32 insn_offset =3D dl->al.offset; + int sreg =3D src->reg1; + int reg_offset; + + if (!has_reg_type(state, dreg)) + return -1; + + tsr =3D &state->regs[dreg]; + tsr->copied_from =3D -1; + +retry: + if (arch_get_reg_offset(dloc->arch, src, sreg, state, false, ®_offset)) + goto load_non_regoff; + + reg_offset +=3D mem_spacing; + + if (!src_tsr || !src_tsr->ok) + return -1; + + /* Dereference the pointer if it has one */ + if (src_tsr->kind =3D=3D TSR_KIND_TYPE && + die_deref_ptr_type(&src_tsr->type, + src_tsr->offset + reg_offset, &type_die)) { + tsr->type =3D type_die; + tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; + tsr->ok =3D true; + + pr_debug_dtp("%s [%x] %#x(reg%d) -> reg%d", + dl->ins.name, insn_offset, reg_offset, sreg, dreg); + pr_debug_type_name(&tsr->type, tsr->kind); + return 0; + } + + /* Handle dereference of TSR_KIND_POINTER registers */ + if (src_tsr->kind =3D=3D TSR_KIND_POINTER && + die_get_member_type(&src_tsr->type, + src_tsr->offset + reg_offset, &type_die)) { + tsr->type =3D src_tsr->type; + tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D src_tsr->offset + reg_offset; + tsr->imm_value =3D 0; + tsr->ok =3D true; + + pr_debug_dtp("%s [%x] addr %#x(reg%d) -> reg%d", + dl->ins.name, insn_offset, reg_offset, sreg, dreg); + pr_debug_type_name(&tsr->type, tsr->kind); + return 0; + } + +load_non_regoff: + /* Try another register if any */ + if (src->multi_regs && src->reg1 !=3D src->reg2 && sreg !=3D src->reg2 && + !(src->extend_type || src->shift_type)) { + sreg =3D src->reg2; + src_tsr =3D src_states[1]; + goto retry; + } + + return -1; +} + +static void update_load_insn_state(struct type_state *state, + struct data_loc_info *dloc, + struct disasm_line *dl, + struct annotated_op_loc *src, + struct annotated_op_loc *dst) +{ + struct type_state_reg snapshots[2]; + struct type_state_reg *src_states[2] =3D {}; + int mem_spacing =3D 0; + + if (!src->mem_ref || /* exclude PC-relative loads */ + !has_reg_type(state, src->reg1)) { + /* Invalidate tracked destination registers */ + if (has_reg_type(state, dst->reg1)) + invalidate_reg_state(&state->regs[dst->reg1]); + if (dst->multi_regs && has_reg_type(state, dst->reg2)) + invalidate_reg_state(&state->regs[dst->reg2]); + goto out_adjust; + } + + /* + * Snapshot source register states before updating destination registers. + * This preserves the original source state for aliased loads (e.g., + * ldp x0, x1, [x0]), where updating the first destination may overwrite + * the source register. + */ + snapshots[0] =3D state->regs[src->reg1]; + src_states[0] =3D &snapshots[0]; + if (src->multi_regs && has_reg_type(state, src->reg2)) { + snapshots[1] =3D state->regs[src->reg2]; + src_states[1] =3D &snapshots[1]; + } + + /* Handle the first destination register */ + if (has_reg_type(state, dst->reg1)) { + if (propagate_load_reg_state(state, dloc, dl, dst->reg1, + src, src_states, mem_spacing)) + invalidate_reg_state(&state->regs[dst->reg1]); + } + + if (!dst->multi_regs || !has_reg_type(state, dst->reg2)) + goto out_adjust; + + /* Handle the second destination register */ + if (!strcmp(dl->ins.name, "ldpsw")) + mem_spacing =3D 4; /* ldpsw loads two 32-bit signed words (4-byte spaci= ng) */ + else + mem_spacing =3D arm64__reg_size(dl->ops.target.raw); + + if (mem_spacing < 0 || + propagate_load_reg_state(state, dloc, dl, dst->reg2, + src, src_states, mem_spacing)) + invalidate_reg_state(&state->regs[dst->reg2]); + +out_adjust: + adjust_reg_index_state(state, dloc, dl, src); +} + static void update_insn_state_arm64(struct type_state *state, struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) { struct annotated_insn_loc loc; + struct annotated_op_loc *src =3D &loc.ops[INSN_OP_SOURCE]; struct annotated_op_loc *dst =3D &loc.ops[INSN_OP_TARGET]; u32 insn_offset =3D dl->al.offset; =20 @@ -525,7 +724,8 @@ static void update_insn_state_arm64(struct type_state *= state, * Invalidate destination register(s) for unsupported instructions to * prevent stale type info from propagating to subsequent instructions. */ - if (has_reg_type(state, dst->reg1) && !dst->mem_ref) { + if (has_reg_type(state, dst->reg1) && !dst->mem_ref && + !is_standard_load_insn(dl->ins.name)) { pr_debug_dtp("%s [%x] invalidate reg%d", dl->ins.name, insn_offset, dst->reg1); invalidate_reg_state(&state->regs[dst->reg1]); @@ -536,6 +736,10 @@ static void update_insn_state_arm64(struct type_state = *state, pr_debug_dtp("\n"); return; } + + /* Memory to register transfers */ + if (is_standard_load_insn(dl->ins.name)) + update_load_insn_state(state, dloc, dl, src, dst); } #endif =20 --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 54F9C3AE184; Wed, 16 Sep 2026 01:30:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522223; cv=none; b=Xv9Kq+F/t6LnEl2YGeIDDcfJFUCtNfLFd/vHh3QWRTZly9A5YlQoi5UOtz/FE895BJW7gnSWVkqWlsElxf7tcD4f12KPWBI4onHCs3XzRteYI5/+ABSFw3Bu1oWMaEpHFn7oZ7ilwMcptzMPpq4wvWwgaDlJGDaw8FQFkimcyWk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522223; c=relaxed/simple; bh=Utqhbkv2WIOYhPGlzpt4T6nqgHcQgx159GQ/E5eyndA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=X68Kdiuc213SjHclTj+xqoVd1hrJbkvF/h8K7A7h+bkQLOxTYSMlvQ64qvqBd9ToZKxcCtr62GJbTfitXMfXK/0g4ksmf25Wz2N5C38jz2ovMEbXXN8dQaYEnP9yGm7a69Jj5SSgniYDEkMK+sNuDanLmqukz5SSNvoiteI7sFA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XK1PlMzKHMW1; Wed, 16 Sep 2026 09:29:53 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 8FD7B405A4; Wed, 16 Sep 2026 09:30:06 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S19; Wed, 16 Sep 2026 09:30:06 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 17/26] perf annotate-arm64: Support store instruction tracking Date: Wed, 16 Sep 2026 01:29:31 +0000 Message-Id: <5f49abec1847e5e684ce4ae4462f06857cdbea89.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S19 X-Coremail-Antispam: 1UD129KBjvJXoWxXryUtF13Jr17XFykCFyxAFb_yoW5JFWDpr Z8Cw1YgF4Utr4I9an3XF4I9r9xua1fKws0kr9Fy397AF42yrn3trZ3Kay3tFW8JrZ3uw1Y qF4qkr4DGayjyaUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Extend update_insn_state_arm64() to handle standard store instructions (str, stur, stlr, stp). Exclusive stores (e.g., stxr, stxp) are omitted as they exhibit different operand semantics. Unlike load instructions, a store instruction sets a value in the struct within the memory where the destination register resides, and does not alter its type. Therefore, no processing is required for the transfer. The only point to note is that store instructions support pre-index and post-index addressing modes, so calling adjust_reg_index_state() is still necessary to handle their addressing. Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index 11b2bdceaacb..a72c7703dd6b 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -659,6 +659,20 @@ static void update_load_insn_state(struct type_state *= state, adjust_reg_index_state(state, dloc, dl, src); } =20 +/* + * Match standard store variants (str, stur, stlr, stp) that follow + * straightforward store semantics: source registers on the left (read-onl= y) + * and memory target on the right. Excludes exclusive stores (stxr, stxp, = etc.) + * which have status/result register side effects. + */ +static bool is_standard_store_insn(const char *name) +{ + return !strncmp(name, "str", 3) || /* str, strb, strh */ + !strncmp(name, "stur", 4) || /* stur, sturb, sturh */ + !strncmp(name, "stlr", 4) || /* stlr, stlrb, stlrh */ + !strncmp(name, "stp", 3); /* stp */ +} + static void update_insn_state_arm64(struct type_state *state, struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) @@ -740,6 +754,17 @@ static void update_insn_state_arm64(struct type_state = *state, /* Memory to register transfers */ if (is_standard_load_insn(dl->ins.name)) update_load_insn_state(state, dloc, dl, src, dst); + /* Register to memory transfers */ + else if (is_standard_store_insn(dl->ins.name)) { + /* + * Ignore transfers since it'd set a value in a struct + * and won't change the type. + * + * Needs to update the pre-index and post-index addressing + * modes for the destination register. + */ + adjust_reg_index_state(state, dloc, dl, dst); + } } #endif =20 --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B06253B47F0; Wed, 16 Sep 2026 01:30:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522228; cv=none; b=kZfeJ21ef8UiiZ82mKoxCShYuiMEWK//r3G3/ZjdPAlAWbBA2xB7LhJFtMv3OTkuDqxOnQC6aE/IbxMieV3mwLdqhgTo1w27S4QKBrbt4D8WejETSOW0t5cOft20nTqj39yzH0SzyVzmpz0vuscdPJE2VJ7r0k//AfKKaj1OaFw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522228; c=relaxed/simple; bh=KC5Ebn92W23t2J+hbN8i7Vtf8adzx46OQkVXzzpFXUE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=An/7th1tW7NzNeC5HyXPOTW1efjPQV/S7luhEe1CmveqxObfRsFC3lEhbniFw8NXYwBc431/CGhZXm1pcn3JrWOq7tkdhqjZ/+Dox7xkKdpgATqm4f3fFn8fphpxxfLHH7acZryzZvAVbIHTzwPdsszufsPI760X62q4fA5KvSs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XV3cn3zYQtrj; Wed, 16 Sep 2026 09:30:02 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 9C77B40578; Wed, 16 Sep 2026 09:30:06 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S20; Wed, 16 Sep 2026 09:30:06 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 18/26] perf annotate-data: Expand type_state_reg imm_value to u64 Date: Wed, 16 Sep 2026 01:29:32 +0000 Message-Id: <12af931b0d7a666f1d8403c01f1a3677698374ba.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S20 X-Coremail-Antispam: 1UD129KBjvJXoWxJr18try5GrW7ZF1DCr4kZwb_yoW8Cw43p3 90k347Jw1UWr4YgrnxtFWrXF1S9r13Za4fGryYgw1fZFWfXFn3tryIqr4YyFW8W3s7Cw1U JwnYqr4Dt3ykGaUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" The arm64 'adrp + add/ldr' instruction pair involves global variable address calculation and passing, which requires storing the 64-bit address in type_state_reg. Currently, there is no field in type_state_reg that can hold such an address. The most likely candidate for reuse is imm_value, but it is defined as u32, which limits the size of values it can carry. To address this, expand imm_value from u32 to u64. Also update related compilation warnings and fix the sign-extension issue introduced by this change. Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- tools/perf/util/annotate-arch/annotate-x86.c | 4 ++-- tools/perf/util/annotate-data.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-x86.c b/tools/perf/util= /annotate-arch/annotate-x86.c index aa381d25a63b..f5e40cef08ab 100644 --- a/tools/perf/util/annotate-arch/annotate-x86.c +++ b/tools/perf/util/annotate-arch/annotate-x86.c @@ -536,11 +536,11 @@ static void update_insn_state_x86(struct type_state *= state, =20 if (src->imm) { tsr->kind =3D TSR_KIND_CONST; - tsr->imm_value =3D src->offset; + tsr->imm_value =3D (s64)src->offset; tsr->offset =3D 0; tsr->ok =3D true; =20 - pr_debug_dtp("mov [%x] imm=3D%#x -> reg%d\n", + pr_debug_dtp("mov [%x] imm=3D%#"PRIx64" -> reg%d\n", insn_offset, tsr->imm_value, dst->reg1); return; } diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index 68e3feda2eda..62efdcd8a79a 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -173,7 +173,7 @@ extern struct annotated_data_stat ann_data_stat; */ struct type_state_reg { Dwarf_Die type; - u32 imm_value; + u64 imm_value; /* * The offset within the struct that the register points to. * A value of 0 means the register points to the beginning. --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55A813AE188; Wed, 16 Sep 2026 01:30:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522223; cv=none; b=tBniPnnXHtK61keuOKtbUQUWItFEHSkwaZq13DsSgQ9np0v9L6gbWe3K/VafQTUKBPAdfU5OVuBJKkYIfnSUidgDnO0caYEp5U+cSpiEajcgVRSt54TEK/lX/C1t/o2gb+WbTB2duA2N0QvWhk3/ammYKWEnH38BAQVvpg/44KM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522223; c=relaxed/simple; bh=gu/irH4xHKyQrTYNpvzC0VdmiHz2BuMy+VGA/tohtYw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=C43wGIIYamPI1EEnlABVxnWSYqDO4FScH2R1Pmv5D/gAHQs+hJpnRqpuFCHgfI3YnKrYM6UWhLy/nnKLhQIFUNpX21m/P7OgGV20MHriZ1ntq41k9PRnMhNEUjw7S7BvsqugsOyTVU3Pjkj3lhGMl6wdW3g7pyPc+Nx0/c7XbkU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=none smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.170]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XK0j86zKHMV4; Wed, 16 Sep 2026 09:29:53 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id B42814056B; Wed, 16 Sep 2026 09:30:06 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S21; Wed, 16 Sep 2026 09:30:06 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 19/26] perf annotate-data: Track imm_value for stack variables Date: Wed, 16 Sep 2026 01:29:33 +0000 Message-Id: <8b29a11ea56bdc9973e3ab65d6f5ebdea0927bfa.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S21 X-Coremail-Antispam: 1UD129KBjvJXoWxGF18uw17Jw1DGFyUGFW8Crg_yoW7JF4xpr WDWFy7W3W7Wr4IqrsxJF4UXr93Gws2gF1Fk3s0qFnayFyxtr1fG3s7tFW5tF47Cryvyw17 Jwn0kr4DXw47KaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Currently, imm_value is tracked in registers but dropped when values are saved to or loaded from stack variables during type profiling. If a register of type TSR_KIND_CONST is stored to the stack, its value will be lost. Add an imm_value field to struct type_state_stack and update set_stack_state() and findnew_stack_state() to accept and preserve the immediate value when updating stack state. Reviewed-by: Shuai Xue Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- tools/perf/util/annotate-arch/annotate-x86.c | 8 ++++++-- tools/perf/util/annotate-data.c | 13 +++++++------ tools/perf/util/annotate-data.h | 5 +++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-x86.c b/tools/perf/util= /annotate-arch/annotate-x86.c index f5e40cef08ab..21729e153fa0 100644 --- a/tools/perf/util/annotate-arch/annotate-x86.c +++ b/tools/perf/util/annotate-arch/annotate-x86.c @@ -591,6 +591,7 @@ static void update_insn_state_x86(struct type_state *st= ate, tsr->type =3D stack->type; tsr->kind =3D stack->kind; tsr->offset =3D stack->ptr_offset; + tsr->imm_value =3D stack->imm_value; tsr->ok =3D true; } else if (die_get_member_type(&stack->type, offset - stack->offset, @@ -598,6 +599,7 @@ static void update_insn_state_x86(struct type_state *st= ate, tsr->type =3D type_die; tsr->kind =3D TSR_KIND_TYPE; tsr->offset =3D 0; + tsr->imm_value =3D 0; tsr->ok =3D true; } else { invalidate_reg_state(tsr); @@ -773,10 +775,12 @@ static void update_insn_state_x86(struct type_state *= state, */ if (!stack->compound) set_stack_state(stack, offset, tsr->kind, - &tsr->type, tsr->offset); + &tsr->type, tsr->offset, + tsr->imm_value); } else { findnew_stack_state(state, offset, tsr->kind, - &tsr->type, tsr->offset); + &tsr->type, tsr->offset, + tsr->imm_value); } =20 if (dst->reg1 =3D=3D fbreg) { diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index d9f0bfd3f0a7..8bd9b6370277 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -594,7 +594,7 @@ struct type_state_stack *find_stack_state(struct type_s= tate *state, } =20 void set_stack_state(struct type_state_stack *stack, int offset, u8 kind, - Dwarf_Die *type_die, int ptr_offset) + Dwarf_Die *type_die, int ptr_offset, u64 imm_value) { int tag; Dwarf_Word size; @@ -611,8 +611,9 @@ void set_stack_state(struct type_state_stack *stack, in= t offset, u8 kind, stack->offset =3D offset; stack->ptr_offset =3D ptr_offset; stack->kind =3D kind; + stack->imm_value =3D imm_value; =20 - if (kind =3D=3D TSR_KIND_POINTER) { + if (kind =3D=3D TSR_KIND_POINTER || kind =3D=3D TSR_KIND_CONST) { stack->compound =3D false; return; } @@ -633,18 +634,18 @@ void set_stack_state(struct type_state_stack *stack, = int offset, u8 kind, struct type_state_stack *findnew_stack_state(struct type_state *state, int offset, u8 kind, Dwarf_Die *type_die, - int ptr_offset) + int ptr_offset, u64 imm_value) { struct type_state_stack *stack =3D find_stack_state(state, offset); =20 if (stack) { - set_stack_state(stack, offset, kind, type_die, ptr_offset); + set_stack_state(stack, offset, kind, type_die, ptr_offset, imm_value); return stack; } =20 stack =3D malloc(sizeof(*stack)); if (stack) { - set_stack_state(stack, offset, kind, type_die, ptr_offset); + set_stack_state(stack, offset, kind, type_die, ptr_offset, imm_value); list_add(&stack->list, &state->stack_vars); } return stack; @@ -939,7 +940,7 @@ static void update_var_state(struct type_state *state, = struct data_loc_info *dlo continue; =20 findnew_stack_state(state, offset, TSR_KIND_TYPE, - &mem_die, /*ptr_offset=3D*/0); + &mem_die, /*ptr_offset=3D*/0, /*imm_value=3D*/0); =20 if (var->reg =3D=3D state->stack_reg) { pr_debug_dtp("var [%"PRIx64"] %#x(reg%d)", diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index 62efdcd8a79a..de92459e8502 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -199,6 +199,7 @@ struct type_state_stack { int size; bool compound; u8 kind; + u64 imm_value; }; =20 /* @@ -253,9 +254,9 @@ bool has_reg_type(struct type_state *state, int reg); struct type_state_stack *findnew_stack_state(struct type_state *state, int offset, u8 kind, Dwarf_Die *type_die, - int ptr_offset); + int ptr_offset, u64 imm_value); void set_stack_state(struct type_state_stack *stack, int offset, u8 kind, - Dwarf_Die *type_die, int ptr_offset); + Dwarf_Die *type_die, int ptr_offset, u64 imm_value); struct type_state_stack *find_stack_state(struct type_state *state, int offset); void invalidate_reg_state(struct type_state_reg *reg); --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8527F3AEF55; Wed, 16 Sep 2026 01:30:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522225; cv=none; b=Gkuuaa091A7xNtkTMXGZ0/LfutYN+4bPWTQEVqN5/MDHxdgl2Yd0vqax8+MQxOFO0wdTERyLSOTzSzNDFe3XpVPgQwdJ3s4TVgMO1+j54/EZwN8MY3i5P+R7eRYc/a7RA3D8E811mjoop2OaZTzLGnKE/naki8+0I8vp4jZyclo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522225; c=relaxed/simple; bh=1LZAFEzm9aAr0LYn1MMN1korAsMJLY/yPRtAe4VBemQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=e0PUk38KABD40KOFCZiRhXUb6r+aRwfdETAmAolasCuSvt6x1ZFX46+ZtumYVcNSesmtJP93PVTOaEBLLIqZVLPTT4fLMhLuDsVYbzBzThnWM8C0pnvEfCGLB7rRaFME+SyU79DTdtAEsS8zfto6dxIfp54CWbRUCrCYxFEbGAI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.177]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XK23Y8zKHMWl; Wed, 16 Sep 2026 09:29:53 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id DAE2040592; Wed, 16 Sep 2026 09:30:06 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S22; Wed, 16 Sep 2026 09:30:06 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 20/26] perf annotate-x86: Delete stale stack state on store of untracked register Date: Wed, 16 Sep 2026 01:29:34 +0000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S22 X-Coremail-Antispam: 1UD129KBjvJXoWxur4xGry8KFyxKrWUGF4xCrg_yoW5KrW7pr yDC343Ww17Gr4SqrnxAFW5XF95Crs7X3WrC3s0qwn2vF1xJr1fGr97tFWYyF47Xr92kw12 yw1DKr4DJa1IgaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH2b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7Cj xVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxc IEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5 MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr 0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0E wIxGrwCI42IY6xIIjxv20xvE14v26ryj6F1UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr 0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI 42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUU U== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" When a register without a tracked type is stored to a stack slot that previously held a valid type, the code currently performs an early return. This leaves the old type information intact in the stack state. As a result, a stale type bug occurs: 1. A tracked register is stored into a stack slot. 2. The register becomes untracked/invalid (e.g., across a function call). 3. The now-untracked register is stored into the same stack slot. 4. Subsequent loads from that slot erroneously pick up the old stale type because the stack entry was never invalidated. Fix this by introducing delete_stack_state() to search and free a stack entry for a given offset. When storing an untracked or invalid source register into a stack location, call delete_stack_state() to delete the stale entry before returning. Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- tools/perf/util/annotate-arch/annotate-x86.c | 17 +++++++++++++---- tools/perf/util/annotate-data.c | 10 ++++++++++ tools/perf/util/annotate-data.h | 1 + 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-x86.c b/tools/perf/util= /annotate-arch/annotate-x86.c index 21729e153fa0..3a6ea7e978e0 100644 --- a/tools/perf/util/annotate-arch/annotate-x86.c +++ b/tools/perf/util/annotate-arch/annotate-x86.c @@ -753,15 +753,24 @@ static void update_insn_state_x86(struct type_state *= state, } /* Case 3. register to memory transfers */ if (!src->mem_ref && dst->mem_ref) { - if (!has_reg_type(state, src->reg1) || - !state->regs[src->reg1].ok) - return; - /* Check stack variables with offset */ if (dst->reg1 =3D=3D fbreg || dst->reg1 =3D=3D state->stack_reg) { struct type_state_stack *stack; int offset =3D dst->offset - fboff; =20 + if (!has_reg_type(state, src->reg1) || + !state->regs[src->reg1].ok) { + stack =3D find_stack_state(state, offset); + /* + * Preserve compound states when only a member + * is overwritten. + */ + if (stack && !stack->compound) + delete_stack_state(state, offset); + + return; + } + tsr =3D &state->regs[src->reg1]; =20 stack =3D find_stack_state(state, offset); diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 8bd9b6370277..9ca59bc2f841 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -651,6 +651,16 @@ struct type_state_stack *findnew_stack_state(struct ty= pe_state *state, return stack; } =20 +void delete_stack_state(struct type_state *state, int offset) +{ + struct type_state_stack *stack =3D find_stack_state(state, offset); + + if (stack) { + list_del(&stack->list); + free(stack); + } +} + void invalidate_reg_state(struct type_state_reg *reg) { reg->kind =3D TSR_KIND_INVALID; diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index de92459e8502..a0d7e20ed725 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -259,6 +259,7 @@ void set_stack_state(struct type_state_stack *stack, in= t offset, u8 kind, Dwarf_Die *type_die, int ptr_offset, u64 imm_value); struct type_state_stack *find_stack_state(struct type_state *state, int offset); +void delete_stack_state(struct type_state *state, int offset); void invalidate_reg_state(struct type_state_reg *reg); bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc, u64 ip, u64 var_addr, int *var_offset, --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 82B0A3AEF34; Wed, 16 Sep 2026 01:30:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522226; cv=none; b=W60ua9WJDds2iPiZhLnAS4XJuJcn0SqEz96DJ4KLy+qP03F+Ab6XOTIti2+zDHkAlfoNeG5s8pf6ueA9lwkuzK/CqueXoRBJ3x4RL3naeMO2keTrTMBnIw7fBD1ZOMgxHjTLIMRqN7YjsHkVX9obboxvaxLhPFA4aDdvCAo2bsY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522226; c=relaxed/simple; bh=T8fOPDbSzuUwTalFsMDiF9HJRjwralWIhRfc7ujjM8I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=u4bB69R+qqUl+k5vPb7hqYeGql7UuBhVvk7vjF75BuRx9FbhKGTv++y20tdivDES+sR2oR7gTZEUy4BXmBxqU0JL2XP0sJHw0wAV/1CskXxhPmGgrd2XcXhZUm5Dpw+WtjBVvZrW5oW7ll5tYIA/sGUl7VbtFKNwfac65b7vAj4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.170]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XK2HyKzKHMXF; Wed, 16 Sep 2026 09:29:53 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id EAB104056F; Wed, 16 Sep 2026 09:30:06 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S23; Wed, 16 Sep 2026 09:30:06 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 21/26] perf annotate-arm64: Support stack variable tracking Date: Wed, 16 Sep 2026 01:29:35 +0000 Message-Id: <11bcde1a75d96b524cc5a7f6fa442025680e56a0.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S23 X-Coremail-Antispam: 1UD129KBjvJXoW3XryDAw1rXry7XF1fAw4UCFg_yoWxuw1xpF 4DGFy3WwsrJr4S9Fs3Xr48Xr93uws7Kr1qkr90van2yFy3tF1Ykayktayavay5Gr97Zw17 Jw4DKr4DX3y7taDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUHFb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVWxJr0_GcWl84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x02 67AKxVW0oVCq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I 80ewAv7VC0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCj c4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YV CY1x02628vn2kIc2xKxwCY1x0262kKe7AKxVW8ZVWrXwCY1x0264kExVAvwVAq07x20xyl 42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJV WUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r4a6rW5MIIYrxkI7VAK I48JMIIF0xvE2Ix0cI8IcVAFwI0_Xr0_Ar1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4UJV WxJr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F4UMIIF 0xvEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjTRQYFCDUUUU X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Extend update_insn_state_arm64() to track data types stored on the stack. The implementation handles: 1. Stack Loads: Identify when a register is loaded from a stack slot and update the register's type state based on the tracked stack content or compound member types. 2. Stack Stores: Update or create new stack state entries when a tracked register type is stored to the stack. Similar to loads, stores also support saving one or two registers (in the case of 'stp'). Therefore, propagate_store_reg_state() is introduced. With these changes, the instruction tracker can now follow data types as they move between registers and memory, specifically for function local variables and compiler-spilled values on arm64. Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 168 ++++++++++++++++-- 1 file changed, 158 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index a72c7703dd6b..8339aab0d314 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -542,6 +542,8 @@ static int propagate_load_reg_state(struct type_state *= state, u32 insn_offset =3D dl->al.offset; int sreg =3D src->reg1; int reg_offset; + int fbreg =3D dloc->fbreg; + int fboff =3D 0; =20 if (!has_reg_type(state, dreg)) return -1; @@ -549,12 +551,57 @@ static int propagate_load_reg_state(struct type_state= *state, tsr =3D &state->regs[dreg]; tsr->copied_from =3D -1; =20 + if (dloc->fb_cfa) { + u64 ip =3D dloc->ms->sym->start + dl->al.offset; + u64 pc =3D map__rip_2objdump(dloc->ms->map, ip); + + if (die_get_cfa(dloc->di->dbg, pc, &fbreg, &fboff) < 0) + fbreg =3D -1; + } + retry: if (arch_get_reg_offset(dloc->arch, src, sreg, state, false, ®_offset)) goto load_non_regoff; =20 reg_offset +=3D mem_spacing; =20 + /* Check stack variables with offset */ + if (sreg !=3D -1 && (sreg =3D=3D fbreg || sreg =3D=3D state->stack_reg)) { + struct type_state_stack *stack; + int offset =3D sreg =3D=3D fbreg ? reg_offset - fboff : reg_offset; + + stack =3D find_stack_state(state, offset); + if (stack =3D=3D NULL) { + return -1; + } else if (!stack->compound) { + tsr->type =3D stack->type; + tsr->kind =3D stack->kind; + tsr->offset =3D stack->ptr_offset; + tsr->imm_value =3D stack->imm_value; + tsr->ok =3D true; + } else if (die_get_member_type(&stack->type, + offset - stack->offset, + &type_die)) { + tsr->type =3D type_die; + tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; + tsr->imm_value =3D 0; + tsr->ok =3D true; + } else { + return -1; + } + + if (sreg =3D=3D fbreg) { + pr_debug_dtp("%s [%x] -%#x(stack) -> reg%d", + dl->ins.name, insn_offset, -offset, dreg); + } else { + pr_debug_dtp("%s [%x] %#x(reg%d) -> reg%d", + dl->ins.name, insn_offset, offset, sreg, dreg); + } + pr_debug_type_name(&tsr->type, tsr->kind); + return 0; + } + if (!src_tsr || !src_tsr->ok) return -1; =20 @@ -673,6 +720,115 @@ static bool is_standard_store_insn(const char *name) !strncmp(name, "stp", 3); /* stp */ } =20 +/* + * For store insns: propagate type from @sreg to the memory location refer= enced + * by @dst, applying @mem_spacing to account for multi-regs stores (e.g. s= tp). + */ +static void propagate_store_reg_state(struct type_state *state, + struct data_loc_info *dloc, + struct disasm_line *dl, int sreg, + struct annotated_op_loc *dst, + int mem_spacing) +{ + struct type_state_reg *tsr; + u32 insn_offset =3D dl->al.offset; + int dreg =3D dst->reg1; + int reg_offset; + int fbreg =3D dloc->fbreg; + int fboff =3D 0; + + if (arch_get_reg_offset(dloc->arch, dst, dreg, state, false, ®_offset)) + return; + + reg_offset +=3D mem_spacing; + + if (dloc->fb_cfa) { + u64 ip =3D dloc->ms->sym->start + dl->al.offset; + u64 pc =3D map__rip_2objdump(dloc->ms->map, ip); + + if (die_get_cfa(dloc->di->dbg, pc, &fbreg, &fboff) < 0) + fbreg =3D -1; + } + + /* Check stack variables with offset */ + if (dreg !=3D -1 && (dreg =3D=3D fbreg || dreg =3D=3D state->stack_reg)) { + struct type_state_stack *stack; + int offset =3D dreg =3D=3D fbreg ? reg_offset - fboff : reg_offset; + + if (!has_reg_type(state, sreg) || !state->regs[sreg].ok) { + stack =3D find_stack_state(state, offset); + /* Preserve compound states when only a member is overwritten. */ + if (stack && !stack->compound) + delete_stack_state(state, offset); + + return; + } + + tsr =3D &state->regs[sreg]; + + stack =3D find_stack_state(state, offset); + if (stack) { + if (!stack->compound) + set_stack_state(stack, offset, tsr->kind, &tsr->type, + tsr->offset, tsr->imm_value); + /* + * If it's a compound type, it means attempting to + * write to a member value of the compound type without + * changing the compound type itself, so do nothing. + */ + } else { + findnew_stack_state(state, offset, tsr->kind, &tsr->type, + tsr->offset, tsr->imm_value); + } + + if (dreg =3D=3D fbreg) { + pr_debug_dtp("%s [%x] reg%d -> -%#x(stack)", + dl->ins.name, insn_offset, sreg, -offset); + } else { + pr_debug_dtp("%s [%x] reg%d -> %#x(reg%d)", + dl->ins.name, insn_offset, sreg, offset, dreg); + } + if (tsr->offset !=3D 0) + pr_debug_dtp(" reg%d offset %#x ->", sreg, tsr->offset); + + pr_debug_type_name(&tsr->type, tsr->kind); + } + /* + * Ignore other transfers since it'd set a value in a struct + * and won't change the type. + */ +} + +static void update_store_insn_state(struct type_state *state, + struct data_loc_info *dloc, + struct disasm_line *dl, + struct annotated_op_loc *src, + struct annotated_op_loc *dst) +{ + int mem_spacing =3D 0; + + if (!has_reg_type(state, dst->reg1)) + return; + + /* Handle the first source register */ + if (has_reg_type(state, src->reg1)) + propagate_store_reg_state(state, dloc, dl, src->reg1, + dst, mem_spacing); + + if (!src->multi_regs || !has_reg_type(state, src->reg2)) + goto out_adjust; + + /* Handle the second source register */ + mem_spacing =3D arm64__reg_size(dl->ops.source.raw); + + if (mem_spacing >=3D 0) + propagate_store_reg_state(state, dloc, dl, src->reg2, + dst, mem_spacing); + +out_adjust: + adjust_reg_index_state(state, dloc, dl, dst); +} + static void update_insn_state_arm64(struct type_state *state, struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) @@ -755,16 +911,8 @@ static void update_insn_state_arm64(struct type_state = *state, if (is_standard_load_insn(dl->ins.name)) update_load_insn_state(state, dloc, dl, src, dst); /* Register to memory transfers */ - else if (is_standard_store_insn(dl->ins.name)) { - /* - * Ignore transfers since it'd set a value in a struct - * and won't change the type. - * - * Needs to update the pre-index and post-index addressing - * modes for the destination register. - */ - adjust_reg_index_state(state, dloc, dl, dst); - } + else if (is_standard_store_insn(dl->ins.name)) + update_store_insn_state(state, dloc, dl, src, dst); } #endif =20 --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 321A33A1687; Wed, 16 Sep 2026 01:30:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522229; cv=none; b=R1chJDTO1e84C0oUvorH9iuZsR8EJCZAo24lLLTxIncu6qN+uSx6317fIGC55V9W/YIZ/J041/qfACe/osP1C9sjkQMpFqCvESzPEK2b5JnCApT5Sq6XD8WnkzHjVmUSP4BgxhbvbnKUk0wyDSzcxUfULiTm/ZUqkmMxVLeU+8o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522229; c=relaxed/simple; bh=B3rtw1GUcBaDVKdEjCsWpU/adlqq99LKX6FeYjabJjo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OHOUTfQPwvNobtJNg+EOZxeWKVqtlgoY5oK+HsQfiGqnTVyNk+WwwjNKLUVYFKn5fqJAIUCd2YI7iBjrc/RvepQy0mLgHabDDNvnFAvAH1eBTi/5N3N6eXFneBp9Lne1OkTUCXINKjmzrDU6htv+39dST+zQsj+hy27TKXn0380= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XV6S1lzYQtm6; Wed, 16 Sep 2026 09:30:02 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 082CD40573; Wed, 16 Sep 2026 09:30:07 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S24; Wed, 16 Sep 2026 09:30:06 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 22/26] perf annotate-arm64: Support 'mov' instruction tracking Date: Wed, 16 Sep 2026 01:29:36 +0000 Message-Id: <7ce94ff2b32c4a6b06a79031bc5c825fb563c12f.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S24 X-Coremail-Antispam: 1UD129KBjvJXoWxGw15ZFWxZrWkXF1xKr48JFb_yoW7Jw1fpa yDC345G39Fqr42gFsIqF47Xr9a9w4xKr12kryqqwsIyFy3tw1rKa97KFWavF45JrykAr17 Gw4DKFZ8Xw42kaUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH0b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVWxJr0_GcWl84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x02 67AKxVW0oVCq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I 80ewAv7VC0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCj c4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YV CY1x02628vn2kIc2xKxwCY1x0262kKe7AKxVW8ZVWrXwCY1x0264kExVAvwVAq07x20xyl 42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJV WUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r4a6rW5MIIYrxkI7VAK I48JMIIF0xvE2Ix0cI8IcVAFwI0_Xr0_Ar1lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4UJV W0owCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAI cVC2z280aVCY1x0267AKxVWxJr0_GcJvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUUU== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Extend update_insn_state_arm64() to support register-to-register and immediate-to-register 'mov' instructions. For register-to-register 'mov' (e.g., mov dreg, sreg), propagate data type information from the source register to the destination register. For immediate-to-register 'mov' (e.g., mov dreg, #imm), store the immediate value in the destination register's imm_value field and set its kind to TSR_KIND_CONST, allowing subsequent instructions to resolve it as a constant. A real-world example is shown below: ffff8000803eebf8 : ffff8000803eec20: mov x21, x0 // x0 (struct vm_area_struct*) -= > x21 ffff8000803eec28: ldr x2, [x0, #112] ffff8000803eec2c: cbz x2, ffff8000803eec94 * ffff8000803eec94: ldr x0, [x21, #152] Before this commit, the type of x21 was unknown, causing the subsequent inference to fail: var [0] reg0 offset 0 type=3D'struct vm_area_struct*' size=3D0x8 chk [9c] reg21 offset=3D0x98 ok=3D0 kind=3D0 cfa : no type information final result: no type information After this commit, the type of x21 is correctly inferred as 'vm_area_struct= ': var [0] reg0 offset 0 type=3D'struct vm_area_struct*' size=3D0x8 mov [28] reg0 -> reg21 type=3D'struct vm_area_struct*' size=3D0x8 chk [9c] reg21 offset=3D0x98 ok=3D1 kind=3D1 (struct vm_area_struct*) : G= ood! found by insn track: 0x98(reg21) type-offset=3D0x98 final result: type=3D'struct vm_area_struct' size=3D0xb0 Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index 8339aab0d314..3358562893b1 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include @@ -612,6 +613,7 @@ static int propagate_load_reg_state(struct type_state *= state, tsr->type =3D type_die; tsr->kind =3D TSR_KIND_TYPE; tsr->offset =3D 0; + tsr->imm_value =3D 0; tsr->ok =3D true; =20 pr_debug_dtp("%s [%x] %#x(reg%d) -> reg%d", @@ -829,6 +831,54 @@ static void update_store_insn_state(struct type_state = *state, adjust_reg_index_state(state, dloc, dl, dst); } =20 +static void update_mov_insn_state(struct type_state *state, + struct disasm_line *dl, + struct annotated_op_loc *src, + struct annotated_op_loc *dst) +{ + struct type_state_reg *tsr; + u32 insn_offset =3D dl->al.offset; + int sreg =3D src->reg1; + int dreg =3D dst->reg1; + + if (!has_reg_type(state, dreg)) + return; + + tsr =3D &state->regs[dreg]; + tsr->copied_from =3D -1; + + if (src->imm) { + invalidate_reg_state(tsr); + tsr->kind =3D TSR_KIND_CONST; + tsr->imm_value =3D (s64)src->offset; + tsr->offset =3D 0; + tsr->ok =3D true; + + pr_debug_dtp("mov [%x] imm=3D%#"PRIx64" -> reg%d\n", + insn_offset, tsr->imm_value, dreg); + return; + } + + if (!has_reg_type(state, sreg) || !state->regs[sreg].ok) { + invalidate_reg_state(tsr); + return; + } + + tsr->type =3D state->regs[sreg].type; + tsr->kind =3D state->regs[sreg].kind; + tsr->imm_value =3D state->regs[sreg].imm_value; + tsr->offset =3D state->regs[sreg].offset; + tsr->lifetime_active =3D state->regs[sreg].lifetime_active; + tsr->lifetime_end =3D state->regs[sreg].lifetime_end; + tsr->ok =3D state->regs[sreg].ok; + + if (tsr->kind =3D=3D TSR_KIND_TYPE || tsr->kind =3D=3D TSR_KIND_POINTER) + tsr->copied_from =3D sreg; + + pr_debug_dtp("mov [%x] reg%d -> reg%d", insn_offset, sreg, dreg); + pr_debug_type_name(&tsr->type, tsr->kind); +} + static void update_insn_state_arm64(struct type_state *state, struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) @@ -895,6 +945,7 @@ static void update_insn_state_arm64(struct type_state *= state, * prevent stale type info from propagating to subsequent instructions. */ if (has_reg_type(state, dst->reg1) && !dst->mem_ref && + strcmp(dl->ins.name, "mov") && !is_standard_load_insn(dl->ins.name)) { pr_debug_dtp("%s [%x] invalidate reg%d", dl->ins.name, insn_offset, dst->reg1); @@ -907,8 +958,11 @@ static void update_insn_state_arm64(struct type_state = *state, return; } =20 + /* Register to register or imm value to register transfers */ + if (!strcmp(dl->ins.name, "mov")) + update_mov_insn_state(state, dl, src, dst); /* Memory to register transfers */ - if (is_standard_load_insn(dl->ins.name)) + else if (is_standard_load_insn(dl->ins.name)) update_load_insn_state(state, dloc, dl, src, dst); /* Register to memory transfers */ else if (is_standard_store_insn(dl->ins.name)) --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8536C3AF644; Wed, 16 Sep 2026 01:30:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522224; cv=none; b=b0seNUf91n2vHL68tlqmor+yaHgs38Zk4sm9mVB9vD6wiw/TKSXqgW4ilVPqlfgJXSlIhFWHOt6IsMjgpoFE8Qoo7S0/JmzRvm9F2LCrSc1yShoiBWplikcUTIEhPdRf3CYF8Z8H4GRPuFR481AhtuKpi2gT0GKilgtTwskoLo8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522224; c=relaxed/simple; bh=rcv7nH7QlrFL27nFmZD6Zu4P0jLt/ggDFLp8hwCSTcw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=u4FIalpHu6d0SK3B16DKTiAC6nlcWcjlukVK2rjuIVFEUPAefgUIXRStb3KlUV4FxPyFu8nINJM+qBdvbrnnsPRQea15FiI6jYGqB++++Wwv8WEU8KKlnmImrp4DGC4frCvNsTkYuTleYpCghk1VNpHtG2pXroXWx67rVw9pCDU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.170]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1XK3RxmzKHMWN; Wed, 16 Sep 2026 09:29:53 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 1EEF140561; Wed, 16 Sep 2026 09:30:07 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP4 (Coremail) with UTF8SMTPA id gCh0CgAn+CoH8alqUcjbAQ--.36458S25; Wed, 16 Sep 2026 09:30:06 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 23/26] perf annotate-arm64: Support 'add' instruction tracking Date: Wed, 16 Sep 2026 01:29:37 +0000 Message-Id: <8bee20cb7054ce8d0b1cfa064a4d62d0a1b29d42.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgAn+CoH8alqUcjbAQ--.36458S25 X-Coremail-Antispam: 1UD129KBjvJXoWxXw15Xw1fJw1UJrWkurWruFg_yoWrtFW8pF Zru34UGw4Iyr4agan3JFWfXr9a9wsrGF1UCr9IqwsayFW3trn5Ka93KrWavFW5Gr93Cw13 Jw4DKFs3Xw429aUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUH0b4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVWxJr0_GcWl84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x02 67AKxVW0oVCq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I 80ewAv7VC0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCj c4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YV CY1x02628vn2kIc2xKxwCY1x0262kKe7AKxVW8ZVWrXwCY1x0264kExVAvwVAq07x20xyl 42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJV WUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r4a6rW5MIIYrxkI7VAK I48JMIIF0xvE2Ix0cI8IcVAFwI0_Xr0_Ar1lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4UJV W0owCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAI cVC2z280aVCY1x0267AKxVWxJr0_GcJvcSsGvfC2KfnxnUUI43ZEXa7sRNg4S3UUUUU== X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Extend update_insn_state_arm64() to track 'add' instructions for structure member address calculation. Unlike x86, the arm64 'add' instruction has an extra base register among its source operands. Therefore, in terms of propagating the data type, it is essentially performing a 'mov', except that before the 'mov', it first needs to be updated by adding the offset or reg2. A real-world example is shown below: ffff80008001c9a8 : ffff80008001c9c4: add x19, x0, #0xeb8 // x0 (task_struct*) + 0xeb8 ->= x19 * ffff80008001c9d0: ldr x0, [x19] Before this commit, the type flow broke at the 'add' instruction, leaving the subsequent load with no type information: chk [28] reg19 offset=3D0 ok=3D0 kind=3D0 cfa : no type information final result: no type information After this commit, the tracker correctly follows the member address calculation: var [0] reg0 offset 0 type=3D'struct task_struct*' add [1c] address of 0xeb8(reg0) -> reg19 type=3D'struct task_struct*' chk [28] reg19 offset=3D0 ok=3D1 kind=3D1 (struct task_struct*) : Good! found by insn track: 0(reg19) type-offset=3D0xeb8 final result: type=3D'struct task_struct' Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 74 ++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index 3358562893b1..68510813f08b 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -879,6 +879,74 @@ static void update_mov_insn_state(struct type_state *s= tate, pr_debug_type_name(&tsr->type, tsr->kind); } =20 +static void update_add_insn_state(struct type_state *state, + struct data_loc_info *dloc, + struct disasm_line *dl, + struct annotated_op_loc *src, + struct annotated_op_loc *dst) +{ + struct type_state_reg *tsr; + struct type_state_reg src_tsr; + u32 insn_offset =3D dl->al.offset; + int sreg =3D src->reg1; + int dreg =3D dst->reg1; + int reg_offset; + + if (!has_reg_type(state, dreg)) + return; + + tsr =3D &state->regs[dreg]; + tsr->copied_from =3D -1; + tsr->lifetime_active =3D false; + tsr->lifetime_end =3D 0; + +retry: + if (!has_reg_type(state, sreg) || !state->regs[sreg].ok) { + invalidate_reg_state(tsr); + return; + } + + src_tsr =3D state->regs[sreg]; + + if (arch_get_reg_offset(dloc->arch, src, sreg, state, false, ®_offset)) + goto add_non_regoff; + + if (src_tsr.kind =3D=3D TSR_KIND_CONST) { + tsr->kind =3D src_tsr.kind; + tsr->imm_value =3D src_tsr.imm_value + reg_offset; + tsr->offset =3D 0; + tsr->ok =3D src_tsr.ok; + + pr_debug_dtp("add [%x] imm %#x(reg%d) -> reg%d\n", + insn_offset, reg_offset, sreg, dreg); + return; + } + + if (src_tsr.kind =3D=3D TSR_KIND_POINTER || + (src_tsr.kind =3D=3D TSR_KIND_TYPE && + dwarf_tag(&src_tsr.type) =3D=3D DW_TAG_pointer_type)) { + tsr->type =3D src_tsr.type; + tsr->kind =3D src_tsr.kind; + tsr->imm_value =3D src_tsr.imm_value; + tsr->offset =3D src_tsr.offset + reg_offset; + tsr->ok =3D src_tsr.ok; + + pr_debug_dtp("add [%x] address of %#x(reg%d) -> reg%d", + insn_offset, reg_offset, sreg, dreg); + pr_debug_type_name(&tsr->type, tsr->kind); + return; + } + +add_non_regoff: + /* Try another register if any */ + if (src->multi_regs && src->reg1 !=3D src->reg2 && sreg !=3D src->reg2 && + !(src->extend_type || src->shift_type)) { + sreg =3D src->reg2; + goto retry; + } + invalidate_reg_state(tsr); +} + static void update_insn_state_arm64(struct type_state *state, struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) @@ -945,7 +1013,7 @@ static void update_insn_state_arm64(struct type_state = *state, * prevent stale type info from propagating to subsequent instructions. */ if (has_reg_type(state, dst->reg1) && !dst->mem_ref && - strcmp(dl->ins.name, "mov") && + strcmp(dl->ins.name, "add") && strcmp(dl->ins.name, "mov") && !is_standard_load_insn(dl->ins.name)) { pr_debug_dtp("%s [%x] invalidate reg%d", dl->ins.name, insn_offset, dst->reg1); @@ -958,8 +1026,10 @@ static void update_insn_state_arm64(struct type_state= *state, return; } =20 + if (!strcmp(dl->ins.name, "add")) + update_add_insn_state(state, dloc, dl, src, dst); /* Register to register or imm value to register transfers */ - if (!strcmp(dl->ins.name, "mov")) + else if (!strcmp(dl->ins.name, "mov")) update_mov_insn_state(state, dl, src, dst); /* Memory to register transfers */ else if (is_standard_load_insn(dl->ins.name)) --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2F52B39A040; Wed, 16 Sep 2026 01:30:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522251; cv=none; b=hZwNtDTurm7FkWcnO+YyUlZGpOaJ0miOtcqYI4U0AtEr94WpNwgWs+5CTZK7uwmVp0+oX4IZqbT8wBJvoCqLcjNu6gsJly+Y18mrtpdeKxBzuqYTlejngFk06n7bT7Q7jg1F2bk3z9+uc2yERt7h+zCGOacqVRzw6/pHab0Z2QU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522251; c=relaxed/simple; bh=6Zxq7rBPqyzY8BE7dFTeqVuI5+vxJ04T/nniM2/l5fM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=i35yYA/G3eIqb6adz/+oZlliNhDI86wTf6Ow21t9QzdIlCfiz8Zynv0lu2CG7JHbuzqYHjnwtw/toN0s+tWMJYOXHiDqzmCaCO86Opu8g5DiqqCwpJv034z0HX3BvEReEGhYUYTvfRpoUH8uVoYxTzN+4YpYYBilBvTf7cmUlxc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hl1YF42QFzYQtm5; Wed, 16 Sep 2026 09:30:41 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id AB7EB40576; Wed, 16 Sep 2026 09:30:45 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP1 (Coremail) with UTF8SMTPA id cCh0CgBHwPo_8alqshDTAQ--.7335S2; Wed, 16 Sep 2026 09:30:45 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 24/26] perf annotate-arm64: Support 'adrp' instruction to track global variables Date: Wed, 16 Sep 2026 01:30:16 +0000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: cCh0CgBHwPo_8alqshDTAQ--.7335S2 X-Coremail-Antispam: 1UD129KBjvJXoW3AF4UZr1xXrWfGr13CF17ZFb_yoWDJry5pF yDC34UW3y7tr4Sgrs3JFWUXr9a9ws7GFyj9ryqywsayFW7trn3GayktFWaqF45WF95Zw13 Jw4qgr4DXw42kaUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBS14x267AKxVW5JVWrJwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4U JVW0owA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r xl6s0DM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj 6xIIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr 0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E 8cxan2IY04v7MxkF7I0En4kS14v26r4a6rW5MxkF7I0Ew4C26cxK6c8Ij28IcwCF04k20x vY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I 3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_GFv_WrylIxkGc2Ij64vIr41lIx AIcVC0I7IYx2IY67AKxVW5JVW7JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Cr1j6rxdMIIF 0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87 Iv6xkF7I0E14v26F4UJVW0obIYCTnIWIevJa73UjIFyTuYvjTRXUUUUUUUU X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Extend update_insn_state_arm64() to track global variable types calculated via page-relative addressing. On arm64, global variables are typically accessed by first calculating the page address using 'adrp', followed by an 'add' or 'ldr' to get the specific symbol address. Without tracking 'adrp', the instruction tracker loses the base address, making it impossible to resolve global symbols and their associated DWARF types. Introduce TSR_KIND_GLOBAL_ADDR to represent a partial global address state. When encountering 'adrp', store the page-aligned target address in the register's type state. Upon a subsequent 'add' or 'ldr' instruction that references a TSR_KIND_GLOBAL_ADDR register, combine the page address with the immediate offset. A real-world example is shown below: ffff80008032e008 : ffff80008032e048: adrp x24, ffff80008202f000 ffff80008032e050: add x24, x24, #0xd40 * ffff80008032e078: ldr x0, [x24] Before this commit, x24 was unknown, leading to no type information: chk [70] reg24 offset=3D0 ok=3D0 kind=3D0 cfa : no type information final result: no type information After this commit, the tracker correctly follows the adrp/add flow: adrp [40] global addr=3D0xffff80008202f000 -> reg24 add [48] global 0xd40(reg24) -> reg24 chk [70] reg24 offset=3D0 ok=3D1 kind=3D7 global addr : Good! final result: type=3D'struct folio*' Signed-off-by: Li Huafei Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 83 +++++++++++++++++-- tools/perf/util/annotate-data.c | 25 +++++- tools/perf/util/annotate-data.h | 1 + 3 files changed, 99 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index 68510813f08b..b25a3c70675c 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -531,7 +531,7 @@ static bool is_standard_load_insn(const char *name) * which is added to the reg offset. */ static int propagate_load_reg_state(struct type_state *state, - struct data_loc_info *dloc, + struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl, int dreg, struct annotated_op_loc *src, struct type_state_reg **src_states, @@ -638,6 +638,33 @@ static int propagate_load_reg_state(struct type_state = *state, return 0; } =20 + /* Or check if it's a global variable */ + if (src_tsr->kind =3D=3D TSR_KIND_GLOBAL_ADDR) { + u64 ip =3D dloc->ms->sym->start + dl->al.offset; + u64 addr =3D src_tsr->imm_value + reg_offset; + int offset; + + if (!get_global_var_type(cu_die, dloc, ip, addr, &offset, &type_die) || + !die_get_member_type(&type_die, offset, &type_die)) + return -1; + + tsr->type =3D type_die; + tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; + tsr->imm_value =3D 0; + tsr->ok =3D true; + + if (src->multi_regs) { + pr_debug_dtp("%s [%x] global (reg%d, reg%d) -> reg%d", + dl->ins.name, insn_offset, src->reg1, src->reg2, dreg); + } else { + pr_debug_dtp("%s [%x] global (reg%d) -> reg%d", + dl->ins.name, insn_offset, sreg, dreg); + } + pr_debug_type_name(&tsr->type, tsr->kind); + return 0; + } + load_non_regoff: /* Try another register if any */ if (src->multi_regs && src->reg1 !=3D src->reg2 && sreg !=3D src->reg2 && @@ -651,7 +678,7 @@ static int propagate_load_reg_state(struct type_state *= state, } =20 static void update_load_insn_state(struct type_state *state, - struct data_loc_info *dloc, + struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl, struct annotated_op_loc *src, struct annotated_op_loc *dst) @@ -685,7 +712,7 @@ static void update_load_insn_state(struct type_state *s= tate, =20 /* Handle the first destination register */ if (has_reg_type(state, dst->reg1)) { - if (propagate_load_reg_state(state, dloc, dl, dst->reg1, + if (propagate_load_reg_state(state, dloc, cu_die, dl, dst->reg1, src, src_states, mem_spacing)) invalidate_reg_state(&state->regs[dst->reg1]); } @@ -700,7 +727,7 @@ static void update_load_insn_state(struct type_state *s= tate, mem_spacing =3D arm64__reg_size(dl->ops.target.raw); =20 if (mem_spacing < 0 || - propagate_load_reg_state(state, dloc, dl, dst->reg2, + propagate_load_reg_state(state, dloc, cu_die, dl, dst->reg2, src, src_states, mem_spacing)) invalidate_reg_state(&state->regs[dst->reg2]); =20 @@ -911,14 +938,16 @@ static void update_add_insn_state(struct type_state *= state, if (arch_get_reg_offset(dloc->arch, src, sreg, state, false, ®_offset)) goto add_non_regoff; =20 - if (src_tsr.kind =3D=3D TSR_KIND_CONST) { + if (src_tsr.kind =3D=3D TSR_KIND_CONST || src_tsr.kind =3D=3D TSR_KIND_GL= OBAL_ADDR) { tsr->kind =3D src_tsr.kind; + /* For 'adrp + add' pair: resolve the full global variable address. */ tsr->imm_value =3D src_tsr.imm_value + reg_offset; tsr->offset =3D 0; tsr->ok =3D src_tsr.ok; =20 - pr_debug_dtp("add [%x] imm %#x(reg%d) -> reg%d\n", - insn_offset, reg_offset, sreg, dreg); + pr_debug_dtp("add [%x] %s %#x(reg%d) -> reg%d\n", + insn_offset, src_tsr.kind =3D=3D TSR_KIND_CONST ? + "imm" : "global", reg_offset, sreg, dreg); return; } =20 @@ -947,6 +976,39 @@ static void update_add_insn_state(struct type_state *s= tate, invalidate_reg_state(tsr); } =20 +static void update_adrp_insn_state(struct type_state *state, + struct disasm_line *dl, + struct annotated_op_loc *dst) +{ + struct type_state_reg *tsr; + u32 insn_offset =3D dl->al.offset; + int dreg =3D dst->reg1; + + if (!has_reg_type(state, dreg)) + return; + + tsr =3D &state->regs[dreg]; + tsr->copied_from =3D -1; + + if (!dl->ops.source.addr) { + invalidate_reg_state(tsr); + return; + } + + tsr->kind =3D TSR_KIND_GLOBAL_ADDR; + /* + * Stores a partial page-relative address. The full absolute address + * of the global variable will be resolved when a subsequent 'add' or + * 'ldr' instruction consumes this register. + */ + tsr->imm_value =3D dl->ops.source.addr; + tsr->offset =3D 0; + tsr->ok =3D true; + + pr_debug_dtp("adrp [%x] global addr=3D%#"PRIx64" -> reg%d\n", + insn_offset, tsr->imm_value, dreg); +} + static void update_insn_state_arm64(struct type_state *state, struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) @@ -1013,6 +1075,7 @@ static void update_insn_state_arm64(struct type_state= *state, * prevent stale type info from propagating to subsequent instructions. */ if (has_reg_type(state, dst->reg1) && !dst->mem_ref && + strcmp(dl->ins.name, "adrp") && strcmp(dl->ins.name, "add") && strcmp(dl->ins.name, "mov") && !is_standard_load_insn(dl->ins.name)) { pr_debug_dtp("%s [%x] invalidate reg%d", @@ -1026,14 +1089,16 @@ static void update_insn_state_arm64(struct type_sta= te *state, return; } =20 - if (!strcmp(dl->ins.name, "add")) + if (!strcmp(dl->ins.name, "adrp")) + update_adrp_insn_state(state, dl, dst); + else if (!strcmp(dl->ins.name, "add")) update_add_insn_state(state, dloc, dl, src, dst); /* Register to register or imm value to register transfers */ else if (!strcmp(dl->ins.name, "mov")) update_mov_insn_state(state, dl, src, dst); /* Memory to register transfers */ else if (is_standard_load_insn(dl->ins.name)) - update_load_insn_state(state, dloc, dl, src, dst); + update_load_insn_state(state, dloc, cu_die, dl, src, dst); /* Register to memory transfers */ else if (is_standard_store_insn(dl->ins.name)) update_store_insn_state(state, dloc, dl, src, dst); diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 9ca59bc2f841..592ad8b1bc96 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -70,6 +70,9 @@ void pr_debug_type_name(Dwarf_Die *die, enum type_state_k= ind kind) case TSR_KIND_CANARY: pr_info(" stack canary\n"); return; + case TSR_KIND_GLOBAL_ADDR: + pr_info(" global address\n"); + return; case TSR_KIND_TYPE: default: break; @@ -613,7 +616,8 @@ void set_stack_state(struct type_state_stack *stack, in= t offset, u8 kind, stack->kind =3D kind; stack->imm_value =3D imm_value; =20 - if (kind =3D=3D TSR_KIND_POINTER || kind =3D=3D TSR_KIND_CONST) { + if (kind =3D=3D TSR_KIND_POINTER || kind =3D=3D TSR_KIND_CONST || + kind =3D=3D TSR_KIND_GLOBAL_ADDR) { stack->compound =3D false; return; } @@ -1368,6 +1372,25 @@ static enum type_match_result check_matching_type(st= ruct type_state *state, if (offset < 0 && reg !=3D state->stack_reg && reg !=3D dloc->fbreg) goto check_kernel; } + + if (state->regs[reg].kind =3D=3D TSR_KIND_GLOBAL_ADDR) { + u64 var_addr =3D state->regs[reg].imm_value + offset; + int var_offset; + + pr_debug_dtp("global addr"); + + /* + * The register holds the address of a global variable. Try to + * find the variable by the address and get its type. + */ + if (get_global_var_type(cu_die, dloc, dloc->ip, var_addr, + &var_offset, type_die)) { + dloc->type_offset =3D var_offset; + return PERF_TMR_OK; + } + /* No need to retry global variables */ + return PERF_TMR_BAIL_OUT; + } check_non_register: if (reg =3D=3D dloc->fbreg || reg =3D=3D state->stack_reg) { struct type_state_stack *stack; diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index a0d7e20ed725..21ae6970cd13 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -37,6 +37,7 @@ enum type_state_kind { TSR_KIND_PERCPU_POINTER, TSR_KIND_POINTER, TSR_KIND_CANARY, + TSR_KIND_GLOBAL_ADDR, }; =20 /** --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A67F03AAF74; Wed, 16 Sep 2026 01:30:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522252; cv=none; b=CptlbR4Wk1uHamxioh4/nTL54vNGjY9ZZAn1v9vWJkMY0hPoWDQ50Hb4zEr/Euy90d4jhjRnPVQxPf6Guq8TzJQWTa/V/u0Lb5EVvL0WEqx3iL2RYoMT+ksqEuapjufdtSBxfiLi5RjTNYCYdFYhxv6ITKdwjS6itw5uLDEr/3I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522252; c=relaxed/simple; bh=T40kEutOn8ITViARUJiEcJEfzEa0SOgxcP+gjzasNto=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=YL35MYsOhtWNAsUBj1i2NpXGHhGR6qyY5ZFOkMxaIkoOk9lCJfnTy1LVGEKGX0mX6CqKT+XWRF3Bz0sv2TyxCqntIZysfLpRBG8TLhNxwYo8rFK2JkFBHStbBMaV45bStxPVBhN1acce9J/GjQO2cAOr1fMNP6Ybk+Yq4kWcmgY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.170]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1Y41D1zzKHMQm; Wed, 16 Sep 2026 09:30:32 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id C7A694056F; Wed, 16 Sep 2026 09:30:45 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP1 (Coremail) with UTF8SMTPA id cCh0CgBHwPo_8alqshDTAQ--.7335S3; Wed, 16 Sep 2026 09:30:45 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 25/26] perf annotate-arm64: Support per-cpu variable access tracking Date: Wed, 16 Sep 2026 01:30:17 +0000 Message-Id: <735c23b4a55db2c67be4920792922550ff4f6409.1789521520.git.wutengda@huaweicloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: cCh0CgBHwPo_8alqshDTAQ--.7335S3 X-Coremail-Antispam: 1UD129KBjvJXoW3Xr15KrWDAF15Cr4ftw4UCFg_yoWxAr1xp3 95Kry5W34vqrsrWws3tFW5XryF9a93Jas2k34Y9w1a9r1xKr1UG397KrW5tF4UGFnay3W7 tr9xtrZrXrnFkaUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQa14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr4l82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr1j6rxdM2 8EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE3s1l e2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI 8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwAC jcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxcIEc7CjxVA2Y2ka0x kIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5MxAIw28IcxkI7VAK I48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7 xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0EwIxGrwCI42IY6xII jxv20xvE14v26ryj6F1UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWxJr0_GcWlIxAIcVCF04 k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIEc7Cj xVAFwI0_Cr1j6rxdYxBIdaVFxhVjvjDU0xZFpf9x0pROJ5rUUUUU= X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Extend update_insn_state_arm64() to handle per-cpu variable addressing. On arm64, per-cpu variables are accessed by adding a per-cpu offset (typically from the '__per_cpu_offset' array) to the address of a global variable or a structure field with '__percpu' modifier (e.g., 's32 __percpu *counters' in struct percpu_counter). This results in instruction patterns like: ldr x0, [x6, x5] // Pattern A: direct load per-cpu instance add x0, x6, x5 // Pattern B: compute per-cpu address where x6 holds the per-cpu offset retrieved from: adrp x4, add x4, x4, #offset // x4 =3D &__per_cpu_offset ldr x6, [x4, w0, sxtw #3] // x6 =3D __per_cpu_offset[cpu] and x5 is one of the following: case 1: global variable adrp x5, add x5, x5, #offset // x5 =3D &global_var case 2: '__percpu' field embedded in a structure ldr x5, [x25, #32] // x5 =3D &percpu_field To handle such cases: 1. Identify per-cpu base initialization: Detect 'adrp + ldr' pairs that resolve to the '__per_cpu_offset' symbol and mark the destination register as TSR_KIND_PERCPU_BASE. 2. Propagate type information: During subsequent 'ldr' or 'add' instructions, if one register is TSR_KIND_PERCPU_BASE, attempt to resolve the type from the other register. A real-world example is shown below: ffff8000808f2d28 : ffff8000808f2d38: adrp x2, ffff800082033000 ffff8000808f2d3c: add x5, x2, #0x3f8 // x5 =3D &__per_cpu_offs= et ffff8000808f2d44: adrp x2, ffff800081f73000 ffff8000808f2d48: add x2, x2, #0x6b8 // x2 =3D &cpu_pcc_subspa= ce_idx ffff8000808f2d6c: ldr x5, [x5, w0, sxtw #3] // x5 =3D __per_cpu_offse= t[cpu] * ffff8000808f2d80: ldr w23, [x5, x2] // per_cpu_var(cpu_pcc_su= bspace_idx) Before this commit, the tracker could not link x5 back to a per-cpu context, resulting in an incorrect data type resolution: adrp [10] global addr=3D0xffff800082033000 -> reg2 add [14] global 0x3f8(reg2) -> reg5 adrp [1c] global addr=3D0xffff800081f73000 -> reg2 add [20] global 0x6b8(reg2) -> reg2 ldr [44] global (reg5, reg0) -> reg5 type=3D'long unsigned int[]' size=3D= 0x1000 chk [58] reg5 offset=3D0 ok=3D1 kind=3D1 (long unsigned int[]) : Good! found by insn track: 0(reg5, reg2) type-offset=3D0 final result: type=3D'long unsigned int' size=3D0x8 After this commit, the tracker correctly identifies the per-cpu flow and resolves the actual variable type: ldr [44] global (reg5, reg0) -> reg5 percpu base chk [58] reg5 offset=3D0 ok=3D1 kind=3D2 percpu var : retry chk [58] reg2 offset=3D0 ok=3D1 kind=3D7 global addr : Good! found by insn track: 0(reg5, reg2) type-offset=3D0 final result: type=3D'int' size=3D0x4 Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 47 ++++++++++++++++++- tools/perf/util/annotate-data.c | 22 ++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index b25a3c70675c..f4b7b0eb44f4 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -12,6 +12,7 @@ #include "../disasm.h" #include "../annotate-data.h" #include "../debug.h" +#include "../dso.h" #include "../map.h" #include "../symbol.h" =20 @@ -643,13 +644,23 @@ static int propagate_load_reg_state(struct type_state= *state, u64 ip =3D dloc->ms->sym->start + dl->al.offset; u64 addr =3D src_tsr->imm_value + reg_offset; int offset; + u8 kind; + const char *var_name =3D NULL; + + /* it might be per-cpu offset */ + if (dso__kernel(map__dso(dloc->ms->map)) && + get_global_var_info(dloc, addr, &var_name, &offset) && + !strcmp(var_name, "__per_cpu_offset")) + kind =3D TSR_KIND_PERCPU_BASE; + else + kind =3D TSR_KIND_TYPE; =20 if (!get_global_var_type(cu_die, dloc, ip, addr, &offset, &type_die) || !die_get_member_type(&type_die, offset, &type_die)) return -1; =20 tsr->type =3D type_die; - tsr->kind =3D TSR_KIND_TYPE; + tsr->kind =3D kind; tsr->offset =3D 0; tsr->imm_value =3D 0; tsr->ok =3D true; @@ -666,6 +677,12 @@ static int propagate_load_reg_state(struct type_state = *state, } =20 load_non_regoff: + /* + * If src_tsr->kind is TSR_KIND_PERCPU_BASE, treat it as an array. + * No special handling is needed here; just fall through to retry + * and resolve the type from the second register. + */ + /* Try another register if any */ if (src->multi_regs && src->reg1 !=3D src->reg2 && sreg !=3D src->reg2 && !(src->extend_type || src->shift_type)) { @@ -967,6 +984,34 @@ static void update_add_insn_state(struct type_state *s= tate, } =20 add_non_regoff: + if (src_tsr.kind =3D=3D TSR_KIND_PERCPU_BASE) { + int reg2; + + if (!src->multi_regs) { + invalidate_reg_state(tsr); + return; + } + + reg2 =3D (sreg =3D=3D src->reg1) ? src->reg2 : src->reg1; + + if (!has_reg_type(state, reg2) || !state->regs[reg2].ok) { + invalidate_reg_state(tsr); + return; + } + + /* Treat percpu as array: inherit type from reg2 */ + tsr->type =3D state->regs[reg2].type; + tsr->kind =3D state->regs[reg2].kind; + tsr->offset =3D state->regs[reg2].offset; + tsr->imm_value =3D state->regs[reg2].imm_value; + tsr->ok =3D state->regs[reg2].ok; + + pr_debug_dtp("add [%x] percpu (reg%d, reg%d) -> reg%d", + insn_offset, src->reg1, src->reg2, dreg); + pr_debug_type_name(&tsr->type, tsr->kind); + return; + } + /* Try another register if any */ if (src->multi_regs && src->reg1 !=3D src->reg2 && sreg !=3D src->reg2 && !(src->extend_type || src->shift_type)) { diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 592ad8b1bc96..a2434b978ec7 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -1342,11 +1342,31 @@ static enum type_match_result check_matching_type(s= truct type_state *state, } =20 if (state->regs[reg].kind =3D=3D TSR_KIND_PERCPU_BASE) { - u64 var_addr =3D (s64) offset; + u64 var_addr; int var_offset; =20 pr_debug_dtp("percpu var"); =20 + if (arch__is_arm64(dloc->arch)) { + int reg2; + + if (!retry || !dloc->op->multi_regs || + dloc->op->reg1 =3D=3D dloc->op->reg2 || + dloc->op->extend_type || dloc->op->shift_type) + return PERF_TMR_BAIL_OUT; + + reg2 =3D dloc->op->reg2; + if (!has_reg_type(state, reg2) || !state->regs[reg2].ok) + return PERF_TMR_NO_TYPE; + + pr_debug_dtp(" : retry\n"); + retry =3D false; + reg =3D reg2; + goto again; + } + + var_addr =3D (s64) offset; + if (dloc->op->multi_regs) { int reg2 =3D dloc->op->reg2; =20 --=20 2.34.1 From nobody Fri Sep 25 06:46:21 2026 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4C883AB260; Wed, 16 Sep 2026 01:30:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522250; cv=none; b=fVEa4umMNam5kJ8VFV1wu+tLYCGI1ZjgZ7b5FTgPdVaT+QiQTgGUMCfTb2nEcqcYp397x892pjMFEuSj+uqWY1x6GffE6/W0ZqM4FjlJLzhrXT5ZZZB0Kso0kyQvuxCmXrPuXkjLuFXWw1ybecADV6ocjzrCOqRI4xJjWPKEaO0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789522250; c=relaxed/simple; bh=l5B4CuMX9B2TkuTVEtSvt5S51IaKguCrelLXzRTnzeo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Nqx2ChgGWHEq+pzHaR2Kh53sfOLfyM4T5SPLVsNooEjr3wxG2X5ukuBknj3i8j1miQB/mne+0rZHVjhSjf7/FLASN79iHtcLDdMSY7AxIB+sOhjwd/xYv+00BpjgjMVweB7rkhUMOpdFFgTzFVsxE3IYHFiIddXCdQfGKzBrrqQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.170]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hl1Y42KhZzKHMPn; Wed, 16 Sep 2026 09:30:32 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id ED4EB4056B; Wed, 16 Sep 2026 09:30:45 +0800 (CST) Received: from huawei.com (unknown [10.67.174.45]) by APP1 (Coremail) with UTF8SMTPA id cCh0CgBHwPo_8alqshDTAQ--.7335S4; Wed, 16 Sep 2026 09:30:45 +0800 (CST) From: Tengda Wu To: Namhyung Kim , james.clark@linaro.org, xueshuai@linux.alibaba.com, Ian Rogers , Adrian Hunter Cc: Peter Zijlstra , leo.yan@linux.dev, Li Huafei , Kim Phillips , Mark Rutland , Arnaldo Carvalho de Melo , Ingo Molnar , Bill Wendling , Nick Desaulniers , Alexander Shishkin , Zecheng Li , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, Tengda Wu Subject: [PATCH v6 26/26] perf annotate-arm64: Support 'mrs' instruction to track 'current' pointer Date: Wed, 16 Sep 2026 01:30:18 +0000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: cCh0CgBHwPo_8alqshDTAQ--.7335S4 X-Coremail-Antispam: 1UD129KBjvJXoW3JrW3KFW3JFW3Jr1xWw13XFb_yoW7Xr4fpa yDC34UWr4kJr42ganxXFWxZr93Wws7W34UCr98XwsayFW2kr1fta1ktFW2ya1rJrykuw13 G3yUKr4DGw4IvFJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQa14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jryl82xGYIkIc2 x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr1j6rxdM2 8EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE3s1l e2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI 8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwAC jcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxcIEc7CjxVA2Y2ka0x kIwI1lc7CjxVAaw2AFwI0_GFv_Wrylc7CjxVAKzI0EY4vE52x082I5MxAIw28IcxkI7VAK I48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7 xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXwCIc40Y0x0EwIxGrwCI42IY6xII jxv20xvE14v26ryj6F1UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWxJr0_GcWlIxAIcVCF04 k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIEc7Cj xVAFwI0_Cr1j6rxdYxBIdaVFxhVjvjDU0xZFpf9x0pR5KsUUUUUU= X-CM-SenderInfo: pzxwv0hjgdqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" Extend update_insn_state_arm64() to handle the 'mrs' instruction, enabling the tracking of the 'current' task pointer in the kernel. On arm64, the kernel uses the 'sp_el0' system register to store the address of the currently executing 'struct task_struct'. This is typically accessed via the 'get_current()' inline function, resulting in the instruction 'mrs xN, sp_el0'. To resolve the data type of the target register, first verify the access is to 'sp_el0' within a kernel DSO. Then, locate the 'get_current()' inline function's DWARF Die at the current PC and extract its return type (which should be 'struct task_struct*'). A real-world example is shown below: ffff8000800deee8 : ffff8000800deef0: mrs x0, sp_el0 // x0 =3D current * ffff8000800deef4: ldr w1, [x0, #44] Before this commit, the type flow starts with no information: chk [c] reg0 offset=3D0x2c ok=3D0 kind=3D0 cfa : no type information final result: no type information After this commit, the tracker identifies the 'current' pointer from the system register: mrs [8] sp_el0 -> reg0 type=3D'struct task_struct*' chk [c] reg0 offset=3D0x2c ok=3D1 kind=3D1 (struct task_struct*) : Good! found by insn track: 0x2c(reg0) type-offset=3D0x2c final result: type=3D'struct task_struct' Signed-off-by: Li Huafei Signed-off-by: Tengda Wu Reviewed-by: Ian Rogers --- .../perf/util/annotate-arch/annotate-arm64.c | 73 ++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/ut= il/annotate-arch/annotate-arm64.c index f4b7b0eb44f4..a4e4a38310cc 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -15,6 +16,7 @@ #include "../dso.h" #include "../map.h" #include "../symbol.h" +#include "../strbuf.h" =20 struct arch_arm64 { struct arch arch; @@ -1054,6 +1056,71 @@ static void update_adrp_insn_state(struct type_state= *state, insn_offset, tsr->imm_value, dreg); } =20 +static void update_mrs_insn_state(struct type_state *state, + struct data_loc_info *dloc, Dwarf_Die *cu_die, + struct disasm_line *dl, + struct annotated_op_loc *dst) +{ + struct type_state_reg *tsr; + Dwarf_Die type_die; + u32 insn_offset =3D dl->al.offset; + int dreg =3D dst->reg1; + Dwarf_Die func_die; + Dwarf_Attribute attr; + u64 ip, pc; + struct strbuf sb; + char *type_name; + + if (!has_reg_type(state, dreg)) + return; + + tsr =3D &state->regs[dreg]; + tsr->copied_from =3D -1; + + /* Handle case difference: LLVM (SP_EL0) vs objdump (sp_el0) */ + if (!dso__kernel(map__dso(dloc->ms->map)) || + strcasecmp(dl->ops.source.raw, "sp_el0")) { + invalidate_reg_state(tsr); + return; + } + + ip =3D dloc->ms->sym->start + dl->al.offset; + pc =3D map__rip_2objdump(dloc->ms->map, ip); + + /* + * Find the inline function 'get_current()' Dwarf_Die and obtain its + * return value data type, which should be 'struct task_struct*'. + */ + if (!die_find_inlinefunc(cu_die, pc, &func_die) || + !die_compare_name(&func_die, "get_current") || + !dwarf_attr_integrate(&func_die, DW_AT_type, &attr) || + !dwarf_formref_die(&attr, &type_die)) { + invalidate_reg_state(tsr); + return; + } + + strbuf_init(&sb, 32); + die_get_typename_from_type(&type_die, &sb); + type_name =3D strbuf_detach(&sb, NULL); + + if (!type_name || strcmp(type_name, "struct task_struct*")) { + invalidate_reg_state(tsr); + goto out_free; + } + + tsr->type =3D type_die; + tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; + tsr->imm_value =3D 0; + tsr->ok =3D true; + + pr_debug_dtp("mrs [%x] sp_el0 -> reg%d", insn_offset, dreg); + pr_debug_type_name(&type_die, tsr->kind); + +out_free: + free(type_name); +} + static void update_insn_state_arm64(struct type_state *state, struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) @@ -1120,7 +1187,7 @@ static void update_insn_state_arm64(struct type_state= *state, * prevent stale type info from propagating to subsequent instructions. */ if (has_reg_type(state, dst->reg1) && !dst->mem_ref && - strcmp(dl->ins.name, "adrp") && + strcmp(dl->ins.name, "mrs") && strcmp(dl->ins.name, "adrp") && strcmp(dl->ins.name, "add") && strcmp(dl->ins.name, "mov") && !is_standard_load_insn(dl->ins.name)) { pr_debug_dtp("%s [%x] invalidate reg%d", @@ -1134,7 +1201,9 @@ static void update_insn_state_arm64(struct type_state= *state, return; } =20 - if (!strcmp(dl->ins.name, "adrp")) + if (!strcmp(dl->ins.name, "mrs")) + update_mrs_insn_state(state, dloc, cu_die, dl, dst); + else if (!strcmp(dl->ins.name, "adrp")) update_adrp_insn_state(state, dl, dst); else if (!strcmp(dl->ins.name, "add")) update_add_insn_state(state, dloc, dl, src, dst); --=20 2.34.1