diff mbox series

[v9,05/16] kbuild: lto: merge module sections

Message ID 20201211184633.3213045-6-samitolvanen@google.com (mailing list archive)
State New, archived
Headers show
Series Add support for Clang LTO | expand

Commit Message

Sami Tolvanen Dec. 11, 2020, 6:46 p.m. UTC
LLD always splits sections with LTO, which increases module sizes. This
change adds linker script rules to merge the split sections in the final
module.

Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
---
 scripts/module.lds.S | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

Comments

Stephen Boyd Feb. 16, 2021, 9:37 p.m. UTC | #1
Quoting Sami Tolvanen (2020-12-11 10:46:22)
> LLD always splits sections with LTO, which increases module sizes. This
> change adds linker script rules to merge the split sections in the final
> module.
> 
> Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
> Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
> Reviewed-by: Kees Cook <keescook@chromium.org>
> ---

This patch fixes a warning I see on arm64 devices running the 5.10 LTS kernel.
Can we queue this to the stable tree once it lands in Linus' tree?

 sysfs: cannot create duplicate filename '/module/configs/sections/__patchable_function_entries'
 CPU: 3 PID: 4173 Comm: modprobe Not tainted 5.10.13 #10
 Hardware name: Google Lazor (rev3+) with KB Backlight (DT)
 Call trace:
  dump_backtrace+0x0/0x1c0
  show_stack+0x24/0x30
  dump_stack+0xc0/0x120
  sysfs_warn_dup+0x74/0x90
  sysfs_add_file_mode_ns+0x12c/0x178
  internal_create_group+0x264/0x36c
  sysfs_create_group+0x24/0x30
  add_sect_attrs+0x154/0x188
  mod_sysfs_setup+0x208/0x284
  load_module+0xff8/0x1158
  __arm64_sys_finit_module+0xb4/0xf0
  el0_svc_common+0xf4/0x1c0
  do_el0_svc_compat+0x2c/0x40
  el0_svc_compat+0x10/0x1c
  el0_sync_compat_handler+0xc0/0xf0
  el0_sync_compat+0x178/0x180

The problem is that the section __patchable_function_entries is present
twice in the kernel module I've compiled. I see that
__patchable_function_entries is used on arm64 now that we have commit
a1326b17ac03 ("module/ftrace: handle patchable-function-entry") combined
with commit 3b23e4991fb6 ("arm64: implement ftrace with regs").

This linker script change nicely combines the section into one instead
of two.

Before:

$ readelf -WS configs.ko 
There are 29 section headers, starting at offset 0xad78:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .plt              NOBITS          0000000000000000 000040 000001 00  AX  0   0 16
  [ 2] .init.plt         NOBITS          0000000000000000 000040 000001 00  AX  0   0  1
  [ 3] .text.ftrace_trampoline NOBITS          0000000000000000 000040 000001 00  AX  0   0  1
  [ 4] .text             PROGBITS        0000000000000000 000040 00004c 00  AX  0   0  4
  [ 5] .rela.text        RELA            0000000000000000 00aa10 000078 18   I 26   4  8
  [ 6] __patchable_function_entries PROGBITS        0000000000000000 000090 000008 00 WAL  4   0  8
  [ 7] .rela__patchable_function_entries RELA            0000000000000000 00aa88 000018 18   I 26   6  8
  [ 8] .rodata           PROGBITS        0000000000000000 000098 009c98 00   A  0   0  8
  [ 9] .rela.rodata      RELA            0000000000000000 00aaa0 000030 18   I 26   8  8
  [10] .init.text        PROGBITS        0000000000000000 009d30 000068 00  AX  0   0  4
  [11] .rela.init.text   RELA            0000000000000000 00aad0 0000f0 18   I 26  10  8
  [12] __patchable_function_entries PROGBITS        0000000000000000 009d98 000008 00 WAL 10   0  8
  [13] .rela__patchable_function_entries RELA            0000000000000000 00abc0 000018 18   I 26  12  8
  [14] .exit.text        PROGBITS        0000000000000000 009da0 000028 00  AX  0   0  4
  [15] .rela.exit.text   RELA            0000000000000000 00abd8 000048 18   I 26  14  8
  [16] .modinfo          PROGBITS        0000000000000000 009dc8 0000b1 00   A  0   0  1
  [17] .rodata.str1.1    PROGBITS        0000000000000000 009e79 00000a 01 AMS  0   0  1
  [18] .comment          PROGBITS        0000000000000000 009e83 0000ce 01  MS  0   0  1
  [19] .note.Linux       NOTE            0000000000000000 009f54 000018 00   A  0   0  4
  [20] .gnu.linkonce.this_module PROGBITS        0000000000000000 009f80 000380 00  WA  0   0 64
  [21] .rela.gnu.linkonce.this_module RELA            0000000000000000 00ac20 000030 18   I 26  20  8
  [22] .note.gnu.build-id NOTE            0000000000000000 00a300 000024 00   A  0   0  4
  [23] .note.gnu.property NOTE            0000000000000000 00a328 000020 00   A  0   0  8
  [24] .note.GNU-stack   PROGBITS        0000000000000000 00a348 000000 00      0   0  1
  [25] .gnu_debuglink    PROGBITS        0000000000000000 00a348 000018 00      0   0  4
  [26] .symtab           SYMTAB          0000000000000000 00a360 0004f8 18     27  43  8
  [27] .strtab           STRTAB          0000000000000000 00a858 0001b1 00      0   0  1
  [28] .shstrtab         STRTAB          0000000000000000 00ac50 000128 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  p (processor specific)

After:

$ readelf -WS configs.ko 
There are 26 section headers, starting at offset 0xad40:
 
Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] __patchable_function_entries PROGBITS        0000000000000000 000040 000010 00 WAL  5   0  8
  [ 2] .rela__patchable_function_entries RELA            0000000000000000 00a9e0 000030 18   I 23   1  8
  [ 3] .rodata           PROGBITS        0000000000000000 000050 009ca2 00 AMS  0   0  8
  [ 4] .rela.rodata      RELA            0000000000000000 00aa10 000030 18   I 23   3  8
  [ 5] .text             PROGBITS        0000000000000000 009cf4 00004c 00  AX  0   0  4
  [ 6] .rela.text        RELA            0000000000000000 00aa40 000078 18   I 23   5  8
  [ 7] .plt              NOBITS          0000000000000000 009d40 000001 00  AX  0   0 16
  [ 8] .init.plt         NOBITS          0000000000000000 009d40 000001 00  AX  0   0  1
  [ 9] .text.ftrace_trampoline NOBITS          0000000000000000 009d40 000001 00  AX  0   0  1
  [10] .init.text        PROGBITS        0000000000000000 009d40 000068 00  AX  0   0  4
  [11] .rela.init.text   RELA            0000000000000000 00aab8 0000f0 18   I 23  10  8
  [12] .exit.text        PROGBITS        0000000000000000 009da8 000028 00  AX  0   0  4
  [13] .rela.exit.text   RELA            0000000000000000 00aba8 000048 18   I 23  12  8
  [14] .modinfo          PROGBITS        0000000000000000 009dd0 0000b1 00   A  0   0  1
  [15] .comment          PROGBITS        0000000000000000 009e81 0000ce 01  MS  0   0  1
  [16] .note.Linux       NOTE            0000000000000000 009f50 000018 00   A  0   0  4
  [17] .gnu.linkonce.this_module PROGBITS        0000000000000000 009f80 000380 00  WA  0   0 64
  [18] .rela.gnu.linkonce.this_module RELA            0000000000000000 00abf0 000030 18   I 23  17  8
  [19] .note.gnu.build-id NOTE            0000000000000000 00a300 000024 00   A  0   0  4
  [20] .note.gnu.property NOTE            0000000000000000 00a328 000020 00   A  0   0  8
  [21] .note.GNU-stack   PROGBITS        0000000000000000 00a348 000000 00      0   0  1
  [22] .gnu_debuglink    PROGBITS        0000000000000000 00a348 000018 00      0   0  4
  [23] .symtab           SYMTAB          0000000000000000 00a360 0004c8 18     24  41  8
  [24] .strtab           STRTAB          0000000000000000 00a828 0001b1 00      0   0  1
  [25] .shstrtab         STRTAB          0000000000000000 00ac20 000119 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  p (processor specific)

>  scripts/module.lds.S | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/scripts/module.lds.S b/scripts/module.lds.S
> index 69b9b71a6a47..18d5b8423635 100644
> --- a/scripts/module.lds.S
> +++ b/scripts/module.lds.S
> @@ -23,6 +23,30 @@ SECTIONS {
>         .init_array             0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) }
>  
>         __jump_table            0 : ALIGN(8) { KEEP(*(__jump_table)) }
> +
> +       __patchable_function_entries : { *(__patchable_function_entries) }
> +
> +       /*
> +        * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and
> +        * -ffunction-sections, which increases the size of the final module.
> +        * Merge the split sections in the final binary.
> +        */
> +       .bss : {
> +               *(.bss .bss.[0-9a-zA-Z_]*)
> +               *(.bss..L*)
> +       }
> +
> +       .data : {
> +               *(.data .data.[0-9a-zA-Z_]*)
> +               *(.data..L*)
> +       }
> +
> +       .rodata : {
> +               *(.rodata .rodata.[0-9a-zA-Z_]*)
> +               *(.rodata..L*)
> +       }
> +
> +       .text : { *(.text .text.[0-9a-zA-Z_]*) }
>  }
>
diff mbox series

Patch

diff --git a/scripts/module.lds.S b/scripts/module.lds.S
index 69b9b71a6a47..18d5b8423635 100644
--- a/scripts/module.lds.S
+++ b/scripts/module.lds.S
@@ -23,6 +23,30 @@  SECTIONS {
 	.init_array		0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) }
 
 	__jump_table		0 : ALIGN(8) { KEEP(*(__jump_table)) }
+
+	__patchable_function_entries : { *(__patchable_function_entries) }
+
+	/*
+	 * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and
+	 * -ffunction-sections, which increases the size of the final module.
+	 * Merge the split sections in the final binary.
+	 */
+	.bss : {
+		*(.bss .bss.[0-9a-zA-Z_]*)
+		*(.bss..L*)
+	}
+
+	.data : {
+		*(.data .data.[0-9a-zA-Z_]*)
+		*(.data..L*)
+	}
+
+	.rodata : {
+		*(.rodata .rodata.[0-9a-zA-Z_]*)
+		*(.rodata..L*)
+	}
+
+	.text : { *(.text .text.[0-9a-zA-Z_]*) }
 }
 
 /* bring in arch-specific sections */