All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yonghong Song <yonghong.song@linux.dev>
To: Alan Maguire <alan.maguire@oracle.com>,
	Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com>,
	dwarves@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	bpf@vger.kernel.org, kernel-team@fb.com
Subject: [PATCH dwarves v9 5/6] btf_encoder: Avoid comparing inlined and out-of-line function prototypes
Date: Tue, 23 Jun 2026 22:26:19 -0700	[thread overview]
Message-ID: <20260624052619.3143003-1-yonghong.song@linux.dev> (raw)
In-Reply-To: <20260624052553.3139112-1-yonghong.song@linux.dev>

When true_signature is enabled, the same function can appear as two kinds
of saved states: an inlined (abstract) instance that carries the original
source signature with no address, and an out-of-line instance that carries
the reconstructed true signature. These two legitimately differ, so
comparing them in saved_functions_combine() wrongly flags the function as
having an inconsistent prototype and drops it from BTF.

Record which kind a state is by adding an 'inlined' bit to
btf_encoder_func_state, set from function__inlined() in
btf_encoder__save_func().

Use it in two places:
 - saved_functions_cmp() breaks ties by 'inlined' so that out-of-line
   (real) instances sort before inlined (abstract) ones. Since
   saved_functions_combine() compares every state in a group against the
   first (anchor) state, keeping a real instance as the anchor ensures real
   instances are still compared against each other for prototype
   consistency.
 - saved_functions_combine() only runs the prototype-consistency check when
   both states are of the same kind (a->inlined == b->inlined). The true
   signature always comes from the out-of-line instance, which is the one
   picked by btf_encoder__select_canonical_state().

Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
 btf_encoder.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/btf_encoder.c b/btf_encoder.c
index 38455a4..81bfda3 100644
--- a/btf_encoder.c
+++ b/btf_encoder.c
@@ -96,6 +96,7 @@ struct btf_encoder_func_state {
 	uint8_t uncertain_parm_loc:1;
 	uint8_t reordered_parm:1;
 	uint8_t ambiguous_addr:1;
+	uint8_t inlined:1;
 	int ret_type_id;
 	struct btf_encoder_func_parm *parms;
 	struct btf_encoder_func_annot *annots;
@@ -1295,6 +1296,7 @@ static int32_t btf_encoder__save_func(struct btf_encoder *encoder, struct functi
 	state->optimized_parms = ftype->optimized_parms;
 	state->uncertain_parm_loc = ftype->uncertain_parm_loc;
 	state->reordered_parm = ftype->reordered_parm;
+	state->inlined = function__inlined(fn);
 	ftype__for_each_parameter(ftype, param) {
 		const char *name;
 		char *final_name = NULL;
@@ -1489,8 +1491,19 @@ static int saved_functions_cmp(const void *_a, const void *_b)
 {
 	const struct btf_encoder_func_state *a = _a;
 	const struct btf_encoder_func_state *b = _b;
+	int ret;
 
-	return elf_function__name_cmp(a->elf, b->elf);
+	ret = elf_function__name_cmp(a->elf, b->elf);
+	if (ret)
+		return ret;
+
+	/* For the same function, sort the out-of-line (real) instances before
+	 * the inlined (abstract) ones. saved_functions_combine() compares every
+	 * state in a group against the first (anchor) one, so keeping a real
+	 * instance as the anchor ensures real instances are still compared
+	 * against each other for prototype consistency.
+	 */
+	return a->inlined - b->inlined;
 }
 
 static int saved_functions_combine(struct btf_encoder *encoder,
@@ -1507,7 +1520,17 @@ static int saved_functions_combine(struct btf_encoder *encoder,
 	inconsistent = a->inconsistent_proto | b->inconsistent_proto;
 	uncertain_parm_loc = a->uncertain_parm_loc | b->uncertain_parm_loc;
 	reordered_parm = a->reordered_parm | b->reordered_parm;
-	if (!unexpected && !inconsistent && !reordered_parm && !funcs__match(encoder, a, b))
+
+	/* Only compare prototypes that are of the same kind. An inlined
+	 * (abstract) instance carries the original signature while the
+	 * out-of-line instance carries the true signature, so the two will
+	 * legitimately differ; comparing them would wrongly flag the function
+	 * as having an inconsistent prototype and drop it from BTF. The true
+	 * signature always comes from the out-of-line (real) instance, which is
+	 * the one selected by btf_encoder__select_canonical_state().
+	 */
+	if (a->inlined == b->inlined &&
+	    !unexpected && !inconsistent && !reordered_parm && !funcs__match(encoder, a, b))
 		inconsistent = 1;
 	a->optimized_parms = b->optimized_parms = optimized;
 	a->unexpected_reg = b->unexpected_reg = unexpected;
-- 
2.53.0-Meta


  parent reply	other threads:[~2026-06-24  5:26 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-24  5:25 [PATCH dwarves v9 0/6] pahole: Encode true signatures in kernel BTF Yonghong Song
2026-06-24  5:25 ` [PATCH dwarves v9 1/6] dwarf_loader: Detect aggregate ABI register usage and signature changes Yonghong Song
2026-06-24  5:26 ` [PATCH dwarves v9 2/6] dwarf_loader: Collect per-parameter information Yonghong Song
2026-06-24  5:26 ` [PATCH dwarves v9 3/6] dwarf_loader: Analyze per-parameter information for true signatures Yonghong Song
2026-06-24  5:26 ` [PATCH dwarves v9 4/6] btf_encoder: Emit true function signatures Yonghong Song
2026-06-24  5:26 ` Yonghong Song [this message]
2026-06-24  5:26 ` [PATCH dwarves v9 6/6] tests: Add BTF true_signature encoding tests Yonghong Song

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260624052619.3143003-1-yonghong.song@linux.dev \
    --to=yonghong.song@linux.dev \
    --cc=alan.maguire@oracle.com \
    --cc=andrii@kernel.org \
    --cc=arnaldo.melo@gmail.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=dwarves@vger.kernel.org \
    --cc=kernel-team@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.