# interpose.ko — out-of-tree kernel module build.
#
# Standard Kbuild M= invocation. Requires the running kernel's headers:
#
#   sudo apt install linux-headers-$(uname -r)     # Debian / Ubuntu
#   sudo dnf install kernel-devel                  # Fedora
#
# `sudo interpose doctor --fix` will install the headers for you on
# Debian-family systems (v0.30.13+).
#
# Build:
#   make
#
# Load / unload (root):
#   sudo insmod interpose.ko
#   sudo rmmod  interpose
#   dmesg | tail   # confirms "interpose: kernel module loaded" line
#
# v0.30.16 ships a DKMS .deb that does this automatically per kernel
# upgrade. Until then, manual build is the path.

obj-m := interpose.o

# Compile with DWARF debug info so the post-build pahole step can derive
# BTF type info. ccflags-y is honored by kbuild's per-module compile pass.
ccflags-y := -g

KDIR   ?= /lib/modules/$(shell uname -r)/build
PWD    := $(shell pwd)
PAHOLE ?= pahole

.PHONY: all clean install btf build

all: btf

# kbuild → BTF generation in two steps.
#
# Distro kernels typically enable CONFIG_DEBUG_INFO_BTF=y so vmlinux
# gets BTF, but NOT CONFIG_DEBUG_INFO_BTF_MODULES=y — meaning kbuild
# does NOT auto-attach .BTF to out-of-tree modules. Without .BTF the
# .BTF_ids section is unresolvable and register_btf_kfunc_id_set()
# returns -EINVAL at insmod ("Invalid argument").
#
# We force BTF generation: `pahole -J` reads DWARF from interpose.ko
# (which is there because of ccflags-y=-g), encodes it as BTF, and
# embeds the result in a new .BTF section in the same .ko in place.
# --btf_base points at the running kernel's BTF so common kernel
# types (struct file, etc.) are referenced by ID rather than
# duplicated.
#
# Soft-fail: if pahole is missing or vmlinux BTF isn't present, we
# print a warning but don't fail the build — the .ko still installs,
# just lacks BTF (which the daemon then logs about at startup).
btf: build
	@if [ ! -f /sys/kernel/btf/vmlinux ]; then \
		echo "WARN: /sys/kernel/btf/vmlinux missing — BTF generation skipped"; \
		echo "      register_btf_kfunc_id_set() will return EINVAL at insmod"; \
	elif ! command -v $(PAHOLE) >/dev/null 2>&1; then \
		echo "WARN: pahole not found — BTF generation skipped"; \
		echo "      install dwarves package and re-run make"; \
	elif [ -f interpose.ko ]; then \
		echo "  BTF [M]  interpose.ko (pahole -J --btf_base=/sys/kernel/btf/vmlinux)"; \
		$(PAHOLE) -J --btf_base=/sys/kernel/btf/vmlinux interpose.ko || \
			echo "WARN: pahole BTF encoding failed; .ko will lack .BTF section"; \
	fi

build:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
	$(MAKE) -C $(KDIR) M=$(PWD) modules clean

install:
	$(MAKE) -C $(KDIR) M=$(PWD) modules_install
	depmod -a
