This series hunts the problems discovered after manual enabling of ARCH_WANT_LD_ORPHAN_WARN. Notably: - adds the missing PAGE_ALIGNED_DATA() section affecting VDSO placement (marked for stable); - properly stops .eh_frame section generation.
Compile and runtime tested on MIPS32R2 CPS board with no issues using two different toolkits: - Binutils 2.35.1, GCC 10.2.0; - LLVM stack 11.0.0.
Since v2 [1]: - stop discarding .eh_frame and just prevent it from generating (Kees); - drop redundant sections assertions (Fangrui); - place GOT table in .text instead of asserting as it's not empty when building with LLVM (Nathan); - catch compound literals in generic definitions when building with LD_DEAD_CODE_DATA_ELIMINATION (Kees); - collect two Reviewed-bys (Kees).
Since v1 [0]: - catch .got entries too as LLD may produce it (Nathan); - check for unwanted sections to be zero-sized instead of discarding (Fangrui).
[0] https://lore.kernel.org/linux-mips/20210104121729.46981-1-alobakin@pm.me [1] https://lore.kernel.org/linux-mips/20210106200713.31840-1-alobakin@pm.me
Alexander Lobakin (7): MIPS: vmlinux.lds.S: add missing PAGE_ALIGNED_DATA() section MIPS: vmlinux.lds.S: add ".gnu.attributes" to DISCARDS MIPS: properly stop .eh_frame generation MIPS: vmlinux.lds.S: catch bad .rel.dyn at link time MIPS: vmlinux.lds.S: explicitly declare .got table vmlinux.lds.h: catch compound literals into data and BSS MIPS: select ARCH_WANT_LD_ORPHAN_WARN
arch/mips/Kconfig | 1 + arch/mips/include/asm/asm.h | 18 ++++++++++++++++++ arch/mips/kernel/vmlinux.lds.S | 15 ++++++++++++++- include/asm-generic/vmlinux.lds.h | 6 +++--- 4 files changed, 36 insertions(+), 4 deletions(-)
MIPS uses its own declaration of rwdata, and thus it should be kept in sync with the asm-generic one. Currently PAGE_ALIGNED_DATA() is missing from the linker script, which emits the following ld warnings:
mips-alpine-linux-musl-ld: warning: orphan section `.data..page_aligned' from `arch/mips/kernel/vdso.o' being placed in section `.data..page_aligned' mips-alpine-linux-musl-ld: warning: orphan section `.data..page_aligned' from `arch/mips/vdso/vdso-image.o' being placed in section `.data..page_aligned'
Add the necessary declaration, so the mentioned structures will be placed in vmlinux as intended:
ffffffff80630580 D __end_once ffffffff80630580 D __start___dyndbg ffffffff80630580 D __start_once ffffffff80630580 D __stop___dyndbg ffffffff80634000 d mips_vdso_data ffffffff80638000 d vdso_data ffffffff80638580 D _gp ffffffff8063c000 T __init_begin ffffffff8063c000 D _edata ffffffff8063c000 T _sinittext
->
ffffffff805a4000 D __end_init_task ffffffff805a4000 D __nosave_begin ffffffff805a4000 D __nosave_end ffffffff805a4000 d mips_vdso_data ffffffff805a8000 d vdso_data ffffffff805ac000 D mmlist_lock ffffffff805ac080 D tasklist_lock
Fixes: ebb5e78cc634 ("MIPS: Initial implementation of a VDSO") Cc: stable@vger.kernel.org # 4.4+ Signed-off-by: Alexander Lobakin alobakin@pm.me Reviewed-by: Kees Cook keescook@chromium.org --- arch/mips/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 5e97e9d02f98..83e27a181206 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -90,6 +90,7 @@ SECTIONS
INIT_TASK_DATA(THREAD_SIZE) NOSAVE_DATA + PAGE_ALIGNED_DATA(PAGE_SIZE) CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) DATA_DATA
Discard GNU attributes (MIPS FP type, GNU Hash etc.) at link time as kernel doesn't use it at all. Solves a dozen of the following ld warnings (one per every file):
mips-alpine-linux-musl-ld: warning: orphan section `.gnu.attributes' from `arch/mips/kernel/head.o' being placed in section `.gnu.attributes' mips-alpine-linux-musl-ld: warning: orphan section `.gnu.attributes' from `init/main.o' being placed in section `.gnu.attributes'
Signed-off-by: Alexander Lobakin alobakin@pm.me --- arch/mips/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 83e27a181206..16468957cba2 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -221,6 +221,7 @@ SECTIONS /* ABI crap starts here */ *(.MIPS.abiflags) *(.MIPS.options) + *(.gnu.attributes) *(.options) *(.pdr) *(.reginfo)
Commit 866b6a89c6d1 ("MIPS: Add DWARF unwinding to assembly") added -fno-asynchronous-unwind-tables to KBUILD_CFLAGS to prevent compiler from emitting .eh_frame symbols. However, as MIPS heavily uses CFI, that's not enough. Use the approach taken for x86 (as it also uses CFI) and explicitly put CFI symbols into the .debug_frame section (except for VDSO). This allows us to drop .eh_frame from DISCARDS as it's no longer being generated.
Fixes: 866b6a89c6d1 ("MIPS: Add DWARF unwinding to assembly") Suggested-by: Kees Cook keescook@chromium.org Signed-off-by: Alexander Lobakin alobakin@pm.me --- arch/mips/include/asm/asm.h | 18 ++++++++++++++++++ arch/mips/kernel/vmlinux.lds.S | 1 - 2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h index 3682d1a0bb80..908f6d6ae24b 100644 --- a/arch/mips/include/asm/asm.h +++ b/arch/mips/include/asm/asm.h @@ -20,10 +20,27 @@ #include <asm/sgidefs.h> #include <asm/asm-eva.h>
+#ifndef __VDSO__ +/* + * Emit CFI data in .debug_frame sections, not .eh_frame sections. + * We don't do DWARF unwinding at runtime, so only the offline DWARF + * information is useful to anyone. Note we should change this if we + * ever decide to enable DWARF unwinding at runtime. + */ +#define CFI_SECTIONS .cfi_sections .debug_frame +#else + /* + * For the vDSO, emit both runtime unwind information and debug + * symbols for the .dbg file. + */ +#define CFI_SECTIONS .cfi_sections .debug_frame, .eh_frame +#endif + /* * LEAF - declare leaf routine */ #define LEAF(symbol) \ + CFI_SECTIONS; \ .globl symbol; \ .align 2; \ .type symbol, @function; \ @@ -36,6 +53,7 @@ symbol: .frame sp, 0, ra; \ * NESTED - declare nested routine entry point */ #define NESTED(symbol, framesize, rpc) \ + CFI_SECTIONS; \ .globl symbol; \ .align 2; \ .type symbol, @function; \ diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 16468957cba2..0f4e46ea4458 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -225,6 +225,5 @@ SECTIONS *(.options) *(.pdr) *(.reginfo) - *(.eh_frame) } }
Catch any symbols placed in .rel.dyn and check for these sections to be zero-sized at link time. Eliminates following ld warning:
mips-alpine-linux-musl-ld: warning: orphan section `.rel.dyn' from `init/main.o' being placed in section `.rel.dyn'
Adopted from x86/kernel/vmlinux.lds.S.
Suggested-by: Fangrui Song maskray@google.com Signed-off-by: Alexander Lobakin alobakin@pm.me --- arch/mips/kernel/vmlinux.lds.S | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 0f4e46ea4458..0f736d60d43e 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -226,4 +226,15 @@ SECTIONS *(.pdr) *(.reginfo) } + + /* + * Sections that should stay zero sized, which is safer to + * explicitly check instead of blindly discarding. + */ + + .rel.dyn : { + *(.rel.*) + *(.rel_*) + } + ASSERT(SIZEOF(.rel.dyn) == 0, "Unexpected run-time relocations (.rel) detected!") }
LLVM stack generates GOT table when building the kernel:
ld.lld: warning: <internal>:(.got) is being placed in '.got'
According to the debug assertions, it's not zero-sized and thus can't be handled the same way as .rel.dyn (like it's done for x86). Use the ARM/ARM64 path here and place it at the end of .text section.
Reported-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Alexander Lobakin alobakin@pm.me --- arch/mips/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 0f736d60d43e..4709959f6985 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -69,6 +69,7 @@ SECTIONS *(.text.*) *(.fixup) *(.gnu.warning) + *(.got) } :text = 0 _etext = .; /* End of text section */
When building kernel with LD_DEAD_CODE_DATA_ELIMINATION, LLVM stack generates separate sections for compound literals, just like in case with enabled LTO [0]:
ld.lld: warning: drivers/built-in.a(mtd/nand/spi/gigadevice.o): (.data..compoundliteral.14) is being placed in '.data..compoundliteral.14' ld.lld: warning: drivers/built-in.a(mtd/nand/spi/gigadevice.o): (.data..compoundliteral.15) is being placed in '.data..compoundliteral.15' ld.lld: warning: drivers/built-in.a(mtd/nand/spi/gigadevice.o): (.data..compoundliteral.16) is being placed in '.data..compoundliteral.16' ld.lld: warning: drivers/built-in.a(mtd/nand/spi/gigadevice.o): (.data..compoundliteral.17) is being placed in '.data..compoundliteral.17'
[...]
Handle this by adding the related sections to generic definitions as suggested by Sami [0].
[0] https://lore.kernel.org/lkml/20201211184633.3213045-3-samitolvanen@google.co...
Suggested-by: Kees Cook keescook@chromium.org Signed-off-by: Alexander Lobakin alobakin@pm.me --- include/asm-generic/vmlinux.lds.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index b2b3d81b1535..5f2f5b1db84f 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -95,10 +95,10 @@ */ #ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION #define TEXT_MAIN .text .text.[0-9a-zA-Z_]* -#define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..LPBX* +#define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..L* .data..compoundliteral* #define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]* -#define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* -#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* +#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_]* #else #define TEXT_MAIN .text
Now, after that all the sections are explicitly described and declared in vmlinux.lds.S, we can enable ld orphan warnings to prevent from missing any new sections in future.
Signed-off-by: Alexander Lobakin alobakin@pm.me Reviewed-by: Kees Cook keescook@chromium.org --- arch/mips/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d68df1febd25..d3e64cc0932b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -18,6 +18,7 @@ config MIPS select ARCH_USE_QUEUED_SPINLOCKS select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU select ARCH_WANT_IPC_PARSE_VERSION + select ARCH_WANT_LD_ORPHAN_WARN select BUILDTIME_TABLE_SORT select CLONE_BACKWARDS select CPU_NO_EFFICIENT_FFS if (TARGET_ISA_REV < 1)
This series hunts the problems discovered after manual enabling of ARCH_WANT_LD_ORPHAN_WARN. Notably:
- adds the missing PAGE_ALIGNED_DATA() section affecting VDSO placement (marked for stable);
- properly stops .eh_frame section generation.
Compile and runtime tested on MIPS32R2 CPS board with no issues using two different toolkits:
- Binutils 2.35.1, GCC 10.2.0;
- LLVM stack 11.0.0.
Since v2 [1]:
- stop discarding .eh_frame and just prevent it from generating (Kees);
- drop redundant sections assertions (Fangrui);
- place GOT table in .text instead of asserting as it's not empty when building with LLVM (Nathan);
- catch compound literals in generic definitions when building with LD_DEAD_CODE_DATA_ELIMINATION (Kees);
- collect two Reviewed-bys (Kees).
Since v1 [0]:
- catch .got entries too as LLD may produce it (Nathan);
- check for unwanted sections to be zero-sized instead of discarding (Fangrui).
[0] https://lore.kernel.org/linux-mips/20210104121729.46981-1-alobakin@pm.me [1] https://lore.kernel.org/linux-mips/20210106200713.31840-1-alobakin@pm.me
Alexander Lobakin (7): MIPS: vmlinux.lds.S: add missing PAGE_ALIGNED_DATA() section MIPS: vmlinux.lds.S: add ".gnu.attributes" to DISCARDS MIPS: properly stop .eh_frame generation
Well, GNU fails to build VDSO with this patch... Sorry, sending v4 now.
MIPS: vmlinux.lds.S: catch bad .rel.dyn at link time MIPS: vmlinux.lds.S: explicitly declare .got table vmlinux.lds.h: catch compound literals into data and BSS MIPS: select ARCH_WANT_LD_ORPHAN_WARN
arch/mips/Kconfig | 1 + arch/mips/include/asm/asm.h | 18 ++++++++++++++++++ arch/mips/kernel/vmlinux.lds.S | 15 ++++++++++++++- include/asm-generic/vmlinux.lds.h | 6 +++--- 4 files changed, 36 insertions(+), 4 deletions(-)
-- 2.30.0
Al
linux-stable-mirror@lists.linaro.org