2023-11-03 15:57:55

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 00/14] DCE/DSE: Add Dead Syscalls Elimination support, part2

Hi, all

This series aims to add Dead Code Elimination(DCE) based Dead Syscalls
Elimination(DSE) support, here is the RFC patchset[1]. The whole series
includes three parts, here is the Part2.

Part1 adds basic DCE based DSE support [5].

Part3 will add DSE test support with nolibc-test.c.

This Part2 further eliminates the unused syscalls forcely kept by the
exception tables. This is just a preliminary approach and requires a lot
of discussion and modifications.

Some syscalls use put_user()/get_user() to access memory from
user-space, the exception tables are added for such memory addresses to
fixup potential exceptions fairily.

These exception tables are added by the simple '.pushsection' directive
and there is no explicit section relationship between them and their
syscall functions, So, all of such tables are explicitly kept by the
KEEP() directive in vmlinux.lds, but such forcely KEEP() operations
prevent DCE from eliminating their syscall functions for the tables used
some addresses in their syscall functions, the insn and fixup addresses
(arch/riscv/include/asm/asm-extable.h) are from their syscall functions,
as a result, the ownership reverses.

To further eliminate such syscalls, we must fix up this ownership
reversal issue. At first, the KEEP() operations must be removed from
vmlinux.lds, but at the same time, we must find a way to tell ld the
real ownership between the syscalls and their exceptions tables.

Fortunately, under the guidance of Zhangjin Wu, I discovered that both
SHF_GROUP and SHF_LINK_ORDER can be helpful for such targets ([6] [7]
[8]), but the former method triggers a warning from as. The binary files
compiled using both methods turn out to be identical. So maybe we just
choose the later one?

This series adds a very elementary level of patchset to demonstate how
to use them to drop KEEP() for all of the exception tables, only for
RISC-V currently.

This may also be a good start for us to rethink the widely used KEEP().
This approach can thoroughly eliminate orphan sections, providing the
compiler with more information. Eventually, most of the KEEP() calls
can be eliminated.

The nolibc-test based initrd run well on riscv64 kernel image with dead
syscalls eliminated:

$ nm build/riscv64/virt/linux/v6.6-rc2/vmlinux | grep "T __riscv_sys" | grep -v sys_ni_syscall | wc -l
40

These options should be enabled:

CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y
CONFIG_LD_DEAD_CODE_DATA_ELIMINATION_DEBUG=y
CONFIG_TRIM_UNUSED_SYSCALLS=y
CONFIG_SECTION_SHF_LINK_ORDER_SUPPORT=y
CONFIG_USED_SYSCALLS="sys_dup sys_dup3 sys_ioctl sys_mknodat sys_mkdirat sys_unlinkat sys_symlinkat sys_linkat sys_mount sys_chdir sys_chroot sys_fchmodat sys_fchownat sys_openat sys_close sys_pipe2 sys_getdents64 sys_lseek sys_read sys_write sys_pselect6 sys_ppoll sys_exit sys_sched_yield sys_kill sys_reboot sys_getpgid sys_prctl sys_gettimeofday sys_getpid sys_getppid sys_getuid sys_geteuid sys_brk sys_munmap sys_clone sys_execve sys_mmap sys_wait4 sys_statx"

Or using section group intead of section link order:

CONFIG_SECTION_SHF_GROUP_SUPPORT=y

Thanks to Song Fangrui's idea [9] of SHF_LINK_ORDER. To be honest, this
part is hard to understand, and there may be some mistakes in my
solutions. Welcome your further advice. :)

Besides, I want to express my thanks to Zhangjin Wu, Zhiming Xu, Anqi
Xiao, Jun Kong, and Yuzhe Ling for their help during the investigation
stage.

Best Regards,
Yuan Tan

---
[1]: https://lore.kernel.org/lkml/[email protected]/
[2]: https://lore.kernel.org/lkml/234017be6d06ef84844583230542e31068fa3685.1676594211.git.falcon@tinylab.org/
[3]: https://lore.kernel.org/lkml/CAFP8O3+41QFVyNTVJ2iZYkB0tqnvdLTAoGShgGy-qPP1PHjBEw@mail.gmail.com/
[4]: https://lore.kernel.org/lkml/cbcbfbb37cabfd9aed6088c75515e4ea86006cff.1676594211.git.falcon@tinylab.org/
[5]: https://lore.kernel.org/lkml/[email protected]/
[6]: https://maskray.me/blog/2021-07-25-comdat-and-section-group
[7]: https://maskray.me/blog/2021-01-31-metadata-sections-comdat-and-shf-link-order
[8]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
[9]: https://sourceware.org/pipermail/binutils/2023-July/128521.html

Yuan Tan (10):
DCE/DSE: add HAVE_SECTION_SHF_LINK_ORDER_SUPPORT option
DCE/DSE: add HAVE_SECTION_SHF_GROUP_SUPPORT option
DCE/DSE: add HAVE_SECTION_NO_KEEP_SUPPORT option
DCE/DSE: add choice of methods to build reference for orphan sections
DCE/DSE: inhibit .size directive for SHF_GROUP
DCE/DSE: riscv: make every ex_table's name unique
DCE/DSE: riscv: build reference for .pushsection in C functions
DCE/DSE: riscv: build reference for .pushsection in assembly
DCE/DSE: add SECTION_NO_KEEP_SUPPORT option
DCE/DSE: vmlinux.lds.h: allow NO_KEEP on __ex_table sections

