Merge tag 'objtool-urgent-2026-02-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull objtool fixes from Ingo Molnar::

- Bump up the Clang minimum version requirements for livepatch
builds, due to Clang assembler section handling bugs causing
silent miscompilations

- Strip livepatching symbol artifacts from non-livepatch modules

- Fix livepatch build warnings when certain Clang LTO options
are enabled

- Fix livepatch build error when CONFIG_MEM_ALLOC_PROFILING_DEBUG=y

* tag 'objtool-urgent-2026-02-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
objtool/klp: Fix unexported static call key access for manually built livepatch modules
objtool/klp: Fix symbol correlation for orphaned local symbols
livepatch: Free klp_{object,func}_ext data after initialization
livepatch: Fix having __klp_objects relics in non-livepatch modules
livepatch/klp-build: Require Clang assembler >= 20

+79 -31
+3
include/linux/livepatch.h
··· 175 175 int klp_module_coming(struct module *mod); 176 176 void klp_module_going(struct module *mod); 177 177 178 + void *klp_find_section_by_name(const struct module *mod, const char *name, 179 + size_t *sec_size); 180 + 178 181 void klp_copy_process(struct task_struct *child); 179 182 void klp_update_patch_state(struct task_struct *task); 180 183
+19
kernel/livepatch/core.c
··· 1356 1356 mutex_unlock(&klp_mutex); 1357 1357 } 1358 1358 1359 + void *klp_find_section_by_name(const struct module *mod, const char *name, 1360 + size_t *sec_size) 1361 + { 1362 + struct klp_modinfo *info = mod->klp_info; 1363 + 1364 + for (int i = 1; i < info->hdr.e_shnum; i++) { 1365 + Elf_Shdr *shdr = &info->sechdrs[i]; 1366 + 1367 + if (!strcmp(info->secstrings + shdr->sh_name, name)) { 1368 + *sec_size = shdr->sh_size; 1369 + return (void *)shdr->sh_addr; 1370 + } 1371 + } 1372 + 1373 + *sec_size = 0; 1374 + return NULL; 1375 + } 1376 + EXPORT_SYMBOL_GPL(klp_find_section_by_name); 1377 + 1359 1378 static int __init klp_init(void) 1360 1379 { 1361 1380 klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj);
+9 -11
scripts/livepatch/init.c
··· 9 9 #include <linux/slab.h> 10 10 #include <linux/livepatch.h> 11 11 12 - extern struct klp_object_ext __start_klp_objects[]; 13 - extern struct klp_object_ext __stop_klp_objects[]; 14 - 15 12 static struct klp_patch *patch; 16 13 17 14 static int __init livepatch_mod_init(void) 18 15 { 16 + struct klp_object_ext *obj_exts; 17 + size_t obj_exts_sec_size; 19 18 struct klp_object *objs; 20 19 unsigned int nr_objs; 21 20 int ret; 22 21 23 - nr_objs = __stop_klp_objects - __start_klp_objects; 24 - 22 + obj_exts = klp_find_section_by_name(THIS_MODULE, ".init.klp_objects", 23 + &obj_exts_sec_size); 24 + nr_objs = obj_exts_sec_size / sizeof(*obj_exts); 25 25 if (!nr_objs) { 26 26 pr_err("nothing to patch!\n"); 27 27 ret = -EINVAL; ··· 41 41 } 42 42 43 43 for (int i = 0; i < nr_objs; i++) { 44 - struct klp_object_ext *obj_ext = __start_klp_objects + i; 44 + struct klp_object_ext *obj_ext = obj_exts + i; 45 45 struct klp_func_ext *funcs_ext = obj_ext->funcs; 46 46 unsigned int nr_funcs = obj_ext->nr_funcs; 47 47 struct klp_func *funcs = objs[i].funcs; ··· 90 90 91 91 static void __exit livepatch_mod_exit(void) 92 92 { 93 - unsigned int nr_objs; 93 + struct klp_object *obj; 94 94 95 - nr_objs = __stop_klp_objects - __start_klp_objects; 96 - 97 - for (int i = 0; i < nr_objs; i++) 98 - kfree(patch->objs[i].funcs); 95 + klp_for_each_object_static(patch, obj) 96 + kfree(obj->funcs); 99 97 100 98 kfree(patch->objs); 101 99 kfree(patch);
+4
scripts/livepatch/klp-build
··· 249 249 [[ -v CONFIG_GCC_PLUGIN_RANDSTRUCT ]] && \ 250 250 die "kernel option 'CONFIG_GCC_PLUGIN_RANDSTRUCT' not supported" 251 251 252 + [[ -v CONFIG_AS_IS_LLVM ]] && \ 253 + [[ "$CONFIG_AS_VERSION" -lt 200000 ]] && \ 254 + die "Clang assembler version < 20 not supported" 255 + 252 256 return 0 253 257 } 254 258
+2 -7
scripts/module.lds.S
··· 34 34 35 35 __patchable_function_entries : { *(__patchable_function_entries) } 36 36 37 - __klp_funcs 0: ALIGN(8) { KEEP(*(__klp_funcs)) } 38 - 39 - __klp_objects 0: ALIGN(8) { 40 - __start_klp_objects = .; 41 - KEEP(*(__klp_objects)) 42 - __stop_klp_objects = .; 43 - } 37 + .init.klp_funcs 0 : ALIGN(8) { KEEP(*(.init.klp_funcs)) } 38 + .init.klp_objects 0 : ALIGN(8) { KEEP(*(.init.klp_objects)) } 44 39 45 40 #ifdef CONFIG_ARCH_USES_CFI_TRAPS 46 41 __kcfi_traps : { KEEP(*(.kcfi_traps)) }
+2 -2
tools/objtool/check.c
··· 683 683 684 684 key_sym = find_symbol_by_name(file->elf, tmp); 685 685 if (!key_sym) { 686 - if (!opts.module || file->klp) { 686 + if (!opts.module) { 687 687 ERROR("static_call: can't find static_call_key symbol: %s", tmp); 688 688 return -1; 689 689 } ··· 4762 4762 !strcmp(sec->name, "__bug_table") || 4763 4763 !strcmp(sec->name, "__ex_table") || 4764 4764 !strcmp(sec->name, "__jump_table") || 4765 - !strcmp(sec->name, "__klp_funcs") || 4765 + !strcmp(sec->name, ".init.klp_funcs") || 4766 4766 !strcmp(sec->name, "__mcount_loc") || 4767 4767 !strcmp(sec->name, ".llvm.call-graph-profile") || 4768 4768 !strcmp(sec->name, ".llvm_bb_addr_map") ||
+5 -5
tools/objtool/include/objtool/klp.h
··· 6 6 #define SHN_LIVEPATCH 0xff20 7 7 8 8 /* 9 - * __klp_objects and __klp_funcs are created by klp diff and used by the patch 10 - * module init code to build the klp_patch, klp_object and klp_func structs 11 - * needed by the livepatch API. 9 + * .init.klp_objects and .init.klp_funcs are created by klp diff and used by the 10 + * patch module init code to build the klp_patch, klp_object and klp_func 11 + * structs needed by the livepatch API. 12 12 */ 13 - #define KLP_OBJECTS_SEC "__klp_objects" 14 - #define KLP_FUNCS_SEC "__klp_funcs" 13 + #define KLP_OBJECTS_SEC ".init.klp_objects" 14 + #define KLP_FUNCS_SEC ".init.klp_funcs" 15 15 16 16 /* 17 17 * __klp_relocs is an intermediate section which are created by klp diff and
+35 -6
tools/objtool/klp-diff.c
··· 364 364 struct symbol *file1_sym, *file2_sym; 365 365 struct symbol *sym1, *sym2; 366 366 367 - /* Correlate locals */ 368 - for (file1_sym = first_file_symbol(e->orig), 369 - file2_sym = first_file_symbol(e->patched); ; 370 - file1_sym = next_file_symbol(e->orig, file1_sym), 371 - file2_sym = next_file_symbol(e->patched, file2_sym)) { 367 + file1_sym = first_file_symbol(e->orig); 368 + file2_sym = first_file_symbol(e->patched); 369 + 370 + /* 371 + * Correlate any locals before the first FILE symbol. This has been 372 + * seen when LTO inexplicably strips the initramfs_data.o FILE symbol 373 + * due to the file only containing data and no code. 374 + */ 375 + for_each_sym(e->orig, sym1) { 376 + if (sym1 == file1_sym || !is_local_sym(sym1)) 377 + break; 378 + 379 + if (dont_correlate(sym1)) 380 + continue; 381 + 382 + for_each_sym(e->patched, sym2) { 383 + if (sym2 == file2_sym || !is_local_sym(sym2)) 384 + break; 385 + 386 + if (sym2->twin || dont_correlate(sym2)) 387 + continue; 388 + 389 + if (strcmp(sym1->demangled_name, sym2->demangled_name)) 390 + continue; 391 + 392 + sym1->twin = sym2; 393 + sym2->twin = sym1; 394 + break; 395 + } 396 + } 397 + 398 + /* Correlate locals after the first FILE symbol */ 399 + for (; ; file1_sym = next_file_symbol(e->orig, file1_sym), 400 + file2_sym = next_file_symbol(e->patched, file2_sym)) { 372 401 373 402 if (!file1_sym && file2_sym) { 374 403 ERROR("FILE symbol mismatch: NULL != %s", file2_sym->name); ··· 1465 1436 } 1466 1437 1467 1438 /* 1468 - * Create __klp_objects and __klp_funcs sections which are intermediate 1439 + * Create .init.klp_objects and .init.klp_funcs sections which are intermediate 1469 1440 * sections provided as input to the patch module's init code for building the 1470 1441 * klp_patch, klp_object and klp_func structs for the livepatch API. 1471 1442 */