diff mbox series

[v2,13/28] kbuild: lto: merge module sections

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

Commit Message

Sami Tolvanen Sept. 3, 2020, 8:30 p.m. UTC
LLD always splits sections with LTO, which increases module sizes. This
change adds a linker script that merges the split sections in the final
module.

Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
---
 Makefile               |  2 ++
 scripts/module-lto.lds | 26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+)
 create mode 100644 scripts/module-lto.lds

Comments

Kees Cook Sept. 3, 2020, 10:23 p.m. UTC | #1
On Thu, Sep 03, 2020 at 01:30:38PM -0700, Sami Tolvanen wrote:
> LLD always splits sections with LTO, which increases module sizes. This
> change adds a linker script that merges the split sections in the final
> module.
> 
> Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
> Signed-off-by: Sami Tolvanen <samitolvanen@google.com>

We'll likely need to come back around to this for FGKASLR (to keep the
.text.* sections separated), but that's no different than the existing
concerns for FGKASLR on the main kernel.

Reviewed-by: Kees Cook <keescook@chromium.org>
Masahiro Yamada Sept. 7, 2020, 3:25 p.m. UTC | #2
On Fri, Sep 4, 2020 at 5:31 AM Sami Tolvanen <samitolvanen@google.com> wrote:
>
> LLD always splits sections with LTO, which increases module sizes. This
> change adds a linker script that merges the split sections in the final
> module.
>
> Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
> Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
> ---
>  Makefile               |  2 ++
>  scripts/module-lto.lds | 26 ++++++++++++++++++++++++++
>  2 files changed, 28 insertions(+)
>  create mode 100644 scripts/module-lto.lds
>
> diff --git a/Makefile b/Makefile
> index c69e07bd506a..bb82a4323f1d 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -921,6 +921,8 @@ CC_FLAGS_LTO_CLANG += -fvisibility=default
>  # Limit inlining across translation units to reduce binary size
>  LD_FLAGS_LTO_CLANG := -mllvm -import-instr-limit=5
>  KBUILD_LDFLAGS += $(LD_FLAGS_LTO_CLANG)
> +
> +KBUILD_LDS_MODULE += $(srctree)/scripts/module-lto.lds
>  endif
>
>  ifdef CONFIG_LTO
> diff --git a/scripts/module-lto.lds b/scripts/module-lto.lds
> new file mode 100644
> index 000000000000..cbb11dc3639a
> --- /dev/null
> +++ b/scripts/module-lto.lds
> @@ -0,0 +1,26 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * 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.
> + */
> +SECTIONS {
> +       __patchable_function_entries : { *(__patchable_function_entries) }
> +
> +       .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_]*) }
> +}
> --
> 2.28.0.402.g5ffc5be6b7-goog
>


After I apply https://patchwork.kernel.org/patch/11757323/,
is it possible to do like this ?


#ifdef CONFIG_LTO
SECTIONS {
     ...
};
#endif

in scripts/module.lds.S
Sami Tolvanen Sept. 8, 2020, 9:07 p.m. UTC | #3
On Tue, Sep 08, 2020 at 12:25:54AM +0900, Masahiro Yamada wrote:
> On Fri, Sep 4, 2020 at 5:31 AM Sami Tolvanen <samitolvanen@google.com> wrote:
> >
> > LLD always splits sections with LTO, which increases module sizes. This
> > change adds a linker script that merges the split sections in the final
> > module.
> >
> > Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
> > Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
> > ---
> >  Makefile               |  2 ++
> >  scripts/module-lto.lds | 26 ++++++++++++++++++++++++++
> >  2 files changed, 28 insertions(+)
> >  create mode 100644 scripts/module-lto.lds
> >
> > diff --git a/Makefile b/Makefile
> > index c69e07bd506a..bb82a4323f1d 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -921,6 +921,8 @@ CC_FLAGS_LTO_CLANG += -fvisibility=default
> >  # Limit inlining across translation units to reduce binary size
> >  LD_FLAGS_LTO_CLANG := -mllvm -import-instr-limit=5
> >  KBUILD_LDFLAGS += $(LD_FLAGS_LTO_CLANG)
> > +
> > +KBUILD_LDS_MODULE += $(srctree)/scripts/module-lto.lds
> >  endif
> >
> >  ifdef CONFIG_LTO
> > diff --git a/scripts/module-lto.lds b/scripts/module-lto.lds
> > new file mode 100644
> > index 000000000000..cbb11dc3639a
> > --- /dev/null
> > +++ b/scripts/module-lto.lds
> > @@ -0,0 +1,26 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * 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.
> > + */
> > +SECTIONS {
> > +       __patchable_function_entries : { *(__patchable_function_entries) }
> > +
> > +       .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_]*) }
> > +}
> > --
> > 2.28.0.402.g5ffc5be6b7-goog
> >
> 
> 
> After I apply https://patchwork.kernel.org/patch/11757323/,
> is it possible to do like this ?
> 
> 
> #ifdef CONFIG_LTO
> SECTIONS {
>      ...
> };
> #endif
> 
> in scripts/module.lds.S

Yes, that should work. I'll change this in v3 after your change is
applied.

Sami
diff mbox series

Patch

diff --git a/Makefile b/Makefile
index c69e07bd506a..bb82a4323f1d 100644
--- a/Makefile
+++ b/Makefile
@@ -921,6 +921,8 @@  CC_FLAGS_LTO_CLANG += -fvisibility=default
 # Limit inlining across translation units to reduce binary size
 LD_FLAGS_LTO_CLANG := -mllvm -import-instr-limit=5
 KBUILD_LDFLAGS += $(LD_FLAGS_LTO_CLANG)
+
+KBUILD_LDS_MODULE += $(srctree)/scripts/module-lto.lds
 endif
 
 ifdef CONFIG_LTO
diff --git a/scripts/module-lto.lds b/scripts/module-lto.lds
new file mode 100644
index 000000000000..cbb11dc3639a
--- /dev/null
+++ b/scripts/module-lto.lds
@@ -0,0 +1,26 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * 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.
+ */
+SECTIONS {
+	__patchable_function_entries : { *(__patchable_function_entries) }
+
+	.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_]*) }
+}