Zhangjin Wu (4):
DCE/DSE: allow keep unique bounded sections
compiler: add a global __QUITE_UNIQUE_ID()
compiler: add unique __SECTION_NAME()
compiler: add unique LABEL_NAME()

Makefile | 3 ++
arch/riscv/include/asm/asm-extable.h | 43 +++++++++++++---
arch/riscv/lib/uaccess.S | 60 +++++++++++-----------
include/asm-generic/vmlinux.lds.h | 28 ++++++++---
include/linux/compiler.h | 25 ++++++++++
include/linux/compiler_types.h | 8 +--
init/Kconfig | 74 ++++++++++++++++++++++++++++
7 files changed, 193 insertions(+), 48 deletions(-)

--
2.34.1


2023-11-03 15:59:10

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 01/14] DCE/DSE: allow keep unique bounded sections

From: Zhangjin Wu <[email protected]>

The bounded sections may break the elimination of some dead code.

Some unused syscalls have been wrongly kept by `__ex_table`, we will
unique `__ex_table` for every inserting and then remove the unused ones
explicitly and eventually, the unused syscalls will be eliminated.

In the future, we should find better methods to solve such issue:

Some code may use '.pushsection/.popsection' to insert data
to a bounded section, use `sys_sendfile` as an example:

sys_sendfile:

".pushsection __ex_table,\"\"\n"
...
".long ((" insn ") - .)\n"
...
".popsection"

`insn` is an address in `sys_sendfile`, even if no real user uses
sys_sendfile, the keeping of __ex_table will become a 'user' and
break the elimination of `sys_sendfile`.

All of the bounded sections should be uniqued, and we should check if
they are the last users of the code, if so, those sections should be
removed and the code should be eliminated.

Signed-off-by: Zhangjin Wu <[email protected]>
---
include/asm-generic/vmlinux.lds.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 9c59409104f6..ea8170e11ab1 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -103,6 +103,7 @@
#define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* .rodata..L*
#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..compoundliteral*
#define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]*
+#define BSEC_MAIN(sec) sec sec##.[0-9a-zA-Z_]*
#else
#define TEXT_MAIN .text
#define DATA_MAIN .data
@@ -110,6 +111,7 @@
#define RODATA_MAIN .rodata
#define BSS_MAIN .bss
#define SBSS_MAIN .sbss
+#define BSEC_MAIN(sec) sec
#endif

/*
@@ -201,12 +203,12 @@

#define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_) \
_BEGIN_##_label_ = .; \
- KEEP(*(_sec_)) \
+ KEEP(*(BSEC_MAIN(_sec_))) \
_END_##_label_ = .;

#define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_) \
_label_##_BEGIN_ = .; \
- KEEP(*(_sec_)) \
+ KEEP(*(BSEC_MAIN(_sec_))) \
_label_##_END_ = .;

#define BOUNDED_SECTION_BY(_sec_, _label_) \
--
2.34.1


2023-11-03 15:59:26

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 03/14] compiler: add unique __SECTION_NAME()

From: Zhangjin Wu <[email protected]>

The new section helper is added for LD_DEAD_CODE_DATA_ELIMINATION to
generate unique section name (strigified).

Signed-off-by: Zhangjin Wu <[email protected]>
Signed-off-by: Yuan Tan <[email protected]>
---
include/linux/compiler.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 405b19cf6cf3..5a9cc3209b12 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -227,11 +227,25 @@ static inline void *offset_to_ptr(const int *off)

#endif /* __ASSEMBLY__ */

+/* Import __stringify. */
+#ifndef __stringify
+#include <linux/stringify.h>
+#endif
+
/* Quite-unique ID. */
#ifndef __QUITE_UNIQUE_ID
# define __QUITE_UNIQUE_ID(prefix) __PASTE(__PASTE(prefix, __LINE__), __COUNTER__)
#endif

+/* Quite-unique Section NAME. */
+#ifndef __SECTION_NAME
+#ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
+# define __SECTION_NAME(prefix) __stringify(__QUITE_UNIQUE_ID(prefix.))
+#else
+# define __SECTION_NAME(prefix) __stringify(prefix)
+#endif
+#endif
+
/* &a[0] degrades to a pointer: a different type from an array */
#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))

--
2.34.1

2023-11-03 15:59:35

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 02/14] compiler: add a global __QUITE_UNIQUE_ID()

From: Zhangjin Wu <[email protected]>

Differs from __UNIQUE_ID(), __QUITE_UNIQUE_ID() also appends the
__COUNTER__ info to make it more unique.

Besides, seems assembly code also require such a unique id, let's make
it global, the same to the required __PASTE macro.

Signed-off-by: Zhangjin Wu <[email protected]>
---
I am not sure whether it is proper to put the __QUITE_UNIQUE_ID and
other stuff later in compiler.h. Welcome discussion as this is just
a preliminary approach.

include/linux/compiler.h | 5 +++++
include/linux/compiler_types.h | 8 ++++----
2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index d7779a18b24f..405b19cf6cf3 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -227,6 +227,11 @@ static inline void *offset_to_ptr(const int *off)

#endif /* __ASSEMBLY__ */

+/* Quite-unique ID. */
+#ifndef __QUITE_UNIQUE_ID
+# define __QUITE_UNIQUE_ID(prefix) __PASTE(__PASTE(prefix, __LINE__), __COUNTER__)
+#endif
+
/* &a[0] degrades to a pointer: a different type from an array */
#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))

diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index c523c6683789..0b79e19d1017 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -70,10 +70,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 */
@@ -308,6 +304,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.34.1

2023-11-03 15:59:37

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 04/14] compiler: add unique LABEL_NAME()

From: Zhangjin Wu <[email protected]>

unique LABEL is required by SHF_LINK_ORDER support.

Signed-off-by: Zhangjin Wu <[email protected]>
---
include/linux/compiler.h | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 5a9cc3209b12..b178f5d51ad6 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -246,6 +246,12 @@ static inline void *offset_to_ptr(const int *off)
#endif
#endif

+/* Unique Label NAME. */
+/* Label is file scope, __LINE__ is enough, and not change in the same macro call */
+#ifndef __LABEL_NAME
+# define __LABEL_NAME(prefix) __stringify(__PASTE(__PASTE(prefix, _), __LINE__))
+#endif
+
/* &a[0] degrades to a pointer: a different type from an array */
#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))

--
2.34.1

2023-11-03 16:00:59

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 05/14] DCE/DSE: add HAVE_SECTION_SHF_LINK_ORDER_SUPPORT option

SHF_LINK_ORDER requires ld >= 2.35.

LLD supports SHF_LINK_ORDER to, but it does not support riscv
HAVE_LD_DEAD_CODE_DATA_ELIMINATION. Therefore, I haven't tested the
minimum compatible version yet.

Signed-off-by: Yuan Tan <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
init/Kconfig | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/init/Kconfig b/init/Kconfig
index aa648ce8bca1..1ef5b19918e5 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1462,6 +1462,11 @@ config HAVE_TRIM_UNUSED_SYSCALLS
depends on HAVE_LD_DEAD_CODE_DATA_ELIMINATION
default n

+config HAVE_SECTION_SHF_LINK_ORDER_SUPPORT
+ bool
+ depends on AS_IS_GNU && AS_VERSION >= 23500
+ default y
+
menuconfig EXPERT
bool "Configure standard kernel features (expert users)"
# Unhide debug options, to make the on-by-default options visible
--
2.34.1

2023-11-03 16:01:06

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 07/14] DCE/DSE: add HAVE_SECTION_NO_KEEP_SUPPORT option

Once there's SECTION_SHF_LINK_ORDER_SUPPORT or
SECTION_SHF_GROUP_SUPPORT, there won't be any orphan section and won't
need KEEP() anymore.

Signed-off-by: Yuan Tan <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
init/Kconfig | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/init/Kconfig b/init/Kconfig
index 4296c97cfc84..9834dbb0ddae 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1462,6 +1462,11 @@ config HAVE_TRIM_UNUSED_SYSCALLS
depends on HAVE_LD_DEAD_CODE_DATA_ELIMINATION
default n

+config HAVE_SECTION_NO_KEEP_SUPPORT
+ bool
+ depends on HAVE_SECTION_SHF_LINK_ORDER_SUPPORT || HAVE_SECTION_SHF_GROUP_SUPPORT
+ default y
+
config HAVE_SECTION_SHF_LINK_ORDER_SUPPORT
bool
depends on AS_IS_GNU && AS_VERSION >= 23500
--
2.34.1

2023-11-03 16:01:38

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 08/14] DCE/DSE: add choice of methods to build reference for orphan sections

Due to .pushsection producing orphan sections, the kernel currently uses
`KEEP()` in the linker script to address this issue.

Here we purpose two methods to build reference for pushed section,
SHF_LINK_ORDER method and SECTION_SHF_GROUP method.

The binary files compiled using both methods turn out to be identical,
and it doesn't produce any side effects.

Signed-off-by: Yuan Tan <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
init/Kconfig | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)

diff --git a/init/Kconfig b/init/Kconfig
index 9834dbb0ddae..9599d2de44e8 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1740,6 +1740,56 @@ config USED_SYSCALLS

If unsure, please disable TRIM_UNUSED_SYSCALLS.

+choice
+ prompt "Trim methods" if EXPERT
+ default RESTRICTED_TRIM_UNUSED_SYSCALLS
+ depends on TRIM_UNUSED_SYSCALLS
+ help
+ This option selects the method to trim unused syscall wrongly kept.
+
+ The binary files compiled using both methods are identical.
+
+ If the trim methods is not specified, some syscalls are kept by
+ linker script and can not be trimmed.
+
+config RESTRICTED_TRIM_UNUSED_SYSCALLS
+ bool "Leave some kept syscalls (EXPERIMENTAL)" if EXPERT
+ help
+ Say Y here to trim 'unused' syscalls wrongly kept by __ex_table
+ like sections in kernel space.
+
+ Some syscalls are kept by linker script and can not be trimmed.
+
+ If unsure, choose this.
+
+config SECTION_SHF_LINK_ORDER_SUPPORT
+ bool "Using SHF_LINK_ORDER attribute (EXPERIMENTAL)" if EXPERT
+ depends on HAVE_SECTION_SHF_LINK_ORDER_SUPPORT
+ help
+ Say Y here to trim more 'unused' syscalls wrongly kept by __ex_table
+ like sections in kernel space.
+
+ This option uses the SHF_LINK_ORDER attribute to build references for
+ orphan sections. Therefore, these sections are no longer kept in the
+ linker script.
+
+ If unsure, not choose this.
+
+config SECTION_SHF_GROUP_SUPPORT
+ bool "Using SHF_GROUP attribute (EXPERIMENTAL)" if EXPERT
+ depends on HAVE_SECTION_SHF_GROUP_SUPPORT
+ help
+ Say Y here to trim more 'unused' syscalls wrongly kept by __ex_table
+ like sections in kernel space.
+
+ This option uses the SHF_GROUP attribute to build references for
+ orphan sections. Therefore, these sections are no longer kept in the
+ linker script.
+
+ If unsure, not choose this.
+
+endchoice
+
config KALLSYMS
bool "Load all symbols for debugging/ksymoops" if EXPERT
default y
--
2.34.1

