Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/kernel: emit CFI data in .debug_frame and discard .eh_frame sections

Using perf probe and libdw on kernel modules failed to find CFI
data for symbols. The CFI data is stored in the .eh_frame section.
The elfutils libdw is not able to extract the CFI data correctly,
because the .eh_frame section requires "non-simple" relocations
for kernel modules.

The suggestion is to avoid these "non-simple" relocations by emitting
the CFI data in the .debug_frame section. Let gcc emit respective
directives by specifying the -fno-asynchronous-unwind-tables option.

Using the .debug_frame section for CFI data, the .eh_frame section
becomes unused and, thus, discard it for kernel and modules builds

The vDSO requires the .eh_frame section and, hence, emit the CFI data
in both, the .eh_frame and .debug_frame sections.

See also discussion on elfutils/libdw bugzilla:
https://sourceware.org/bugzilla/show_bug.cgi?id=22452

Suggested-by: Mark Wielaard <mark@klomp.org>
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Hendrik Brueckner and committed by
Martin Schwidefsky
bc3703f2 a5f10055

+43
+1
arch/s390/Makefile
··· 90 90 91 91 KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y) 92 92 KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare 93 + KBUILD_CFLAGS += -fno-asynchronous-unwind-tables 93 94 KBUILD_AFLAGS += $(aflags-y) 94 95 95 96 OBJCOPYFLAGS := -O binary
+25
arch/s390/include/asm/dwarf.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _ASM_S390_DWARF_H 3 + #define _ASM_S390_DWARF_H 4 + 5 + #ifdef __ASSEMBLY__ 6 + 7 + #ifndef BUILD_VDSO 8 + /* 9 + * Emit CFI data in .debug_frame sections and not in .eh_frame 10 + * sections. The .eh_frame CFI is used for runtime unwind 11 + * information that is not being used. Hence, vmlinux.lds.S 12 + * can discard the .eh_frame sections. 13 + */ 14 + .cfi_sections .debug_frame 15 + #else 16 + /* 17 + * For vDSO, emit CFI data in both, .eh_frame and .debug_frame 18 + * sections. 19 + */ 20 + .cfi_sections .eh_frame, .debug_frame 21 + #endif 22 + 23 + #endif /* __ASSEMBLY__ */ 24 + 25 + #endif /* _ASM_S390_DWARF_H */
+3
arch/s390/kernel/vdso32/Makefile
··· 10 10 targets := $(obj-vdso32) vdso32.so vdso32.so.dbg 11 11 obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) 12 12 13 + KBUILD_AFLAGS += -DBUILD_VDSO 14 + KBUILD_CFLAGS += -DBUILD_VDSO 15 + 13 16 KBUILD_AFLAGS_31 := $(filter-out -m64,$(KBUILD_AFLAGS)) 14 17 KBUILD_AFLAGS_31 += -m31 -s 15 18
+1
arch/s390/kernel/vdso32/clock_getres.S
··· 9 9 #include <asm/vdso.h> 10 10 #include <asm/asm-offsets.h> 11 11 #include <asm/unistd.h> 12 + #include <asm/dwarf.h> 12 13 13 14 .text 14 15 .align 4
+1
arch/s390/kernel/vdso32/clock_gettime.S
··· 9 9 #include <asm/vdso.h> 10 10 #include <asm/asm-offsets.h> 11 11 #include <asm/unistd.h> 12 + #include <asm/dwarf.h> 12 13 13 14 .text 14 15 .align 4
+1
arch/s390/kernel/vdso32/getcpu.S
··· 8 8 */ 9 9 #include <asm/vdso.h> 10 10 #include <asm/asm-offsets.h> 11 + #include <asm/dwarf.h> 11 12 12 13 .text 13 14 .align 4
+1
arch/s390/kernel/vdso32/gettimeofday.S
··· 9 9 #include <asm/vdso.h> 10 10 #include <asm/asm-offsets.h> 11 11 #include <asm/unistd.h> 12 + #include <asm/dwarf.h> 12 13 13 14 .text 14 15 .align 4
+3
arch/s390/kernel/vdso64/Makefile
··· 10 10 targets := $(obj-vdso64) vdso64.so vdso64.so.dbg 11 11 obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64)) 12 12 13 + KBUILD_AFLAGS += -DBUILD_VDSO 14 + KBUILD_CFLAGS += -DBUILD_VDSO 15 + 13 16 KBUILD_AFLAGS_64 := $(filter-out -m64,$(KBUILD_AFLAGS)) 14 17 KBUILD_AFLAGS_64 += -m64 -s 15 18
+1
arch/s390/kernel/vdso64/clock_getres.S
··· 9 9 #include <asm/vdso.h> 10 10 #include <asm/asm-offsets.h> 11 11 #include <asm/unistd.h> 12 + #include <asm/dwarf.h> 12 13 13 14 .text 14 15 .align 4
+1
arch/s390/kernel/vdso64/clock_gettime.S
··· 9 9 #include <asm/vdso.h> 10 10 #include <asm/asm-offsets.h> 11 11 #include <asm/unistd.h> 12 + #include <asm/dwarf.h> 12 13 13 14 .text 14 15 .align 4
+1
arch/s390/kernel/vdso64/getcpu.S
··· 8 8 */ 9 9 #include <asm/vdso.h> 10 10 #include <asm/asm-offsets.h> 11 + #include <asm/dwarf.h> 11 12 12 13 .text 13 14 .align 4
+1
arch/s390/kernel/vdso64/gettimeofday.S
··· 9 9 #include <asm/vdso.h> 10 10 #include <asm/asm-offsets.h> 11 11 #include <asm/unistd.h> 12 + #include <asm/dwarf.h> 12 13 13 14 .text 14 15 .align 4
+3
arch/s390/kernel/vmlinux.lds.S
··· 141 141 142 142 /* Sections to be discarded */ 143 143 DISCARDS 144 + /DISCARD/ : { 145 + *(.eh_frame) 146 + } 144 147 }