From: Josh Poimboeuf Enable sframe generation in the VDSO library so kernel and user space can unwind through it. SFrame isn't supported for x32 or x86-32. Discard .sframe sections for those VDSOs. [ Jens Remus: Add support for SFrame V3. Prevent GNU_SFRAME program table entry to empty .sframe section. ] Signed-off-by: Josh Poimboeuf Signed-off-by: Steven Rostedt (Google) Signed-off-by: Jens Remus --- Notes (jremus): Changes in v8: - Discard .sframe for x32 and x86-32 VDSOs. (Josh/Indu) Note that the use of KEEP_SFRAME enables to define it for x86-64 VDSO only. Unlike CONFIG_AS_SFRAME, which may also be defined for x32 and x86-32 VDSO. In x32 VDSO it would result in superfluous .sframe (copied from the x86-64 build - could be removed in X32 build step). In x86-32 VDSO it would cause a bogus GNU_SFRAME program table entry. - Reword commit message (append Josh's private fix). - Drop .cfi_sections .sframe in dwarf2.h in favor of the explicitly specified more specific assembler option --gsframe-3. With this it is not necessary to undefine CONFIG_AS_SFRAME in fake_32bit_build.h. arch/Kconfig | 7 +++++++ arch/x86/entry/vdso/common/vdso-layout.lds.S | 15 +++++++++++++++ arch/x86/entry/vdso/vdso64/Makefile | 1 + arch/x86/entry/vdso/vdso64/vdso64.lds.S | 4 ++++ 4 files changed, 27 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index 31220f512b16..8170e492a44c 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -479,6 +479,13 @@ config HAVE_HARDLOCKUP_DETECTOR_ARCH It uses the same command line parameters, and sysctl interface, as the generic hardlockup detectors. +config AS_SFRAME + bool + +config AS_SFRAME3 + def_bool $(as-instr,.cfi_startproc\n.cfi_endproc,-Wa$(comma)--gsframe-3) + select AS_SFRAME + config UNWIND_USER bool diff --git a/arch/x86/entry/vdso/common/vdso-layout.lds.S b/arch/x86/entry/vdso/common/vdso-layout.lds.S index 856b8b9d278c..47e6a6a0560a 100644 --- a/arch/x86/entry/vdso/common/vdso-layout.lds.S +++ b/arch/x86/entry/vdso/common/vdso-layout.lds.S @@ -60,6 +60,13 @@ SECTIONS *(.eh_frame.*) } :text +#ifdef KEEP_SFRAME + .sframe : { + KEEP (*(.sframe)) + *(.sframe.*) + } :text :sframe +#endif + /* * Text is well-separated from actual data: there's plenty of * stuff that isn't used at runtime in between. @@ -80,6 +87,10 @@ SECTIONS *(.discard) *(.discard.*) *(__bug_table) +#ifndef KEEP_SFRAME + *(.sframe) + *(.sframe.*) +#endif } } @@ -89,6 +100,7 @@ SECTIONS #define PT_GNU_EH_FRAME 0x6474e550 #define PT_GNU_STACK 0x6474e551 #define PT_GNU_PROPERTY 0x6474e553 +#define PT_GNU_SFRAME 0x6474e554 /* * We must supply the ELF program headers explicitly to get just one @@ -104,6 +116,9 @@ PHDRS dynamic PT_DYNAMIC PF_R; note PT_NOTE PF_R; eh_frame_hdr PT_GNU_EH_FRAME PF_R; +#ifdef KEEP_SFRAME + sframe PT_GNU_SFRAME PF_R; +#endif gnu_stack PT_GNU_STACK PF_RW; gnu_property PT_GNU_PROPERTY PF_R; } diff --git a/arch/x86/entry/vdso/vdso64/Makefile b/arch/x86/entry/vdso/vdso64/Makefile index bfffaf1aeecc..459f8026531e 100644 --- a/arch/x86/entry/vdso/vdso64/Makefile +++ b/arch/x86/entry/vdso/vdso64/Makefile @@ -14,6 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o # Compilation flags flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small +flags-$(CONFIG_AS_SFRAME3) += -Wa,--gsframe-3 # The location of this include matters! include $(src)/../common/Makefile.include diff --git a/arch/x86/entry/vdso/vdso64/vdso64.lds.S b/arch/x86/entry/vdso/vdso64/vdso64.lds.S index 5ce3f2b6373a..13e30d3b4827 100644 --- a/arch/x86/entry/vdso/vdso64/vdso64.lds.S +++ b/arch/x86/entry/vdso/vdso64/vdso64.lds.S @@ -9,6 +9,10 @@ #define BUILD_VDSO64 +#ifdef CONFIG_AS_SFRAME +# define KEEP_SFRAME +#endif + #include "common/vdso-layout.lds.S" /* -- 2.51.0