2023-11-03 16:02:28

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 06/14] DCE/DSE: add HAVE_SECTION_SHF_GROUP_SUPPORT option

SHF_GROUP requires ld >= 2.36.

LLD supports SHF_GROUP too, but it does not support riscv
HAVE_LD_DEAD_CODE_DATA_ELIMINATION. Therefore, I haven't tested the
minimum compatible version yet.

Signed-off-by: Yuan Tan <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
init/Kconfig | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/init/Kconfig b/init/Kconfig
index 1ef5b19918e5..4296c97cfc84 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1467,6 +1467,11 @@ config HAVE_SECTION_SHF_LINK_ORDER_SUPPORT
depends on AS_IS_GNU && AS_VERSION >= 23500
default y

+config HAVE_SECTION_SHF_GROUP_SUPPORT
+ bool
+ depends on AS_IS_GNU && AS_VERSION >= 23600
+ default y
+
menuconfig EXPERT
bool "Configure standard kernel features (expert users)"
# Unhide debug options, to make the on-by-default options visible
--
2.34.1

2023-11-03 16:02:36

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 09/14] DCE/DSE: inhibit .size directive for SHF_GROUP

.size directive fails in some functions with SHF_GROUP, this is not
really required for normal building, inhibit it to silence the compiling
failures with SHF_GROUP.

Signed-off-by: Yuan Tan <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
Makefile | 3 +++
1 file changed, 3 insertions(+)

diff --git a/Makefile b/Makefile
index a4e522b747cb..f67b6e8d2c45 100644
--- a/Makefile
+++ b/Makefile
@@ -936,6 +936,9 @@ endif
# `rustc`'s `-Zfunction-sections` applies to data too (as of 1.59.0).
ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections
+ifdef CONFIG_SECTION_SHF_GROUP_SUPPORT
+KBUILD_CFLAGS_KERNEL += -finhibit-size-directive
+endif
KBUILD_RUSTFLAGS_KERNEL += -Zfunction-sections=y
LDFLAGS_vmlinux += --gc-sections
ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION_DEBUG
--
2.34.1

2023-11-03 16:02:56

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 10/14] DCE/DSE: riscv: make every ex_table's name unique

gc-sections require section names to be unique.

Signed-off-by: Yuan Tan <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
arch/riscv/include/asm/asm-extable.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/asm-extable.h b/arch/riscv/include/asm/asm-extable.h
index 00a96e7a9664..d0be5a838242 100644
--- a/arch/riscv/include/asm/asm-extable.h
+++ b/arch/riscv/include/asm/asm-extable.h
@@ -9,10 +9,12 @@

#ifdef CONFIG_MMU

+#include <linux/compiler.h>
+
#ifdef __ASSEMBLY__

#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
- .pushsection __ex_table, "a"; \
+ .pushsection __SECTION_NAME(__ex_table), "a"; \
.balign 4; \
.long ((insn) - .); \
.long ((fixup) - .); \
@@ -31,7 +33,7 @@
#include <asm/gpr-num.h>

#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
- ".pushsection __ex_table, \"a\"\n" \
+ ".pushsection " __SECTION_NAME(__ex_table) ", \"a\"\n" \
".balign 4\n" \
".long ((" insn ") - .)\n" \
".long ((" fixup ") - .)\n" \
--
2.34.1

2023-11-03 16:04:02

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 11/14] DCE/DSE: riscv: build reference for .pushsection in C functions

Add the SECTION_SHF_LINK_ORDER method and the SECTION_SHF_GROUP method
to refactor __ASM_EXTABLE_RAW, so it won't produce orphan sections
anymore.

Signed-off-by: Yuan Tan <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
arch/riscv/include/asm/asm-extable.h | 34 ++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/asm-extable.h b/arch/riscv/include/asm/asm-extable.h
index d0be5a838242..7164d871e038 100644
--- a/arch/riscv/include/asm/asm-extable.h
+++ b/arch/riscv/include/asm/asm-extable.h
@@ -13,6 +13,21 @@

#ifdef __ASSEMBLY__

+#if defined(CONFIG_SECTION_SHF_LINK_ORDER_SUPPORT)
+#define __ASM_EXTABLE_PUSH_SECTION \
+ __LABEL_NAME(.L__ex_table) : \
+ .pushsection __SECTION_NAME(__ex_table), "ao", __LABEL_NAME(.L__ex_table)
+
+#elif defined(CONFIG_SECTION_SHF_GROUP_SUPPORT)
+#define __ASM_EXTABLE_PUSH_SECTION \
+ .attach_to_group __SECTION_NAME(__ex_table); \
+ .pushsection __SECTION_NAME(__ex_table), "a?"
+
+#else
+#define __ASM_EXTABLE_PUSH_SECTION \
+ .pushsection __SECTION_NAME(__ex_table), "a"
+#endif
+
#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
.pushsection __SECTION_NAME(__ex_table), "a"; \
.balign 4; \
@@ -32,8 +47,23 @@
#include <linux/stringify.h>
#include <asm/gpr-num.h>

