From nobody Sun Feb 8 22:06:17 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 BD8AC14F136; Fri, 12 Apr 2024 18:33:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712946792; cv=none; b=Lkf/jDYSj3uym0+5TlB7zyiYi5fScVB7vkV4dAKmLWuOcj2QkN1n/Kwi8qfu67xoUibljASpVrmlHibXNZm/FAJ6qJxPvDQlwua69KfwG4fgfbBV7e0N8cmYoBUXXMutxcV6eUisNjBBdHVdG25cwpKGJCIynmSoPO5+pWx24g4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712946792; c=relaxed/simple; bh=vaVisn2Hv+xkW0BEkChkfySYlnshZGIQoNtORS9lyKU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bIBBKKCBsFzE51RwIYS32RwT9Pw1fL4MqEoGDMY83Pu4GhbEr20IAoImrhmeRJ0CdETDoWBuAvSnxp9ZDyMfkikOuE508XQm8fWxr7o/Alnwjw7RweOZx9mGmgJAwe4V/PPc6Hrl8d2mgXrh3kbY2RdkepYLH+31JpdWH7YS4Xw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hVoJ2eoK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hVoJ2eoK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 01BFCC2BBFC; Fri, 12 Apr 2024 18:33:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712946792; bh=vaVisn2Hv+xkW0BEkChkfySYlnshZGIQoNtORS9lyKU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hVoJ2eoKqlPDIU5AGscdTPr6jQMwXYRf6BUQ8hk4g6Z9LR2dD7XjJzWXB4FAXJ5rq JPHZvlTy1iVsItaByVesEmels9hIQppxao7aF4gFp988sMWXPC6tCvWWLJmJfrNhuI Fo/NDXyQUjLZr6LO0dg8sgPyCHqrThbqv2MXHPWYE1bBtzPvudNJs14h/SFZV1SR8o ifKRTlztm9men99rMRxgZZ2eqCdwuQbvmjnAtoJBF/tGsoNnRzglr/2Z6K5yr03z8E DYQH4+6PqLnjtAGRkyCVBV/Z37eF0kTZVk6z73FKCWYomRikJCvR1ob8e871GXcyXD LWJbpSG/bqMJQ== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers , Kan Liang Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org Subject: [PATCH 1/4] perf annotate-data: Improve debug message with location info Date: Fri, 12 Apr 2024 11:33:07 -0700 Message-ID: <20240412183310.2518474-2-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.683.g7961c838ac-goog In-Reply-To: <20240412183310.2518474-1-namhyung@kernel.org> References: <20240412183310.2518474-1-namhyung@kernel.org> 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 Content-Type: text/plain; charset="utf-8" To verify it found the correct variable, let's add the location expression to the debug message. $ perf --debug type-profile annotate --data-type ... ----------------------------------------------------------- find data type for 0xaf0(reg15) at schedule+0xeb CU for kernel/sched/core.c (die:0x1180523) frame base: cfa=3D0 fbreg=3D6 found "rq" in scope=3D3/4 (die: 0x11b6a00) type_offset=3D0xaf0 variable location: reg15 type=3D'struct rq' size=3D0xfc0 (die:0x11892e2) ----------------------------------------------------------- find data type for 0x7bc(reg3) at tcp_get_info+0x62 CU for net/ipv4/tcp.c (die:0x7b5f516) frame base: cfa=3D0 fbreg=3D6 offset: 1980 is bigger than size: 760 check variable "sk" failed (die: 0x7b92b2c) variable location: reg3 type=3D'struct sock' size=3D0x2f8 (die:0x7b63c3a) ----------------------------------------------------------- ... The first case is fine. It looked up a data type in r15 with offset of 0xaf0 at the schedule+0xeb. It found CU die and the frame base info and the variable "rq" was found in the scope 3/4. Its location is the r15 register and the type size is 0xfc0 which includes 0xaf0. But the second case is not good. It looked up a data type in rbx (reg3) with offset 0x7bc. It found a CU and the frame base which is good so far. And it also found a variable "sk" but the access offset is bigger than the type size (1980 vs. 760 or 0x7bc vs. 0x2f8). The variable has the right location (reg3) but I need to figure out why it accesses beyond what it's supposed to. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 99 +++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 17 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 1cd857400038..c6eb5b2cc4d5 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -46,6 +46,7 @@ static void pr_debug_type_name(Dwarf_Die *die, enum type_= state_kind kind) { struct strbuf sb; char *str; + Dwarf_Word size =3D 0; =20 if (!debug_type_profile && verbose < 3) return; @@ -72,13 +73,67 @@ static void pr_debug_type_name(Dwarf_Die *die, enum typ= e_state_kind kind) break; } =20 + dwarf_aggregate_size(die, &size); + strbuf_init(&sb, 32); die_get_typename_from_type(die, &sb); str =3D strbuf_detach(&sb, NULL); - pr_info(" type=3D%s (die:%lx)\n", str, (long)dwarf_dieoffset(die)); + pr_info(" type=3D'%s' size=3D%#lx (die:%#lx)\n", + str, (long)size, (long)dwarf_dieoffset(die)); free(str); } =20 +static void pr_debug_location(Dwarf_Die *die, u64 pc, int reg) +{ + ptrdiff_t off =3D 0; + Dwarf_Attribute attr; + Dwarf_Addr base, start, end; + Dwarf_Op *ops; + size_t nops; + + if (!debug_type_profile && verbose < 3) + return; + + if (dwarf_attr(die, DW_AT_location, &attr) =3D=3D NULL) + return; + + while ((off =3D dwarf_getlocations(&attr, off, &base, &start, &end, &ops,= &nops)) > 0) { + if (reg !=3D DWARF_REG_PC && end < pc) + continue; + if (reg !=3D DWARF_REG_PC && start > pc) + break; + + pr_info(" variable location: "); + switch (ops->atom) { + case DW_OP_reg0 ...DW_OP_reg31: + pr_info("reg%d\n", ops->atom - DW_OP_reg0); + break; + case DW_OP_breg0 ...DW_OP_breg31: + pr_info("base=3Dreg%d, offset=3D%#lx\n", + ops->atom - DW_OP_breg0, ops->number); + break; + case DW_OP_regx: + pr_info("reg%ld\n", ops->number); + break; + case DW_OP_bregx: + pr_info("base=3Dreg%ld, offset=3D%#lx\n", + ops->number, ops->number2); + break; + case DW_OP_fbreg: + pr_info("use frame base, offset=3D%#lx\n", ops->number); + break; + case DW_OP_addr: + pr_info("address=3D%#lx\n", ops->number); + break; + default: + pr_info("unknown: code=3D%#x, number=3D%#lx\n", + ops->atom, ops->number); + break; + } + break; + } +} + /* * Type information in a register, valid when @ok is true. * The @caller_saved registers are invalidated after a function call. @@ -1404,7 +1459,7 @@ static int find_data_type_block(struct data_loc_info = *dloc, int reg, found =3D find_data_type_insn(dloc, reg, &basic_blocks, var_types, cu_die, type_die); if (found > 0) { - pr_debug_dtp("found by insn track: %#x(reg%d) type-offset=3D%#x", + pr_debug_dtp("found by insn track: %#x(reg%d) type-offset=3D%#x\n", dloc->op->offset, reg, dloc->type_offset); pr_debug_type_name(type_die, TSR_KIND_TYPE); ret =3D 0; @@ -1440,16 +1495,16 @@ static int find_data_type_die(struct data_loc_info = *dloc, Dwarf_Die *type_die) char buf[64]; =20 if (dloc->op->multi_regs) - snprintf(buf, sizeof(buf), " or reg%d", dloc->op->reg2); + snprintf(buf, sizeof(buf), "reg%d, reg%d", dloc->op->reg1, dloc->op->reg= 2); else if (dloc->op->reg1 =3D=3D DWARF_REG_PC) - snprintf(buf, sizeof(buf), " (PC)"); + snprintf(buf, sizeof(buf), "PC"); else - buf[0] =3D '\0'; + snprintf(buf, sizeof(buf), "reg%d", dloc->op->reg1); =20 pr_debug_dtp("-----------------------------------------------------------= \n"); - pr_debug_dtp("%s [%"PRIx64"] for reg%d%s offset=3D%#x in %s\n", - __func__, dloc->ip - dloc->ms->sym->start, - dloc->op->reg1, buf, dloc->op->offset, dloc->ms->sym->name); + pr_debug_dtp("find data type for %#x(%s) at %s+%#"PRIx64"\n", + dloc->op->offset, buf, dloc->ms->sym->name, + dloc->ip - dloc->ms->sym->start); =20 /* * IP is a relative instruction address from the start of the map, as @@ -1468,14 +1523,15 @@ static int find_data_type_die(struct data_loc_info = *dloc, Dwarf_Die *type_die) reg =3D loc->reg1; offset =3D loc->offset; =20 - pr_debug_dtp("CU die offset: %#lx\n", (long)dwarf_dieoffset(&cu_die)); + pr_debug_dtp("CU for %s (die:%#lx)\n", + dwarf_diename(&cu_die), (long)dwarf_dieoffset(&cu_die)); =20 if (reg =3D=3D DWARF_REG_PC) { if (get_global_var_type(&cu_die, dloc, dloc->ip, dloc->var_addr, &offset, type_die)) { dloc->type_offset =3D offset; =20 - pr_debug_dtp("found PC-rel by addr=3D%#"PRIx64" offset=3D%#x", + pr_debug_dtp("found by addr=3D%#"PRIx64" type_offset=3D%#x\n", dloc->var_addr, offset); pr_debug_type_name(type_die, TSR_KIND_TYPE); ret =3D 0; @@ -1537,13 +1593,22 @@ static int find_data_type_die(struct data_loc_info = *dloc, Dwarf_Die *type_die) pr_debug_dtp("found \"%s\" in scope=3D%d/%d (die: %#lx) ", dwarf_diename(&var_die), i+1, nr_scopes, (long)dwarf_dieoffset(&scopes[i])); - if (reg =3D=3D DWARF_REG_PC) - pr_debug_dtp("%#x(PC) offset=3D%#x", loc->offset, offset); - else if (reg =3D=3D DWARF_REG_FB || is_fbreg) - pr_debug_dtp("%#x(reg%d) stack fb_offset=3D%#x offset=3D%#x", - loc->offset, reg, fb_offset, offset); - else - pr_debug_dtp("%#x(reg%d)", loc->offset, reg); + if (reg =3D=3D DWARF_REG_PC) { + pr_debug_dtp("addr=3D%#"PRIx64" type_offset=3D%#x\n", + dloc->var_addr, offset); + } else if (reg =3D=3D DWARF_REG_FB || is_fbreg) { + pr_debug_dtp("stack_offset=3D%#x type_offset=3D%#x\n", + fb_offset, offset); + } else { + pr_debug_dtp("type_offset=3D%#x\n", offset); + } + pr_debug_location(&var_die, pc, reg); + pr_debug_type_name(type_die, TSR_KIND_TYPE); + } else { + pr_debug_dtp("check variable \"%s\" failed (die: %#lx)\n", + dwarf_diename(&var_die), + (long)dwarf_dieoffset(&var_die)); + pr_debug_location(&var_die, pc, reg); pr_debug_type_name(type_die, TSR_KIND_TYPE); } dloc->type_offset =3D offset; --=20 2.44.0.683.g7961c838ac-goog From nobody Sun Feb 8 22:06:17 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 07D7114F13A; Fri, 12 Apr 2024 18:33:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712946793; cv=none; b=HnzOrTqnFfFMNyJzHicxoIavCoGlZWust7iABs5jjF1NN8Je8VFjO2ELvr8EWeYYLTbAWuOUX7Om+p73hGiRWUtI9qIxUQfgYuxsL8cWEiIATCMrzdRDqbKUFi3TIa8Qc24GA24YwEnk2UNLruc0RL9ittzoeAV5pGWBxqIBvxQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712946793; c=relaxed/simple; bh=MdGKWRljF8Qw40speV6mfVp91ivhhrN0E6WVpTJ1KU8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YinOAQdX9N20oGGHdekpe+Rjgsn7v8C8tauNNGj5yafCQIDo0DTsBE3GIAQbIHMLVlbvPPzQBDM1lpbjuaneAQcpkffMSNR/PSRS+mDp22PrwCzBsb8MZkgbSqEQ0DczgStGP1IZtei3UH8X8+x/6RJNwp5DpAY6BnCtMxW1VpA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pKc1bG6x; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pKc1bG6x" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7A59EC32781; Fri, 12 Apr 2024 18:33:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712946792; bh=MdGKWRljF8Qw40speV6mfVp91ivhhrN0E6WVpTJ1KU8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pKc1bG6xBUUOOwZfvk+GES4RLab54aBAQYX5QKGkQKyT4DXmN4B+nNUmoiFHs5/t9 l8AdYR5YjDmtdW3+h23XK/eKqYvQRImgOGvaawwhSk/U+rNQozdkP3Vu0BEDtYp18t BWrnih5lmEhINYQSYIOAp5ULFee/vrapuwoNLZm3CxECaNXulv8HKOU+9ae2MdVEjI ZPXmBTKkY3gt9ZrApbBjBcr3Y+oS+ofAgis+6GoqM9asJ0m3+PraBjJF/TOV0BsxJ4 VzmScnmdbU4W1WMrlcrSN8Y6PCFIhFP+T8YupllWYVo7OiWCM7j0fn2ZxJ6IytpAGq p/TnWClbb3GvQ== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers , Kan Liang Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Masami Hiramatsu Subject: [PATCH 2/4] perf dwarf-aux: Check pointer offset when checking variables Date: Fri, 12 Apr 2024 11:33:08 -0700 Message-ID: <20240412183310.2518474-3-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.683.g7961c838ac-goog In-Reply-To: <20240412183310.2518474-1-namhyung@kernel.org> References: <20240412183310.2518474-1-namhyung@kernel.org> 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 Content-Type: text/plain; charset="utf-8" In match_var_offset(), it checks the offset range with the target type only for non-pointer types. But it also needs to check the pointer types with the target type. This is because there can be more than one pointer variables located in the same register. Let's look at the following example. It's looking up a variable for reg3 at tcp_get_info+0x62. It found "sk" variable but it wasn't the right one since it accesses beyond the target type (struct 'sock' in this case) size. ----------------------------------------------------------- find data type for 0x7bc(reg3) at tcp_get_info+0x62 CU for net/ipv4/tcp.c (die:0x7b5f516) frame base: cfa=3D0 fbreg=3D6 offset: 1980 is bigger than size: 760 check variable "sk" failed (die: 0x7b92b2c) variable location: reg3 type=3D'struct sock' size=3D0x2f8 (die:0x7b63c3a) Actually there was another variable "tp" in the function and it's located at the same (reg3) because it's just type-casted like below. void tcp_get_info(struct sock *sk, struct tcp_info *info) { const struct tcp_sock *tp =3D tcp_sk(sk); ... The struct tcp_sock contains the struct sock at offset 0 so it can just use the same address as a pointer to tcp_sock. That means it should match variables correctly by checking the offset and size. Actually it cannot distinguish if the offset was smaller than the size of the original struct sock. But I think it's fine as they are the same at that part. So let's check the target type size and retry if it doesn't match. Now it succeeded to find the correct variable. ----------------------------------------------------------- find data type for 0x7bc(reg3) at tcp_get_info+0x62 CU for net/ipv4/tcp.c (die:0x7b5f516) frame base: cfa=3D0 fbreg=3D6 found "tp" in scope=3D1/1 (die: 0x7b92b16) type_offset=3D0x7bc variable location: reg3 type=3D'struct tcp_sock' size=3D0xa68 (die:0x7b81380) Fixes: bc10db8eb895 ("perf annotate-data: Support stack variables") Cc: Masami Hiramatsu Signed-off-by: Namhyung Kim --- tools/perf/util/dwarf-aux.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 7dad99ee3ff3..b361fd7ebd56 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1361,7 +1361,7 @@ struct find_var_data { #define DWARF_OP_DIRECT_REGS 32 =20 static bool match_var_offset(Dwarf_Die *die_mem, struct find_var_data *dat= a, - u64 addr_offset, u64 addr_type) + u64 addr_offset, u64 addr_type, bool is_pointer) { Dwarf_Die type_die; Dwarf_Word size; @@ -1375,6 +1375,12 @@ static bool match_var_offset(Dwarf_Die *die_mem, str= uct find_var_data *data, if (die_get_real_type(die_mem, &type_die) =3D=3D NULL) return false; =20 + if (is_pointer && dwarf_tag(&type_die) =3D=3D DW_TAG_pointer_type) { + /* Get the target type of the pointer */ + if (die_get_real_type(&type_die, &type_die) =3D=3D NULL) + return false; + } + if (dwarf_aggregate_size(&type_die, &size) < 0) return false; =20 @@ -1442,31 +1448,38 @@ static int __die_find_var_reg_cb(Dwarf_Die *die_mem= , void *arg) if (data->is_fbreg && ops->atom =3D=3D DW_OP_fbreg && data->offset >=3D (int)ops->number && check_allowed_ops(ops, nops) && - match_var_offset(die_mem, data, data->offset, ops->number)) + match_var_offset(die_mem, data, data->offset, ops->number, + /*is_pointer=3D*/false)) return DIE_FIND_CB_END; =20 /* Only match with a simple case */ if (data->reg < DWARF_OP_DIRECT_REGS) { /* pointer variables saved in a register 0 to 31 */ if (ops->atom =3D=3D (DW_OP_reg0 + data->reg) && - check_allowed_ops(ops, nops)) + check_allowed_ops(ops, nops) && + match_var_offset(die_mem, data, data->offset, 0, + /*is_pointer=3D*/true)) return DIE_FIND_CB_END; =20 /* Local variables accessed by a register + offset */ if (ops->atom =3D=3D (DW_OP_breg0 + data->reg) && check_allowed_ops(ops, nops) && - match_var_offset(die_mem, data, data->offset, ops->number)) + match_var_offset(die_mem, data, data->offset, ops->number, + /*is_pointer=3D*/false)) return DIE_FIND_CB_END; } else { /* pointer variables saved in a register 32 or above */ if (ops->atom =3D=3D DW_OP_regx && ops->number =3D=3D data->reg && - check_allowed_ops(ops, nops)) + check_allowed_ops(ops, nops) && + match_var_offset(die_mem, data, data->offset, 0, + /*is_pointer=3D*/true)) return DIE_FIND_CB_END; =20 /* Local variables accessed by a register + offset */ if (ops->atom =3D=3D DW_OP_bregx && data->reg =3D=3D ops->number && check_allowed_ops(ops, nops) && - match_var_offset(die_mem, data, data->offset, ops->number2)) + match_var_offset(die_mem, data, data->offset, ops->number2, + /*is_poitner=3D*/false)) return DIE_FIND_CB_END; } } @@ -1528,7 +1541,8 @@ static int __die_find_var_addr_cb(Dwarf_Die *die_mem,= void *arg) continue; =20 if (check_allowed_ops(ops, nops) && - match_var_offset(die_mem, data, data->addr, ops->number)) + match_var_offset(die_mem, data, data->addr, ops->number, + /*is_pointer=3D*/false)) return DIE_FIND_CB_END; } return DIE_FIND_CB_SIBLING; --=20 2.44.0.683.g7961c838ac-goog From nobody Sun Feb 8 22:06:17 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 83708142E78; Fri, 12 Apr 2024 18:33:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712946793; cv=none; b=EWejSM85wUsrZRy6edJ01yLFiXbba2xFPFg+Il0S6ERpEWKX7nm9xzyohJnKw4fLlcfPc71S/NDL6ZoYz45sNRciEp/bxiO4mHNokxLrw+sOdwgrcFr3jykyjgvMSwE2djk+OF1f5IyDUWUZwNP3OEyAM/Z8asF1raqfdCglZcQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712946793; c=relaxed/simple; bh=d46/j7SfBjlB5pOHNg/gyQVFI44DuFqnaghicJF9/+0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cfrmTcP6kK342u3EIYTamiBVTSuGKgSnXDLzvW1nf6dgazr09zN83GRlmo+WZK5TF1vq2Uurl9VwCA9M60yyOtt92aKEZQnSJIj9nqyoQVbt4IwE97P2V5efQo6LWHsbPVOfiggYc/oV/+leLcgUsbdKum26z3M1TKjYnerAeZQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hGRJdUmR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hGRJdUmR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 069A6C4AF0F; Fri, 12 Apr 2024 18:33:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712946793; bh=d46/j7SfBjlB5pOHNg/gyQVFI44DuFqnaghicJF9/+0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hGRJdUmRz6JuH14PX2oW4J4iKBjLs5L9muwe1c2FZK29AehqdZ31TOhFYx5EhswF5 BsY0I9tseGqOdZPk7PPwZ6IHEeff65pklUfyKU+Um97Wg0rMcBjnw+csgugB9hFBcY 4/d/SdQtmJcKigKH8GNQD9+e2d2idRXzcZmISzH4e/EyyoMUwHyXBj1/laeRVFsKV3 1HbkK+FZXUBTY/XfRuPyLDgkQ16V07C1ojJZOCJbjcLG8myUlu52tCHCET7deHfNgV FyCLTOs1z0FntzEseAYfggLgmvCfnQpNdVaaOlDYdKoJcUMMlLhdaQlkb3Ut6CaJVe rOHkpCkLIFXcA== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers , Kan Liang Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Masami Hiramatsu Subject: [PATCH 3/4] perf dwarf-aux: Check variable address range properly Date: Fri, 12 Apr 2024 11:33:09 -0700 Message-ID: <20240412183310.2518474-4-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.683.g7961c838ac-goog In-Reply-To: <20240412183310.2518474-1-namhyung@kernel.org> References: <20240412183310.2518474-1-namhyung@kernel.org> 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 Content-Type: text/plain; charset="utf-8" In match_var_offset(), it just checked the end address of the variable with the given offset because it assumed the register holds a pointer to the data type and the offset starts from the base. But I found some cases that the stack pointer (rsp =3D reg7) register is used to pointer a stack variable while the frame base is maintained by a different register (rbp =3D reg6). In that case, it cannot simply use the stack pointer as it cannot guarantee that it points to the frame base. So it needs to check the both boundaries of the variable location. Before: ----------------------------------------------------------- find data type for 0x7c(reg7) at tcp_getsockopt+0xb62 CU for net/ipv4/tcp.c (die:0x7b5f516) frame base: cfa=3D0 fbreg=3D6 no pointer or no type check variable "tss" failed (die: 0x7b95801) variable location: base reg7, offset=3D0x110 type=3D'struct scm_timestamping_internal' size=3D0x30 (die:0x7b8c126) So the current code just checks register number for the non-PC and non-FB registers and assuming it has offset 0. But this variable has offset 0x110 so it should not match to this. After: ----------------------------------------------------------- find data type for 0x7c(reg7) at tcp_getsockopt+0xb62 CU for net/ipv4/tcp.c (die:0x7b5f516) frame base: cfa=3D0 fbreg=3D6 no pointer or no type check variable "zc" failed (die: 0x7b9580a) variable location: base=3Dreg7, offset=3D0x40 type=3D'struct tcp_zerocopy_receive' size=3D0x40 (die:7b947f4) Now it find the correct variable "zc". It was located at reg7 + 0x40 and the size if 0x40 which means it should cover [0x40, 0x80). And the access was for reg7 + 0x7c so it found the right one. But it still failed to use the variable and it would be handled in the next patch. Cc: Masami Hiramatsu Signed-off-by: Namhyung Kim --- tools/perf/util/dwarf-aux.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index b361fd7ebd56..40cfbdfe2d75 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1372,6 +1372,9 @@ static bool match_var_offset(Dwarf_Die *die_mem, stru= ct find_var_data *data, return true; } =20 + if (addr_offset < addr_type) + return false; + if (die_get_real_type(die_mem, &type_die) =3D=3D NULL) return false; =20 @@ -1446,7 +1449,6 @@ static int __die_find_var_reg_cb(Dwarf_Die *die_mem, = void *arg) =20 /* Local variables accessed using frame base register */ if (data->is_fbreg && ops->atom =3D=3D DW_OP_fbreg && - data->offset >=3D (int)ops->number && check_allowed_ops(ops, nops) && match_var_offset(die_mem, data, data->offset, ops->number, /*is_pointer=3D*/false)) @@ -1537,9 +1539,6 @@ static int __die_find_var_addr_cb(Dwarf_Die *die_mem,= void *arg) if (ops->atom !=3D DW_OP_addr) continue; =20 - if (data->addr < ops->number) - continue; - if (check_allowed_ops(ops, nops) && match_var_offset(die_mem, data, data->addr, ops->number, /*is_pointer=3D*/false)) --=20 2.44.0.683.g7961c838ac-goog From nobody Sun Feb 8 22:06:17 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 603C614F9FD; Fri, 12 Apr 2024 18:33:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712946794; cv=none; b=DrEPjou17N4htiU2E2x7OYfmjOxQaQpaaqc4eIfrnkD6+prBKmQvAwZwaHgR83/uMxW41nEtB6ZhvmbOvAYw7EbeNyAzX3WtayijJUcgp3BWcTqA+MydmFNOoqBkDwwF1lycRw5v2gumPYXLLSV/GbKF6fyp10gVMxWZv/A7eZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712946794; c=relaxed/simple; bh=Mt6sBBBPrGWipkKUwBCkIzYuDK3HGlK3FMB4X+GvFnk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mVWLMo/XQdh4gBdxrbFMT/kuTAvAUMW0F1gsUr4Dk3q8SRYmO/lZQyveUTu/YGMhbRpraXUJR2YbMaJavPZuv5VgDMNKkbCf8WyZ4guIge+HHOdV8Rp/z4aGr5+QgreKp1RHS7TqmAkJZdWJ48r8Iejo8sRCtUGALirvdrExI5k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cR2WVq5+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cR2WVq5+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8CF6DC2BBFC; Fri, 12 Apr 2024 18:33:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712946793; bh=Mt6sBBBPrGWipkKUwBCkIzYuDK3HGlK3FMB4X+GvFnk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cR2WVq5+L6yzaiB3qWpk0hll5h+FzZF2WrIWeo7NJfouZ0k9kps81jEHkev8wg/d3 qBqF+XwW6fjiPOSPAk+MjxKZPnJVHJPcXoXU+pnV8ZJIcjUny2J2DBkT/5RKeN0vJS Vtp/s81axGPcYpGvUU9EeFy9Bq4D3FyYjsrQdrbslBsjxpjn0/ymVKpWIGHpFWMs8X +VLdo3LheHehC6TLtqBZNvF2wXBf7vEY05C3mRH2UzzPAN3Zzk+y2pFLztQlyMIW7F 9bO76mFiRJYzXlIded2eG7bq+6vc4VRxRlUVVwsZxuE9T/H1+jQ0Na2aa18AOqXbtt YSVMS2sBxpJlA== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers , Kan Liang Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org Subject: [PATCH 4/4] perf annotate-data: Handle RSP if it's not the FB register Date: Fri, 12 Apr 2024 11:33:10 -0700 Message-ID: <20240412183310.2518474-5-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.683.g7961c838ac-goog In-Reply-To: <20240412183310.2518474-1-namhyung@kernel.org> References: <20240412183310.2518474-1-namhyung@kernel.org> 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 Content-Type: text/plain; charset="utf-8" In some cases, the stack pointer on x86 (rsp =3D reg7) is used to point variables on stack but it's not the frame base register. Then it should handle the register like normal registers (IOW not to access the other stack variables using offset calculation) but it should not assume it would have a pointer. Before: ----------------------------------------------------------- find data type for 0x7c(reg7) at tcp_getsockopt+0xb62 CU for net/ipv4/tcp.c (die:0x7b5f516) frame base: cfa=3D0 fbreg=3D6 no pointer or no type check variable "zc" failed (die: 0x7b9580a) variable location: base=3Dreg7, offset=3D0x40 type=3D'struct tcp_zerocopy_receive' size=3D0x40 (die:0x7b947f4) After: ----------------------------------------------------------- find data type for 0x7c(reg7) at tcp_getsockopt+0xb62 CU for net/ipv4/tcp.c (die:0x7b5f516) frame base: cfa=3D0 fbreg=3D6 found "zc" in scope=3D3/3 (die: 0x7b957fc) type_offset=3D0x3c variable location: base=3Dreg7, offset=3D0x40 type=3D'struct tcp_zerocopy_receive' size=3D0x40 (die:0x7b947f4) Note that the type-offset was properly calculated to 0x3c as the variable starts at 0x40. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index c6eb5b2cc4d5..2dfbdd804222 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -25,6 +25,9 @@ #include "symbol_conf.h" #include "thread.h" =20 +/* register number of the stack pointer */ +#define X86_REG_SP 7 + enum type_state_kind { TSR_KIND_INVALID =3D 0, TSR_KIND_TYPE, @@ -197,7 +200,7 @@ static void init_type_state(struct type_state *state, s= truct arch *arch) state->regs[10].caller_saved =3D true; state->regs[11].caller_saved =3D true; state->ret_reg =3D 0; - state->stack_reg =3D 7; + state->stack_reg =3D X86_REG_SP; } } =20 @@ -382,10 +385,18 @@ static bool find_cu_die(struct debuginfo *di, u64 pc,= Dwarf_Die *cu_die) } =20 /* The type info will be saved in @type_die */ -static int check_variable(Dwarf_Die *var_die, Dwarf_Die *type_die, int off= set, - bool is_pointer) +static int check_variable(struct data_loc_info *dloc, Dwarf_Die *var_die, + Dwarf_Die *type_die, int reg, int offset, bool is_fbreg) { Dwarf_Word size; + bool is_pointer =3D true; + + if (reg =3D=3D DWARF_REG_PC) + is_pointer =3D false; + else if (reg =3D=3D dloc->fbreg || is_fbreg) + is_pointer =3D false; + else if (arch__is(dloc->arch, "x86") && reg =3D=3D X86_REG_SP) + is_pointer =3D false; =20 /* Get the type of the variable */ if (die_get_real_type(var_die, type_die) =3D=3D NULL) { @@ -607,7 +618,6 @@ static bool get_global_var_type(Dwarf_Die *cu_die, stru= ct data_loc_info *dloc, { u64 pc; int offset; - bool is_pointer =3D false; const char *var_name =3D NULL; struct global_var_entry *gvar; Dwarf_Die var_die; @@ -623,7 +633,8 @@ static bool get_global_var_type(Dwarf_Die *cu_die, stru= ct data_loc_info *dloc, =20 /* Try to get the variable by address first */ if (die_find_variable_by_addr(cu_die, var_addr, &var_die, &offset) && - check_variable(&var_die, type_die, offset, is_pointer) =3D=3D 0) { + check_variable(dloc, &var_die, type_die, DWARF_REG_PC, offset, + /*is_fbreg=3D*/false) =3D=3D 0) { var_name =3D dwarf_diename(&var_die); *var_offset =3D offset; goto ok; @@ -636,7 +647,8 @@ static bool get_global_var_type(Dwarf_Die *cu_die, stru= ct data_loc_info *dloc, =20 /* Try to get the name of global variable */ if (die_find_variable_at(cu_die, var_name, pc, &var_die) && - check_variable(&var_die, type_die, *var_offset, is_pointer) =3D=3D 0) + check_variable(dloc, &var_die, type_die, DWARF_REG_PC, *var_offset, + /*is_fbreg=3D*/false) =3D=3D 0) goto ok; =20 return false; @@ -1587,8 +1599,7 @@ static int find_data_type_die(struct data_loc_info *d= loc, Dwarf_Die *type_die) } =20 /* Found a variable, see if it's correct */ - ret =3D check_variable(&var_die, type_die, offset, - reg !=3D DWARF_REG_PC && !is_fbreg); + ret =3D check_variable(dloc, &var_die, type_die, reg, offset, is_fbreg); if (ret =3D=3D 0) { pr_debug_dtp("found \"%s\" in scope=3D%d/%d (die: %#lx) ", dwarf_diename(&var_die), i+1, nr_scopes, --=20 2.44.0.683.g7961c838ac-goog