[PATCH-next v3] arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION

Ard Biesheuvel ardb at kernel.org
Fri Mar 15 01:06:31 PDT 2024


On Fri, 15 Mar 2024 at 07:37, Yuntao Liu <liuyuntao12 at huawei.com> wrote:
>
> The current arm32 architecture does not yet support the
> HAVE_LD_DEAD_CODE_DATA_ELIMINATION feature. arm32 is widely used in
> embedded scenarios, and enabling this feature would be beneficial for
> reducing the size of the kernel image.
>
> In order to make this work, we keep the necessary tables by annotating
> them with KEEP, also it requires further changes to linker script to KEEP
> some tables and wildcard compiler generated sections into the right place.
> When using ld.lld for linking, the KEEP keyword is not recognized within
> the OVERLAY command, Ard proposed a concise method to solve this problem.
>
> It boots normally with defconfig, vexpress_defconfig and tinyconfig.
> The size comparison of zImage is as follows:
> defconfig       vexpress_defconfig      tinyconfig
> 5137712         5138024                 424192          no dce
> 5032560         4997824                 298384          dce
> 2.0%            2.7%                    29.7%           shrink
>
> When using smaller config file, there is a significant reduction in the
> size of the zImage.
>
> We also tested this patch on a commercially available single-board
> computer, and the comparison is as follows:
> a15eb_config
> 2161384         no dce
> 2092240         dce
> 3.2%            shrink
>
> The zImage size has been reduced by approximately 3.2%, which is 70KB on
> 2.1M.
>
> Signed-off-by: Yuntao Liu <liuyuntao12 at huawei.com>
> Tested-by: Arnd Bergmann <arnd at arndb.de>
> Reviewed-by: Arnd Bergmann <arnd at arndb.de>
> ---
> v3:
>    - A better way to KEEP .vectors section for ld.lld linking.
>
> v2:
>    - Support config XIP_KERNEL.
>    - Support LLVM compilation.
>    - https://lore.kernel.org/all/20240307151231.654025-1-liuyuntao12@huawei.com/
>
> v1: https://lore.kernel.org/all/20240220081527.23408-1-liuyuntao12@huawei.com/
> ---
>  arch/arm/Kconfig                       | 1 +
>  arch/arm/boot/compressed/vmlinux.lds.S | 6 +++++-
>  arch/arm/include/asm/vmlinux.lds.h     | 2 +-
>  arch/arm/kernel/entry-armv.S           | 3 +++
>  arch/arm/kernel/vmlinux-xip.lds.S      | 4 ++--
>  arch/arm/kernel/vmlinux.lds.S          | 6 +++---
>  6 files changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index b14aed3a17ab..45f25f6e7a62 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -114,6 +114,7 @@ config ARM
>         select HAVE_KERNEL_XZ
>         select HAVE_KPROBES if !XIP_KERNEL && !CPU_ENDIAN_BE32 && !CPU_V7M
>         select HAVE_KRETPROBES if HAVE_KPROBES
> +       select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
>         select HAVE_MOD_ARCH_SPECIFIC
>         select HAVE_NMI
>         select HAVE_OPTPROBES if !THUMB2_KERNEL
> diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S
> index 3fcb3e62dc56..affd30714f01 100644
> --- a/arch/arm/boot/compressed/vmlinux.lds.S
> +++ b/arch/arm/boot/compressed/vmlinux.lds.S
> @@ -89,7 +89,11 @@ SECTIONS
>       * The EFI stub always executes from RAM, and runs strictly before the
>       * decompressor, so we can make an exception for its r/w data, and keep it
>       */
> +#ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
> +    *(.data.* .bss.*)
> +#else
>      *(.data.efistub .bss.efistub)
> +#endif
>      __pecoff_data_end = .;
>

This is still not right.

Can you just add -fno-data-sections to cflags-$(CONFIG_ARM) in
drivers/firmware/efi/libstub/Makefile?