-#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
- ".pushsection " __SECTION_NAME(__ex_table) ", \"a\"\n" \
+#ifdef CONFIG_SECTION_SHF_LINK_ORDER_SUPPORT
+#define __ASM_EXTABLE_PUSH_SECTION \
+ __LABEL_NAME(.L__ex_table) ":" \
+ ".pushsection " __SECTION_NAME(__ex_table) ", \"ao\"," __LABEL_NAME(.L__ex_table) "\n"
+
+#elif defined(CONFIG_SECTION_SHF_GROUP_SUPPORT)
+#define __ASM_EXTABLE_PUSH_SECTION \
+ ".attach_to_group " __SECTION_NAME(__ex_table) "\n" \
+ ".pushsection " __SECTION_NAME(__ex_table) ", \"a?\"\n"
+
+#else
+#define __ASM_EXTABLE_PUSH_SECTION \
+ ".pushsection " __SECTION_NAME(__ex_table) ", \"a\"\n"
+#endif
+
+#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
+ __ASM_EXTABLE_PUSH_SECTION \
".balign 4\n" \
".long ((" insn ") - .)\n" \
".long ((" fixup ") - .)\n" \
--
2.34.1

2023-11-03 16:04:34

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 12/14] DCE/DSE: riscv: build reference for .pushsection in assembly

Add the SECTION_SHF_LINK_ORDER method and the SECTION_SHF_GROUP method
to refactor __ASM_EXTABLE_RAW, so it won't produce orphan sections
anymore.

Signed-off-by: Yuan Tan <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
arch/riscv/include/asm/asm-extable.h | 7 ++--
arch/riscv/lib/uaccess.S | 60 ++++++++++++++--------------
2 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/arch/riscv/include/asm/asm-extable.h b/arch/riscv/include/asm/asm-extable.h
index 7164d871e038..99e472b7a1be 100644
--- a/arch/riscv/include/asm/asm-extable.h
+++ b/arch/riscv/include/asm/asm-extable.h
@@ -29,7 +29,7 @@
#endif

#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
- .pushsection __SECTION_NAME(__ex_table), "a"; \
+ __ASM_EXTABLE_PUSH_SECTION; \
.balign 4; \
.long ((insn) - .); \
.long ((fixup) - .); \
@@ -37,9 +37,8 @@
.short (data); \
.popsection;

- .macro _asm_extable, insn, fixup
- __ASM_EXTABLE_RAW(\insn, \fixup, EX_TYPE_FIXUP, 0)
- .endm
+#define _asm_extable(insn, fixup) \
+ __ASM_EXTABLE_RAW(insn, fixup, EX_TYPE_FIXUP, 0)

#else /* __ASSEMBLY__ */

diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S
index 09b47ebacf2e..91c76d3fbe2f 100644
--- a/arch/riscv/lib/uaccess.S
+++ b/arch/riscv/lib/uaccess.S
@@ -4,11 +4,9 @@
#include <asm/asm-extable.h>
#include <asm/csr.h>

- .macro fixup op reg addr lbl
-100:
- \op \reg, \addr
- _asm_extable 100b, \lbl
- .endm
+#define fixup(op, reg, addr, lbl) \
+ 100: op reg, addr; \
+ _asm_extable(100b, lbl)

ENTRY(__asm_copy_to_user)
ENTRY(__asm_copy_from_user)
@@ -50,9 +48,9 @@ ENTRY(__asm_copy_from_user)
beq a0, t1, .Lskip_align_dst
1:
/* a5 - one byte for copying data */
- fixup lb a5, 0(a1), 10f
+ fixup(lb, a5, 0(a1), 10f)
addi a1, a1, 1 /* src */
- fixup sb a5, 0(a0), 10f
+ fixup(sb, a5, 0(a0), 10f)
addi a0, a0, 1 /* dst */
bltu a0, t1, 1b /* t1 - start of aligned dst */

@@ -77,22 +75,22 @@ ENTRY(__asm_copy_from_user)
*/
addi t0, t0, -(8*SZREG) /* not to over run */
2:
- fixup REG_L a4, 0(a1), 10f
- fixup REG_L a5, SZREG(a1), 10f
- fixup REG_L a6, 2*SZREG(a1), 10f
- fixup REG_L a7, 3*SZREG(a1), 10f
- fixup REG_L t1, 4*SZREG(a1), 10f
- fixup REG_L t2, 5*SZREG(a1), 10f
- fixup REG_L t3, 6*SZREG(a1), 10f
- fixup REG_L t4, 7*SZREG(a1), 10f
- fixup REG_S a4, 0(a0), 10f
- fixup REG_S a5, SZREG(a0), 10f
- fixup REG_S a6, 2*SZREG(a0), 10f
- fixup REG_S a7, 3*SZREG(a0), 10f
- fixup REG_S t1, 4*SZREG(a0), 10f
- fixup REG_S t2, 5*SZREG(a0), 10f
- fixup REG_S t3, 6*SZREG(a0), 10f
- fixup REG_S t4, 7*SZREG(a0), 10f
+ fixup(REG_L, a4, 0(a1), 10f)
+ fixup(REG_L, a5, SZREG(a1), 10f)
+ fixup(REG_L, a6, 2*SZREG(a1), 10f)
+ fixup(REG_L, a7, 3*SZREG(a1), 10f)
+ fixup(REG_L, t1, 4*SZREG(a1), 10f)
+ fixup(REG_L, t2, 5*SZREG(a1), 10f)
+ fixup(REG_L, t3, 6*SZREG(a1), 10f)
+ fixup(REG_L, t4, 7*SZREG(a1), 10f)
+ fixup(REG_S, a4, 0(a0), 10f)
+ fixup(REG_S, a5, SZREG(a0), 10f)
+ fixup(REG_S, a6, 2*SZREG(a0), 10f)
+ fixup(REG_S, a7, 3*SZREG(a0), 10f)
+ fixup(REG_S, t1, 4*SZREG(a0), 10f)
+ fixup(REG_S, t2, 5*SZREG(a0), 10f)
+ fixup(REG_S, t3, 6*SZREG(a0), 10f)
+ fixup(REG_S, t4, 7*SZREG(a0), 10f)
addi a0, a0, 8*SZREG
addi a1, a1, 8*SZREG
bltu a0, t0, 2b
@@ -130,7 +128,7 @@ ENTRY(__asm_copy_from_user)
sub t4, a5, t3

