This series introduces new objtool features and a klp-build script to generate livepatch modules using a source .patch as input.
This builds on concepts from the longstanding out-of-tree kpatch [1] project which began in 2012 and has been used for many years to generate livepatch modules for production kernels. However, this is a complete rewrite which incorporates hard-earned lessons from 12+ years of maintaining kpatch. Key improvements compared to kpatch-build: - Integrated with objtool: Leverages objtool's existing control-flow graph analysis to help detect changed functions. - Works on vmlinux.o: Supports late-linked objects, making it compatible with LTO, IBT, and similar. - Simplified code base: ~3k fewer lines of code. - Upstream: No more out-of-tree #ifdef hacks, far less cruft. - Cleaner internals: Vastly simplified logic for symbol/section/reloc inclusion and special section extraction. - Robust __LINE__ macro handling: Avoids false positive binary diffs caused by the __LINE__ macro by introducing a fix-patch-lines script which injects #line directives into the source .patch to preserve the original line numbers at compile time. The primary user interface is the klp-build script which does the following: - Builds an original kernel with -function-sections and -fdata-sections, plus objtool function checksumming. - Applies the .patch file and rebuilds the kernel using the same options. - Runs 'objtool klp diff' to detect changed functions and generate intermediate binary diff objects. - Builds a kernel module which links the diff objects with some livepatch module init code (scripts/livepatch/init.c). - Finalizes the livepatch module (aka work around linker wreckage) using 'objtool klp post-link'. I've tested with a variety of patches on defconfig and Fedora-config kernels with both GCC and Clang. These patches can also be found at: git://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.git klp-build-v2 Please test! [1] https://github.com/dynup/kpatch Changes since the RFC: https://lore.kernel.org/cover.1725334260.git.jpoim...@kernel.org - Too many to list. Doubled the patch count exactly ;-) Josh Poimboeuf (62): s390/vmlinux.lds.S: Prevent thunk functions from getting placed with normal text vmlinux.lds: Unify TEXT_MAIN, DATA_MAIN, and related macros x86/module: Improve relocation error messages x86/kprobes: Remove STACK_FRAME_NON_STANDARD annotation compiler: Tweak __UNIQUE_ID() naming compiler.h: Make addressable symbols less of an eyesore elfnote: Change ELFNOTE() to use __UNIQUE_ID() kbuild: Remove 'kmod_' prefix from __KBUILD_MODNAME modpost: Ignore unresolved section bounds symbols x86/alternative: Refactor INT3 call emulation selftest objtool: Make find_symbol_containing() less arbitrary objtool: Speed up SHT_GROUP reindexing objtool: Fix broken error handling in read_symbols() objtool: Propagate elf_truncate_section() error in elf_write() objtool: Add empty symbols to the symbol tree again objtool: Fix interval tree insertion for zero-length symbols objtool: Fix weak symbol detection objtool: Fix x86 addend calculation objtool: Fix __pa_symbol() relocation handling objtool: Fix "unexpected end of section" warning for alternatives objtool: Check for missing annotation entries in read_annotate() objtool: Const string cleanup objtool: Clean up compiler flag usage objtool: Remove .parainstructions reference objtool: Convert elf iterator macros to use 'struct elf' objtool: Add section/symbol type helpers objtool: Mark .cold subfunctions objtool: Fix weak symbol hole detection for .cold functions objtool: Mark prefix functions objtool: Simplify reloc offset calculation in unwind_read_hints() objtool: Avoid emptying lists for duplicate sections objtool: Suppress section skipping warnings with --dryrun objtool: Rename --Werror to --werror objtool: Reindent check_options[] objtool: Refactor add_jump_destinations() objtool: Simplify special symbol handling in elf_update_symbol() objtool: Generalize elf_create_symbol() objtool: Generalize elf_create_section() objtool: Add elf_create_data() objtool: Introduce elf_create_reloc() and elf_init_reloc() objtool: Add elf_create_file() kbuild,x86: Fix module permissions for __jump_table and __bug_table x86/alternative: Define ELF section entry size for alternatives x86/jump_label: Define ELF section entry size for jump table x86/extable: Define ELF section entry size for exception tables x86/bug: Define ELF section entry size for the bug table x86/orc: Define ELF section entry size for unwind hints objtool: Make STACK_FRAME_NON_STANDARD consistent kbuild,objtool: Defer objtool validation step for CONFIG_LIVEPATCH objtool/klp: Add --checksum option to generate per-function checksums objtool/klp: Add --debug-checksum=<funcs> to show per-instruction checksums objtool/klp: Introduce klp diff subcommand for diffing object files objtool/klp: Add --debug option to show cloning decisions objtool/klp: Add post-link subcommand to finalize livepatch modules objtool: Disallow duplicate prefix symbols objtool: Add base objtool support for livepatch modules livepatch/klp-build: Introduce fix-patch-lines script to avoid __LINE__ diff noise livepatch/klp-build: Add stub init code for livepatch modules livepatch/klp-build: Introduce klp-build script for generating livepatch modules livepatch/klp-build: Add --debug option to show cloning decisions livepatch/klp-build: Add --show-first-changed option to show function divergence livepatch: Introduce source code helpers for livepatch modules MAINTAINERS | 3 +- arch/Kconfig | 3 + arch/s390/include/asm/nospec-insn.h | 2 +- arch/s390/kernel/vmlinux.lds.S | 2 +- arch/x86/Kconfig | 1 + arch/x86/include/asm/alternative.h | 7 +- arch/x86/include/asm/asm.h | 20 +- arch/x86/include/asm/bug.h | 44 +- arch/x86/include/asm/jump_label.h | 32 +- arch/x86/kernel/alternative.c | 53 +- arch/x86/kernel/kprobes/opt.c | 4 - arch/x86/kernel/module.c | 15 +- arch/x86/kernel/unwind_orc.c | 2 + include/asm-generic/vmlinux.lds.h | 40 +- include/linux/compiler.h | 8 +- include/linux/elfnote.h | 13 +- include/linux/init.h | 3 +- include/linux/jump_label.h | 20 +- include/linux/livepatch.h | 25 +- include/linux/livepatch_external.h | 76 + include/linux/livepatch_helpers.h | 68 + include/linux/objtool.h | 16 +- kernel/extable.c | 2 + kernel/livepatch/core.c | 8 +- scripts/Makefile.lib | 6 +- scripts/Makefile.modfinal | 18 +- scripts/Makefile.vmlinux_o | 2 +- scripts/link-vmlinux.sh | 3 +- scripts/livepatch/fix-patch-lines | 79 + scripts/livepatch/init.c | 108 ++ scripts/livepatch/klp-build | 781 +++++++++ scripts/mod/modpost.c | 5 + scripts/module.lds.S | 26 +- tools/include/linux/interval_tree_generic.h | 2 +- tools/include/linux/livepatch_external.h | 76 + tools/objtool/Build | 4 +- tools/objtool/Makefile | 48 +- tools/objtool/arch/loongarch/decode.c | 6 +- tools/objtool/arch/powerpc/decode.c | 6 +- tools/objtool/arch/x86/decode.c | 68 +- tools/objtool/arch/x86/special.c | 2 +- tools/objtool/builtin-check.c | 70 +- tools/objtool/builtin-klp.c | 53 + tools/objtool/check.c | 690 +++++--- tools/objtool/elf.c | 812 ++++++--- tools/objtool/include/objtool/arch.h | 5 +- tools/objtool/include/objtool/builtin.h | 6 +- tools/objtool/include/objtool/check.h | 6 +- tools/objtool/include/objtool/checksum.h | 43 + .../objtool/include/objtool/checksum_types.h | 25 + tools/objtool/include/objtool/elf.h | 186 +- tools/objtool/include/objtool/klp.h | 35 + tools/objtool/include/objtool/objtool.h | 6 +- tools/objtool/include/objtool/warn.h | 40 + tools/objtool/klp-diff.c | 1504 +++++++++++++++++ tools/objtool/klp-post-link.c | 165 ++ tools/objtool/objtool.c | 42 +- tools/objtool/orc_gen.c | 8 +- tools/objtool/special.c | 4 +- tools/objtool/sync-check.sh | 1 + tools/objtool/weak.c | 7 + 61 files changed, 4687 insertions(+), 728 deletions(-) create mode 100644 include/linux/livepatch_external.h create mode 100644 include/linux/livepatch_helpers.h create mode 100755 scripts/livepatch/fix-patch-lines create mode 100644 scripts/livepatch/init.c create mode 100755 scripts/livepatch/klp-build create mode 100644 tools/include/linux/livepatch_external.h create mode 100644 tools/objtool/builtin-klp.c create mode 100644 tools/objtool/include/objtool/checksum.h create mode 100644 tools/objtool/include/objtool/checksum_types.h create mode 100644 tools/objtool/include/objtool/klp.h create mode 100644 tools/objtool/klp-diff.c create mode 100644 tools/objtool/klp-post-link.c -- 2.49.0