public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:6.10 commit in: /
Date: Mon, 30 Sep 2024 16:11:36 +0000 (UTC)	[thread overview]
Message-ID: <1727712682.13d4521ec8233c1a6e250857c77d1c62a7fcb1e0.mpagano@gentoo> (raw)

commit:     13d4521ec8233c1a6e250857c77d1c62a7fcb1e0
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Sep 30 16:11:22 2024 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Sep 30 16:11:22 2024 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=13d4521e

Remove older dtrace patch

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 2995_dtrace-6.10_p3.patch | 2352 ---------------------------------------------
 1 file changed, 2352 deletions(-)

diff --git a/2995_dtrace-6.10_p3.patch b/2995_dtrace-6.10_p3.patch
deleted file mode 100644
index 775a7868..00000000
--- a/2995_dtrace-6.10_p3.patch
+++ /dev/null
@@ -1,2352 +0,0 @@
-diff --git a/Documentation/dontdiff b/Documentation/dontdiff
-index 3c399f132e2db..75b9655e57914 100644
---- a/Documentation/dontdiff
-+++ b/Documentation/dontdiff
-@@ -179,7 +179,7 @@ mkutf8data
- modpost
- modules-only.symvers
- modules.builtin
--modules.builtin.modinfo
-+modules.builtin.*
- modules.nsdeps
- modules.order
- modversions.h*
-diff --git a/Documentation/kbuild/kbuild.rst b/Documentation/kbuild/kbuild.rst
-index 9c8d1d046ea56..79e104ffee715 100644
---- a/Documentation/kbuild/kbuild.rst
-+++ b/Documentation/kbuild/kbuild.rst
-@@ -17,6 +17,11 @@ modules.builtin
- This file lists all modules that are built into the kernel. This is used
- by modprobe to not fail when trying to load something builtin.
- 
-+modules.builtin.objs
-+-----------------------
-+This file contains object mapping of modules that are built into the kernel
-+to their corresponding object files used to build the module.
-+
- modules.builtin.modinfo
- -----------------------
- This file contains modinfo from all modules that are built into the kernel.
-diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
-index 5685d7bfe4d0f..8db62fe4dadff 100644
---- a/Documentation/process/changes.rst
-+++ b/Documentation/process/changes.rst
-@@ -63,9 +63,13 @@ cpio                   any              cpio --version
- GNU tar                1.28             tar --version
- gtags (optional)       6.6.5            gtags --version
- mkimage (optional)     2017.01          mkimage --version
-+GNU AWK (optional)     5.1.0            gawk --version
-+GNU C\ [#f2]_          12.0             gcc --version
-+binutils\ [#f2]_       2.36             ld -v
- ====================== ===============  ========================================
- 
- .. [#f1] Sphinx is needed only to build the Kernel documentation
-+.. [#f2] These are needed at build-time when CONFIG_CTF is enabled
- 
- Kernel compilation
- ******************
-@@ -198,6 +202,12 @@ platforms. The tool is available via the ``u-boot-tools`` package or can be
- built from the U-Boot source code. See the instructions at
- https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux
- 
-+GNU AWK
-+-------
-+
-+GNU AWK is needed if you want kernel builds to generate address range data for
-+builtin modules (CONFIG_BUILTIN_MODULE_RANGES).
-+
- System utilities
- ****************
- 
-diff --git a/Makefile b/Makefile
-index 2e5ac6ab3d476..635896f269f1f 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1024,6 +1024,7 @@ include-$(CONFIG_UBSAN)		+= scripts/Makefile.ubsan
- include-$(CONFIG_KCOV)		+= scripts/Makefile.kcov
- include-$(CONFIG_RANDSTRUCT)	+= scripts/Makefile.randstruct
- include-$(CONFIG_GCC_PLUGINS)	+= scripts/Makefile.gcc-plugins
-+include-$(CONFIG_CTF)		+= scripts/Makefile.ctfa-toplevel
- 
- include $(addprefix $(srctree)/, $(include-y))
- 
-@@ -1151,7 +1152,11 @@ PHONY += vmlinux_o
- vmlinux_o: vmlinux.a $(KBUILD_VMLINUX_LIBS)
- 	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.vmlinux_o
- 
--vmlinux.o modules.builtin.modinfo modules.builtin: vmlinux_o
-+MODULES_BUILTIN := modules.builtin.modinfo
-+MODULES_BUILTIN += modules.builtin
-+MODULES_BUILTIN += modules.builtin.objs
-+
-+vmlinux.o $(MODULES_BUILTIN): vmlinux_o
- 	@:
- 
- PHONY += vmlinux
-@@ -1490,9 +1495,10 @@ endif # CONFIG_MODULES
- 
- # Directories & files removed with 'make clean'
- CLEAN_FILES += vmlinux.symvers modules-only.symvers \
--	       modules.builtin modules.builtin.modinfo modules.nsdeps \
-+	       modules.builtin modules.builtin.* modules.nsdeps \
- 	       compile_commands.json rust/test \
--	       rust-project.json .vmlinux.objs .vmlinux.export.c
-+	       rust-project.json .vmlinux.objs .vmlinux.export.c \
-+	       vmlinux.ctfa
- 
- # Directories & files removed with 'make mrproper'
- MRPROPER_FILES += include/config include/generated          \
-@@ -1586,6 +1592,8 @@ help:
- 	@echo  '                    (requires a recent binutils and recent build (System.map))'
- 	@echo  '  dir/file.ko     - Build module including final link'
- 	@echo  '  modules_prepare - Set up for building external modules'
-+	@echo  '  ctf             - Generate CTF type information, installed by make ctf_install'
-+	@echo  '  ctf_install     - Install CTF to INSTALL_MOD_PATH (default: /)'
- 	@echo  '  tags/TAGS	  - Generate tags file for editors'
- 	@echo  '  cscope	  - Generate cscope index'
- 	@echo  '  gtags           - Generate GNU GLOBAL index'
-@@ -1942,7 +1950,7 @@ clean: $(clean-dirs)
- 	$(call cmd,rmfiles)
- 	@find $(or $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
- 		\( -name '*.[aios]' -o -name '*.rsi' -o -name '*.ko' -o -name '.*.cmd' \
--		-o -name '*.ko.*' \
-+		-o -name '*.ko.*' -o -name '*.ctf' \
- 		-o -name '*.dtb' -o -name '*.dtbo' \
- 		-o -name '*.dtb.S' -o -name '*.dtbo.S' \
- 		-o -name '*.dt.yaml' -o -name 'dtbs-list' \
-diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile
-index 01067a2bc43b7..d2193b8dfad83 100644
---- a/arch/arm/vdso/Makefile
-+++ b/arch/arm/vdso/Makefile
-@@ -14,6 +14,10 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
- ccflags-y := -fPIC -fno-common -fno-builtin -fno-stack-protector
- ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO32
- 
-+# CTF in the vDSO would introduce a new section, which would
-+# expand the vDSO to more than a page.
-+ccflags-y += $(call cc-option,-gctf0)
-+
- ldflags-$(CONFIG_CPU_ENDIAN_BE8) := --be8
- ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
- 	    -z max-page-size=4096 -shared $(ldflags-y) \
-diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
-index d63930c828397..6e84d3822cfe3 100644
---- a/arch/arm64/kernel/vdso/Makefile
-+++ b/arch/arm64/kernel/vdso/Makefile
-@@ -33,6 +33,10 @@ ldflags-y += -T
- ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18
- ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
- 
-+# CTF in the vDSO would introduce a new section, which would
-+# expand the vDSO to more than a page.
-+ccflags-y += $(call cc-option,-gctf0)
-+
- # -Wmissing-prototypes and -Wmissing-declarations are removed from
- # the CFLAGS of vgettimeofday.c to make possible to build the
- # kernel with CONFIG_WERROR enabled.
-diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
-index d724d46b07c84..fbedb95223ae1 100644
---- a/arch/loongarch/vdso/Makefile
-+++ b/arch/loongarch/vdso/Makefile
-@@ -21,7 +21,8 @@ cflags-vdso := $(ccflags-vdso) \
- 	-O2 -g -fno-strict-aliasing -fno-common -fno-builtin \
- 	-fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \
- 	$(call cc-option, -fno-asynchronous-unwind-tables) \
--	$(call cc-option, -fno-stack-protector)
-+	$(call cc-option, -fno-stack-protector) \
-+	$(call cc-option,-gctf0)
- aflags-vdso := $(ccflags-vdso) \
- 	-D__ASSEMBLY__ -Wa,-gdwarf-2
- 
-diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
-index b289b2c1b2946..6c8d777525f9b 100644
---- a/arch/mips/vdso/Makefile
-+++ b/arch/mips/vdso/Makefile
-@@ -30,7 +30,8 @@ cflags-vdso := $(ccflags-vdso) \
- 	-O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
- 	-mrelax-pic-calls $(call cc-option, -mexplicit-relocs) \
- 	-fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \
--	$(call cc-option, -fno-asynchronous-unwind-tables)
-+	$(call cc-option, -fno-asynchronous-unwind-tables) \
-+	$(call cc-option,-gctf0)
- aflags-vdso := $(ccflags-vdso) \
- 	-D__ASSEMBLY__ -Wa,-gdwarf-2
- 
-diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile
-index 243dbfc4609d8..e4f3e47074e9d 100644
---- a/arch/sparc/vdso/Makefile
-+++ b/arch/sparc/vdso/Makefile
-@@ -44,7 +44,7 @@ $(obj)/vdso-image-%.c: $(obj)/vdso%.so.dbg $(obj)/vdso%.so $(obj)/vdso2c FORCE
- CFL := $(PROFILING) -mcmodel=medlow -fPIC -O2 -fasynchronous-unwind-tables -m64 \
-        $(filter -g%,$(KBUILD_CFLAGS)) -fno-stack-protector \
-        -fno-omit-frame-pointer -foptimize-sibling-calls \
--       -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
-+       $(call cc-option,-gctf0) -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
- 
- SPARC_REG_CFLAGS = -ffixed-g4 -ffixed-g5 -fcall-used-g5 -fcall-used-g7
- 
-diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
-index 215a1b202a918..2fa1613a06275 100644
---- a/arch/x86/entry/vdso/Makefile
-+++ b/arch/x86/entry/vdso/Makefile
-@@ -54,6 +54,7 @@ $(obj)/vdso-image-%.c: $(obj)/vdso%.so.dbg $(obj)/vdso%.so $(obj)/vdso2c FORCE
- CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
-        $(filter -g%,$(KBUILD_CFLAGS)) -fno-stack-protector \
-        -fno-omit-frame-pointer -foptimize-sibling-calls \
-+       $(call cc-option,-gctf0) \
-        -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
- 
- ifdef CONFIG_MITIGATION_RETPOLINE
-@@ -131,6 +132,7 @@ KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
- KBUILD_CFLAGS_32 += -fno-stack-protector
- KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
- KBUILD_CFLAGS_32 += -fno-omit-frame-pointer
-+KBUILD_CFLAGS_32 += $(call cc-option,-gctf0)
- KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING
- 
- ifdef CONFIG_MITIGATION_RETPOLINE
-diff --git a/arch/x86/um/vdso/Makefile b/arch/x86/um/vdso/Makefile
-index 6a77ea6434ffd..6db233b5edd75 100644
---- a/arch/x86/um/vdso/Makefile
-+++ b/arch/x86/um/vdso/Makefile
-@@ -40,7 +40,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
- #
- CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
-        $(filter -g%,$(KBUILD_CFLAGS)) -fno-stack-protector \
--       -fno-omit-frame-pointer -foptimize-sibling-calls
-+       -fno-omit-frame-pointer -foptimize-sibling-calls $(call cc-option,-gctf0)
- 
- $(vobjs): KBUILD_CFLAGS += $(CFL)
- 
-diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
-index f00a8e18f389f..2e307c0824574 100644
---- a/include/asm-generic/vmlinux.lds.h
-+++ b/include/asm-generic/vmlinux.lds.h
-@@ -1014,6 +1014,7 @@
- 	*(.discard.*)							\
- 	*(.export_symbol)						\
- 	*(.modinfo)							\
-+	*(.ctf)								\
- 	/* ld.bfd warns about .gnu.version* even when not emitted */	\
- 	*(.gnu.version*)						\
- 
-diff --git a/include/linux/module.h b/include/linux/module.h
-index 330ffb59efe51..2d9fcca542d13 100644
---- a/include/linux/module.h
-+++ b/include/linux/module.h
-@@ -180,7 +180,13 @@ extern void cleanup_module(void);
- #ifdef MODULE
- #define MODULE_FILE
- #else
--#define MODULE_FILE	MODULE_INFO(file, KBUILD_MODFILE);
-+#ifdef CONFIG_CTF
-+#define MODULE_FILE					                      \
-+			MODULE_INFO(file, KBUILD_MODFILE);                    \
-+			MODULE_INFO(objs, KBUILD_MODOBJS);
-+#else
-+#define MODULE_FILE MODULE_INFO(file, KBUILD_MODFILE);
-+#endif
- #endif
- 
- /*
-diff --git a/init/Kconfig b/init/Kconfig
-index 9684e5d2b81c6..c1b00b2e4a43d 100644
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -111,6 +111,12 @@ config PAHOLE_VERSION
- 	int
- 	default $(shell,$(srctree)/scripts/pahole-version.sh $(PAHOLE))
- 
-+config HAVE_CTF_TOOLCHAIN
-+	def_bool $(cc-option,-gctf) && $(ld-option,-lbfd -liberty -lctf -lbfd -liberty -lz -ldl -lc -o /dev/null)
-+	depends on CC_IS_GCC
-+	help
-+	  GCC and binutils support CTF generation.
-+
- config CONSTRUCTORS
- 	bool
- 
-diff --git a/lib/Kconfig b/lib/Kconfig
-index b0a76dff5c182..61d0be30b3562 100644
---- a/lib/Kconfig
-+++ b/lib/Kconfig
-@@ -633,6 +633,16 @@ config DIMLIB
- #
- config LIBFDT
- 	bool
-+#
-+# CTF support is select'ed if needed
-+#
-+config CTF
-+        bool "Compact Type Format generation"
-+        depends on HAVE_CTF_TOOLCHAIN
-+        help
-+          Emit a compact, compressed description of the kernel's datatypes and
-+          global variables into the vmlinux.ctfa archive (for in-tree modules)
-+          or into .ctf sections in kernel modules (for out-of-tree modules).
- 
- config OID_REGISTRY
- 	tristate
-diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
-index 59b6765d86b8f..dab7e6983eace 100644
---- a/lib/Kconfig.debug
-+++ b/lib/Kconfig.debug
-@@ -571,6 +571,21 @@ config VMLINUX_MAP
- 	  pieces of code get eliminated with
- 	  CONFIG_LD_DEAD_CODE_DATA_ELIMINATION.
- 
-+config BUILTIN_MODULE_RANGES
-+	bool "Generate address range information for builtin modules"
-+	depends on !LTO
-+	depends on VMLINUX_MAP
-+	help
-+	 When modules are built into the kernel, there will be no module name
-+	 associated with its symbols in /proc/kallsyms.  Tracers may want to
-+	 identify symbols by module name and symbol name regardless of whether
-+	 the module is configured as loadable or not.
-+
-+	 This option generates modules.builtin.ranges in the build tree with
-+	 offset ranges (per ELF section) for the module(s) they belong to.
-+	 It also records an anchor symbol to determine the load address of the
-+	 section.
-+
- config DEBUG_FORCE_WEAK_PER_CPU
- 	bool "Force weak per-cpu definitions"
- 	depends on DEBUG_KERNEL
-+y!/Makefile.ctf
-diff --git a/scripts/Makefile b/scripts/Makefile
-index fe56eeef09dd4..8e7eb174d3154 100644
---- a/scripts/Makefile
-+++ b/scripts/Makefile
-@@ -54,6 +54,7 @@ targets += module.lds
- 
- subdir-$(CONFIG_GCC_PLUGINS) += gcc-plugins
- subdir-$(CONFIG_MODVERSIONS) += genksyms
-+subdir-$(CONFIG_CTF)         += ctf
- subdir-$(CONFIG_SECURITY_SELINUX) += selinux
- 
- # Let clean descend into subdirs
-diff --git a/scripts/Makefile.ctfa b/scripts/Makefile.ctfa
-new file mode 100644
-index 0000000000000..b65d9d391c29c
---- /dev/null
-+++ b/scripts/Makefile.ctfa
-@@ -0,0 +1,92 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+# ===========================================================================
-+# Module CTF/CTFA generation
-+# ===========================================================================
-+
-+include include/config/auto.conf
-+include $(srctree)/scripts/Kbuild.include
-+
-+# CTF is already present in every object file if CONFIG_CTF is enabled.
-+# vmlinux.lds.h strips it out of the finished kernel, but if nothing is done
-+# it will be deduplicated into module .ko's.  For out-of-tree module builds,
-+# this is what we want, but for in-tree modules we can save substantial
-+# space by deduplicating it against all the core kernel types as well.  So
-+# split the CTF out of in-tree module .ko's into separate .ctf files so that
-+# it doesn't take up space in the modules on disk, and let the specialized
-+# ctfarchive tool consume it and all the CTF in the vmlinux.o files when
-+# 'make ctf' is invoked, and use the same machinery that the linker uses to
-+# do CTF deduplication to emit vmlinux.ctfa containing the deduplicated CTF.
-+
-+# Nothing special needs to be done if CTF is turned off or if a standalone
-+# module is being built.
-+module-ctf-postlink = mv $(1).tmp $(1)
-+
-+ifdef CONFIG_CTF
-+
-+# This is quite tricky.  The CTF machinery needs to be told about all the
-+# built-in objects as well as all the external modules -- but Makefile.modfinal
-+# only knows about the latter.  So the toplevel makefile emits the names of the
-+# built-in objects into a temporary file, which is then catted and its contents
-+# used as prerequisites by this rule.
-+#
-+# We write the names of the object files to be scanned for CTF content into a
-+# file, then use that, to avoid hitting command-line length limits.
-+
-+ifeq ($(KBUILD_EXTMOD),)
-+ctf-modules := $(shell find . -name '*.ko.ctf' -print)
-+quiet_cmd_ctfa_raw = CTFARAW
-+      cmd_ctfa_raw = scripts/ctf/ctfarchive $@ .tmp_objects.builtin modules.builtin.objs $(ctf-filelist)
-+ctf-builtins := .tmp_objects.builtin
-+ctf-filelist := .tmp_ctf.filelist
-+ctf-filelist-raw := .tmp_ctf.filelist.raw
-+
-+define module-ctf-postlink =
-+	$(OBJCOPY) --only-section=.ctf $(1).tmp $(1).ctf && \
-+	$(OBJCOPY) --remove-section=.ctf $(1).tmp $(1) && rm -f $(1).tmp
-+endef
-+
-+# Split a list up like shell xargs does.
-+define xargs =
-+$(1) $(wordlist 1,1024,$(2))
-+$(if $(word 1025,$(2)),$(call xargs,$(1),$(wordlist 1025,$(words $(2)),$(2))))
-+endef
-+
-+$(ctf-filelist-raw): $(ctf-builtins) $(ctf-modules)
-+	@rm -f $(ctf-filelist-raw);
-+	$(call xargs,@printf "%s\n" >> $(ctf-filelist-raw),$^)
-+	@touch $(ctf-filelist-raw)
-+
-+$(ctf-filelist): $(ctf-filelist-raw)
-+	@rm -f $(ctf-filelist);
-+	@cat $(ctf-filelist-raw) | while read -r obj; do \
-+		case $$obj in \
-+		$(ctf-builtins)) cat $$obj >> $(ctf-filelist);; \
-+		*.a) $(AR) t $$obj > $(ctf-filelist);; \
-+		*.builtin) cat $$obj >> $(ctf-filelist);; \
-+		*) echo "$$obj" >> $(ctf-filelist);; \
-+		esac; \
-+	done
-+	@touch $(ctf-filelist)
-+
-+# The raw CTF depends on the output CTF file list, and that depends
-+# on the .ko files for the modules.
-+.tmp_vmlinux.ctfa.raw: $(ctf-filelist) FORCE
-+	$(call if_changed,ctfa_raw)
-+
-+quiet_cmd_ctfa = CTFA
-+      cmd_ctfa = { echo 'int main () { return 0; } ' | \
-+		$(CC) -x c -c -o $<.stub -; \
-+	$(OBJCOPY) '--remove-section=.*' --add-section=.ctf=$< \
-+		 $<.stub $@; }
-+
-+# The CTF itself is an ELF executable with one section: the CTF.  This lets
-+# objdump work on it, at minimal size cost.
-+vmlinux.ctfa: .tmp_vmlinux.ctfa.raw FORCE
-+	$(call if_changed,ctfa)
-+
-+targets += vmlinux.ctfa
-+
-+endif		# KBUILD_EXTMOD
-+
-+endif		# !CONFIG_CTF
-+
-diff --git a/scripts/Makefile.ctfa-toplevel b/scripts/Makefile.ctfa-toplevel
-new file mode 100644
-index 0000000000000..210bef3854e9b
---- /dev/null
-+++ b/scripts/Makefile.ctfa-toplevel
-@@ -0,0 +1,54 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+# ===========================================================================
-+# CTF rules for the top-level makefile only
-+# ===========================================================================
-+
-+KBUILD_CFLAGS	+= $(call cc-option,-gctf)
-+KBUILD_LDFLAGS	+= $(call ld-option, --ctf-variables)
-+
-+ifeq ($(KBUILD_EXTMOD),)
-+
-+# CTF generation for in-tree code (modules, built-in and not, and core kernel)
-+
-+# This contains all the object files that are built directly into the
-+# kernel (including built-in modules), for consumption by ctfarchive in
-+# Makefile.modfinal.
-+# This is made doubly annoying by the presence of '.o' files which are actually
-+# thin ar archives, and the need to support file(1) versions too old to
-+# recognize them as archives at all.  (So we assume that everything that is notr
-+# an ELF object is an archive.)
-+ifeq ($(SRCARCH),x86)
-+.tmp_objects.builtin: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),bzImage) FORCE
-+else
-+ifeq ($(SRCARCH),arm64)
-+.tmp_objects.builtin: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),Image) FORCE
-+else
-+.tmp_objects.builtin: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) FORCE
-+endif
-+endif
-+	@echo $(KBUILD_VMLINUX_OBJS) | \
-+		tr " " "\n" | grep "\.o$$" | xargs -r file | \
-+		grep ELF | cut -d: -f1 > .tmp_objects.builtin
-+	@for archive in $$(echo $(KBUILD_VMLINUX_OBJS) |\
-+		tr " " "\n" | xargs -r file | grep -v ELF | cut -d: -f1); do \
-+		$(AR) t "$$archive" >> .tmp_objects.builtin; \
-+	done
-+
-+ctf: vmlinux.ctfa
-+PHONY += ctf ctf_install
-+
-+# Making CTF needs the builtin files.  We need to force everything to be
-+# built if not already done, since we need the .o files for the machinery
-+# above to work.
-+vmlinux.ctfa: KBUILD_BUILTIN := 1
-+vmlinux.ctfa: modules.builtin.objs .tmp_objects.builtin
-+	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal vmlinux.ctfa
-+
-+ctf_install:
-+	$(Q)mkdir -p $(MODLIB)/kernel
-+	@ln -sf $(abspath $(srctree)) $(MODLIB)/source
-+	$(Q)cp -f $(objtree)/vmlinux.ctfa $(MODLIB)/kernel
-+
-+CLEAN_FILES += vmlinux.ctfa
-+
-+endif
-diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
-index 7f8ec77bf35c9..8e67961ba2ec9 100644
---- a/scripts/Makefile.lib
-+++ b/scripts/Makefile.lib
-@@ -118,6 +118,8 @@ modname-multi = $(sort $(foreach m,$(multi-obj-ym),\
- __modname = $(or $(modname-multi),$(basetarget))
- 
- modname = $(subst $(space),:,$(__modname))
-+modname-objs = $($(modname)-objs) $($(modname)-y) $($(modname)-Y)
-+modname-objs-prefixed = $(sort $(strip $(addprefix $(obj)/, $(modname-objs))))
- modfile = $(addprefix $(obj)/,$(__modname))
- 
- # target with $(obj)/ and its suffix stripped
-@@ -133,6 +135,10 @@ modname_flags  = -DKBUILD_MODNAME=$(call name-fix,$(modname)) \
- 		 -D__KBUILD_MODNAME=kmod_$(call name-fix-token,$(modname))
- modfile_flags  = -DKBUILD_MODFILE=$(call stringify,$(modfile))
- 
-+ifdef CONFIG_CTF
-+modfile_flags  += -DKBUILD_MODOBJS=$(call stringify,$(modfile).o:$(subst $(space),|,$(modname-objs-prefixed)))
-+endif
-+
- _c_flags       = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \
-                      $(filter-out $(ccflags-remove-y), \
-                          $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \
-@@ -238,7 +244,7 @@ modkern_rustflags =                                              \
- 
- modkern_aflags = $(if $(part-of-module),				\
- 			$(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE),	\
--			$(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL))
-+			$(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL) $(modfile_flags))
- 
- c_flags        = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
- 		 -include $(srctree)/include/linux/compiler_types.h       \
-@@ -248,7 +254,7 @@ c_flags        = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
- rust_flags     = $(_rust_flags) $(modkern_rustflags) @$(objtree)/include/generated/rustc_cfg
- 
- a_flags        = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
--		 $(_a_flags) $(modkern_aflags)
-+		 $(_a_flags) $(modkern_aflags) $(modname_flags)
- 
- cpp_flags      = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
- 		 $(_cpp_flags)
-diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
-index 3bec9043e4f38..06807e403d162 100644
---- a/scripts/Makefile.modfinal
-+++ b/scripts/Makefile.modfinal
-@@ -30,11 +30,16 @@ quiet_cmd_cc_o_c = CC [M]  $@
- %.mod.o: %.mod.c FORCE
- 	$(call if_changed_dep,cc_o_c)
- 
-+# for module-ctf-postlink
-+include $(srctree)/scripts/Makefile.ctfa
-+
- quiet_cmd_ld_ko_o = LD [M]  $@
-       cmd_ld_ko_o +=							\
- 	$(LD) -r $(KBUILD_LDFLAGS)					\
- 		$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE)		\
--		-T scripts/module.lds -o $@ $(filter %.o, $^)
-+		-T scripts/module.lds $(LDFLAGS_$(modname)) -o $@.tmp	\
-+		$(filter %.o, $^) &&					\
-+	$(call module-ctf-postlink,$@)					\
- 
- quiet_cmd_btf_ko = BTF [M] $@
-       cmd_btf_ko = 							\
-diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
-index 0afd75472679f..e668469ce098c 100644
---- a/scripts/Makefile.modinst
-+++ b/scripts/Makefile.modinst
-@@ -30,10 +30,12 @@ $(MODLIB)/modules.order: modules.order FORCE
- quiet_cmd_install_modorder = INSTALL $@
-       cmd_install_modorder = sed 's:^\(.*\)\.o$$:kernel/\1.ko:' $< > $@
- 
--# Install modules.builtin(.modinfo) even when CONFIG_MODULES is disabled.
--install-y += $(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo)
-+# Install modules.builtin(.modinfo,.ranges,.objs) even when CONFIG_MODULES is disabled.
-+install-y += $(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo modules.builtin.objs)
- 
--$(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo): $(MODLIB)/%: % FORCE
-+install-$(CONFIG_BUILTIN_MODULE_RANGES) += $(MODLIB)/modules.builtin.ranges
-+
-+$(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo modules.builtin.ranges modules.builtin.objs): $(MODLIB)/%: % FORCE
- 	$(call cmd,install)
- 
- endif
-diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux
-index 49946cb968440..7e8b703799c85 100644
---- a/scripts/Makefile.vmlinux
-+++ b/scripts/Makefile.vmlinux
-@@ -33,6 +33,24 @@ targets += vmlinux
- vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE
- 	+$(call if_changed_dep,link_vmlinux)
- 
-+# module.builtin.ranges
-+# ---------------------------------------------------------------------------
-+ifdef CONFIG_BUILTIN_MODULE_RANGES
-+__default: modules.builtin.ranges
-+
-+quiet_cmd_modules_builtin_ranges = GEN     $@
-+      cmd_modules_builtin_ranges = $(real-prereqs) > $@
-+
-+targets += modules.builtin.ranges
-+modules.builtin.ranges: $(srctree)/scripts/generate_builtin_ranges.awk \
-+			modules.builtin vmlinux.map vmlinux.o.map FORCE
-+	$(call if_changed,modules_builtin_ranges)
-+
-+vmlinux.map: vmlinux
-+	@:
-+
-+endif
-+
- # Add FORCE to the prequisites of a target to force it to be always rebuilt.
- # ---------------------------------------------------------------------------
- 
-diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o
-index 6de297916ce68..86d6f8887313f 100644
---- a/scripts/Makefile.vmlinux_o
-+++ b/scripts/Makefile.vmlinux_o
-@@ -1,7 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0-only
- 
- PHONY := __default
--__default: vmlinux.o modules.builtin.modinfo modules.builtin
-+__default: vmlinux.o modules.builtin.modinfo modules.builtin modules.builtin.objs
- 
- include include/config/auto.conf
- include $(srctree)/scripts/Kbuild.include
-@@ -27,6 +27,18 @@ ifdef CONFIG_LTO_CLANG
- initcalls-lds := .tmp_initcalls.lds
- endif
- 
-+# Generate a linker script to delete CTF sections
-+# -----------------------------------------------
-+
-+quiet_cmd_gen_remove_ctf.lds = GEN     $@
-+      cmd_gen_remove_ctf.lds = \
-+	$(LD) $(KBUILD_LDFLAGS) -r --verbose | awk -f $(real-prereqs) > $@
-+
-+.tmp_remove-ctf.lds: $(srctree)/scripts/remove-ctf-lds.awk FORCE
-+	$(call if_changed,gen_remove_ctf.lds)
-+
-+targets := .tmp_remove-ctf.lds
-+
- # objtool for vmlinux.o
- # ---------------------------------------------------------------------------
- #
-@@ -42,13 +54,18 @@ vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION)	+= --noinstr \
- 
- objtool-args = $(vmlinux-objtool-args-y) --link
- 
--# Link of vmlinux.o used for section mismatch analysis
-+# Link of vmlinux.o used for section mismatch analysis: we also strip the CTF
-+# section out at this stage, since ctfarchive gets it from the underlying object
-+# files and linking it further is a waste of time.
- # ---------------------------------------------------------------------------
- 
-+vmlinux-o-ld-args-$(CONFIG_BUILTIN_MODULE_RANGES)	+= -Map=$@.map
-+
- quiet_cmd_ld_vmlinux.o = LD      $@
-       cmd_ld_vmlinux.o = \
- 	$(LD) ${KBUILD_LDFLAGS} -r -o $@ \
--	$(addprefix -T , $(initcalls-lds)) \
-+	$(vmlinux-o-ld-args-y) \
-+	$(addprefix -T , $(initcalls-lds)) -T .tmp_remove-ctf.lds \
- 	--whole-archive vmlinux.a --no-whole-archive \
- 	--start-group $(KBUILD_VMLINUX_LIBS) --end-group \
- 	$(cmd_objtool)
-@@ -58,7 +75,7 @@ define rule_ld_vmlinux.o
- 	$(call cmd,gen_objtooldep)
- endef
- 
--vmlinux.o: $(initcalls-lds) vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE
-+vmlinux.o: $(initcalls-lds) vmlinux.a $(KBUILD_VMLINUX_LIBS) .tmp_remove-ctf.lds FORCE
- 	$(call if_changed_rule,ld_vmlinux.o)
- 
- targets += vmlinux.o
-@@ -87,6 +104,19 @@ targets += modules.builtin
- modules.builtin: modules.builtin.modinfo FORCE
- 	$(call if_changed,modules_builtin)
- 
-+# module.builtin.objs
-+# ---------------------------------------------------------------------------
-+quiet_cmd_modules_builtin_objs = GEN     $@
-+      cmd_modules_builtin_objs = \
-+	tr '\0' '\n' < $< | \
-+	sed -n 's/^[[:alnum:]:_]*\.objs=//p' | \
-+	tr ' ' '\n' | uniq | sed -e 's|:|: |' -e 's:|: :g' | \
-+	tr -s ' ' > $@
-+
-+targets += modules.builtin.objs
-+modules.builtin.objs: modules.builtin.modinfo FORCE
-+	$(call if_changed,modules_builtin_objs)
-+
- # Add FORCE to the prequisites of a target to force it to be always rebuilt.
- # ---------------------------------------------------------------------------
- 
-diff --git a/scripts/ctf/.gitignore b/scripts/ctf/.gitignore
-new file mode 100644
-index 0000000000000..6a0eb1c3ceeab
---- /dev/null
-+++ b/scripts/ctf/.gitignore
-@@ -0,0 +1 @@
-+ctfarchive
-diff --git a/scripts/ctf/Makefile b/scripts/ctf/Makefile
-new file mode 100644
-index 0000000000000..3b83f93bb9f9a
---- /dev/null
-+++ b/scripts/ctf/Makefile
-@@ -0,0 +1,5 @@
-+ifdef CONFIG_CTF
-+hostprogs-always-y	:= ctfarchive
-+ctfarchive-objs		:= ctfarchive.o modules_builtin.o
-+HOSTLDLIBS_ctfarchive := -lctf
-+endif
-diff --git a/scripts/ctf/ctfarchive.c b/scripts/ctf/ctfarchive.c
-new file mode 100644
-index 0000000000000..92cc4912ed0ee
---- /dev/null
-+++ b/scripts/ctf/ctfarchive.c
-@@ -0,0 +1,413 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * ctfmerge.c: Read in CTF extracted from generated object files from a
-+ * specified directory and generate a CTF archive whose members are the
-+ * deduplicated CTF derived from those object files, split up by kernel
-+ * module.
-+ *
-+ * Copyright (c) 2019, 2023, Oracle and/or its affiliates.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#define _GNU_SOURCE 1
-+#include <errno.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <ctf-api.h>
-+#include "modules_builtin.h"
-+
-+static ctf_file_t *output;
-+
-+static int private_ctf_link_add_ctf(ctf_file_t *fp,
-+				    const char *name)
-+{
-+#if !defined (CTF_LINK_FINAL)
-+	return ctf_link_add_ctf(fp, NULL, name);
-+#else
-+	/* Non-upstreamed, erroneously-broken API.  */
-+	return ctf_link_add_ctf(fp, NULL, name, NULL, 0);
-+#endif
-+}
-+
-+/*
-+ * Add a file to the link.
-+ */
-+static void add_to_link(const char *fn)
-+{
-+	if (private_ctf_link_add_ctf(output, fn) < 0)
-+	{
-+		fprintf(stderr, "Cannot add CTF file %s: %s\n", fn,
-+			ctf_errmsg(ctf_errno(output)));
-+		exit(1);
-+	}
-+}
-+
-+struct from_to
-+{
-+	char *from;
-+	char *to;
-+};
-+
-+/*
-+ * The world's stupidest hash table of FROM -> TO.
-+ */
-+static struct from_to **from_tos[256];
-+static size_t alloc_from_tos[256];
-+static size_t num_from_tos[256];
-+
-+static unsigned char from_to_hash(const char *from)
-+{
-+	unsigned char hval = 0;
-+
-+	const char *p;
-+	for (p = from; *p; p++)
-+		hval += *p;
-+
-+	return hval;
-+}
-+
-+/*
-+ * Note that we will need to add a CU mapping later on.
-+ *
-+ * Present purely to work around a binutils bug that stops
-+ * ctf_link_add_cu_mapping() working right when called repeatedly
-+ * with the same FROM.
-+ */
-+static int add_cu_mapping(const char *from, const char *to)
-+{
-+	ssize_t i, j;
-+
-+	i = from_to_hash(from);
-+
-+	for (j = 0; j < num_from_tos[i]; j++)
-+		if (strcmp(from, from_tos[i][j]->from) == 0) {
-+			char *tmp;
-+
-+			free(from_tos[i][j]->to);
-+			tmp = strdup(to);
-+			if (!tmp)
-+				goto oom;
-+			from_tos[i][j]->to = tmp;
-+			return 0;
-+		    }
-+
-+	if (num_from_tos[i] >= alloc_from_tos[i]) {
-+		struct from_to **tmp;
-+		if (alloc_from_tos[i] < 16)
-+			alloc_from_tos[i] = 16;
-+		else
-+			alloc_from_tos[i] *= 2;
-+
-+		tmp = realloc(from_tos[i], alloc_from_tos[i] * sizeof(struct from_to *));
-+		if (!tmp)
-+			goto oom;
-+
-+		from_tos[i] = tmp;
-+	}
-+
-+	j = num_from_tos[i];
-+	from_tos[i][j] = malloc(sizeof(struct from_to));
-+	if (from_tos[i][j] == NULL)
-+		goto oom;
-+	from_tos[i][j]->from = strdup(from);
-+	from_tos[i][j]->to = strdup(to);
-+	if (!from_tos[i][j]->from || !from_tos[i][j]->to)
-+		goto oom;
-+	num_from_tos[i]++;
-+
-+	return 0;
-+  oom:
-+	fprintf(stderr,
-+		"out of memory in add_cu_mapping\n");
-+	exit(1);
-+}
-+
-+/*
-+ * Finally tell binutils to add all the CU mappings, with duplicate FROMs
-+ * replaced with the most recent one.
-+ */
-+static void commit_cu_mappings(void)
-+{
-+	ssize_t i, j;
-+
-+	for (i = 0; i < 256; i++)
-+		for (j = 0; j < num_from_tos[i]; j++)
-+			ctf_link_add_cu_mapping(output, from_tos[i][j]->from,
-+						from_tos[i][j]->to);
-+}
-+
-+/*
-+ * Add a CU mapping to the link.
-+ *
-+ * CU mappings for built-in modules are added by suck_in_modules, below: here,
-+ * we only want to add mappings for names ending in '.ko.ctf', i.e. external
-+ * modules, which appear only in the filelist (since they are not built-in).
-+ * The pathnames are stripped off because modules don't have any, and hyphens
-+ * are translated into underscores.
-+ */
-+static void add_cu_mappings(const char *fn)
-+{
-+	const char *last_slash;
-+	const char *modname = fn;
-+	char *dynmodname = NULL;
-+	char *dash;
-+	size_t n;
-+
-+	last_slash = strrchr(modname, '/');
-+	if (last_slash)
-+		last_slash++;
-+	else
-+		last_slash = modname;
-+	modname = last_slash;
-+	if (strchr(modname, '-') != NULL)
-+	{
-+		dynmodname = strdup(last_slash);
-+		dash = dynmodname;
-+		while (dash != NULL) {
-+			dash = strchr(dash, '-');
-+			if (dash != NULL)
-+				*dash = '_';
-+		}
-+		modname = dynmodname;
-+	}
-+
-+	n = strlen(modname);
-+	if (strcmp(modname + n - strlen(".ko.ctf"), ".ko.ctf") == 0) {
-+		char *mod;
-+
-+		n -= strlen(".ko.ctf");
-+		mod = strndup(modname, n);
-+		add_cu_mapping(fn, mod);
-+		free(mod);
-+	}
-+	free(dynmodname);
-+}
-+
-+/*
-+ * Add the passed names as mappings to "vmlinux".
-+ */
-+static void add_builtins(const char *fn)
-+{
-+	if (add_cu_mapping(fn, "vmlinux") < 0)
-+	{
-+		fprintf(stderr, "Cannot add CTF CU mapping from %s to \"vmlinux\"\n",
-+			ctf_errmsg(ctf_errno(output)));
-+		exit(1);
-+	}
-+}
-+
-+/*
-+ * Do something with a file, line by line.
-+ */
-+static void suck_in_lines(const char *filename, void (*func)(const char *line))
-+{
-+	FILE *f;
-+	char *line = NULL;
-+	size_t line_size = 0;
-+
-+	f = fopen(filename, "r");
-+	if (f == NULL) {
-+		fprintf(stderr, "Cannot open %s: %s\n", filename,
-+			strerror(errno));
-+		exit(1);
-+	}
-+
-+	while (getline(&line, &line_size, f) >= 0) {
-+		size_t len = strlen(line);
-+
-+		if (len == 0)
-+			continue;
-+
-+		if (line[len-1] == '\n')
-+			line[len-1] = '\0';
-+
-+		func(line);
-+	}
-+	free(line);
-+
-+	if (ferror(f)) {
-+		fprintf(stderr, "Error reading from %s: %s\n", filename,
-+			strerror(errno));
-+		exit(1);
-+	}
-+
-+	fclose(f);
-+}
-+
-+/*
-+ * Pull in modules.builtin.objs and turn it into CU mappings.
-+ */
-+static void suck_in_modules(const char *modules_builtin_name)
-+{
-+	struct modules_builtin_iter *i;
-+	char *module_name = NULL;
-+	char **paths;
-+
-+	i = modules_builtin_iter_new(modules_builtin_name);
-+	if (i == NULL) {
-+		fprintf(stderr, "Cannot iterate over builtin module file.\n");
-+		exit(1);
-+	}
-+
-+	while ((paths = modules_builtin_iter_next(i, &module_name)) != NULL) {
-+		size_t j;
-+
-+		for (j = 0; paths[j] != NULL; j++) {
-+			char *alloc = NULL;
-+			char *path = paths[j];
-+			/*
-+			 * If the name doesn't start in ./, add it, to match the names
-+			 * passed to add_builtins.
-+			 */
-+			if (strncmp(paths[j], "./", 2) != 0) {
-+				char *p;
-+				if ((alloc = malloc(strlen(paths[j]) + 3)) == NULL) {
-+					fprintf(stderr, "Cannot allocate memory for "
-+						"builtin module object name %s.\n",
-+						paths[j]);
-+					exit(1);
-+				}
-+				p = alloc;
-+				p = stpcpy(p, "./");
-+				p = stpcpy(p, paths[j]);
-+				path = alloc;
-+			}
-+			if (add_cu_mapping(path, module_name) < 0) {
-+				fprintf(stderr, "Cannot add path -> module mapping for "
-+					"%s -> %s: %s\n", path, module_name,
-+					ctf_errmsg(ctf_errno(output)));
-+				exit(1);
-+			}
-+			free (alloc);
-+		}
-+		free(paths);
-+	}
-+	free(module_name);
-+	modules_builtin_iter_free(i);
-+}
-+
-+/*
-+ * Strip the leading .ctf. off all the module names: transform the default name
-+ * from _CTF_SECTION into shared_ctf, and chop any trailing .ctf off (since that
-+ * derives from the intermediate file used to keep the CTF out of the final
-+ * module).
-+ */
-+static char *transform_module_names(ctf_file_t *fp __attribute__((__unused__)),
-+				    const char *name,
-+				    void *arg __attribute__((__unused__)))
-+{
-+	if (strcmp(name, ".ctf") == 0)
-+		return strdup("shared_ctf");
-+
-+	if (strncmp(name, ".ctf", 4) == 0) {
-+		size_t n = strlen (name);
-+		if (strcmp(name + n - 4, ".ctf") == 0)
-+			n -= 4;
-+		return strndup(name + 4, n - 4);
-+	}
-+	return NULL;
-+}
-+
-+int main(int argc, char *argv[])
-+{
-+	int err;
-+	const char *output_file;
-+	unsigned char *file_data = NULL;
-+	size_t file_size;
-+	FILE *fp;
-+
-+	if (argc != 5) {
-+		fprintf(stderr, "Syntax: ctfarchive output-file objects.builtin modules.builtin\n");
-+		fprintf(stderr, "                   filelist\n");
-+		exit(1);
-+	}
-+
-+	output_file = argv[1];
-+
-+	/*
-+	 * First pull in the input files and add them to the link.
-+	 */
-+
-+	output = ctf_create(&err);
-+	if (!output) {
-+		fprintf(stderr, "Cannot create output CTF archive: %s\n",
-+			ctf_errmsg(err));
-+		return 1;
-+	}
-+
-+	suck_in_lines(argv[4], add_to_link);
-+
-+	/*
-+	 * Make sure that, even if all their types are shared, all modules have
-+	 * a ctf member that can be used as a child of the shared CTF.
-+	 */
-+	suck_in_lines(argv[4], add_cu_mappings);
-+
-+	/*
-+	 * Then pull in the builtin objects list and add them as
-+	 * mappings to "vmlinux".
-+	 */
-+
-+	suck_in_lines(argv[2], add_builtins);
-+
-+	/*
-+	 * Finally, pull in the object -> module mapping and add it
-+	 * as appropriate mappings.
-+	 */
-+	suck_in_modules(argv[3]);
-+
-+	/*
-+	 * Commit the added CU mappings.
-+	 */
-+	commit_cu_mappings();
-+
-+	/*
-+	 * Arrange to fix up the module names.
-+	 */
-+	ctf_link_set_memb_name_changer(output, transform_module_names, NULL);
-+
-+	/*
-+	 * Do the link.
-+	 */
-+	if (ctf_link(output, CTF_LINK_SHARE_DUPLICATED |
-+                     CTF_LINK_EMPTY_CU_MAPPINGS) < 0)
-+		goto ctf_err;
-+
-+	/*
-+	 * Write the output.
-+	 */
-+
-+	file_data = ctf_link_write(output, &file_size, 4096);
-+	if (!file_data)
-+		goto ctf_err;
-+
-+	fp = fopen(output_file, "w");
-+	if (!fp)
-+		goto err;
-+
-+	while ((err = fwrite(file_data, file_size, 1, fp)) == 0);
-+	if (ferror(fp)) {
-+		errno = ferror(fp);
-+		goto err;
-+	}
-+	if (fclose(fp) < 0)
-+		goto err;
-+	free(file_data);
-+	ctf_file_close(output);
-+
-+	return 0;
-+err:
-+	free(file_data);
-+	fprintf(stderr, "Cannot create output CTF archive: %s\n",
-+		strerror(errno));
-+	return 1;
-+ctf_err:
-+	fprintf(stderr, "Cannot create output CTF archive: %s\n",
-+		ctf_errmsg(ctf_errno(output)));
-+	return 1;
-+}
-diff --git a/scripts/ctf/modules_builtin.c b/scripts/ctf/modules_builtin.c
-new file mode 100644
-index 0000000000000..10af2bbc80e0c
---- /dev/null
-+++ b/scripts/ctf/modules_builtin.c
-@@ -0,0 +1,2 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#include "../modules_builtin.c"
-diff --git a/scripts/ctf/modules_builtin.h b/scripts/ctf/modules_builtin.h
-new file mode 100644
-index 0000000000000..5e0299e5600c2
---- /dev/null
-+++ b/scripts/ctf/modules_builtin.h
-@@ -0,0 +1,2 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#include "../modules_builtin.h"
-diff --git a/scripts/generate_builtin_ranges.awk b/scripts/generate_builtin_ranges.awk
-new file mode 100755
-index 0000000000000..51ae0458ffbdd
---- /dev/null
-+++ b/scripts/generate_builtin_ranges.awk
-@@ -0,0 +1,516 @@
-+#!/usr/bin/gawk -f
-+# SPDX-License-Identifier: GPL-2.0
-+# generate_builtin_ranges.awk: Generate address range data for builtin modules
-+# Written by Kris Van Hees <kris.van.hees@oracle.com>
-+#
-+# Usage: generate_builtin_ranges.awk modules.builtin vmlinux.map \
-+#		vmlinux.o.map [ <build-dir> ] > modules.builtin.ranges
-+#
-+
-+# Return the module name(s) (if any) associated with the given object.
-+#
-+# If we have seen this object before, return information from the cache.
-+# Otherwise, retrieve it from the corresponding .cmd file.
-+#
-+function get_module_info(fn, mod, obj, s) {
-+	if (fn in omod)
-+		return omod[fn];
-+
-+	if (match(fn, /\/[^/]+$/) == 0)
-+		return "";
-+
-+	obj = fn;
-+	mod = "";
-+	fn = kdir "/" substr(fn, 1, RSTART) "." substr(fn, RSTART + 1) ".cmd";
-+	if (getline s <fn == 1) {
-+		if (match(s, /DKBUILD_MODFILE=['"]+[^'"]+/) > 0) {
-+			mod = substr(s, RSTART + 16, RLENGTH - 16);
-+			gsub(/['"]/, "", mod);
-+		} else if (match(s, /RUST_MODFILE=[^ ]+/) > 0)
-+			mod = substr(s, RSTART + 13, RLENGTH - 13);
-+	}
-+	close(fn);
-+
-+	# A single module (common case) also reflects objects that are not part
-+	# of a module.  Some of those objects have names that are also a module
-+	# name (e.g. core).  We check the associated module file name, and if
-+	# they do not match, the object is not part of a module.
-+	if (mod !~ / /) {
-+		if (!(mod in mods))
-+			mod = "";
-+	}
-+
-+	gsub(/([^/ ]*\/)+/, "", mod);
-+	gsub(/-/, "_", mod);
-+
-+	# At this point, mod is a single (valid) module name, or a list of
-+	# module names (that do not need validation).
-+	omod[obj] = mod;
-+
-+	return mod;
-+}
-+
-+# Update the ranges entry for the given module 'mod' in section 'osect'.
-+#
-+# We use a modified absolute start address (soff + base) as index because we
-+# may need to insert an anchor record later that must be at the start of the
-+# section data, and the first module may very well start at the same address.
-+# So, we use (addr << 1) + 1 to allow a possible anchor record to be placed at
-+# (addr << 1).  This is safe because the index is only used to sort the entries
-+# before writing them out.
-+#
-+function update_entry(osect, mod, soff, eoff, sect, idx) {
-+	sect = sect_in[osect];
-+	idx = (soff + sect_base[osect]) * 2 + 1;
-+	entries[idx] = sprintf("%s %08x-%08x %s", sect, soff, eoff, mod);
-+	count[sect]++;
-+}
-+
-+# Determine the kernel build directory to use (default is .).
-+#
-+BEGIN {
-+	if (ARGC > 4) {
-+		kdir = ARGV[ARGC - 1];
-+		ARGV[ARGC - 1] = "";
-+	} else
-+		kdir = ".";
-+}
-+
-+# (1) Build a lookup map of built-in module names.
-+#
-+# The first file argument is used as input (modules.builtin).
-+#
-+# Lines will be like:
-+#	kernel/crypto/lzo-rle.ko
-+# and we record the object name "crypto/lzo-rle".
-+#
-+ARGIND == 1 {
-+	sub(/kernel\//, "");			# strip off "kernel/" prefix
-+	sub(/\.ko$/, "");			# strip off .ko suffix
-+
-+	mods[$1] = 1;
-+	next;
-+}
-+
-+# (2) Collect address information for each section.
-+#
-+# The second file argument is used as input (vmlinux.map).
-+#
-+# We collect the base address of the section in order to convert all addresses
-+# in the section into offset values.
-+#
-+# We collect the address of the anchor (or first symbol in the section if there
-+# is no explicit anchor) to allow users of the range data to calculate address
-+# ranges based on the actual load address of the section in the running kernel.
-+#
-+# We collect the start address of any sub-section (section included in the top
-+# level section being processed).  This is needed when the final linking was
-+# done using vmlinux.a because then the list of objects contained in each
-+# section is to be obtained from vmlinux.o.map.  The offset of the sub-section
-+# is recorded here, to be used as an addend when processing vmlinux.o.map
-+# later.
-+#
-+
-+# Both GNU ld and LLVM lld linker map format are supported by converting LLVM
-+# lld linker map records into equivalent GNU ld linker map records.
-+#
-+# The first record of the vmlinux.map file provides enough information to know
-+# which format we are dealing with.
-+#
-+ARGIND == 2 && FNR == 1 && NF == 7 && $1 == "VMA" && $7 == "Symbol" {
-+	map_is_lld = 1;
-+	if (dbg)
-+		printf "NOTE: %s uses LLVM lld linker map format\n", FILENAME >"/dev/stderr";
-+	next;
-+}
-+
-+# (LLD) Convert a section record fronm lld format to ld format.
-+#
-+# lld: ffffffff82c00000          2c00000   2493c0  8192 .data
-+#  ->
-+# ld:  .data           0xffffffff82c00000   0x2493c0 load address 0x0000000002c00000
-+#
-+ARGIND == 2 && map_is_lld && NF == 5 && /[0-9] [^ ]+$/ {
-+	$0 = $5 " 0x"$1 " 0x"$3 " load address 0x"$2;
-+}
-+
-+# (LLD) Convert an anchor record from lld format to ld format.
-+#
-+# lld: ffffffff81000000          1000000        0     1         _text = .
-+#  ->
-+# ld:                  0xffffffff81000000                _text = .
-+#
-+ARGIND == 2 && map_is_lld && !anchor && NF == 7 && raw_addr == "0x"$1 && $6 == "=" && $7 == "." {
-+	$0 = "  0x"$1 " " $5 " = .";
-+}
-+
-+# (LLD) Convert an object record from lld format to ld format.
-+#
-+# lld:            11480            11480     1f07    16         vmlinux.a(arch/x86/events/amd/uncore.o):(.text)
-+#  ->
-+# ld:   .text          0x0000000000011480     0x1f07 arch/x86/events/amd/uncore.o
-+#
-+ARGIND == 2 && map_is_lld && NF == 5 && $5 ~ /:\(/ {
-+	gsub(/\)/, "");
-+	sub(/ vmlinux\.a\(/, " ");
-+	sub(/:\(/, " ");
-+	$0 = " "$6 " 0x"$1 " 0x"$3 " " $5;
-+}
-+
-+# (LLD) Convert a symbol record from lld format to ld format.
-+#
-+# We only care about these while processing a section for which no anchor has
-+# been determined yet.
-+#
-+# lld: ffffffff82a859a4          2a859a4        0     1                 btf_ksym_iter_id
-+#  ->
-+# ld:                  0xffffffff82a859a4                btf_ksym_iter_id
-+#
-+ARGIND == 2 && map_is_lld && sect && !anchor && NF == 5 && $5 ~ /^[_A-Za-z][_A-Za-z0-9]*$/ {
-+	$0 = "  0x"$1 " " $5;
-+}
-+
-+# (LLD) We do not need any other ldd linker map records.
-+#
-+ARGIND == 2 && map_is_lld && /^[0-9a-f]{16} / {
-+	next;
-+}
-+
-+# (LD) Section records with just the section name at the start of the line
-+#      need to have the next line pulled in to determine whether it is a
-+#      loadable section.  If it is, the next line will contains a hex value
-+#      as first and second items.
-+#
-+ARGIND == 2 && !map_is_lld && NF == 1 && /^[^ ]/ {
-+	s = $0;
-+	getline;
-+	if ($1 !~ /^0x/ || $2 !~ /^0x/)
-+		next;
-+
-+	$0 = s " " $0;
-+}
-+
-+# (LD) Object records with just the section name denote records with a long
-+#      section name for which the remainder of the record can be found on the
-+#      next line.
-+#
-+# (This is also needed for vmlinux.o.map, when used.)
-+#
-+ARGIND >= 2 && !map_is_lld && NF == 1 && /^ [^ \*]/ {
-+	s = $0;
-+	getline;
-+	$0 = s " " $0;
-+}
-+
-+# Beginning a new section - done with the previous one (if any).
-+#
-+ARGIND == 2 && /^[^ ]/ {
-+	sect = 0;
-+}
-+
-+# Process a loadable section (we only care about .-sections).
-+#
-+# Record the section name and its base address.
-+# We also record the raw (non-stripped) address of the section because it can
-+# be used to identify an anchor record.
-+#
-+# Note:
-+# Since some AWK implementations cannot handle large integers, we strip off the
-+# first 4 hex digits from the address.  This is safe because the kernel space
-+# is not large enough for addresses to extend into those digits.  The portion
-+# to strip off is stored in addr_prefix as a regexp, so further clauses can
-+# perform a simple substitution to do the address stripping.
-+#
-+ARGIND == 2 && /^\./ {
-+	# Explicitly ignore a few sections that are not relevant here.
-+	if ($1 ~ /^\.orc_/ || $1 ~ /_sites$/ || $1 ~ /\.percpu/)
-+		next;
-+
-+	# Sections with a 0-address can be ignored as well.
-+	if ($2 ~ /^0x0+$/)
-+		next;
-+
-+	raw_addr = $2;
-+	addr_prefix = "^" substr($2, 1, 6);
-+	base = $2;
-+	sub(addr_prefix, "0x", base);
-+	base = strtonum(base);
-+	sect = $1;
-+	anchor = 0;
-+	sect_base[sect] = base;
-+	sect_size[sect] = strtonum($3);
-+
-+	if (dbg)
-+		printf "[%s] BASE   %016x\n", sect, base >"/dev/stderr";
-+
-+	next;
-+}
-+
-+# If we are not in a section we care about, we ignore the record.
-+#
-+ARGIND == 2 && !sect {
-+	next;
-+}
-+
-+# Record the first anchor symbol for the current section.
-+#
-+# An anchor record for the section bears the same raw address as the section
-+# record.
-+#
-+ARGIND == 2 && !anchor && NF == 4 && raw_addr == $1 && $3 == "=" && $4 == "." {
-+	anchor = sprintf("%s %08x-%08x = %s", sect, 0, 0, $2);
-+	sect_anchor[sect] = anchor;
-+
-+	if (dbg)
-+		printf "[%s] ANCHOR %016x = %s (.)\n", sect, 0, $2 >"/dev/stderr";
-+
-+	next;
-+}
-+
-+# If no anchor record was found for the current section, use the first symbol
-+# in the section as anchor.
-+#
-+ARGIND == 2 && !anchor && NF == 2 && $1 ~ /^0x/ && $2 !~ /^0x/ {
-+	addr = $1;
-+	sub(addr_prefix, "0x", addr);
-+	addr = strtonum(addr) - base;
-+	anchor = sprintf("%s %08x-%08x = %s", sect, addr, addr, $2);
-+	sect_anchor[sect] = anchor;
-+
-+	if (dbg)
-+		printf "[%s] ANCHOR %016x = %s\n", sect, addr, $2 >"/dev/stderr";
-+
-+	next;
-+}
-+
-+# The first occurrence of a section name in an object record establishes the
-+# addend (often 0) for that section.  This information is needed to handle
-+# sections that get combined in the final linking of vmlinux (e.g. .head.text
-+# getting included at the start of .text).
-+#
-+# If the section does not have a base yet, use the base of the encapsulating
-+# section.
-+#
-+ARGIND == 2 && sect && NF == 4 && /^ [^ \*]/ && !($1 in sect_addend) {
-+	if (!($1 in sect_base)) {
-+		sect_base[$1] = base;
-+
-+		if (dbg)
-+			printf "[%s] BASE   %016x\n", $1, base >"/dev/stderr";
-+	}
-+
-+	addr = $2;
-+	sub(addr_prefix, "0x", addr);
-+	addr = strtonum(addr);
-+	sect_addend[$1] = addr - sect_base[$1];
-+	sect_in[$1] = sect;
-+
-+	if (dbg)
-+		printf "[%s] ADDEND %016x - %016x = %016x\n",  $1, addr, base, sect_addend[$1] >"/dev/stderr";
-+
-+	# If the object is vmlinux.o then we will need vmlinux.o.map to get the
-+	# actual offsets of objects.
-+	if ($4 == "vmlinux.o")
-+		need_o_map = 1;
-+}
-+
-+# (3) Collect offset ranges (relative to the section base address) for built-in
-+# modules.
-+#
-+# If the final link was done using the actual objects, vmlinux.map contains all
-+# the information we need (see section (3a)).
-+# If linking was done using vmlinux.a as intermediary, we will need to process
-+# vmlinux.o.map (see section (3b)).
-+
-+# (3a) Determine offset range info using vmlinux.map.
-+#
-+# Since we are already processing vmlinux.map, the top level section that is
-+# being processed is already known.  If we do not have a base address for it,
-+# we do not need to process records for it.
-+#
-+# Given the object name, we determine the module(s) (if any) that the current
-+# object is associated with.
-+#
-+# If we were already processing objects for a (list of) module(s):
-+#  - If the current object belongs to the same module(s), update the range data
-+#    to include the current object.
-+#  - Otherwise, ensure that the end offset of the range is valid.
-+#
-+# If the current object does not belong to a built-in module, ignore it.
-+#
-+# If it does, we add a new built-in module offset range record.
-+#
-+ARGIND == 2 && !need_o_map && /^ [^ ]/ && NF == 4 && $3 != "0x0" {
-+	if (!(sect in sect_base))
-+		next;
-+
-+	# Turn the address into an offset from the section base.
-+	soff = $2;
-+	sub(addr_prefix, "0x", soff);
-+	soff = strtonum(soff) - sect_base[sect];
-+	eoff = soff + strtonum($3);
-+
-+	# Determine which (if any) built-in modules the object belongs to.
-+	mod = get_module_info($4);
-+
-+	# If we are processing a built-in module:
-+	#   - If the current object is within the same module, we update its
-+	#     entry by extending the range and move on
-+	#   - Otherwise:
-+	#       + If we are still processing within the same main section, we
-+	#         validate the end offset against the start offset of the
-+	#         current object (e.g. .rodata.str1.[18] objects are often
-+	#         listed with an incorrect size in the linker map)
-+	#       + Otherwise, we validate the end offset against the section
-+	#         size
-+	if (mod_name) {
-+		if (mod == mod_name) {
-+			mod_eoff = eoff;
-+			update_entry(mod_sect, mod_name, mod_soff, eoff);
-+
-+			next;
-+		} else if (sect == sect_in[mod_sect]) {
-+			if (mod_eoff > soff)
-+				update_entry(mod_sect, mod_name, mod_soff, soff);
-+		} else {
-+			v = sect_size[sect_in[mod_sect]];
-+			if (mod_eoff > v)
-+				update_entry(mod_sect, mod_name, mod_soff, v);
-+		}
-+	}
-+
-+	mod_name = mod;
-+
-+	# If we encountered an object that is not part of a built-in module, we
-+	# do not need to record any data.
-+	if (!mod)
-+		next;
-+
-+	# At this point, we encountered the start of a new built-in module.
-+	mod_name = mod;
-+	mod_soff = soff;
-+	mod_eoff = eoff;
-+	mod_sect = $1;
-+	update_entry($1, mod, soff, mod_eoff);
-+
-+	next;
-+}
-+
-+# If we do not need to parse the vmlinux.o.map file, we are done.
-+#
-+ARGIND == 3 && !need_o_map {
-+	if (dbg)
-+		printf "Note: %s is not needed.\n", FILENAME >"/dev/stderr";
-+	exit;
-+}
-+
-+# (3) Collect offset ranges (relative to the section base address) for built-in
-+# modules.
-+#
-+
-+# (LLD) Convert an object record from lld format to ld format.
-+#
-+ARGIND == 3 && map_is_lld && NF == 5 && $5 ~ /:\(/ {
-+	gsub(/\)/, "");
-+	sub(/:\(/, " ");
-+
-+	sect = $6;
-+	if (!(sect in sect_addend))
-+		next;
-+
-+	sub(/ vmlinux\.a\(/, " ");
-+	$0 = " "sect " 0x"$1 " 0x"$3 " " $5;
-+}
-+
-+# (3b) Determine offset range info using vmlinux.o.map.
-+#
-+# If we do not know an addend for the object's section, we are interested in
-+# anything within that section.
-+#
-+# Determine the top-level section that the object's section was included in
-+# during the final link.  This is the section name offset range data will be
-+# associated with for this object.
-+#
-+# The remainder of the processing of the current object record follows the
-+# procedure outlined in (3a).
-+#
-+ARGIND == 3 && /^ [^ ]/ && NF == 4 && $3 != "0x0" {
-+	osect = $1;
-+	if (!(osect in sect_addend))
-+		next;
-+
-+	# We need to work with the main section.
-+	sect = sect_in[osect];
-+
-+	# Turn the address into an offset from the section base.
-+	soff = $2;
-+	sub(addr_prefix, "0x", soff);
-+	soff = strtonum(soff) + sect_addend[osect];
-+	eoff = soff + strtonum($3);
-+
-+	# Determine which (if any) built-in modules the object belongs to.
-+	mod = get_module_info($4);
-+
-+	# If we are processing a built-in module:
-+	#   - If the current object is within the same module, we update its
-+	#     entry by extending the range and move on
-+	#   - Otherwise:
-+	#       + If we are still processing within the same main section, we
-+	#         validate the end offset against the start offset of the
-+	#         current object (e.g. .rodata.str1.[18] objects are often
-+	#         listed with an incorrect size in the linker map)
-+	#       + Otherwise, we validate the end offset against the section
-+	#         size
-+	if (mod_name) {
-+		if (mod == mod_name) {
-+			mod_eoff = eoff;
-+			update_entry(mod_sect, mod_name, mod_soff, eoff);
-+
-+			next;
-+		} else if (sect == sect_in[mod_sect]) {
-+			if (mod_eoff > soff)
-+				update_entry(mod_sect, mod_name, mod_soff, soff);
-+		} else {
-+			v = sect_size[sect_in[mod_sect]];
-+			if (mod_eoff > v)
-+				update_entry(mod_sect, mod_name, mod_soff, v);
-+		}
-+	}
-+
-+	mod_name = mod;
-+
-+	# If we encountered an object that is not part of a built-in module, we
-+	# do not need to record any data.
-+	if (!mod)
-+		next;
-+
-+	# At this point, we encountered the start of a new built-in module.
-+	mod_name = mod;
-+	mod_soff = soff;
-+	mod_eoff = eoff;
-+	mod_sect = osect;
-+	update_entry(osect, mod, soff, mod_eoff);
-+
-+	next;
-+}
-+
-+# (4) Generate the output.
-+#
-+# Anchor records are added for each section that contains offset range data
-+# records.  They are added at an adjusted section base address (base << 1) to
-+# ensure they come first in the second records (see update_entry() above for
-+# more information).
-+#
-+# All entries are sorted by (adjusted) address to ensure that the output can be
-+# parsed in strict ascending address order.
-+#
-+END {
-+	for (sect in count) {
-+		if (sect in sect_anchor)
-+			entries[sect_base[sect] * 2] = sect_anchor[sect];
-+	}
-+
-+	n = asorti(entries, indices);
-+	for (i = 1; i <= n; i++)
-+		print entries[indices[i]];
-+}
-diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
-index f48d72d22dc2a..d7e6cd7781256 100644
---- a/scripts/mod/modpost.c
-+++ b/scripts/mod/modpost.c
-@@ -733,6 +733,7 @@ static const char *const section_white_list[] =
- 	".comment*",
- 	".debug*",
- 	".zdebug*",		/* Compressed debug sections. */
-+        ".ctf",			/* Type info */
- 	".GCC.command.line",	/* record-gcc-switches */
- 	".mdebug*",        /* alpha, score, mips etc. */
- 	".pdr",            /* alpha, score, mips etc. */
-diff --git a/scripts/modules_builtin.c b/scripts/modules_builtin.c
-new file mode 100644
-index 0000000000000..df52932a4417b
---- /dev/null
-+++ b/scripts/modules_builtin.c
-@@ -0,0 +1,200 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * A simple modules_builtin reader.
-+ *
-+ * (C) 2014, 2022 Oracle, Inc.  All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#include <errno.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#include "modules_builtin.h"
-+
-+/*
-+ * Read a modules.builtin.objs file and translate it into a stream of
-+ * name / module-name pairs.
-+ */
-+
-+/*
-+ * Construct a modules.builtin.objs iterator.
-+ */
-+struct modules_builtin_iter *
-+modules_builtin_iter_new(const char *modules_builtin_file)
-+{
-+	struct modules_builtin_iter *i;
-+
-+	i = calloc(1, sizeof(struct modules_builtin_iter));
-+	if (i == NULL)
-+		return NULL;
-+
-+	i->f = fopen(modules_builtin_file, "r");
-+
-+	if (i->f == NULL) {
-+		fprintf(stderr, "Cannot open builtin module file %s: %s\n",
-+			modules_builtin_file, strerror(errno));
-+		return NULL;
-+	}
-+
-+	return i;
-+}
-+
-+/*
-+ * Iterate, returning a new null-terminated array of object file names, and a
-+ * new dynamically-allocated module name.  (The module name passed in is freed.)
-+ *
-+ * The array of object file names should be freed by the caller: the strings it
-+ * points to are owned by the iterator, and should not be freed.
-+ */
-+
-+char ** __attribute__((__nonnull__))
-+modules_builtin_iter_next(struct modules_builtin_iter *i, char **module_name)
-+{
-+	size_t npaths = 1;
-+	char **module_paths;
-+	char *last_slash;
-+	char *last_dot;
-+	char *trailing_linefeed;
-+	char *object_name = i->line;
-+	char *dash;
-+	int composite = 0;
-+
-+	/*
-+	 * Read in all module entries, computing the suffixless, pathless name
-+	 * of the module and building the next arrayful of object file names for
-+	 * return.
-+	 *
-+	 * Modules can consist of multiple files: in this case, the portion
-+	 * before the colon is the path to the module (as before): the portion
-+	 * after the colon is a space-separated list of files that should be
-+	 * considered part of this module.  In this case, the portion before the
-+	 * name is an "object file" that does not actually exist: it is merged
-+	 * into built-in.a without ever being written out.
-+	 *
-+	 * All module names have - translated to _, to match what is done to the
-+	 * names of the same things when built as modules.
-+	 */
-+
-+	/*
-+	 * Reinvocation of exhausted iterator. Return NULL, once.
-+	 */
-+retry:
-+	if (getline(&i->line, &i->line_size, i->f) < 0) {
-+		if (ferror(i->f)) {
-+			fprintf(stderr, "Error reading from modules_builtin file:"
-+				" %s\n", strerror(errno));
-+			exit(1);
-+		}
-+		rewind(i->f);
-+		return NULL;
-+	}
-+
-+	if (i->line[0] == '\0')
-+		goto retry;
-+
-+	trailing_linefeed = strchr(i->line, '\n');
-+	if (trailing_linefeed != NULL)
-+		*trailing_linefeed = '\0';
-+
-+	/*
-+	 * Slice the line in two at the colon, if any.  If there is anything
-+	 * past the ': ', this is a composite module.  (We allow for no colon
-+	 * for robustness, even though one should always be present.)
-+	 */
-+	if (strchr(i->line, ':') != NULL) {
-+		char *name_start;
-+
-+		object_name = strchr(i->line, ':');
-+		*object_name = '\0';
-+		object_name++;
-+		name_start = object_name + strspn(object_name, " \n");
-+		if (*name_start != '\0') {
-+			composite = 1;
-+			object_name = name_start;
-+		}
-+	}
-+
-+	/*
-+	 * Figure out the module name.
-+	 */
-+	last_slash = strrchr(i->line, '/');
-+	last_slash = (!last_slash) ? i->line :
-+		last_slash + 1;
-+	free(*module_name);
-+	*module_name = strdup(last_slash);
-+	dash = *module_name;
-+
-+	while (dash != NULL) {
-+		dash = strchr(dash, '-');
-+		if (dash != NULL)
-+			*dash = '_';
-+	}
-+
-+	last_dot = strrchr(*module_name, '.');
-+	if (last_dot != NULL)
-+		*last_dot = '\0';
-+
-+	/*
-+	 * Multifile separator? Object file names explicitly stated:
-+	 * slice them up and shuffle them in.
-+	 *
-+	 * The array size may be an overestimate if any object file
-+	 * names start or end with spaces (very unlikely) but cannot be
-+	 * an underestimate.  (Check for it anyway.)
-+	 */
-+	if (composite) {
-+		char *one_object;
-+
-+		for (npaths = 0, one_object = object_name;
-+		     one_object != NULL;
-+		     npaths++, one_object = strchr(one_object + 1, ' '));
-+	}
-+
-+	module_paths = malloc((npaths + 1) * sizeof(char *));
-+	if (!module_paths) {
-+		fprintf(stderr, "%s: out of memory on module %s\n", __func__,
-+			*module_name);
-+		exit(1);
-+	}
-+
-+	if (composite) {
-+		char *one_object;
-+		size_t i = 0;
-+
-+		while ((one_object = strsep(&object_name, " ")) != NULL) {
-+			if (i >= npaths) {
-+				fprintf(stderr, "%s: num_objs overflow on module "
-+					"%s: this is a bug.\n", __func__,
-+					*module_name);
-+				exit(1);
-+			}
-+
-+			module_paths[i++] = one_object;
-+		}
-+	} else
-+		module_paths[0] = i->line;	/* untransformed module name */
-+
-+	module_paths[npaths] = NULL;
-+
-+	return module_paths;
-+}
-+
-+/*
-+ * Free an iterator. Can be called while iteration is underway, so even
-+ * state that is freed at the end of iteration must be freed here too.
-+ */
-+void
-+modules_builtin_iter_free(struct modules_builtin_iter *i)
-+{
-+	if (i == NULL)
-+		return;
-+	fclose(i->f);
-+	free(i->line);
-+	free(i);
-+}
-diff --git a/scripts/modules_builtin.h b/scripts/modules_builtin.h
-new file mode 100644
-index 0000000000000..5138792b42ef0
---- /dev/null
-+++ b/scripts/modules_builtin.h
-@@ -0,0 +1,48 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * A simple modules.builtin.objs reader.
-+ *
-+ * (C) 2014, 2022 Oracle, Inc.  All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#ifndef _LINUX_MODULES_BUILTIN_H
-+#define _LINUX_MODULES_BUILTIN_H
-+
-+#include <stdio.h>
-+#include <stddef.h>
-+
-+/*
-+ * modules.builtin.objs iteration state.
-+ */
-+struct modules_builtin_iter {
-+	FILE *f;
-+	char *line;
-+	size_t line_size;
-+};
-+
-+/*
-+ * Construct a modules_builtin.objs iterator.
-+ */
-+struct modules_builtin_iter *
-+modules_builtin_iter_new(const char *modules_builtin_file);
-+
-+/*
-+ * Iterate, returning a new null-terminated array of object file names, and a
-+ * new dynamically-allocated module name.  (The module name passed in is freed.)
-+ *
-+ * The array of object file names should be freed by the caller: the strings it
-+ * points to are owned by the iterator, and should not be freed.
-+ */
-+
-+char ** __attribute__((__nonnull__))
-+modules_builtin_iter_next(struct modules_builtin_iter *i, char **module_name);
-+
-+void
-+modules_builtin_iter_free(struct modules_builtin_iter *i);
-+
-+#endif
-diff --git a/scripts/package/kernel.spec b/scripts/package/kernel.spec
-index c52d517b93647..8f75906a96314 100644
---- a/scripts/package/kernel.spec
-+++ b/scripts/package/kernel.spec
-@@ -53,12 +53,18 @@ patch -p1 < %{SOURCE2}
- 
- %build
- %{make} %{makeflags} KERNELRELEASE=%{KERNELRELEASE} KBUILD_BUILD_VERSION=%{release}
-+%if %{with_ctf}
-+%{make} %{makeflags} KERNELRELEASE=%{KERNELRELEASE} KBUILD_BUILD_VERSION=%{release} ctf
-+%endif
- 
- %install
- mkdir -p %{buildroot}/lib/modules/%{KERNELRELEASE}
- cp $(%{make} %{makeflags} -s image_name) %{buildroot}/lib/modules/%{KERNELRELEASE}/vmlinuz
- # DEPMOD=true makes depmod no-op. We do not package depmod-generated files.
- %{make} %{makeflags} INSTALL_MOD_PATH=%{buildroot} DEPMOD=true modules_install
-+%if %{with_ctf}
-+%{make} %{makeflags} INSTALL_MOD_PATH=%{buildroot} ctf_install
-+%endif
- %{make} %{makeflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
- cp System.map %{buildroot}/lib/modules/%{KERNELRELEASE}
- cp .config %{buildroot}/lib/modules/%{KERNELRELEASE}/config
-diff --git a/scripts/package/mkspec b/scripts/package/mkspec
-index ce201bfa8377c..aeb43c7ab1229 100755
---- a/scripts/package/mkspec
-+++ b/scripts/package/mkspec
-@@ -21,10 +21,16 @@ else
- echo '%define with_devel 0'
- fi
- 
-+if grep -q CONFIG_CTF=y include/config/auto.conf; then
-+echo '%define with_ctf %{?_without_ctf: 0} %{?!_without_ctf: 1}'
-+else
-+echo '%define with_ctf 0'
-+fi
- cat<<EOF
- %define ARCH ${ARCH}
- %define KERNELRELEASE ${KERNELRELEASE}
- %define pkg_release $("${srctree}/init/build-version")
-+
- EOF
- 
- cat "${srctree}/scripts/package/kernel.spec"
-diff --git a/scripts/remove-ctf-lds.awk b/scripts/remove-ctf-lds.awk
-new file mode 100644
-index 0000000000000..5d94d6ee99227
---- /dev/null
-+++ b/scripts/remove-ctf-lds.awk
-@@ -0,0 +1,12 @@
-+# SPDX-License-Identifier: GPL-2.0
-+# See Makefile.vmlinux_o
-+
-+BEGIN {
-+    discards = 0; p = 0
-+}
-+
-+/^====/ { p = 1; next; }
-+p && /\.ctf/ { next; }
-+p && !discards && /DISCARD/ { sub(/\} *$/, " *(.ctf) }"); discards = 1 }
-+p && /^\}/ && !discards { print "  /DISCARD/ : { *(.ctf) }"; }
-+p { print $0; }
-diff --git a/scripts/verify_builtin_ranges.awk b/scripts/verify_builtin_ranges.awk
-new file mode 100755
-index 0000000000000..f513841da83e1
---- /dev/null
-+++ b/scripts/verify_builtin_ranges.awk
-@@ -0,0 +1,356 @@
-+#!/usr/bin/gawk -f
-+# SPDX-License-Identifier: GPL-2.0
-+# verify_builtin_ranges.awk: Verify address range data for builtin modules
-+# Written by Kris Van Hees <kris.van.hees@oracle.com>
-+#
-+# Usage: verify_builtin_ranges.awk modules.builtin.ranges System.map \
-+#				   modules.builtin vmlinux.map vmlinux.o.map \
-+#				   [ <build-dir> ]
-+#
-+
-+# Return the module name(s) (if any) associated with the given object.
-+#
-+# If we have seen this object before, return information from the cache.
-+# Otherwise, retrieve it from the corresponding .cmd file.
-+#
-+function get_module_info(fn, mod, obj, s) {
-+	if (fn in omod)
-+		return omod[fn];
-+
-+	if (match(fn, /\/[^/]+$/) == 0)
-+		return "";
-+
-+	obj = fn;
-+	mod = "";
-+	fn = kdir "/" substr(fn, 1, RSTART) "." substr(fn, RSTART + 1) ".cmd";
-+	if (getline s <fn == 1) {
-+		if (match(s, /DKBUILD_MODFILE=['"]+[^'"]+/) > 0) {
-+			mod = substr(s, RSTART + 16, RLENGTH - 16);
-+			gsub(/['"]/, "", mod);
-+		} else if (match(s, /RUST_MODFILE=[^ ]+/) > 0)
-+			mod = substr(s, RSTART + 13, RLENGTH - 13);
-+	} else {
-+		print "ERROR: Failed to read: " fn "\n\n" \
-+		      "  Invalid kernel build directory (" kdir ")\n" \
-+		      "  or its content does not match " ARGV[1] >"/dev/stderr";
-+		close(fn);
-+		total = 0;
-+		exit(1);
-+	}
-+	close(fn);
-+
-+	# A single module (common case) also reflects objects that are not part
-+	# of a module.  Some of those objects have names that are also a module
-+	# name (e.g. core).  We check the associated module file name, and if
-+	# they do not match, the object is not part of a module.
-+	if (mod !~ / /) {
-+		if (!(mod in mods))
-+			mod = "";
-+	}
-+
-+	gsub(/([^/ ]*\/)+/, "", mod);
-+	gsub(/-/, "_", mod);
-+
-+	# At this point, mod is a single (valid) module name, or a list of
-+	# module names (that do not need validation).
-+	omod[obj] = mod;
-+
-+	return mod;
-+}
-+
-+# Return a representative integer value for a given hexadecimal address.
-+#
-+# Since all kernel addresses fall within the same memory region, we can safely
-+# strip off the first 6 hex digits before performing the hex-to-dec conversion,
-+# thereby avoiding integer overflows.
-+#
-+function addr2val(val) {
-+	sub(/^0x/, "", val);
-+	if (length(val) == 16)
-+		val = substr(val, 5);
-+	return strtonum("0x" val);
-+}
-+
-+# Determine the kernel build directory to use (default is .).
-+#
-+BEGIN {
-+	if (ARGC > 6) {
-+		kdir = ARGV[ARGC - 1];
-+		ARGV[ARGC - 1] = "";
-+	} else
-+		kdir = ".";
-+}
-+
-+# (1) Load the built-in module address range data.
-+#
-+ARGIND == 1 {
-+	ranges[FNR] = $0;
-+	rcnt++;
-+	next;
-+}
-+
-+# (2) Annotate System.map symbols with module names.
-+#
-+ARGIND == 2 {
-+	addr = addr2val($1);
-+	name = $3;
-+
-+	while (addr >= mod_eaddr) {
-+		if (sect_symb) {
-+			if (sect_symb != name)
-+				next;
-+
-+			sect_base = addr - sect_off;
-+			if (dbg)
-+				printf "[%s] BASE (%s) %016x - %016x = %016x\n", sect_name, sect_symb, addr, sect_off, sect_base >"/dev/stderr";
-+			sect_symb = 0;
-+		}
-+
-+		if (++ridx > rcnt)
-+			break;
-+
-+		$0 = ranges[ridx];
-+		sub(/-/, " ");
-+		if ($4 != "=") {
-+			sub(/-/, " ");
-+			mod_saddr = strtonum("0x" $2) + sect_base;
-+			mod_eaddr = strtonum("0x" $3) + sect_base;
-+			$1 = $2 = $3 = "";
-+			sub(/^ +/, "");
-+			mod_name = $0;
-+
-+			if (dbg)
-+				printf "[%s] %s from %016x to %016x\n", sect_name, mod_name, mod_saddr, mod_eaddr >"/dev/stderr";
-+		} else {
-+			sect_name = $1;
-+			sect_off = strtonum("0x" $2);
-+			sect_symb = $5;
-+		}
-+	}
-+
-+	idx = addr"-"name;
-+	if (addr >= mod_saddr && addr < mod_eaddr)
-+		sym2mod[idx] = mod_name;
-+
-+	next;
-+}
-+
-+# Once we are done annotating the System.map, we no longer need the ranges data.
-+#
-+FNR == 1 && ARGIND == 3 {
-+	delete ranges;
-+}
-+
-+# (3) Build a lookup map of built-in module names.
-+#
-+# Lines from modules.builtin will be like:
-+#	kernel/crypto/lzo-rle.ko
-+# and we record the object name "crypto/lzo-rle".
-+#
-+ARGIND == 3 {
-+	sub(/kernel\//, "");			# strip off "kernel/" prefix
-+	sub(/\.ko$/, "");			# strip off .ko suffix
-+
-+	mods[$1] = 1;
-+	next;
-+}
-+
-+# (4) Get a list of symbols (per object).
-+#
-+# Symbols by object are read from vmlinux.map, with fallback to vmlinux.o.map
-+# if vmlinux is found to have inked in vmlinux.o.
-+#
-+
-+# If we were able to get the data we need from vmlinux.map, there is no need to
-+# process vmlinux.o.map.
-+#
-+FNR == 1 && ARGIND == 5 && total > 0 {
-+	if (dbg)
-+		printf "Note: %s is not needed.\n", FILENAME >"/dev/stderr";
-+	exit;
-+}
-+
-+# First determine whether we are dealing with a GNU ld or LLVM lld linker map.
-+#
-+ARGIND >= 4 && FNR == 1 && NF == 7 && $1 == "VMA" && $7 == "Symbol" {
-+	map_is_lld = 1;
-+	next;
-+}
-+
-+# (LLD) Convert a section record fronm lld format to ld format.
-+#
-+ARGIND >= 4 && map_is_lld && NF == 5 && /[0-9] [^ ]/ {
-+	$0 = $5 " 0x"$1 " 0x"$3 " load address 0x"$2;
-+}
-+
-+# (LLD) Convert an object record from lld format to ld format.
-+#
-+ARGIND >= 4 && map_is_lld && NF == 5 && $5 ~ /:\(\./ {
-+	gsub(/\)/, "");
-+	sub(/:\(/, " ");
-+	sub(/ vmlinux\.a\(/, " ");
-+	$0 = " "$6 " 0x"$1 " 0x"$3 " " $5;
-+}
-+
-+# (LLD) Convert a symbol record from lld format to ld format.
-+#
-+ARGIND >= 4 && map_is_lld && NF == 5 && $5 ~ /^[A-Za-z_][A-Za-z0-9_]*$/ {
-+	$0 = "  0x" $1 " " $5;
-+}
-+
-+# (LLD) We do not need any other ldd linker map records.
-+#
-+ARGIND >= 4 && map_is_lld && /^[0-9a-f]{16} / {
-+	next;
-+}
-+
-+# Handle section records with long section names (spilling onto a 2nd line).
-+#
-+ARGIND >= 4 && !map_is_lld && NF == 1 && /^[^ ]/ {
-+	s = $0;
-+	getline;
-+	$0 = s " " $0;
-+}
-+
-+# Next section - previous one is done.
-+#
-+ARGIND >= 4 && /^[^ ]/ {
-+	sect = 0;
-+}
-+
-+# Get the (top level) section name.
-+#
-+ARGIND >= 4 && /^[^ ]/ && $2 ~ /^0x/ && $3 ~ /^0x/ {
-+	# Empty section or per-CPU section - ignore.
-+	if (NF < 3 || $1 ~ /\.percpu/) {
-+		sect = 0;
-+		next;
-+	}
-+
-+	sect = $1;
-+
-+	next;
-+}
-+
-+# If we are not currently in a section we care about, ignore records.
-+#
-+!sect {
-+	next;
-+}
-+
-+# Handle object records with long section names (spilling onto a 2nd line).
-+#
-+ARGIND >= 4 && /^ [^ \*]/ && NF == 1 {
-+	# If the section name is long, the remainder of the entry is found on
-+	# the next line.
-+	s = $0;
-+	getline;
-+	$0 = s " " $0;
-+}
-+
-+# If the object is vmlinux.o, we need to consult vmlinux.o.map for per-object
-+# symbol information
-+#
-+ARGIND == 4 && /^ [^ ]/ && NF == 4 {
-+	idx = sect":"$1;
-+	if (!(idx in sect_addend)) {
-+		sect_addend[idx] = addr2val($2);
-+		if (dbg)
-+			printf "ADDEND %s = %016x\n", idx, sect_addend[idx] >"/dev/stderr";
-+	}
-+	if ($4 == "vmlinux.o") {
-+		need_o_map = 1;
-+		next;
-+	}
-+}
-+
-+# If data from vmlinux.o.map is needed, we only process section and object
-+# records from vmlinux.map to determine which section we need to pay attention
-+# to in vmlinux.o.map.  So skip everything else from vmlinux.map.
-+#
-+ARGIND == 4 && need_o_map {
-+	next;
-+}
-+
-+# Get module information for the current object.
-+#
-+ARGIND >= 4 && /^ [^ ]/ && NF == 4 {
-+	msect = $1;
-+	mod_name = get_module_info($4);
-+	mod_eaddr = addr2val($2) + addr2val($3);
-+
-+	next;
-+}
-+
-+# Process a symbol record.
-+#
-+# Evaluate the module information obtained from vmlinux.map (or vmlinux.o.map)
-+# as follows:
-+#  - For all symbols in a given object:
-+#     - If the symbol is annotated with the same module name(s) that the object
-+#       belongs to, count it as a match.
-+#     - Otherwise:
-+#        - If the symbol is known to have duplicates of which at least one is
-+#          in a built-in module, disregard it.
-+#        - If the symbol us not annotated with any module name(s) AND the
-+#          object belongs to built-in modules, count it as missing.
-+#        - Otherwise, count it as a mismatch.
-+#
-+ARGIND >= 4 && /^ / && NF == 2 && $1 ~ /^0x/ {
-+	idx = sect":"msect;
-+	if (!(idx in sect_addend))
-+		next;
-+
-+	addr = addr2val($1);
-+
-+	# Handle the rare but annoying case where a 0-size symbol is placed at
-+	# the byte *after* the module range.  Based on vmlinux.map it will be
-+	# considered part of the current object, but it falls just beyond the
-+	# module address range.  Unfortunately, its address could be at the
-+	# start of another built-in module, so the only safe thing to do is to
-+	# ignore it.
-+	if (mod_name && addr == mod_eaddr)
-+		next;
-+
-+	# If we are processing vmlinux.o.map, we need to apply the base address
-+	# of the section to the relative address on the record.
-+	#
-+	if (ARGIND == 5)
-+		addr += sect_addend[idx];
-+
-+	idx = addr"-"$2;
-+	mod = "";
-+	if (idx in sym2mod) {
-+		mod = sym2mod[idx];
-+		if (sym2mod[idx] == mod_name) {
-+			mod_matches++;
-+			matches++;
-+		} else if (mod_name == "") {
-+			print $2 " in " sym2mod[idx] " (should NOT be)";
-+			mismatches++;
-+		} else {
-+			print $2 " in " sym2mod[idx] " (should be " mod_name ")";
-+			mismatches++;
-+		}
-+	} else if (mod_name != "") {
-+		print $2 " should be in " mod_name;
-+		missing++;
-+	} else
-+		matches++;
-+
-+	total++;
-+
-+	next;
-+}
-+
-+# Issue the comparison report.
-+#
-+END {
-+	if (total) {
-+		printf "Verification of %s:\n", ARGV[1];
-+		printf "  Correct matches:  %6d (%d%% of total)\n", matches, 100 * matches / total;
-+		printf "    Module matches: %6d (%d%% of matches)\n", mod_matches, 100 * mod_matches / matches;
-+		printf "  Mismatches:       %6d (%d%% of total)\n", mismatches, 100 * mismatches / total;
-+		printf "  Missing:          %6d (%d%% of total)\n", missing, 100 * missing / total;
-+	}
-+}


             reply	other threads:[~2024-09-30 16:11 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-30 16:11 Mike Pagano [this message]
  -- strict thread matches above, loose matches on Subject: below --
2024-10-10 11:35 [gentoo-commits] proj/linux-patches:6.10 commit in: / Mike Pagano
2024-10-04 15:22 Mike Pagano
2024-09-30 16:03 Mike Pagano
2024-09-24 18:52 Mike Pagano
2024-09-18 18:01 Mike Pagano
2024-09-12 13:08 Mike Pagano
2024-09-12 12:30 Mike Pagano
2024-09-08 11:05 Mike Pagano
2024-09-07 18:10 Mike Pagano
2024-09-07 14:26 Mike Pagano
2024-09-07 14:23 Mike Pagano
2024-09-07 14:23 Mike Pagano
2024-09-05 13:58 Mike Pagano
2024-09-04 14:06 Mike Pagano
2024-09-04 13:51 Mike Pagano
2024-09-04 13:50 Mike Pagano
2024-09-04 13:50 Mike Pagano
2024-08-29 16:48 Mike Pagano
2024-08-19 10:23 Mike Pagano
2024-08-15 14:05 Mike Pagano
2024-08-15 13:19 Mike Pagano
2024-08-14 15:18 Mike Pagano
2024-08-14 14:49 Mike Pagano
2024-08-14 14:08 Mike Pagano
2024-08-14 14:08 Mike Pagano
2024-08-11 13:27 Mike Pagano
2024-08-09 18:13 Mike Pagano
2024-08-03 15:55 Mike Pagano
2024-08-03 15:16 Mike Pagano
2024-07-27 22:16 Mike Pagano
2024-07-27 22:04 Mike Pagano
2024-07-27 13:45 Mike Pagano
2024-07-24 16:59 Mike Pagano
2024-07-24 16:44 Mike Pagano
2024-07-24 16:43 Mike Pagano
2024-07-19 22:35 Mike Pagano
2024-07-15 22:24 Mike Pagano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1727712682.13d4521ec8233c1a6e250857c77d1c62a7fcb1e0.mpagano@gentoo \
    --to=mpagano@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox