From 31eca25f3a3b0de960ca9a478e5a4b2d0b2e8558 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 17 Sep 2025 09:03:33 -0700 Subject: objtool: Clean up compiler flag usage KBUILD_HOSTCFLAGS and KBUILD_HOSTLDFLAGS aren't defined when objtool is built standalone. Also, the EXTRA_WARNINGS flags are rather arbitrary. Make things simpler and more consistent by specifying compiler flags explicitly and tweaking the warnings. Also make a few code tweaks to make the new warnings happy. Acked-by: Petr Mladek Tested-by: Joe Lawrence Signed-off-by: Josh Poimboeuf --- tools/objtool/Makefile | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'tools/objtool/Makefile') diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 8c20361dd100..fc82d47f2b9a 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -23,6 +23,11 @@ LIBELF_LIBS := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lel all: $(OBJTOOL) +WARNINGS := -Werror -Wall -Wextra -Wmissing-prototypes \ + -Wmissing-declarations -Wwrite-strings \ + -Wno-implicit-fallthrough -Wno-sign-compare \ + -Wno-unused-parameter + INCLUDES := -I$(srctree)/tools/include \ -I$(srctree)/tools/include/uapi \ -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \ @@ -30,11 +35,11 @@ INCLUDES := -I$(srctree)/tools/include \ -I$(srctree)/tools/objtool/include \ -I$(srctree)/tools/objtool/arch/$(SRCARCH)/include \ -I$(LIBSUBCMD_OUTPUT)/include -# Note, EXTRA_WARNINGS here was determined for CC and not HOSTCC, it -# is passed here to match a legacy behavior. -WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed -Wno-nested-externs -OBJTOOL_CFLAGS := -Werror $(WARNINGS) $(KBUILD_HOSTCFLAGS) -g $(INCLUDES) $(LIBELF_FLAGS) -OBJTOOL_LDFLAGS := $(LIBELF_LIBS) $(LIBSUBCMD) $(KBUILD_HOSTLDFLAGS) + +OBJTOOL_CFLAGS := -std=gnu11 -fomit-frame-pointer -O2 -g \ + $(WARNINGS) $(INCLUDES) $(LIBELF_FLAGS) $(HOSTCFLAGS) + +OBJTOOL_LDFLAGS := $(LIBSUBCMD) $(LIBELF_LIBS) $(HOSTLDFLAGS) # Allow old libelf to be used: elfshdr := $(shell echo '$(pound)include ' | $(HOSTCC) $(OBJTOOL_CFLAGS) -x c -E - 2>/dev/null | grep elf_getshdr) -- cgit v1.2.3 From 0d83da43b1e1c8ce19f2bb10f54a0fdf795364f7 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 17 Sep 2025 09:03:57 -0700 Subject: objtool/klp: Add --checksum option to generate per-function checksums In preparation for the objtool klp diff subcommand, add a command-line option to generate a unique checksum for each function. This will enable detection of functions which have changed between two versions of an object file. Acked-by: Petr Mladek Tested-by: Joe Lawrence Signed-off-by: Josh Poimboeuf --- tools/objtool/Makefile | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'tools/objtool/Makefile') diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index fc82d47f2b9a..958761c05b7c 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -2,6 +2,27 @@ include ../scripts/Makefile.include include ../scripts/Makefile.arch +ifeq ($(SRCARCH),x86) + BUILD_ORC := y + ARCH_HAS_KLP := y +endif + +ifeq ($(SRCARCH),loongarch) + BUILD_ORC := y +endif + +ifeq ($(ARCH_HAS_KLP),y) + HAVE_XXHASH = $(shell echo "int main() {}" | \ + $(HOSTCC) -xc - -o /dev/null -lxxhash 2> /dev/null && echo y || echo n) + ifeq ($(HAVE_XXHASH),y) + LIBXXHASH_CFLAGS := $(shell $(HOSTPKG_CONFIG) libxxhash --cflags 2>/dev/null) \ + -DBUILD_KLP + LIBXXHASH_LIBS := $(shell $(HOSTPKG_CONFIG) libxxhash --libs 2>/dev/null || echo -lxxhash) + endif +endif + +export BUILD_ORC + ifeq ($(srctree),) srctree := $(patsubst %/,%,$(dir $(CURDIR))) srctree := $(patsubst %/,%,$(dir $(srctree))) @@ -36,10 +57,10 @@ INCLUDES := -I$(srctree)/tools/include \ -I$(srctree)/tools/objtool/arch/$(SRCARCH)/include \ -I$(LIBSUBCMD_OUTPUT)/include -OBJTOOL_CFLAGS := -std=gnu11 -fomit-frame-pointer -O2 -g \ - $(WARNINGS) $(INCLUDES) $(LIBELF_FLAGS) $(HOSTCFLAGS) +OBJTOOL_CFLAGS := -std=gnu11 -fomit-frame-pointer -O2 -g $(WARNINGS) \ + $(INCLUDES) $(LIBELF_FLAGS) $(LIBXXHASH_CFLAGS) $(HOSTCFLAGS) -OBJTOOL_LDFLAGS := $(LIBSUBCMD) $(LIBELF_LIBS) $(HOSTLDFLAGS) +OBJTOOL_LDFLAGS := $(LIBSUBCMD) $(LIBELF_LIBS) $(LIBXXHASH_LIBS) $(HOSTLDFLAGS) # Allow old libelf to be used: elfshdr := $(shell echo '$(pound)include ' | $(HOSTCC) $(OBJTOOL_CFLAGS) -x c -E - 2>/dev/null | grep elf_getshdr) @@ -51,17 +72,6 @@ HOST_OVERRIDES := CC="$(HOSTCC)" LD="$(HOSTLD)" AR="$(HOSTAR)" AWK = awk MKDIR = mkdir -BUILD_ORC := n - -ifeq ($(SRCARCH),x86) - BUILD_ORC := y -endif - -ifeq ($(SRCARCH),loongarch) - BUILD_ORC := y -endif - -export BUILD_ORC export srctree OUTPUT CFLAGS SRCARCH AWK include $(srctree)/tools/build/Makefile.include -- cgit v1.2.3 From dd590d4d57ebeeb826823c288741f2ed20f452af Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 17 Sep 2025 09:03:59 -0700 Subject: objtool/klp: Introduce klp diff subcommand for diffing object files Add a new klp diff subcommand which performs a binary diff between two object files and extracts changed functions into a new object which can then be linked into a livepatch module. 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 (coming in a later patch) which injects #line directives into the source .patch to preserve the original line numbers at compile time. Note the end result of this subcommand is not yet functionally complete. Livepatch needs some ELF magic which linkers don't like: - Two relocation sections (.rela*, .klp.rela*) for the same text section. - Use of SHN_LIVEPATCH to mark livepatch symbols. Unfortunately linkers tend to mangle such things. To work around that, klp diff generates a linker-compliant intermediate binary which encodes the relevant KLP section/reloc/symbol metadata. After module linking, a klp post-link step (coming soon) will clean up the mess and convert the linked .ko into a fully compliant livepatch module. Note this subcommand requires the diffed binaries to have been compiled with -ffunction-sections and -fdata-sections, and processed with 'objtool --checksum'. Those constraints will be handled by a klp-build script introduced in a later patch. Without '-ffunction-sections -fdata-sections', reliable object diffing would be infeasible due to toolchain limitations: - For intra-file+intra-section references, the compiler might occasionally generated hard-coded instruction offsets instead of relocations. - Section-symbol-based references can be ambiguous: - Overlapping or zero-length symbols create ambiguity as to which symbol is being referenced. - A reference to the end of a symbol (e.g., checking array bounds) can be misinterpreted as a reference to the next symbol, or vice versa. A potential future alternative to '-ffunction-sections -fdata-sections' would be to introduce a toolchain option that forces symbol-based (non-section) relocations. Acked-by: Petr Mladek Tested-by: Joe Lawrence Signed-off-by: Josh Poimboeuf --- tools/objtool/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools/objtool/Makefile') diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 958761c05b7c..48928c9bebef 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -15,13 +15,14 @@ ifeq ($(ARCH_HAS_KLP),y) HAVE_XXHASH = $(shell echo "int main() {}" | \ $(HOSTCC) -xc - -o /dev/null -lxxhash 2> /dev/null && echo y || echo n) ifeq ($(HAVE_XXHASH),y) + BUILD_KLP := y LIBXXHASH_CFLAGS := $(shell $(HOSTPKG_CONFIG) libxxhash --cflags 2>/dev/null) \ -DBUILD_KLP LIBXXHASH_LIBS := $(shell $(HOSTPKG_CONFIG) libxxhash --libs 2>/dev/null || echo -lxxhash) endif endif -export BUILD_ORC +export BUILD_ORC BUILD_KLP ifeq ($(srctree),) srctree := $(patsubst %/,%,$(dir $(CURDIR))) -- cgit v1.2.3