/* Load the first word to combine with second word */
- fixup REG_L a5, 0(a1), 10f
+ fixup(REG_L, a5, 0(a1), 10f)

3:
/* Main shifting copy
@@ -142,11 +140,11 @@ ENTRY(__asm_copy_from_user)

/* At least one iteration will be executed */
srl a4, a5, t3
- fixup REG_L a5, SZREG(a1), 10f
+ fixup(REG_L, a5, SZREG(a1), 10f)
addi a1, a1, SZREG
sll a2, a5, t4
or a2, a2, a4
- fixup REG_S a2, 0(a0), 10f
+ fixup(REG_S, a2, 0(a0), 10f)
addi a0, a0, SZREG
bltu a0, t1, 3b

@@ -163,9 +161,9 @@ ENTRY(__asm_copy_from_user)
*/
bgeu a0, t0, .Lout_copy_user /* check if end of copy */
4:
- fixup lb a5, 0(a1), 10f
+ fixup(lb, a5, 0(a1), 10f)
addi a1, a1, 1 /* src */
- fixup sb a5, 0(a0), 10f
+ fixup(sb, a5, 0(a0), 10f)
addi a0, a0, 1 /* dst */
bltu a0, t0, 4b /* t0 - end of dst */

@@ -205,7 +203,7 @@ ENTRY(__clear_user)
bgeu t0, t1, 2f
bltu a0, t0, 4f
1:
- fixup REG_S, zero, (a0), 11f
+ fixup(REG_S, zero, (a0), 11f)
addi a0, a0, SZREG
bltu a0, t1, 1b
2:
@@ -217,12 +215,12 @@ ENTRY(__clear_user)
li a0, 0
ret
4: /* Edge case: unalignment */
- fixup sb, zero, (a0), 11f
+ fixup(sb, zero, (a0), 11f)
addi a0, a0, 1
bltu a0, t0, 4b
j 1b
5: /* Edge case: remainder */
- fixup sb, zero, (a0), 11f
+ fixup(sb, zero, (a0), 11f)
addi a0, a0, 1
bltu a0, a3, 5b
j 3b
--
2.34.1

2023-11-03 16:05:18

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 13/14] DCE/DSE: add SECTION_NO_KEEP_SUPPORT option

It is able to drop the brute KEEP() keyword for some sections, when the
sections are able to link or group together with one of the used
sections.

Some syscalls are actually orphan sections.
SECTION_SHF_LINK_ORDER_SUPPORT or SECTION_SHF_GROUP_SUPPORT creates
references for these sections, eliminating the need for the KEEP()
directive.

Signed-off-by: Yuan Tan <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
include/asm-generic/vmlinux.lds.h | 24 ++++++++++++++++++------
init/Kconfig | 9 +++++++++
2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index ea8170e11ab1..f10afc42a1ac 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -201,18 +201,30 @@
# endif
#endif

-#define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_) \
+#ifdef CONFIG_SECTION_NO_KEEP_SUPPORT
+#define NO_KEEP(sec) sec
+#else
+#define NO_KEEP(sec) KEEP(sec)
+#endif
+
+#define _BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_, _KEEP_, ...) \
_BEGIN_##_label_ = .; \
- KEEP(*(BSEC_MAIN(_sec_))) \
+ _KEEP_(*(BSEC_MAIN(_sec_))) \
_END_##_label_ = .;

-#define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_) \
+#define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_, ...) \
+ _BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_, ##__VA_ARGS__, KEEP)
+
+#define _BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_, _KEEP_, ...)\
_label_##_BEGIN_ = .; \
- KEEP(*(BSEC_MAIN(_sec_))) \
+ _KEEP_(*(BSEC_MAIN(_sec_))) \
_label_##_END_ = .;

-#define BOUNDED_SECTION_BY(_sec_, _label_) \
- BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, __start, __stop)
+#define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_, ...) \
+ _BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_, ##__VA_ARGS__, KEEP)
+
+#define BOUNDED_SECTION_BY(_sec_, _label_, ...) \
+ _BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, __start, __stop, ##__VA_ARGS__, KEEP)

#define BOUNDED_SECTION(_sec) BOUNDED_SECTION_BY(_sec, _sec)

diff --git a/init/Kconfig b/init/Kconfig
index 9599d2de44e8..aeb859e410b2 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1467,6 +1467,13 @@ config HAVE_SECTION_NO_KEEP_SUPPORT
depends on HAVE_SECTION_SHF_LINK_ORDER_SUPPORT || HAVE_SECTION_SHF_GROUP_SUPPORT
default y

