From nobody Fri Sep 25 06:03:30 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 4AECC371D15; Sat, 19 Sep 2026 06:37:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789799877; cv=none; b=CctwqSbtKoCz3Jb7ppaEgSgW8y9D8iCRzFnO+bQUnrY9ZLkWUQmAcLZIrwX41obp7nFdbCes5aL7CFfLA0ZU6/Q9utlJXEYROqqSHZMMhdFPUDo1nmrXBS4yHCMDTOXRBrIcH25umuvh6pog2s8cE2nDYax7gsO3ovYtzdIKLvU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789799877; c=relaxed/simple; bh=UFRbCyPFOpIhiJkgvdA1N7r2subnEKtJZgFjm96tkgg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tXt+X0LTUUU0Rj9AHnldc6UGbTACw9+cauBkaywIJLX70OLkM3U/iKF6Cw4lUJLBesbLl8IHb9panfeNZBEhVDGb7K8FnlZsEWgq0vtLBrLrrZbcLHMD71QDXD7qRdfLbIxRY/bLxHlkFc5KeGJezJNdIdlUFnn6KR9HRlgNvCw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DEZh4BL3; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DEZh4BL3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 191561F0089B; Sat, 19 Sep 2026 06:37:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789799873; bh=3r9HJ9ewao2icCySTmJJ7SlG5OXWYkY8ylhpaNhdIjI=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=DEZh4BL3ibaxsHt9v7b8iP8yLmKBxqp7t16Nlq/vRG9hQcHFkyJWiVirLtM3dJc5k oC/LdC+KEyTf2GqIsRC25qpjnB8yFS0rD1qavfMc/ycCIRcrVukz9MmIGpbHMY5fBU 5S0DbQ/OJ70Gecd7GaeUFSEr3ynOi3X/tg1Zrgz+Ld0TNH4voUp1xqHDEObPKtNfdi uGk9DHoTl+ettOYDxnaCXTNQGvnXbYYHRlgkzVLAkBoBTmAlBTnzhmrOGotIyKFbee 5heGnUGI2Zq7DXmwXrKUzMddXOTEcacN9RZ7a1dE5UMkmhTOzyHbOrFr+FoI5Ien5F 9vPS9ZvC0JLyQ== From: Namhyung Kim To: Arnaldo Carvalho de Melo Cc: Ian Rogers , Jiri Olsa , Adrian Hunter , James Clark , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Zecheng Li , Yanbo Zhao , Tengda Wu , Shuai Xue , "Masami Hiramatsu (Google)" Subject: [PATCH v5 1/4] perf dwarf-aux: Add die_has_flex_array() helper Date: Fri, 18 Sep 2026 23:37:42 -0700 Message-ID: <20260919063745.48444-2-namhyung@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260919063745.48444-1-namhyung@kernel.org> References: <20260919063745.48444-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" The die_has_flex_array() returns true when the given type is a compound type and contains an array at the end. To prevent an infinite recursion add a depth field to the internal function. Acked-by: Masami Hiramatsu (Google) Signed-off-by: Namhyung Kim --- tools/perf/util/dwarf-aux.c | 107 ++++++++++++++++++++++++++++++++++++ tools/perf/util/dwarf-aux.h | 3 + 2 files changed, 110 insertions(+) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index d7160f87ac7d7ab3..1560e721479a1ac2 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "debug.h" #include "dwarf-aux.h" #include "dwarf-regs.h" @@ -2180,3 +2181,109 @@ Dwarf_Die *die_deref_ptr_type(Dwarf_Die *ptr_die, i= nt offset, =20 return die_get_member_type(&type_die, offset, die_mem); } + +static bool is_flex_array_member(Dwarf_Die *mb_die) +{ + Dwarf_Die type_die; + Dwarf_Word size; + + /* get the type of the member */ + if (die_get_real_type(mb_die, &type_die) =3D=3D NULL) + return false; + + if (dwarf_tag(&type_die) !=3D DW_TAG_array_type) + return false; + + return dwarf_aggregate_size(&type_die, &size) < 0 || size =3D=3D 0; +} + +#define MAX_FLEX_ARRAY_RECURSION 256 /* arbitrary */ + +static bool die_has_flex_array_recurse(Dwarf_Die *parent_die, int depth) +{ + Dwarf_Die die_mem, last_mb; + int tag =3D dwarf_tag(parent_die); + bool found =3D false; + Dwarf_Word loc, last_loc =3D 0; + + if (tag !=3D DW_TAG_structure_type && tag !=3D DW_TAG_union_type) + return false; + + /* prevent infinite recursion */ + if (depth > MAX_FLEX_ARRAY_RECURSION) + return false; + + if (dwarf_child(parent_die, &die_mem)) + return false; + + do { + if (dwarf_tag(&die_mem) !=3D DW_TAG_member) + continue; + + if (tag =3D=3D DW_TAG_union_type) { + if (is_flex_array_member(&die_mem)) + return true; + + if (die_get_real_type(&die_mem, &last_mb) && + die_has_flex_array_recurse(&last_mb, depth + 1)) + return true; + } + + if (tag =3D=3D DW_TAG_structure_type) { + if (die_get_data_member_location(&die_mem, &loc) < 0) { + /* ignore bitfields */ + loc =3D 0; + } + + if (last_loc <=3D loc) { + memcpy(&last_mb, &die_mem, sizeof(last_mb)); + last_loc =3D loc; + } + } + + found =3D true; + } while (dwarf_siblingof(&die_mem, &die_mem) =3D=3D 0); + + if (tag =3D=3D DW_TAG_structure_type && found) { + if (is_flex_array_member(&last_mb)) + return true; + + if (die_get_real_type(&last_mb, &die_mem)) + return die_has_flex_array_recurse(&die_mem, depth + 1); + } + + return false; +} + +/** + * die_has_flex_array - Check if the given type has a flex-array at the end + * @type_die: a pointer to type DIE + * + * This function returns %true iff @type_die is a struct or union type and= has + * an array at the end. Note that the flex-array has no element, it shoul= d have + * no size and the parent size doesn't include the flex-array. So it shou= ld + * locate at the offset of the parent size. + * + * For simplicity, it assumes the parent size of aligned with the flex-arr= ay. + */ +bool die_has_flex_array(Dwarf_Die *type_die) +{ + Dwarf_Die real_type; + + switch (dwarf_tag(type_die)) { + case DW_TAG_typedef: + case DW_TAG_const_type: + case DW_TAG_restrict_type: + case DW_TAG_volatile_type: + case DW_TAG_shared_type: + if (die_get_real_type(type_die, &real_type) =3D=3D NULL) + return false; + + type_die =3D &real_type; + break; + default: + break; + } + + return die_has_flex_array_recurse(type_die, 0); +} diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index 161f0bf980b6ee6a..9b662db710220522 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h @@ -189,4 +189,7 @@ void die_collect_global_vars(Dwarf_Die *cu_die, struct = die_var_type **var_types) /* Get the frame base information from CFA */ int die_get_cfa(Dwarf *dwarf, u64 pc, int *preg, int *poffset); =20 +/* Check whether given type has a flex array */ +bool die_has_flex_array(Dwarf_Die *parent_die); + #endif /* _DWARF_AUX_H */ --=20 2.55.0 From nobody Fri Sep 25 06:03:30 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 52D8472621; Sat, 19 Sep 2026 06:37:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789799878; cv=none; b=RfUSSVH1ch1SBTcKYb57vzhW0I8ExMrYnqHmcy/xCiAm7FpKerpO7CWIU+QnXi5Vyk4eINYOTHQhPgi9pQP/HEEtzm6CKdkOIO//TGK419bL+Xd5MhTY0POL8sC6EPEnOXi+UE0WqAUw/WHw8l2KFnJrz6r7oTKqExzL3pHwR4I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789799878; c=relaxed/simple; bh=TQQtXJJjH04u/hnOnUZauq3jKLD5V0udNUkvLQRvtBs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dg119G2aZ6zqPbN58Tq2MoZ1MrhmTXaGdfnK9BKCa0zzfo2ZNfT95s6OP7fAzCOA5UYR/Ql9KIXWWMhkjOO82FEeCfI5k9DY+61HwVA7SvE3inqUFWH00WBWcAJG7bF6YwaEypjr/2cSn+Gu1HctJrT7puh2+2gsnRT1FoEvf3s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WCd0fNQ/; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="WCd0fNQ/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B3BAC1F00898; Sat, 19 Sep 2026 06:37:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789799874; bh=LlAx1lSVoQCyKt9jZ16pnAFFWy81J3aKHgE6uB1i6CA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=WCd0fNQ/1mB5wceqRd2xN/SJeIMiiMRMn+QdaPNeH36hU34tAncHFLAS9iyKeilAg uRUMzANQ7MeteDSbQQgig4vf6whoLLbCTdLBiLIVQGJOQBoPXVEPjaMkXPEspPL0vo y5ts1hv9dUT5dVN4bRxjUWuX8wFFL2VVb8hPfOK7NcnXMFTt/WfImFGYGofZUKmnCh KCtK/EZOfkFqrssETFauMdim4uOQdCdNECN1PhNf/Ug+xtK9focQnihQggC4s0f0sq uGhE6tvRiRAt92h/F77bLDB+N3ND3z6rDSb5onJY6Ax02M8q4LRbcPXpZc0LL+O16x izEa3T+bOPzlA== From: Namhyung Kim To: Arnaldo Carvalho de Melo Cc: Ian Rogers , Jiri Olsa , Adrian Hunter , James Clark , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Zecheng Li , Yanbo Zhao , Tengda Wu , Shuai Xue Subject: [PATCH v5 2/4] perf annotate-data: A small cleanup in __add_member_cb() Date: Fri, 18 Sep 2026 23:37:43 -0700 Message-ID: <20260919063745.48444-3-namhyung@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260919063745.48444-1-namhyung@kernel.org> References: <20260919063745.48444-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" Check return value of strbuf_init() and die_get_typename() to make sure if typename of a member gets never NULL. Also remove the check for typedef by just using die_get_real_type(). It can get rid of member_type variable as well. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index aff60a630fd05b01..845a5d8c2b84b6a6 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -226,7 +226,7 @@ static int __add_member_cb(Dwarf_Die *die, void *arg) { struct annotated_member *parent =3D arg; struct annotated_member *member; - Dwarf_Die member_type, die_mem; + Dwarf_Die die_mem; Dwarf_Word size, loc, bit_size =3D 0; Dwarf_Attribute attr; struct strbuf sb; @@ -239,14 +239,15 @@ static int __add_member_cb(Dwarf_Die *die, void *arg) if (member =3D=3D NULL) return DIE_FIND_CB_END; =20 - strbuf_init(&sb, 32); - die_get_typename(die, &sb); + if (strbuf_init(&sb, 32) < 0) { + free(member); + return DIE_FIND_CB_END; + } =20 - __die_get_real_type(die, &member_type); - if (dwarf_tag(&member_type) =3D=3D DW_TAG_typedef) - die_get_real_type(&member_type, &die_mem); - else - die_mem =3D member_type; + if (die_get_typename(die, &sb) < 0) + strbuf_add(&sb, "(unknown type)", 14); + + die_get_real_type(die, &die_mem); =20 if (dwarf_aggregate_size(&die_mem, &size) < 0) size =3D 0; --=20 2.55.0 From nobody Fri Sep 25 06:03:30 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 53DA337C903; Sat, 19 Sep 2026 06:37:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789799880; cv=none; b=FDHIlXQ84lopTSboo41iLMHa8d/skNRVFTIYIc+Tpv4tyPiAg23tp8aQ0KpAwi6boOpWqmhdaaKL9jnm765nAdNqBWvXVwke55kUpvJjVcTj/EQQ0m3YerN6MsHdngKiOu0jOzsX3GmukU4nMEHloiysR0T9RZ9VZQtY9HSpd8s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789799880; c=relaxed/simple; bh=Hqk/Vspkt4I9EttbLbcBjp1rM/k7Q923m+aS37h9O6Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UqXQGU5lllQSj7ZiP/2eR4bPPGNgTHDA2am7mS3Ysa9Yy58XwZRyPZYiTwANE7JVsaswayx2nDvfYG5sX/8qGMsccQTDUs7Rdk1xEdh1k5X+FjbxkdJdcttPblo7/vTNENF0ykhHVTpHLodo+3hoUpHwvKE2vrS4FSdv3KANvIs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UbHZ4xzN; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UbHZ4xzN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 549C91F00899; Sat, 19 Sep 2026 06:37:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789799874; bh=O8MjfrwV8yk1Fc4uVimleJ3OeeIK7YwAhHdhnAUKz9Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=UbHZ4xzNQknoIQS2c96xgezlmaTGG4XhZ+gxedxVwgDYH+WXrHly2whiUspYTAf2R c2X8nJ4gHnxU8/vG7xI9TJQ6VgbNkpprfySGAeyrIGRaKMMgx+AG/6unogHtemMRG2 8H2oZzjz3QEWFLlbglvg9Wqxp6SvSR7EbiS7PUcFFD5zAk8RPzWErMXd41+w67aj9p RspGr6RbfRAMiGgJ8H2SOVc8nTjh+ubmmAwxqxQaJJBRum4PTzGDSvX85Qjac3ZsKq QsE4K0urTYTOmFI1aHq3dzfcJ9sMyaQHoivve7MlQGgd/+y23Lt3ahmhAA3j98IT83 UOkjjetndHQqQ== From: Namhyung Kim To: Arnaldo Carvalho de Melo Cc: Ian Rogers , Jiri Olsa , Adrian Hunter , James Clark , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Zecheng Li , Yanbo Zhao , Tengda Wu , Shuai Xue Subject: [PATCH v5 3/4] perf annotate-data: Allow out-of-size access for flex-array types Date: Fri, 18 Sep 2026 23:37:44 -0700 Message-ID: <20260919063745.48444-4-namhyung@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260919063745.48444-1-namhyung@kernel.org> References: <20260919063745.48444-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" Structs that have a flex array will have accesses beyond its original size as the array was declared as 0 sized. For now, it just allow any offset bigger than the size. It could be refined later. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 63 ++++++++++++++++++--------------- tools/perf/util/annotate-data.h | 2 ++ 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 845a5d8c2b84b6a6..5dd6c6ec2d42451d 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include =20 @@ -249,8 +250,15 @@ static int __add_member_cb(Dwarf_Die *die, void *arg) =20 die_get_real_type(die, &die_mem); =20 - if (dwarf_aggregate_size(&die_mem, &size) < 0) - size =3D 0; + if (dwarf_aggregate_size(&die_mem, &size) < 0 || size =3D=3D 0) { + if (dwarf_tag(&die_mem) =3D=3D DW_TAG_array_type) { /* flex-array? */ + die_get_real_type(&die_mem, &die_mem); + if (dwarf_aggregate_size(&die_mem, &size) < 0) + size =3D 0; + } else { + size =3D 0; + } + } =20 if (dwarf_attr_integrate(die, DW_AT_data_member_location, &attr)) { if (dwarf_formudata(&attr, &loc) !=3D 0) { @@ -400,6 +408,7 @@ static struct annotated_data_type *dso__findnew_data_ty= pe(struct dso *dso, result->self.type_name =3D type_name; result->self.size =3D size; INIT_LIST_HEAD(&result->self.children); + result->flex_array =3D die_has_flex_array(type_die); =20 if (symbol_conf.annotate_data_member) add_member_types(result, type_die); @@ -518,13 +527,30 @@ static bool is_better_type(Dwarf_Die *type_a, Dwarf_D= ie *type_b) return false; } =20 +static enum type_match_result check_type_offset(Dwarf_Die *type_die, int o= ffset) +{ + Dwarf_Word size; + + /* Get the size of the actual type */ + if (dwarf_aggregate_size(type_die, &size) < 0) + return PERF_TMR_NO_SIZE; + + /* Minimal sanity check */ + if (offset < 0) + return PERF_TMR_BAD_OFFSET; + + if ((unsigned)offset >=3D size && !die_has_flex_array(type_die)) + return PERF_TMR_BAD_OFFSET; + + return PERF_TMR_OK; +} + /* The type info will be saved in @type_die */ static enum type_match_result 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 needs_pointer =3D true; Dwarf_Die sized_type; =20 @@ -555,15 +581,7 @@ static enum type_match_result check_variable(struct da= ta_loc_info *dloc, else sized_type =3D *type_die; =20 - /* Get the size of the actual type */ - if (dwarf_aggregate_size(&sized_type, &size) < 0) - return PERF_TMR_NO_SIZE; - - /* Minimal sanity check */ - if ((unsigned)offset >=3D size) - return PERF_TMR_BAD_OFFSET; - - return PERF_TMR_OK; + return check_type_offset(&sized_type, offset); } =20 struct type_state_stack *find_stack_state(struct type_state *state, @@ -1113,7 +1131,6 @@ static enum type_match_result check_matching_type(str= uct type_state *state, struct disasm_line *dl, Dwarf_Die *type_die) { - Dwarf_Word size; u32 insn_offset =3D dl->al.offset; int reg =3D dloc->op->reg1; int offset =3D dloc->op->offset; @@ -1167,12 +1184,7 @@ static enum type_match_result check_matching_type(st= ruct type_state *state, else sized_type =3D *type_die; =20 - /* Get the size of the actual type */ - if (dwarf_aggregate_size(&sized_type, &size) < 0 || - (unsigned)dloc->type_offset >=3D size) - return PERF_TMR_BAD_OFFSET; - - return PERF_TMR_OK; + return check_type_offset(&sized_type, dloc->type_offset); } =20 if (state->regs[reg].kind =3D=3D TSR_KIND_POINTER) { @@ -1191,12 +1203,7 @@ static enum type_match_result check_matching_type(st= ruct type_state *state, =20 dloc->type_offset =3D dloc->op->offset + state->regs[reg].offset; =20 - /* Get the size of the actual type */ - if (dwarf_aggregate_size(type_die, &size) < 0 || - (unsigned)dloc->type_offset >=3D size) - return PERF_TMR_BAD_OFFSET; - - return PERF_TMR_OK; + return check_type_offset(type_die, dloc->type_offset); } =20 if (state->regs[reg].kind =3D=3D TSR_KIND_PERCPU_POINTER) { @@ -1210,9 +1217,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, =20 dloc->type_offset =3D dloc->op->offset; =20 - /* Get the size of the actual type */ - if (dwarf_aggregate_size(type_die, &size) < 0 || - (unsigned)dloc->type_offset >=3D size) + if (check_type_offset(type_die, dloc->type_offset) !=3D PERF_TMR_OK) return PERF_TMR_BAIL_OUT; =20 return PERF_TMR_OK; @@ -1840,7 +1845,7 @@ int annotated_data_type__update_samples(struct annota= ted_data_type *adt, return -1; } =20 - if (offset < 0 || offset >=3D adt->self.size) + if (offset < 0 || (offset >=3D adt->self.size && !adt->flex_array)) return -1; =20 h =3D &adt->histograms[evsel->core.idx]; diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index ca2096a9ee62cbfe..957726334907cc0e 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -85,6 +85,7 @@ struct type_hist { * struct annotated_data_type - Data type to profile * @node: RB-tree node for dso->type_tree * @self: Actual type information + * @flex_array: Whether it has a flex array * @nr_histogram: Number of histogram entries * @histograms: An array of histograms * @@ -93,6 +94,7 @@ struct type_hist { struct annotated_data_type { struct rb_node node; struct annotated_member self; + bool flex_array; int nr_histograms; struct type_hist *histograms; }; --=20 2.55.0 From nobody Fri Sep 25 06:03:30 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 46EB43515DC; Sat, 19 Sep 2026 06:37:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789799881; cv=none; b=JDNItco342oeot5h3R4IcSN/G6JLN4oXt0tduo+3vS8sGbATKAhPKQTzMtxKfZpUlkZt1l6tJGcqvkHjwMGB5M+qlE5lzpO7LLgIyiWNlWeFc12QjHzJ3ffO7MtCI9n7kX1vQIFOtNBrMLeFPkrVMLActl5GkwFf+Z8Ono58zPs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789799881; c=relaxed/simple; bh=c0oefu3ZRdD0J4clKz3RxVr35grHfxVn3NLlHA2WsM0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pe71sRT6o0jkz1KBPoGKUKYCZqkJfzAZWW3IZzeBlLoCVyqynj/t6cf67ckRYX/lPq2dD1pdeRMFgwS8amzH+jE0BQ0pTOOTaVMVrHDIjqgus+nywgLtXH0gGtDEbOL4PDO06GDbtUReWP0baRZBRiAXlpuzLVSfElc8ZZWMRtY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NtQ32Ve4; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NtQ32Ve4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EB3471F0089A; Sat, 19 Sep 2026 06:37:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789799875; bh=usnmYS7u84GLIEK0S3Ait9fvhPzlxHBW3emjiTs/iAE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=NtQ32Ve4euPuPwXwGpowXS8fY4N53abcIpjUxE3+OpWbz281M4pI3EaVgJcPz2OVH qhcIJ9gDBCjtUPi4OwZw+jHLu/DQELzQ7hSaiDBiRYHxX121NTVSwui+NwkhWr4oZF FLZSL3cwNj+O5jDDjyIWK7UFkBra7j+7SiLLB+sKWnTkL5YNMP+TMGxL6ZA2yIweNE i7FV5yPbfERT/MCk+YFosUdU6cXSBPaUaACVEMC/Xxg/4in6dBDTKed9bZKva9YVGu DMXHfaVXXZXhX4i1ilR9yzXJdVxIKH0xBAIhUnOoDzmB6rWDgFLsMf/t8kukbSX72S HUgEGmtlXV0Bg== From: Namhyung Kim To: Arnaldo Carvalho de Melo Cc: Ian Rogers , Jiri Olsa , Adrian Hunter , James Clark , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Zecheng Li , Yanbo Zhao , Tengda Wu , Shuai Xue Subject: [PATCH v5 4/4] perf annotate-data: Adjust type offset for flex-array Date: Fri, 18 Sep 2026 23:37:45 -0700 Message-ID: <20260919063745.48444-5-namhyung@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260919063745.48444-1-namhyung@kernel.org> References: <20260919063745.48444-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" The flex array members are located beyond the original type size. Also it needs to adjust the offset in an array to find a corresponding element using module operation. Note that we focus on access to type and field, so array index is not important. Make sure to find a field name for flex arrays. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 112 +++++++++++++++++++++++++++++--- tools/perf/util/annotate-data.h | 4 ++ 2 files changed, 107 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 5dd6c6ec2d42451d..e9b58a3d587be45b 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -226,7 +226,7 @@ static bool data_type_less(struct rb_node *node_a, cons= t struct rb_node *node_b) static int __add_member_cb(Dwarf_Die *die, void *arg) { struct annotated_member *parent =3D arg; - struct annotated_member *member; + struct annotated_member *member, *prev; Dwarf_Die die_mem; Dwarf_Word size, loc, bit_size =3D 0; Dwarf_Attribute attr; @@ -253,6 +253,7 @@ static int __add_member_cb(Dwarf_Die *die, void *arg) if (dwarf_aggregate_size(&die_mem, &size) < 0 || size =3D=3D 0) { if (dwarf_tag(&die_mem) =3D=3D DW_TAG_array_type) { /* flex-array? */ die_get_real_type(&die_mem, &die_mem); + member->is_flex_array =3D true; if (dwarf_aggregate_size(&die_mem, &size) < 0) size =3D 0; } else { @@ -299,12 +300,19 @@ static int __add_member_cb(Dwarf_Die *die, void *arg) member->size =3D size; member->offset =3D loc + parent->offset; INIT_LIST_HEAD(&member->children); - list_add_tail(&member->node, &parent->children); + + list_for_each_entry_reverse(prev, &parent->children, node) { + if (prev->offset <=3D member->offset) + break; + } + list_add(&member->node, &prev->node); =20 tag =3D dwarf_tag(&die_mem); switch (tag) { - case DW_TAG_structure_type: case DW_TAG_union_type: + member->is_union =3D true; + /* fall through */ + case DW_TAG_structure_type: die_find_child(&die_mem, __add_member_cb, member, &die_mem); break; default: @@ -333,20 +341,84 @@ static void delete_members(struct annotated_member *m= ember) } } =20 +static struct annotated_member *find_flex_array(struct annotated_member *m) +{ + struct annotated_member *child; + + if (list_empty(&m->children)) + return NULL; + + if (m->is_union) { + list_for_each_entry(child, &m->children, node) { + if (child->is_flex_array) + return child; + } + list_for_each_entry(child, &m->children, node) { + struct annotated_member *grand_child; + + grand_child =3D find_flex_array(child); + if (grand_child) + return grand_child; + } + return NULL; + } + + child =3D list_last_entry(&m->children, struct annotated_member, node); + if (child->is_flex_array) + return child; + + return find_flex_array(child); +} + +static struct annotated_member *get_flex_array_member(struct annotated_dat= a_type *adt) +{ + return find_flex_array(&adt->self); +} + static int fill_member_name(char *buf, size_t sz, struct annotated_member = *m, - int offset, bool first) + int offset, bool first, bool has_flex_array) { struct annotated_member *child; + bool found =3D false; + int len; =20 if (list_empty(&m->children)) return 0; =20 list_for_each_entry(child, &m->children, node) { - int len; - if (offset < child->offset || offset >=3D child->offset + child->size) continue; =20 + found =3D true; + break; + } + + if (!found && has_flex_array) { + /* + * It may have an intermediate struct that has another struct that + * contains a flex array. In that case, the outer struct itself is + * has no array and the size is less than the offset so the above + * logic won't find the outer struct at the offset. + */ + child =3D find_flex_array(m); + if (child =3D=3D NULL || offset < child->offset) + return 0; + + /* find the immediate child that includes a flex array */ + if (m->is_union) { + list_for_each_entry(child, &m->children, node) { + if (child->is_flex_array || find_flex_array(child)) { + found =3D true; + break; + } + } + } else { + child =3D list_last_entry(&m->children, struct annotated_member, node); + found =3D true; + } + } + + if (found) { /* It can have anonymous struct/union members */ if (child->var_name) { len =3D scnprintf(buf, sz, "%s%s", @@ -356,15 +428,18 @@ static int fill_member_name(char *buf, size_t sz, str= uct annotated_member *m, len =3D 0; } =20 - return fill_member_name(buf + len, sz - len, child, offset, first) + len; + return fill_member_name(buf + len, sz - len, child, offset, first, + has_flex_array) + len; } + return 0; } =20 int annotated_data_type__get_member_name(struct annotated_data_type *adt, char *buf, size_t sz, int member_offset) { - return fill_member_name(buf, sz, &adt->self, member_offset, /*first=3D*/t= rue); + return fill_member_name(buf, sz, &adt->self, member_offset, /*first=3D*/t= rue, + adt->flex_array); } =20 static struct annotated_data_type *dso__findnew_data_type(struct dso *dso, @@ -1741,6 +1816,7 @@ struct annotated_data_type *find_data_type(struct dat= a_loc_info *dloc) { struct dso *dso =3D map__dso(dloc->ms->map); Dwarf_Die type_die; + struct annotated_data_type *result; =20 /* * The type offset is the same as instruction offset by default. @@ -1753,7 +1829,25 @@ struct annotated_data_type *find_data_type(struct da= ta_loc_info *dloc) if (find_data_type_die(dloc, &type_die) < 0) return NULL; =20 - return dso__findnew_data_type(dso, &type_die); + result =3D dso__findnew_data_type(dso, &type_die); + if (result =3D=3D NULL) + return NULL; + + if (result->flex_array && dloc->type_offset > result->self.size) { + struct annotated_member *flex_array =3D get_flex_array_member(result); + + if (flex_array && flex_array->size > 0) { + int offset =3D dloc->type_offset; + + /* adjust offset in the flex array */ + offset -=3D flex_array->offset; + offset %=3D flex_array->size; + offset +=3D flex_array->offset; + + dloc->type_offset =3D offset; + } + } + return result; } =20 static size_t data_type_hash(long key, void *ctx __maybe_unused) diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index 957726334907cc0e..14b8113521a927cf 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -47,6 +47,8 @@ enum type_state_kind { * @var_name: Name of the member variable * @offset: Offset from the outer data type * @size: Size of the member field + * @is_union: Whether it's an union type + * @is_flex_array: Whether it's a flex array * * This represents a member type in a data type. */ @@ -57,6 +59,8 @@ struct annotated_member { char *var_name; int offset; int size; + bool is_union; + bool is_flex_array; }; =20 /** --=20 2.55.0