On Tue, Jun 30, 2026 at 02:40:42PM -0400, Joe Lawrence wrote:
> The root cause is that create_fake_symbols() skips the entire special
> section if any symbol exists at offset 0.  But Clang places a .Ltmp*
> label at the start of .kcfi_traps, so no per-entry fake symbols are
> created and clone_special_sections() extracts nothing.
> 
>   static int create_fake_symbols(struct elf *elf)
>   {
>   ...
>       /*
>        * 2) Make symbols for sh_entsize, and simple arrays of pointers:
>        */
>   entsize:
>       for_each_sec(elf, sec) {
>               unsigned int entry_size;
>               unsigned long offset;
> 
>               if (!is_special_section(sec) || find_symbol_by_offset(sec, 0))
>                       continue;
> 
>   $ llvm-readelf --wide --symbols klp-tmp/3-checksum-patched/vmlinux.o | \
>           awk '$7 == 74993'
>    93266: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   74993 .Ltmp78
>    93544: 0000000000000000     0 SECTION LOCAL  DEFAULT   74993 .kcfi_traps
> 
> 
> Possible fix: ignore .L* assembler-local labels at section offset 0
> using the existing is_local_label() helper.
> 
> -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8--
> 
> diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
> index b9624bd9439b..4ba400926647 100644
> --- a/tools/objtool/klp-diff.c
> +++ b/tools/objtool/klp-diff.c
> @@ -1860,8 +1860,17 @@ static int create_fake_symbols(struct elf *elf)
>       for_each_sec(elf, sec) {
>               unsigned int entry_size;
>               unsigned long offset;
> +             struct symbol *sym_at_0;
> 
> -             if (!is_special_section(sec) || find_symbol_by_offset(sec, 0))
> +             if (!is_special_section(sec))
> +                     continue;
> +
> +             /*
> +              * Clang may place assembler-local .L* labels at offset 0;
> +              * they must not prevent per-entry fake symbol creation.
> +              */
> +             sym_at_0 = find_symbol_by_offset(sec, 0);
> +             if (sym_at_0 && !is_local_label(sym_at_0))
>                       continue;

Thanks, I'll fix this with my other series of fixes in the next version.

find_symbol_by_offset() might not work because there can be multiple
symbols at offset 0.  Instead we can just traverse the symbols in the
section, looking for sym->fake.

-- 
Josh

Reply via email to