+config SECTION_NO_KEEP_SUPPORT
+ bool
+ depends on SECTION_SHF_LINK_ORDER_SUPPORT || SECTION_SHF_GROUP_SUPPORT
+ default y
+ help
+ This option allows some sections unkept so they can be GC
+
config HAVE_SECTION_SHF_LINK_ORDER_SUPPORT
bool
depends on AS_IS_GNU && AS_VERSION >= 23500
@@ -1765,6 +1772,7 @@ config RESTRICTED_TRIM_UNUSED_SYSCALLS
config SECTION_SHF_LINK_ORDER_SUPPORT
bool "Using SHF_LINK_ORDER attribute (EXPERIMENTAL)" if EXPERT
depends on HAVE_SECTION_SHF_LINK_ORDER_SUPPORT
+ select SECTION_NO_KEEP_SUPPORT
help
Say Y here to trim more 'unused' syscalls wrongly kept by __ex_table
like sections in kernel space.
@@ -1778,6 +1786,7 @@ config SECTION_SHF_LINK_ORDER_SUPPORT
config SECTION_SHF_GROUP_SUPPORT
bool "Using SHF_GROUP attribute (EXPERIMENTAL)" if EXPERT
depends on HAVE_SECTION_SHF_GROUP_SUPPORT
+ select SECTION_NO_KEEP_SUPPORT
help
Say Y here to trim more 'unused' syscalls wrongly kept by __ex_table
like sections in kernel space.
--
2.34.1

2023-11-03 16:06:28

by Yuan Tan

[permalink] [raw]
Subject: [PATCH v1 14/14] DCE/DSE: vmlinux.lds.h: allow NO_KEEP on __ex_table sections

With SHF_LINK_ORDER or SHF_GROUP, all of the __extable sections are no
longer orphan sections. In this case, KEEP() is no longer needed.

Signed-off-by: Yuan Tan <[email protected]>
Signed-off-by: Zhangjin Wu <[email protected]>
---
include/asm-generic/vmlinux.lds.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index f10afc42a1ac..e5e5850ea573 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -658,7 +658,7 @@
#define EXCEPTION_TABLE(align) \
. = ALIGN(align); \
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { \
- BOUNDED_SECTION_BY(__ex_table, ___ex_table) \
+ BOUNDED_SECTION_BY(__ex_table, ___ex_table, NO_KEEP) \
}

