Re: [PATCH v2 20/53] objtool/klp: Don't correlate .rodata.cst* constant pool objects

From: Song Liu

Date: Fri May 01 2026 - 06:38:11 EST


On Fri, May 1, 2026 at 5:08 AM Josh Poimboeuf <jpoimboe@xxxxxxxxxx> wrote:
>
> Clang aggregates UBSAN type descriptors into shared anonymous
> .data..L__unnamed_* sections. This data is used by UBSAN trap handlers.
>
> When a changed function has an UBSAN bounds check, klp-diff clones the
> entire UBSAN data section associated with the TU. Relocations within
> the cloned section that reference named rodata objects in .rodata.cst*
> (like 'exponent', 'pirq_ali_set.irqmap') become KLP relocations because
> those objects now get correlated.
>
> That results in a .klp.rela.vmlinux..data section which can easily have
> thousands of KLP relocs, most of which are completely superfluous, used
> by functions which aren't cloned to the patch module.
>
> The .rodata.cst* sections are SHF_MERGE constant pool sections
> containing small fixed-size data (lookup tables, bitmasks) that is only
> read by value. Pointer identity is never relevant for these objects, so
> correlating them is unnecessary.
>
> Exclude .rodata.cst* objects from correlation so they get cloned as
> local data instead of generating KLP relocations.
>
> It might be possible to someday treat UBSAN data sections as special
> sections, and only extract the few needed entries. But this works for
> now.
>
> Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
> ---
> tools/objtool/klp-diff.c | 17 ++++++++++++++++-
> 1 file changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
> index bf37c652188b..ca87bcb9afa3 100644
> --- a/tools/objtool/klp-diff.c
> +++ b/tools/objtool/klp-diff.c
> @@ -372,6 +372,21 @@ static bool is_initcall_sym(struct symbol *sym)
> strstarts(sym->name, "__initstub__");
> }
>
> +/*
> + * Some .rodata is anonymous and can't be correlated due to there being no
> + * symbol names.
> + *
> + * The .rodata.cst* sections aren't technically anonymous, they're SHF_MERGE
> + * constant pool sections containing small fixed-size data (lookup tables,
> + * bitmasks) which are only read by value, so pointer equivalence isn't needed.
> + * They are typically referenced by UBSAN data sections.
> + */
> +static bool is_anonymous_rodata(struct symbol *sym)
> +{
> + return is_rodata_sec(sym->sec) &&
> + (!is_object_sym(sym) || strstarts(sym->sec->name, ".rodata.cst"));
> +}
> +
> /*
> * These symbols should never be correlated, so their local patched versions
> * are used instead of linking to the originals.
> @@ -386,7 +401,7 @@ static bool dont_correlate(struct symbol *sym)
> is_uncorrelated_static_local(sym) ||
> is_local_label(sym) ||
> is_string_sec(sym->sec) ||
> - (is_rodata_sec(sym->sec) && !is_object_sym(sym)) ||
^^^^
This line was added in 19/53. Maybe we can merge 19 and 20?

Thanks,
Song

> + is_anonymous_rodata(sym) ||
> is_initcall_sym(sym) ||
> is_addressable_sym(sym) ||
> is_special_section(sym->sec) ||
> --
> 2.53.0
>