BPF List
 help / color / mirror / Atom feed
* [PATCH dwarves] dwarf_loader: Limit parameter location analysis to x86_64 and arm64
@ 2026-10-03  8:43 Yonghong Song
  2026-10-03 10:13 ` Alan Maguire
  0 siblings, 1 reply; 3+ messages in thread
From: Yonghong Song @ 2026-10-03  8:43 UTC (permalink / raw)
  To: Alan Maguire, Arnaldo Carvalho de Melo, dwarves
  Cc: Alexei Starovoitov, Andrii Nakryiko, bpf, kernel-team,
	Nathan Chancellor

Since commit e96290426e18 ("dwarf_loader: Analyze per-parameter
information for true signatures"), clang-built kernels on arm, powerpc
and riscv lose most of their functions from BTF, and resolve_btfids
emits thousands of warnings like:

  WARN: resolve_btfids: no BTF func for kfunc bpf_xdp_get_xfrm_state in xfrm_state_kfunc_set
  WARN: resolve_btfids: unresolved symbol bpf_xdp_get_xfrm_state

For clang functions whose signature did not change, the new
function__match_clang_parameter_locations() checks that each parameter
lives in its expected ABI argument register. arch__nr_register_params()
returns a non-zero count for powerpc, riscv, mips, arc and sparc, but
arch__set_register_params() only fills in the register map for s390,
x86_64, arm and arm64, leaving the other entries at -1. Every parameter
held in a register then fails the match, the function is marked
unexpected_reg and is skipped. The previous per-parameter check in
parameter__new() ignored unknown expected registers, so this is a
regression. 32-bit arm has a register map, but it does not match
AAPCS32 (only r0-r3 carry arguments, and 64-bit arguments need an
even/odd register pair).

The parameter location matching and true signature reconstruction have
only been validated on x86_64 and arm64. Add cu->param_loc_supported and
set it only for those two architectures. On other architectures, skip
the clang register matching and do not do true signature analysis in
the DWARF loader or the BTF encoder, keeping the basic optimized-out
parameter detection that existed before.

With a riscv64 or powerpc64le object built by clang 22, functions such
as int f(int a, int b) are now encoded again instead of being skipped
with "unexpected register usage for parameter". x86_64 and arm64 output
is unchanged, with and without true_signature.

Fixes: e96290426e180703 ("dwarf_loader: Analyze per-parameter information for true signatures")
Reported-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Nathan Chancellor <nathan@kernel.org> # build
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
 btf_encoder.c  |  2 +-
 dwarf_loader.c | 23 +++++++++++++++++++++--
 dwarves.h      |  1 +
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/btf_encoder.c b/btf_encoder.c
index d6b9be6..2f137ee 100644
--- a/btf_encoder.c
+++ b/btf_encoder.c
@@ -2913,7 +2913,7 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam
 		encoder->tag_kfuncs	 = conf_load->btf_decl_tag_kfuncs;
 		encoder->gen_distilled_base = conf_load->btf_gen_distilled_base;
 		encoder->encode_attributes = conf_load->btf_attributes;
-		encoder->true_signature = conf_load->true_signature;
+		encoder->true_signature = conf_load->true_signature && cu->param_loc_supported;
 		encoder->verbose	 = verbose;
 		encoder->has_index_type  = false;
 		encoder->need_index_type = false;
diff --git a/dwarf_loader.c b/dwarf_loader.c
index 1e5363a..9f9b9c9 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -1518,6 +1518,22 @@ static bool arch__arg_align_two_regs(const GElf_Ehdr *ehdr)
 	}
 }
 
+/*
+ * Architectures whose argument register mapping has been validated for
+ * matching clang parameter locations and reconstructing true signatures.
+ * Other architectures keep only the basic optimized-out detection.
+ */
+static bool arch__param_loc_supported(const GElf_Ehdr *ehdr)
+{
+	switch (ehdr->e_machine) {
+	case EM_X86_64:
+	case EM_AARCH64:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static struct template_type_param *template_type_param__new(Dwarf_Die *die, struct cu *cu, struct conf_load *conf)
 {
 	struct template_type_param *ttparm = tag__alloc(cu, sizeof(*ttparm));
@@ -3777,7 +3793,8 @@ static void function__analyze_parameter_locations(struct function *fn, struct cu
 {
 	struct ftype *ftype = &fn->proto;
 	struct parameter *pos;
-	bool true_sig_enabled = conf->true_signature && ftype->signature_changed;
+	bool true_sig_enabled = cu->param_loc_supported && conf->true_signature &&
+				ftype->signature_changed;
 	bool check_locations = !cu->producer_clang || ftype->signature_changed;
 	int reg_idx = 0;
 
@@ -3785,7 +3802,8 @@ static void function__analyze_parameter_locations(struct function *fn, struct cu
 		/* Producer is clang and the signature was not changed: match
 		 * each parameter against its expected ABI argument register.
 		 */
-		function__match_clang_parameter_locations(ftype, cu);
+		if (cu->param_loc_supported)
+			function__match_clang_parameter_locations(ftype, cu);
 		return;
 	}
 
@@ -4533,6 +4551,7 @@ static int cu__set_common(struct cu *cu, struct conf_load *conf,
 	cu->nr_register_params = arch__nr_register_params(&ehdr);
 	cu->agg_use_two_regs = arch__agg_use_two_regs(&ehdr);
 	cu->arg_align_two_regs = arch__arg_align_two_regs(&ehdr);
+	cu->param_loc_supported = arch__param_loc_supported(&ehdr);
 	arch__set_register_params(&ehdr, cu);
 	return 0;
 }
diff --git a/dwarves.h b/dwarves.h
index f3453ed..6b75ece 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -305,6 +305,7 @@ struct cu {
 	uint8_t		 producer_clang:1;
 	uint8_t		 agg_use_two_regs:1;	/* An aggregate like {long a; long b;} */
 	uint8_t		 arg_align_two_regs:1;	/* An over-aligned arg starts on an even register */
+	uint8_t		 param_loc_supported:1;	/* Parameter location analysis is validated for this arch */
 	uint8_t		 nr_register_params;
 	int		 register_params[ARCH_MAX_REGISTER_PARAMS];
 	int		 functions_saved;
-- 
2.53.0-Meta


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH dwarves] dwarf_loader: Limit parameter location analysis to x86_64 and arm64
  2026-10-03  8:43 [PATCH dwarves] dwarf_loader: Limit parameter location analysis to x86_64 and arm64 Yonghong Song
@ 2026-10-03 10:13 ` Alan Maguire
  2026-10-04  6:50   ` Alan Maguire
  0 siblings, 1 reply; 3+ messages in thread
From: Alan Maguire @ 2026-10-03 10:13 UTC (permalink / raw)
  To: Yonghong Song, Arnaldo Carvalho de Melo, dwarves
  Cc: Alexei Starovoitov, Andrii Nakryiko, bpf, kernel-team,
	Nathan Chancellor

On 03/10/2026 09:43, Yonghong Song wrote:
> Since commit e96290426e18 ("dwarf_loader: Analyze per-parameter
> information for true signatures"), clang-built kernels on arm, powerpc
> and riscv lose most of their functions from BTF, and resolve_btfids
> emits thousands of warnings like:
> 
>   WARN: resolve_btfids: no BTF func for kfunc bpf_xdp_get_xfrm_state in xfrm_state_kfunc_set
>   WARN: resolve_btfids: unresolved symbol bpf_xdp_get_xfrm_state
> 
> For clang functions whose signature did not change, the new
> function__match_clang_parameter_locations() checks that each parameter
> lives in its expected ABI argument register. arch__nr_register_params()
> returns a non-zero count for powerpc, riscv, mips, arc and sparc, but
> arch__set_register_params() only fills in the register map for s390,
> x86_64, arm and arm64, leaving the other entries at -1. Every parameter
> held in a register then fails the match, the function is marked
> unexpected_reg and is skipped. The previous per-parameter check in
> parameter__new() ignored unknown expected registers, so this is a
> regression. 32-bit arm has a register map, but it does not match
> AAPCS32 (only r0-r3 carry arguments, and 64-bit arguments need an
> even/odd register pair).
> 
> The parameter location matching and true signature reconstruction have
> only been validated on x86_64 and arm64. Add cu->param_loc_supported and
> set it only for those two architectures. On other architectures, skip
> the clang register matching and do not do true signature analysis in
> the DWARF loader or the BTF encoder, keeping the basic optimized-out
> parameter detection that existed before.
> 
> With a riscv64 or powerpc64le object built by clang 22, functions such
> as int f(int a, int b) are now encoded again instead of being skipped
> with "unexpected register usage for parameter". x86_64 and arm64 output
> is unchanged, with and without true_signature.
> 
> Fixes: e96290426e180703 ("dwarf_loader: Analyze per-parameter information for true signatures")
> Reported-by: Nathan Chancellor <nathan@kernel.org>
> Tested-by: Nathan Chancellor <nathan@kernel.org> # build
> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>

Thanks; fix looks low-risk, high-value to me so I will apply shortly unless
anyone objects..

> ---
>  btf_encoder.c  |  2 +-
>  dwarf_loader.c | 23 +++++++++++++++++++++--
>  dwarves.h      |  1 +
>  3 files changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/btf_encoder.c b/btf_encoder.c
> index d6b9be6..2f137ee 100644
> --- a/btf_encoder.c
> +++ b/btf_encoder.c
> @@ -2913,7 +2913,7 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam
>  		encoder->tag_kfuncs	 = conf_load->btf_decl_tag_kfuncs;
>  		encoder->gen_distilled_base = conf_load->btf_gen_distilled_base;
>  		encoder->encode_attributes = conf_load->btf_attributes;
> -		encoder->true_signature = conf_load->true_signature;
> +		encoder->true_signature = conf_load->true_signature && cu->param_loc_supported;
>  		encoder->verbose	 = verbose;
>  		encoder->has_index_type  = false;
>  		encoder->need_index_type = false;
> diff --git a/dwarf_loader.c b/dwarf_loader.c
> index 1e5363a..9f9b9c9 100644
> --- a/dwarf_loader.c
> +++ b/dwarf_loader.c
> @@ -1518,6 +1518,22 @@ static bool arch__arg_align_two_regs(const GElf_Ehdr *ehdr)
>  	}
>  }
>  
> +/*
> + * Architectures whose argument register mapping has been validated for
> + * matching clang parameter locations and reconstructing true signatures.
> + * Other architectures keep only the basic optimized-out detection.
> + */
> +static bool arch__param_loc_supported(const GElf_Ehdr *ehdr)
> +{
> +	switch (ehdr->e_machine) {
> +	case EM_X86_64:
> +	case EM_AARCH64:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
>  static struct template_type_param *template_type_param__new(Dwarf_Die *die, struct cu *cu, struct conf_load *conf)
>  {
>  	struct template_type_param *ttparm = tag__alloc(cu, sizeof(*ttparm));
> @@ -3777,7 +3793,8 @@ static void function__analyze_parameter_locations(struct function *fn, struct cu
>  {
>  	struct ftype *ftype = &fn->proto;
>  	struct parameter *pos;
> -	bool true_sig_enabled = conf->true_signature && ftype->signature_changed;
> +	bool true_sig_enabled = cu->param_loc_supported && conf->true_signature &&
> +				ftype->signature_changed;
>  	bool check_locations = !cu->producer_clang || ftype->signature_changed;
>  	int reg_idx = 0;
>  
> @@ -3785,7 +3802,8 @@ static void function__analyze_parameter_locations(struct function *fn, struct cu
>  		/* Producer is clang and the signature was not changed: match
>  		 * each parameter against its expected ABI argument register.
>  		 */
> -		function__match_clang_parameter_locations(ftype, cu);
> +		if (cu->param_loc_supported)
> +			function__match_clang_parameter_locations(ftype, cu);
>  		return;
>  	}
>  
> @@ -4533,6 +4551,7 @@ static int cu__set_common(struct cu *cu, struct conf_load *conf,
>  	cu->nr_register_params = arch__nr_register_params(&ehdr);
>  	cu->agg_use_two_regs = arch__agg_use_two_regs(&ehdr);
>  	cu->arg_align_two_regs = arch__arg_align_two_regs(&ehdr);
> +	cu->param_loc_supported = arch__param_loc_supported(&ehdr);
>  	arch__set_register_params(&ehdr, cu);
>  	return 0;
>  }
> diff --git a/dwarves.h b/dwarves.h
> index f3453ed..6b75ece 100644
> --- a/dwarves.h
> +++ b/dwarves.h
> @@ -305,6 +305,7 @@ struct cu {
>  	uint8_t		 producer_clang:1;
>  	uint8_t		 agg_use_two_regs:1;	/* An aggregate like {long a; long b;} */
>  	uint8_t		 arg_align_two_regs:1;	/* An over-aligned arg starts on an even register */
> +	uint8_t		 param_loc_supported:1;	/* Parameter location analysis is validated for this arch */
>  	uint8_t		 nr_register_params;
>  	int		 register_params[ARCH_MAX_REGISTER_PARAMS];
>  	int		 functions_saved;


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH dwarves] dwarf_loader: Limit parameter location analysis to x86_64 and arm64
  2026-10-03 10:13 ` Alan Maguire
