[RFC 30/31] livepatch: Enable -ffunction-sections -fdata-sections

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Doing a binary diff of two objects can be problematic:

  - For intra-section references, the compiler might use hard-coded
    offsets rather than relocations.

  - Data references can be ambiguous if the compiler uses section symbol
    references:

    - Symbol overlap and zero-length symbols create ambiguity as to
      which symbol is being referenced.

    - An access to the end of a symbol (e.g., array bounds) could be
      incorrectly interpreted as an access to the beginning of the next
      symbol.

Remove those ambiguities by turning on -ffunction-sections and
-fdata-sections for CONFIG_LIVEPATCH.

They could alternatively be turned on only during the comparison builds,
rather than also in the production kernel, but that might theoretically
leave the possibility open for unexpected differences between the
kernels.  The compared kernels should be identical to the original
kernel as much as possible.

The performance impact should be small.  Intra-TU references are quite
rare in practice.  And the resulting final code layout is similar.

Distros are likely going to start using these options soon anyway for
things like LTO and fgKASLR.

A potential alternative approach would be to add a toolchain option to
always use (symbol) relocations.

Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
---
 Makefile                          |  9 +++++++++
 include/asm-generic/vmlinux.lds.h |  2 +-
 scripts/Makefile.lib              |  2 +-
 scripts/module.lds.S              | 13 +++++++++----
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 3d10e3aadeda..2a15b560ecc0 100644
--- a/Makefile
+++ b/Makefile
@@ -931,10 +931,19 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH
 KBUILD_CFLAGS += -fno-inline-functions-called-once
 endif
 
+ifdef CONFIG_LIVEPATCH
+KBUILD_CFLAGS += -ffunction-sections -fdata-sections
 # `rustc`'s `-Zfunction-sections` applies to data too (as of 1.59.0).
+KBUILD_RUSTFLAGS += -Zfunction-sections=y
+else
 ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
 KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections
+# `rustc`'s `-Zfunction-sections` applies to data too (as of 1.59.0).
 KBUILD_RUSTFLAGS_KERNEL += -Zfunction-sections=y
+endif
+endif
+
+ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
 LDFLAGS_vmlinux += --gc-sections
 endif
 
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 5703526d6ebf..a7ac3ca596ad 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -98,7 +98,7 @@
  * RODATA_MAIN is not used because existing code already defines .rodata.x
  * sections to be brought in with rodata.
  */
-#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG)
+#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG) || defined(CONFIG_LIVEPATCH)
 #define TEXT_MAIN .text .text.[0-9a-zA-Z_]*
 #define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..L* .data..compoundliteral* .data.$__unnamed_* .data.$L*
 #define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]*
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 9f4708702ef7..ca7497f74247 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -289,7 +289,7 @@ objtool-args = $(objtool-args-y)					\
 	$(if $(delay-objtool), --link)					\
 	$(if $(part-of-module), --module)
 
-delay-objtool := $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT))
+delay-objtool := $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT),$(CONFIG_LIVEPATCH))
 
 cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool-args) $@)
 cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd)
diff --git a/scripts/module.lds.S b/scripts/module.lds.S
index 3f43edef813c..5cbae820bca0 100644
--- a/scripts/module.lds.S
+++ b/scripts/module.lds.S
@@ -36,12 +36,17 @@ SECTIONS {
 	__kcfi_traps 		: { KEEP(*(.kcfi_traps)) }
 #endif
 
-#ifdef CONFIG_LTO_CLANG
+#if defined(CONFIG_LTO_CLANG) || defined(CONFIG_LIVEPATCH)
+
 	/*
-	 * 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.
+	 * Merge -ffunction-sections and -fdata-sections sections to decrease
+	 * module size.
 	 */
+
+	.text : {
+		*(.text .text.[0-9a-zA-Z_]*)
+	}
+
 	.bss : {
 		*(.bss .bss.[0-9a-zA-Z_]*)
 		*(.bss..L*)
-- 
2.45.2





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux