On Fri, May 1, 2026 at 5:08 AM Josh Poimboeuf <[email protected]> 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 <[email protected]> > --- > 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 >