@ 2026-10-04  6:50   ` Alan Maguire
  0 siblings, 0 replies; 3+ messages in thread
From: Alan Maguire @ 2026-10-04  6:50 UTC (permalink / raw)
  To: Yonghong Song, Arnaldo Carvalho de Melo, dwarves
  Cc: Alexei Starovoitov, Andrii Nakryiko, bpf, kernel-team,
	Nathan Chancellor

On 03/10/2026 11:13, Alan Maguire wrote:
> On 03/10/2026 09:43, Yonghong Song wrote:
>> Since commit e96290426e18 ("dwarf_loader: Analyze per-parameter
>> information for true signatures"), clang-built kernels on arm, powerpc
>> and riscv lose most of their functions from BTF, and resolve_btfids
>> emits thousands of warnings like:
>>
>>   WARN: resolve_btfids: no BTF func for kfunc bpf_xdp_get_xfrm_state in xfrm_state_kfunc_set
>>   WARN: resolve_btfids: unresolved symbol bpf_xdp_get_xfrm_state
>>
>> For clang functions whose signature did not change, the new
>> function__match_clang_parameter_locations() checks that each parameter
>> lives in its expected ABI argument register. arch__nr_register_params()
>> returns a non-zero count for powerpc, riscv, mips, arc and sparc, but
>> arch__set_register_params() only fills in the register map for s390,
>> x86_64, arm and arm64, leaving the other entries at -1. Every parameter
>> held in a register then fails the match, the function is marked
>> unexpected_reg and is skipped. The previous per-parameter check in
>> parameter__new() ignored unknown expected registers, so this is a
>> regression. 32-bit arm has a register map, but it does not match
>> AAPCS32 (only r0-r3 carry arguments, and 64-bit arguments need an
>> even/odd register pair).
>>
>> The parameter location matching and true signature reconstruction have
>> only been validated on x86_64 and arm64. Add cu->param_loc_supported and
>> set it only for those two architectures. On other architectures, skip
>> the clang register matching and do not do true signature analysis in
>> the DWARF loader or the BTF encoder, keeping the basic optimized-out
>> parameter detection that existed before.
>>
>> With a riscv64 or powerpc64le object built by clang 22, functions such
>> as int f(int a, int b) are now encoded again instead of being skipped
>> with "unexpected register usage for parameter". x86_64 and arm64 output
>> is unchanged, with and without true_signature.
>>
>> Fixes: e96290426e180703 ("dwarf_loader: Analyze per-parameter information for true signatures")
>> Reported-by: Nathan Chancellor <nathan@kernel.org>
>> Tested-by: Nathan Chancellor <nathan@kernel.org> # build
>> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
> 
> Thanks; fix looks low-risk, high-value to me so I will apply shortly unless
> anyone objects..
>

applied, thanks.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-04  6:50 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-03  8:43 [PATCH dwarves] dwarf_loader: Limit parameter location analysis to x86_64 and arm64 Yonghong Song
2026-10-03 10:13 ` Alan Maguire
2026-10-04  6:50   ` Alan Maguire

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox