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
next prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox