Browse Source

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>
Hendrik Brueckner 7 years ago
parent
commit
bc3703f21c

+ 1 - 0
arch/s390/Makefile

@@ -90,6 +90,7 @@ endif
 
 KBUILD_CFLAGS	+= -mbackchain -msoft-float $(cflags-y)
 KBUILD_CFLAGS	+= -pipe -fno-strength-reduce -Wno-sign-compare
+KBUILD_CFLAGS	+= -fno-asynchronous-unwind-tables
 KBUILD_AFLAGS	+= $(aflags-y)
 
 OBJCOPYFLAGS	:= -O binary

+ 25 - 0
arch/s390/include/asm/dwarf.h

@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_S390_DWARF_H
+#define _ASM_S390_DWARF_H
+
+#ifdef __ASSEMBLY__
+
+#ifndef BUILD_VDSO
+	/*
+	 * Emit CFI data in .debug_frame sections and not in .eh_frame
+	 * sections.  The .eh_frame CFI is used for runtime unwind
+	 * information that is not being used.  Hence, vmlinux.lds.S
+	 * can discard the .eh_frame sections.
+	 */
+	.cfi_sections .debug_frame
+#else
+	/*
+	 * For vDSO, emit CFI data in both, .eh_frame and .debug_frame
+	 * sections.
+	 */
+	.cfi_sections .eh_frame, .debug_frame
+#endif
+
+#endif	/* __ASSEMBLY__ */
+
+#endif	/* _ASM_S390_DWARF_H */

+ 3 - 0
arch/s390/kernel/vdso32/Makefile

@@ -10,6 +10,9 @@ obj-vdso32 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o
 targets := $(obj-vdso32) vdso32.so vdso32.so.dbg
 obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
 
+KBUILD_AFLAGS += -DBUILD_VDSO
+KBUILD_CFLAGS += -DBUILD_VDSO
+
 KBUILD_AFLAGS_31 := $(filter-out -m64,$(KBUILD_AFLAGS))
 KBUILD_AFLAGS_31 += -m31 -s
 

+ 1 - 0
arch/s390/kernel/vdso32/clock_getres.S

@@ -9,6 +9,7 @@
 #include <asm/vdso.h>
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
+#include <asm/dwarf.h>
 
 	.text
 	.align 4

+ 1 - 0
arch/s390/kernel/vdso32/clock_gettime.S

@@ -9,6 +9,7 @@
 #include <asm/vdso.h>
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
+#include <asm/dwarf.h>
 
 	.text
 	.align 4

+ 1 - 0
arch/s390/kernel/vdso32/getcpu.S

@@ -8,6 +8,7 @@
  */
 #include <asm/vdso.h>
 #include <asm/asm-offsets.h>
+#include <asm/dwarf.h>
 
 	.text
 	.align 4

+ 1 - 0
arch/s390/kernel/vdso32/gettimeofday.S

@@ -9,6 +9,7 @@
 #include <asm/vdso.h>
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
+#include <asm/dwarf.h>
 
 	.text
 	.align 4

+ 3 - 0
arch/s390/kernel/vdso64/Makefile

@@ -10,6 +10,9 @@ obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o
 targets := $(obj-vdso64) vdso64.so vdso64.so.dbg
 obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
 
+KBUILD_AFLAGS += -DBUILD_VDSO
+KBUILD_CFLAGS += -DBUILD_VDSO
+
 KBUILD_AFLAGS_64 := $(filter-out -m64,$(KBUILD_AFLAGS))
 KBUILD_AFLAGS_64 += -m64 -s
 

+ 1 - 0
arch/s390/kernel/vdso64/clock_getres.S

@@ -9,6 +9,7 @@
 #include <asm/vdso.h>
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
+#include <asm/dwarf.h>
 
 	.text
 	.align 4

+ 1 - 0
arch/s390/kernel/vdso64/clock_gettime.S

@@ -9,6 +9,7 @@
 #include <asm/vdso.h>
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
+#include <asm/dwarf.h>
 
 	.text
 	.align 4

+ 1 - 0
arch/s390/kernel/vdso64/getcpu.S

@@ -8,6 +8,7 @@
  */
 #include <asm/vdso.h>
 #include <asm/asm-offsets.h>
+#include <asm/dwarf.h>
 
 	.text
 	.align 4

+ 1 - 0
arch/s390/kernel/vdso64/gettimeofday.S

@@ -9,6 +9,7 @@
 #include <asm/vdso.h>
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
+#include <asm/dwarf.h>
 
 	.text
 	.align 4

+ 3 - 0
arch/s390/kernel/vmlinux.lds.S

@@ -141,4 +141,7 @@ SECTIONS
 
 	/* Sections to be discarded */
 	DISCARDS
+	/DISCARD/ : {
+		*(.eh_frame)
+	}
 }