[<prev] [next>] [day] [month] [year] [list]
Message-ID: <8BFF520DF61C1BB6+096017ae9362c21b090c1f3c97bbd0fdf305bd27.1760463245.git.tanyuan@tinylab.org>
Date: Wed, 15 Oct 2025 14:22:15 +0800
From: Yuan Tan <tanyuan@...ylab.org>
To: arnd@...db.de,
masahiroy@...nel.org,
nathan@...nel.org,
palmer@...belt.com,
linux-kbuild@...r.kernel.org,
linux-riscv@...ts.infradead.org
Cc: linux-arch@...r.kernel.org,
linux-kernel@...r.kernel.org,
i@...kray.me,
tanyuan@...ylab.org,
falcon@...ylab.org,
ronbogo@...look.com,
z1652074432@...il.com,
lx24@....ynu.edu.cn
Subject: [PATCH v2 7/8] vmlinux.lds.h: support conditional KEEP() in linker script
Introduce a conditional KEEP() helper, COND_KEEP(), that allows a
section to be kept only if a corresponding NOKEEP_<sec> macro is not
defined. This provides a finer-grained mechanism to control which
sections are protected from garbage collection.
Traditionally, many sections — for example, the exception table and jump
table — are created by .pushsection and wrapped with KEEP() in
vmlinux.lds.h to prevent them from being discarded by the linker, even when
they are not actually referenced. This can block dead code and data
elimination (DCE) when the section is known to be safe to drop.
With COND_KEEP(), architectures or subsystems can safely remove the KEEP()
in cases where the section can be safely garbage-collected.
The implementation adds:
- __KEEP_ACT_0() / __KEEP_ACT_1() helpers for macro expansion
- BSEC_MAIN() to handle possible sub-section patterns, such as
__ex_table.18
- COND_KEEP() macro, which wraps KEEP() conditionally based on
__is_defined(NOKEEP_<sec>)
Example usage:
COND_KEEP(alternative, *(.alternative*))
Additionally, move the ___PASTE()/__PASTE() definitions in
include/linux/compiler_types.h out from under the '#ifndef __ASSEMBLY__'
guard so that they are visible to assembly.
No functional change unless NOKEEP_<sec> is defined.
Signed-off-by: Yuan Tan <tanyuan@...ylab.org>
Signed-off-by: Zhangjin Wu <falcon@...ylab.org>
Signed-off-by: Peihan Liu <ronbogo@...look.com>
---
include/asm-generic/vmlinux.lds.h | 12 ++++++++++--
include/linux/compiler_types.h | 8 ++++----
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 8a9a2e732a65..8bb411ace863 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -51,6 +51,7 @@
*/
#include <asm-generic/codetag.lds.h>
+#include <linux/compiler_types.h>
#ifndef LOAD_OFFSET
#define LOAD_OFFSET 0
@@ -113,14 +114,21 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
#define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* .rodata..L*
#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..L* .bss..compoundliteral*
#define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]*
+#define BSEC_MAIN(sec) sec sec##.[0-9a-zA-Z_]*
#else
#define DATA_MAIN .data .data.rel .data.rel.local
#define SDATA_MAIN .sdata
#define RODATA_MAIN .rodata
#define BSS_MAIN .bss
#define SBSS_MAIN .sbss
+#define BSEC_MAIN(sec) sec
#endif
+#define __KEEP_ACT_0(sec) KEEP(sec)
+#define __KEEP_ACT_1(sec) sec
+
+#define COND_KEEP(sec, list) __PASTE(__KEEP_ACT_, __is_defined(NOKEEP_##sec))(list)
+
/*
* GCC 4.5 and later have a 32 bytes section alignment for structures.
* Except GCC 4.9, that feels the need to align on 64 bytes.
@@ -196,12 +204,12 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
#define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_) \
_BEGIN_##_label_ = .; \
- KEEP(*(_sec_)) \
+ COND_KEEP(_sec_, *(BSEC_MAIN(_sec_))) \
_END_##_label_ = .;
#define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_) \
_label_##_BEGIN_ = .; \
- KEEP(*(_sec_)) \
+ COND_KEEP(_sec_, *(BSEC_MAIN(_sec_))) \
_label_##_END_ = .;
#define BOUNDED_SECTION_BY(_sec_, _label_) \
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 59288a2c1ad2..680ba4afbe7d 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -79,10 +79,6 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { }
# define __builtin_warning(x, y...) (1)
#endif /* __CHECKER__ */
-/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
-#define ___PASTE(a,b) a##b
-#define __PASTE(a,b) ___PASTE(a,b)
-
#ifdef __KERNEL__
/* Attributes */
@@ -425,6 +421,10 @@ struct ftrace_likely_data {
#endif /* __ASSEMBLY__ */
+/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
+#define ___PASTE(a, b) a##b
+#define __PASTE(a, b) ___PASTE(a, b)
+
/*
* The below symbols may be defined for one or more, but not ALL, of the above
* compilers. We don't consider that to be an error, so set them to nothing.
--
2.43.0
Powered by blists - more mailing lists