>      /*
> @@ -125,7 +129,7 @@ SECTIONS
>
>    . = BSS_START;
>    __bss_start = .;
> -  .bss                 : { *(.bss) }
> +  .bss                 : { *(.bss .bss.*) }
>    _end = .;
>
>    . = ALIGN(8);                /* the stack must be 64-bit aligned */
> diff --git a/arch/arm/include/asm/vmlinux.lds.h b/arch/arm/include/asm/vmlinux.lds.h
> index 4c8632d5c432..d60f6e83a9f7 100644
> --- a/arch/arm/include/asm/vmlinux.lds.h
> +++ b/arch/arm/include/asm/vmlinux.lds.h
> @@ -42,7 +42,7 @@
>  #define PROC_INFO                                                      \
>                 . = ALIGN(4);                                           \
>                 __proc_info_begin = .;                                  \
> -               *(.proc.info.init)                                      \
> +               KEEP(*(.proc.info.init))                                \
>                 __proc_info_end = .;
>
>  #define IDMAP_TEXT                                                     \
> diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
> index 6150a716828c..f01d23a220e6 100644
> --- a/arch/arm/kernel/entry-armv.S
> +++ b/arch/arm/kernel/entry-armv.S
> @@ -1065,6 +1065,7 @@ vector_addrexcptn:
>         .globl  vector_fiq
>
>         .section .vectors, "ax", %progbits
> +       .reloc  .text, R_ARM_NONE, .
>         W(b)    vector_rst
>         W(b)    vector_und
>  ARM(   .reloc  ., R_ARM_LDR_PC_G0, .L__vector_swi              )
> @@ -1078,6 +1079,7 @@ THUMB(    .reloc  ., R_ARM_THM_PC12, .L__vector_swi               )
>
>  #ifdef CONFIG_HARDEN_BRANCH_HISTORY
>         .section .vectors.bhb.loop8, "ax", %progbits
> +       .reloc  .text, R_ARM_NONE, .
>         W(b)    vector_rst
>         W(b)    vector_bhb_loop8_und
>  ARM(   .reloc  ., R_ARM_LDR_PC_G0, .L__vector_bhb_loop8_swi    )
> @@ -1090,6 +1092,7 @@ THUMB(    .reloc  ., R_ARM_THM_PC12, .L__vector_bhb_loop8_swi     )
>         W(b)    vector_bhb_loop8_fiq
>
>         .section .vectors.bhb.bpiall, "ax", %progbits
> +       .reloc  .text, R_ARM_NONE, .
>         W(b)    vector_rst
>         W(b)    vector_bhb_bpiall_und
>  ARM(   .reloc  ., R_ARM_LDR_PC_G0, .L__vector_bhb_bpiall_swi   )
> diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S
> index c16d196b5aad..5eddb75a7174 100644
> --- a/arch/arm/kernel/vmlinux-xip.lds.S
> +++ b/arch/arm/kernel/vmlinux-xip.lds.S
> @@ -63,7 +63,7 @@ SECTIONS
>         . = ALIGN(4);
>         __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
>                 __start___ex_table = .;
> -               ARM_MMU_KEEP(*(__ex_table))
> +               ARM_MMU_KEEP(KEEP(*(__ex_table)))
>                 __stop___ex_table = .;
>         }
>
> @@ -83,7 +83,7 @@ SECTIONS
>         }
>         .init.arch.info : {
>                 __arch_info_begin = .;
> -               *(.arch.info.init)
> +               KEEP(*(.arch.info.init))
>                 __arch_info_end = .;
>         }
>         .init.tagtable : {
> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
> index bd9127c4b451..de373c6c2ae8 100644
> --- a/arch/arm/kernel/vmlinux.lds.S
> +++ b/arch/arm/kernel/vmlinux.lds.S
> @@ -74,7 +74,7 @@ SECTIONS
>         . = ALIGN(4);
>         __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
>                 __start___ex_table = .;
> -               ARM_MMU_KEEP(*(__ex_table))
> +               ARM_MMU_KEEP(KEEP(*(__ex_table)))
>                 __stop___ex_table = .;
>         }
>
> @@ -99,7 +99,7 @@ SECTIONS
>         }
>         .init.arch.info : {
>                 __arch_info_begin = .;
> -               *(.arch.info.init)
> +               KEEP(*(.arch.info.init))
>                 __arch_info_end = .;
>         }
>         .init.tagtable : {
> @@ -116,7 +116,7 @@ SECTIONS
>  #endif
>         .init.pv_table : {
>                 __pv_table_begin = .;
> -               *(.pv_table)
> +               KEEP(*(.pv_table))
>                 __pv_table_end = .;
>         }
>
> --
> 2.34.1
>



More information about the linux-arm-kernel mailing list