From: Josh Poimboeuf <jpoimboe@kernel.org>
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 <jpoimboe@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---
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
On 2026-02-06 11:36, Jens Remus wrote: > From: Josh Poimboeuf <jpoimboe@kernel.org> > > 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. ] > This will not break the x86-32 build if the assembler encounters .sframe? > 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. For x32, this would be a "valid" sframe, right, even if the tools currently don't know how to consume it (and potentially never will)? If so, is there really any reason to explicitly remove it? > /* > * 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 This #ifndef is actually not necessary: if we have already "consumed" the .sframe* sections they will not be encountered here. I would prefer to have KEEP_SFRAME always defined (as true or false, and using #if) instead of using #ifdef. I believe that also means you can do: #define KEEP_SFRAME IS_ENABLED(CONFIG_AS_SFRAME) ... instead of #ifdef. -hpa
© 2016 - 2026 Red Hat, Inc.