/*
--
2.34.1

2023-11-05 20:57:57

by Fangrui Song

[permalink] [raw]
Subject: Re: [PATCH v1 09/14] DCE/DSE: inhibit .size directive for SHF_GROUP

On Fri, Nov 3, 2023 at 9:01 AM Yuan Tan <[email protected]> wrote:
>
> .size directive fails in some functions with SHF_GROUP, this is not
> really required for normal building, inhibit it to silence the compiling
> failures with SHF_GROUP.
>
> Signed-off-by: Yuan Tan <[email protected]>
> Signed-off-by: Zhangjin Wu <[email protected]>
> ---
> Makefile | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Makefile b/Makefile
> index a4e522b747cb..f67b6e8d2c45 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -936,6 +936,9 @@ endif
> # `rustc`'s `-Zfunction-sections` applies to data too (as of 1.59.0).
> ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
> KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections
> +ifdef CONFIG_SECTION_SHF_GROUP_SUPPORT
> +KBUILD_CFLAGS_KERNEL += -finhibit-size-directive
> +endif
> KBUILD_RUSTFLAGS_KERNEL += -Zfunction-sections=y
> LDFLAGS_vmlinux += --gc-sections
> ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION_DEBUG
> --
> 2.34.1
>

Clang doesn't support -finhibit-size-directive, so this would break
Clang builds.

GCC has had this option since 1992, but it is not used in the wild.
https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-finhibit-size-directive
says

> ... This option is used when compiling crtstuff.c; you should not need to use it for anything else.

What problem have you seen with .size directives (st_size field in
symbol table entries)?

% cat a.c
int v;
void f() {}
% diff -u0 <(gcc -S a.c -o -) <(gcc -S -finhibit-size-directive a.c -o -)
--- /proc/self/fd/11 2023-11-05 12:42:51.298618475 -0800
+++ /proc/self/fd/15 2023-11-05 12:42:51.298618475 -0800
@@ -7 +6,0 @@
- .size v, 4
@@ -27 +25,0 @@
- .size f, .-f

2023-11-05 21:21:16

by Fangrui Song

[permalink] [raw]
Subject: Re: [PATCH v1 10/14] DCE/DSE: riscv: make every ex_table's name unique

On Fri, Nov 3, 2023 at 9:02 AM Yuan Tan <[email protected]> wrote:
>
> gc-sections require section names to be unique.

This is not precise, since a monolithic section can be garbage
collected as well.

https://maskray.me/blog/2021-02-28-linker-garbage-collection

"Without the options, the compiler tends to produce monolithic text
and data sections. The large sections make the GC coarse-grained and
they will likely be retained as a whole. ld --gc-sections can still
discard some sections, but the effect is likely very poor."


> Signed-off-by: Yuan Tan <[email protected]>
> Signed-off-by: Zhangjin Wu <[email protected]>
> ---
> arch/riscv/include/asm/asm-extable.h | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/include/asm/asm-extable.h b/arch/riscv/include/asm/asm-extable.h
> index 00a96e7a9664..d0be5a838242 100644
> --- a/arch/riscv/include/asm/asm-extable.h
> +++ b/arch/riscv/include/asm/asm-extable.h
> @@ -9,10 +9,12 @@
>
> #ifdef CONFIG_MMU
>
> +#include <linux/compiler.h>
> +
> #ifdef __ASSEMBLY__
>
> #define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
> - .pushsection __ex_table, "a"; \
> + .pushsection __SECTION_NAME(__ex_table), "a"; \
> .balign 4; \
> .long ((insn) - .); \
> .long ((fixup) - .); \
> @@ -31,7 +33,7 @@
> #include <asm/gpr-num.h>

__SECTION_NAME is probably added by a previous patch.
An alternative is to use the .section directive's `unique` feature
(binutils>=2.35).

> #define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
> - ".pushsection __ex_table, \"a\"\n" \
> + ".pushsection " __SECTION_NAME(__ex_table) ", \"a\"\n" \
> ".balign 4\n" \
> ".long ((" insn ") - .)\n" \
> ".long ((" fixup ") - .)\n" \
> --
> 2.34.1
>

2023-11-05 21:35:36

by Fangrui Song

[permalink] [raw]
Subject: Re: [PATCH v1 08/14] DCE/DSE: add choice of methods to build reference for orphan sections

On Fri, Nov 3, 2023 at 9:01 AM Yuan Tan <[email protected]> wrote:
>
> Due to .pushsection producing orphan sections, the kernel currently uses
> `KEEP()` in the linker script to address this issue.
>
> Here we purpose two methods to build reference for pushed section,
> SHF_LINK_ORDER method and SECTION_SHF_GROUP method.
>
> The binary files compiled using both methods turn out to be identical,
> and it doesn't produce any side effects.
>
> Signed-off-by: Yuan Tan <[email protected]>
> Signed-off-by: Zhangjin Wu <[email protected]>
> ---
> init/Kconfig | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 50 insertions(+)
>
> diff --git a/init/Kconfig b/init/Kconfig
> index 9834dbb0ddae..9599d2de44e8 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1740,6 +1740,56 @@ config USED_SYSCALLS
>
> If unsure, please disable TRIM_UNUSED_SYSCALLS.
>
> +choice
> + prompt "Trim methods" if EXPERT
> + default RESTRICTED_TRIM_UNUSED_SYSCALLS
> + depends on TRIM_UNUSED_SYSCALLS
> + help
> + This option selects the method to trim unused syscall wrongly kept.
> +
> + The binary files compiled using both methods are identical.
> +
> + If the trim methods is not specified, some syscalls are kept by
> + linker script and can not be trimmed.
> +
> +config RESTRICTED_TRIM_UNUSED_SYSCALLS
> + bool "Leave some kept syscalls (EXPERIMENTAL)" if EXPERT
> + help
> + Say Y here to trim 'unused' syscalls wrongly kept by __ex_table
> + like sections in kernel space.
> +
> + Some syscalls are kept by linker script and can not be trimmed.
> +
> + If unsure, choose this.
> +
> +config SECTION_SHF_LINK_ORDER_SUPPORT
> + bool "Using SHF_LINK_ORDER attribute (EXPERIMENTAL)" if EXPERT
> + depends on HAVE_SECTION_SHF_LINK_ORDER_SUPPORT
> + help
> + Say Y here to trim more 'unused' syscalls wrongly kept by __ex_table
> + like sections in kernel space.

SHF_LINK_ORDER can be used for other metadata sections. The help
message reads as that __ex_table is the only use case.
It can be rephrased to us __ex_table as an example.

> + This option uses the SHF_LINK_ORDER attribute to build references for
> + orphan sections. Therefore, these sections are no longer kept in the
> + linker script.

https://sourceware.org/binutils/docs/ld/Orphan-Sections.html
"Orphan sections are sections present in the input files which are not
explicitly placed into the output file by the linker script."

If the linker script still references the relevant sections, they are
not orphan.
I think it's best to focus on the semantics (metadata sections),
rather than the linker input property (orphan).

Suggest:

This option allows the use of SHF_LINK_ORDER to mark a metadata
section as discardable when the linker discards its referenced
section.
The linker semantics require that the metadata section is not
referenced by any other section.

> + If unsure, not choose this.
> +


> +config SECTION_SHF_GROUP_SUPPORT
> + bool "Using SHF_GROUP attribute (EXPERIMENTAL)" if EXPERT
> + depends on HAVE_SECTION_SHF_GROUP_SUPPORT
> + help
> + Say Y here to trim more 'unused' syscalls wrongly kept by __ex_table
> + like sections in kernel space.
> +
> + This option uses the SHF_GROUP attribute to build references for
> + orphan sections. Therefore, these sections are no longer kept in the
> + linker script.
> +
> + If unsure, not choose this.
> +
> +endchoice
> +

SHF_GROUP has size overhead in relocatable object files. If
SHF_LINK_ORDER works for __extable, I suggest that we postpone
SECTION_SHF_GROUP_SUPPORT until it is absolutely needed.

As I mentioned in a binutils thread, .attach_to_group is not supported
by LLVM integrated assembler and it could be tricky to implement.
The toolchain requirement (2020) is no better than SHF_LINK_ORDER.

> config KALLSYMS
> bool "Load all symbols for debugging/ksymoops" if EXPERT
> default y
> --
> 2.34.1
>