From 48937d40c13c4be0b15964f0e02bb1bd070b8c27 Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Tue, 14 Jan 2025 20:27:44 +0000 Subject: [PATCH 1/3] lisa._assets.kmodules.lisa: Fix generated C shims header usage FIX The C shims header depends on cffi.h, so ensure the latter is always included before. --- lisa/_assets/kmodules/lisa/rust/lisakmod/bindings.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lisa/_assets/kmodules/lisa/rust/lisakmod/bindings.h b/lisa/_assets/kmodules/lisa/rust/lisakmod/bindings.h index 86d80ee8a..6048dcaed 100644 --- a/lisa/_assets/kmodules/lisa/rust/lisakmod/bindings.h +++ b/lisa/_assets/kmodules/lisa/rust/lisakmod/bindings.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include "rust/lisakmod/cbindgen.h" +#include "rust/lisakmod-macros/cffi.h" #include "generated/rust/rust_c_shims.h" -- GitLab From b1d8ab753f198b2b9e1e4d1fccf4ab315faa69e6 Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Tue, 14 Jan 2025 20:50:38 +0000 Subject: [PATCH 2/3] lisa._assets.kmodules.lisa: Makefile: Remove leftover from in-tree builds --- lisa/_assets/kmodules/lisa/Makefile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lisa/_assets/kmodules/lisa/Makefile b/lisa/_assets/kmodules/lisa/Makefile index af2fe3dfd..4e5ab858c 100644 --- a/lisa/_assets/kmodules/lisa/Makefile +++ b/lisa/_assets/kmodules/lisa/Makefile @@ -15,11 +15,6 @@ # limitations under the License. # -# This would break the IN_TREE_BUILD detection -ifeq ($(KBUILD_ABS_SRCTREE),1) -$(error KBUILD_ABS_SRCTREE=1 is not handled by the lisa module) -endif - # Invoked by Kbuild ifneq ($(KERNELRELEASE),) MODULE_OBJ := $(obj) -- GitLab From e8bab90e9c3e1a41512d3245ce097e1090a579f2 Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Tue, 14 Jan 2025 13:51:42 +0000 Subject: [PATCH 3/3] lisa._assets.kmodules.lisa: Makefile: Fix grouped rule FIX Makefile rules with multiple targets is just a short-hand to duplicating the recipe for each of those targets. Unfortunately, that means that if make needs to build all these targets, it will run the same recipe concurrently multiple times. This leads to file corruption as multiple tools are writing to them concurrently. Fix that by splitting the rule such that we do not need multiple targets for the same rule anymore. --- lisa/_assets/kmodules/lisa/Makefile | 71 +++++++++++++---------------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/lisa/_assets/kmodules/lisa/Makefile b/lisa/_assets/kmodules/lisa/Makefile index 4e5ab858c..b8a1de2ca 100644 --- a/lisa/_assets/kmodules/lisa/Makefile +++ b/lisa/_assets/kmodules/lisa/Makefile @@ -27,9 +27,6 @@ else endif GENERATED := $(MODULE_OBJ)/generated -$(GENERATED): - rm -r "$@" 2>&1 || true - mkdir -p "$@" clean-files := $(GENERATED) RUST_VERSION ?= nightly @@ -37,24 +34,26 @@ RUSTFLAGS := -Clinker=rust-lld -Clink-self-contained=y -Clto=n -Crelocation-mode LISA_EVAL_C := $(MODULE_SRC)/lisa-eval-c.sh +RUSTUP_HOME ?= $(HOME)/.rustup +CARGO_HOME ?= $(HOME)/.cargo + RUST_SRC := $(MODULE_SRC)/rust/lisakmod RUST_LDS := $(RUST_SRC)/rust.lds RUST_GENERATED := $(GENERATED)/rust RUST_OBJECT := $(RUST_GENERATED)/rust.o RUST_OBJECT_CMD := $(RUST_GENERATED)/.rust.o.cmd -RUST_CBINDGEN_H := $(RUST_SRC)/cbindgen.h RUST_C_SHIMS_H := $(RUST_GENERATED)/rust_c_shims.h RUST_C_SHIMS_C := $(RUST_GENERATED)/rust_c_shims.c -RUST_C_SHIMS_DIR := $(RUST_GENERATED)/rust_c_shims - -RUSTUP_HOME ?= $(HOME)/.rustup -CARGO_HOME ?= $(HOME)/.cargo -CARGO_TARGET_DIR ?= $(RUST_BUILD_DIR)/target RUST_BUILD_DIR := $(RUST_GENERATED)/build +RUST_C_SHIMS_DIR := $(RUST_BUILD_DIR)/rust_c_shims +RUST_OBJECT_RAW := $(RUST_BUILD_DIR)/rust.raw.o RUST_SYMBOLS := $(RUST_BUILD_DIR)/exported.list RUST_SYMBOLS_CLI := $(RUST_BUILD_DIR)/exported.cli + +RUST_CBINDGEN_H := $(RUST_SRC)/cbindgen.h RUST_CBINDGEN_BIN := $(CARGO_HOME)/bin/cbindgen +CARGO_TARGET_DIR ?= $(RUST_BUILD_DIR)/target # Export c_flags so that lisa-eval-c.sh can compile a C source with the # appropriate flags. Trying to pass down $(c_flags) via parameters or @@ -72,41 +71,23 @@ export LISA_EVAL_C_CFLAGS=$(shell echo $(c_flags)) rust_cmd = chmod +x '$(LISA_EVAL_C)' && export RUSTC_BOOTSTRAP=1 PATH="$(CARGO_HOME)/bin:$$PATH" 'RUSTUP_HOME=$(RUSTUP_HOME)' 'CARGO_HOME=$(CARGO_HOME)' 'CARGO_TARGET_DIR=$(CARGO_TARGET_DIR)' 'LISA_EVAL_C=$(LISA_EVAL_C)' && $(1) cargo_cmd = $(call rust_cmd,cargo +$(RUST_VERSION) $(1)) -$(RUST_GENERATED): $(GENERATED) - mkdir -p "$@" - -$(RUST_BUILD_DIR): $(RUST_GENERATED) - mkdir -p "$@" - -$(CARGO_TARGET_DIR): +$(CARGO_TARGET_DIR) $(GENERATED) $(RUST_GENERATED) $(RUST_BUILD_DIR) $(RUST_C_SHIMS_DIR): mkdir -p "$@" # Build the rust code into a static archive, then prelink it into an object # file and filter the symbols to only keep as GLOBAL the exported pub # #[no_mangle] ones. This avoids having tons of GLOBAL symbols from core lib. -$(RUST_OBJECT) $(RUST_C_SHIMS_H) $(RUST_C_SHIMS_C): $(RUST_BUILD_DIR) $(CARGO_TARGET_DIR) +$(RUST_OBJECT_RAW): $(RUST_BUILD_DIR) $(CARGO_TARGET_DIR) # Build the crate into a static library cd $(RUST_SRC) && export RUSTFLAGS="$(RUSTFLAGS)" && $(call cargo_cmd,build --release --target=$(RUST_SRC)/rustc_targets/$(ARCH)/target.json -Zbuild-std=core$(comma)alloc) # Prelink the archive into a single object file. - $(LD) $(KBUILD_LDFLAGS) -nostdlib -r -o $(RUST_OBJECT) --whole-archive $(CARGO_TARGET_DIR)/target/release/liblisakmod.a + $(LD) $(KBUILD_LDFLAGS) -nostdlib -r -o $(RUST_OBJECT_RAW) --whole-archive $(CARGO_TARGET_DIR)/target/release/liblisakmod.a - # Get the list of exported symbols - python3 "$(MODULE_SRC)/rust_exported_symbols.py" --rust-object $(RUST_OBJECT) --out-symbols-plain $(RUST_SYMBOLS) --out-symbols-cli $(RUST_SYMBOLS_CLI) - # Extract the C shims created by our inlinec Rust module from the - # binary, so they can be compiled and linked later. - mkdir -p "$(RUST_C_SHIMS_DIR)" - touch $(RUST_C_SHIMS_DIR)/shim_.binstore.c.header. $(RUST_C_SHIMS_DIR)/shim_.binstore.c.code. - # Both llvm-objdump and llvm-objcopy can have a bug where the input - # file is overwritten by some garbage. This therefore destroys rust.o, - # which we unfortunately need intact for linking, so we make a copy for - # each of those tool to play with. - cp $(RUST_OBJECT) $(RUST_OBJECT)_objdump.o - $(OBJDUMP) -h $(RUST_OBJECT)_objdump.o | awk '{ print $$2 }' | grep '^.binstore.c.' | xargs -n1 sh -c '$(OBJCOPY) --dump-section $$0=$(RUST_C_SHIMS_DIR)/shim_$$0 $(RUST_OBJECT) /dev/null' - LC_ALL=C cat $(RUST_C_SHIMS_DIR)/shim_.binstore.c.header.* > $(RUST_C_SHIMS_H) - LC_ALL=C cat $(RUST_C_SHIMS_DIR)/shim_.binstore.c.code.* > $(RUST_C_SHIMS_C) - cat $(RUST_C_SHIMS_H) $(RUST_C_SHIMS_C) | if which clang-format 2>&1 1>/dev/null; then clang-format; else cat; fi +$(RUST_OBJECT): $(RUST_BUILD_DIR) $(RUST_OBJECT_RAW) + # Get the list of exported symbols + python3 "$(MODULE_SRC)/rust_exported_symbols.py" --rust-object $(RUST_OBJECT_RAW) --out-symbols-plain $(RUST_SYMBOLS) --out-symbols-cli $(RUST_SYMBOLS_CLI) # Garbage collect unused sections in the object file, after we have # extracted the binstore sections (otherwise they get discarded). @@ -115,9 +96,7 @@ $(RUST_OBJECT) $(RUST_C_SHIMS_H) $(RUST_C_SHIMS_C): $(RUST_BUILD_DIR) $(CARGO_TA # EXTERN() command in a linker script since older GNU ld version seem # to ignore the EXTERN() command with --gc-sections. $(LD) --version - # Some versions of ld.lld are broken and this will not work. In that - # case, we just let it be and the binary will simply be bigger - ($(LD) $(KBUILD_LDFLAGS) $$(cat $(RUST_SYMBOLS_CLI)) --gc-sections -nostdlib -r -o $(RUST_OBJECT)_gced.o $(RUST_OBJECT) && mv $(RUST_OBJECT)_gced.o $(RUST_OBJECT)) || true + $(LD) $(KBUILD_LDFLAGS) $$(cat $(RUST_SYMBOLS_CLI)) --gc-sections -nostdlib -r -o $(RUST_OBJECT) $(RUST_OBJECT_RAW) # Only keep as GLOBAL symbols the ones that are to be exported (and the # undefined ones to be provided by C code) @@ -127,6 +106,22 @@ $(RUST_OBJECT) $(RUST_C_SHIMS_H) $(RUST_C_SHIMS_C): $(RUST_BUILD_DIR) $(CARGO_TA cp $(RUST_OBJECT) $(RUST_OBJECT)_shipped touch $(RUST_OBJECT_CMD) + +$(RUST_C_SHIMS_H): $(RUST_OBJECT_RAW) $(RUST_C_SHIMS_DIR) + # Extract the C shims created by our inlinec Rust module from the + # binary, so they can be compiled and linked later. + + # Create some empty files so that the globbing pattern later on always + # matches something. + touch $(RUST_C_SHIMS_DIR)/shim_.binstore.c.header. $(RUST_C_SHIMS_DIR)/shim_.binstore.c.code. + + cp $(RUST_OBJECT_RAW) $(RUST_OBJECT_RAW)_objdump.o + $(OBJDUMP) -h $(RUST_OBJECT_RAW)_objdump.o | awk '{ print $$2 }' | grep '^.binstore.c.' | sort | xargs -P$$(nproc) -n1 sh -c '$(OBJCOPY) --dump-section $$0=$(RUST_C_SHIMS_DIR)/shim_$$0 $(RUST_OBJECT_RAW) /dev/null' + LC_ALL=C cat $(RUST_C_SHIMS_DIR)/shim_.binstore.c.header.* > $(RUST_C_SHIMS_H) + LC_ALL=C cat $(RUST_C_SHIMS_DIR)/shim_.binstore.c.code.* > $(RUST_C_SHIMS_C) + cat $(RUST_C_SHIMS_H) $(RUST_C_SHIMS_C) | if which clang-format 2>&1 1>/dev/null; then clang-format; else cat; fi + + # This rule is necessary as Kbuild cannot cope with absolute paths on the # object file list to link in the module. Unfortunately, make is not smart # enough to realize that the relative path being asked for is the same location @@ -150,8 +145,6 @@ $(RUST_CBINDGEN_BIN): $(CARGO_HOME) refresh-rust-bindings: $(RUST_CBINDGEN_BIN) cd $(RUST_SRC) && $(call rust_cmd,cbindgen --config $(RUST_SRC)/cbindgen.toml --lang c --crate lisakmod --output $(RUST_CBINDGEN_H)) -$(RUST_SYMBOLS): $(RUST_OBJECT) - # kbuild part of makefile. Only Kbuild-related targets should be used here to # avoid any sort of clash. ifneq ($(KERNELRELEASE),) @@ -245,7 +238,7 @@ $(KALLSYMS): $(GENERATED) # Make all object files depend on the generated sources. We use both the # relative and absolute paths as kernels <= 6.12 require an absolute path # whereas >= 6.13 requires a relative path. -$($(LISA_KMOD_NAME)-y) $(addprefix $(MODULE_OBJ)/,$($(LISA_KMOD_NAME)-y)): $(INTROSPECTION_DATA_H) $(SYMBOL_NAMESPACES_H) $(MODULE_VERSION_H) $(SYMBOLS_LDS) $(RUST_CBINDGEN_H) $(RUST_C_SHIMS_H) $(RUST_C_SHIMS_C) +$($(LISA_KMOD_NAME)-y) $(addprefix $(MODULE_OBJ)/,$($(LISA_KMOD_NAME)-y)): $(INTROSPECTION_DATA_H) $(SYMBOL_NAMESPACES_H) $(MODULE_VERSION_H) $(SYMBOLS_LDS) $(RUST_CBINDGEN_H) $(RUST_C_SHIMS_H) # Non-Kbuild part else -- GitLab