From: Jens Remus <jremus@linux.ibm.com>
To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
linux-s390@vger.kernel.org, x86@kernel.org,
Steven Rostedt <rostedt@kernel.org>,
Josh Poimboeuf <jpoimboe@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Heiko Carstens <hca@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Alexander Gordeev <agordeev@linux.ibm.com>,
Ilya Leoshkevich <iii@linux.ibm.com>,
Indu Bhagat <ibhagatgnu@gmail.com>,
Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
"H. Peter Anvin" <hpa@zytor.com>,
Namhyung Kim <namhyung@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>, Kees Cook <kees@kernel.org>,
Sam James <sam@gentoo.org>
Subject: Re: [RFC PATCH v1 00/25] unwind_user: Implement .eh_frame handling
Date: Wed, 19 Aug 2026 10:35:51 +0200 [thread overview]
Message-ID: <58c95510-a245-495f-8df6-bbd70d71e637@linux.ibm.com> (raw)
In-Reply-To: <20260818144954.2320378-1-jremus@linux.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 946 bytes --]
On 8/18/2026 4:49 PM, Jens Remus wrote:
> This series adds support for parsing DWARF Call Frame Information (CFI)
> from the .eh_frame_hdr and .eh_frame sections of user space ELF files.
I am working on Sashiko's AI review feedback and will send a RFC v2
soon.
> Patch 25 adds a prctl() interface for (un)registering .eh_frame_hdr
> sections for shared libraries. I will send a related test-patch for
> Glibc separately.
Meanwhile find attached a Glibc 2.44 test patch that registers
.eh_frame_hdr sections referenced by GNU_EH_FRAME in shared libraries
with the kernel.
Regards,
Jens
--
Jens Remus
Linux on Z Development (D3303)
jremus@de.ibm.com / jremus@linux.ibm.com
IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/
[-- Attachment #2: glibc-2.44_register-GNU_EH_FRAME.patch --]
[-- Type: text/plain, Size: 7379 bytes --]
From 159003ef0ef2107ddc8ec8fd8e6ce06198ebbfdc Mon Sep 17 00:00:00 2001
From: Jens Remus <jremus@linux.ibm.com>
Date: Wed, 19 Aug 2026 10:15:53 +0200
Subject: [PATCH] TEST: glibc: Register GNU_EH_FRAME PHDRs to the kernel
The kernel does not have direct visibility to the ELF contents of
shared libraries. In the dynamic linker register and unregister
.eh_frame_hdr sections referenced by GNU_EH_FRAME program headers
via a proposed prctl() interface [1] to the kernel, so it knows
where to find these for stacktracing purposes.
Register .eh_frame_hdr sections during shared object loading and
during setup of VDSO. Unregister them during unmapping. Uses
proposed PR_{REGISTER|UNREGISTER}_EH_FRAME prctl.
Based on Josh Poimboeuf's respective GNU_SFRAME test patch.
[1]: [RFC PATCH v1 25/25] unwind_user/eh_frame: Add prctl() interface
for (un)registering .eh_frame_hdr sections,
https://lore.kernel.org/all/20260818144954.2320378-26-jremus@linux.ibm.com/
[ This patch is for test purposes only. ]
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---
elf/dl-load.c | 46 ++++++++++++++++++++++++++++++++++++++++-
elf/dl-unmap-segments.h | 30 +++++++++++++++++++++++++++
elf/setup-vdso.h | 40 +++++++++++++++++++++++++++++++++++
include/link.h | 3 +++
4 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 95404adae942..10ef365bc81b 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -29,6 +29,7 @@
#include <bits/wordsize.h>
#include <sys/mman.h>
#include <sys/param.h>
+#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <gnu/lib-names.h>
@@ -65,6 +66,23 @@
#define STRING(x) __STRING (x)
+#ifndef _FUTURE_LINUX_EH_FRAME
+#define _FUTURE_LINUX_EH_FRAME
+
+/* From <linux/prctl.h>. */
+#define PR_REGISTER_EH_FRAME 82
+#define PR_UNREGISTER_EH_FRAME 83
+
+/* From <linux/eh_frame.h>. */
+struct eh_frame_setup {
+ __u64 eh_frame_hdr_start;
+ __u64 eh_frame_hdr_size;
+ __u64 text_start;
+ __u64 text_size;
+};
+
+#endif /* _FUTURE_LINUX_EH_FRAME */
+
/* This is the decomposed LD_LIBRARY_PATH search path. */
struct r_search_path_struct __rtld_env_path_list attribute_relro;
@@ -1096,6 +1114,11 @@ _dl_map_object_scan_phdrs (struct dl_pt_load_iterator *it,
l->l_relro_addr = ph->p_vaddr;
l->l_relro_size = ph->p_memsz;
break;
+
+ case PT_GNU_EH_FRAME:
+ l->l_eh_frame_start = ph->p_vaddr;
+ l->l_eh_frame_size = ph->p_memsz;
+ break;
}
}
@@ -1384,13 +1407,34 @@ cannot enable executable stack as shared object requires");
if (l->l_tls_initimage != NULL)
l->l_tls_initimage = (void*)((uintptr_t)l->l_tls_initimage + l->l_addr);
+ /* Adjust the address of the .eh_frame_hdr start address. */
+ if (l->l_eh_frame_start != 0)
+ l->l_eh_frame_start += l->l_addr;
+
/* Process program headers again after load segments are mapped in
case processing requires accessing those segments. Scan program
headers backward since PT_GNU_PROPERTY is close to the end of
program headers. */
for (ph = &l->l_phdr[l->l_phnum]; ph != l->l_phdr; --ph)
- if (ph[-1].p_type == PT_GNU_PROPERTY)
+ switch (ph[-1].p_type)
{
+ case PT_LOAD:
+ if (l->l_eh_frame_start != 0
+ && ph[-1].p_flags & PF_X)
+ {
+ ElfW(Addr) text_start = l->l_addr + ph[-1].p_vaddr;
+ size_t text_size = ph[-1].p_memsz;
+ struct eh_frame_setup data = {
+ .eh_frame_hdr_start = l->l_eh_frame_start,
+ .eh_frame_hdr_size = l->l_eh_frame_size,
+ .text_start = text_start,
+ .text_size = text_size,
+ };
+
+ __prctl(PR_REGISTER_EH_FRAME, &data, sizeof(data), 0, 0);
+ }
+ break;
+ case PT_GNU_PROPERTY:
_dl_process_pt_gnu_property (l, fd, &ph[-1]);
break;
}
diff --git a/elf/dl-unmap-segments.h b/elf/dl-unmap-segments.h
index c3e46d50ec72..eae0843e85a8 100644
--- a/elf/dl-unmap-segments.h
+++ b/elf/dl-unmap-segments.h
@@ -21,6 +21,24 @@
#include <link.h>
#include <sys/mman.h>
+#include <sys/prctl.h>
+
+#ifndef _FUTURE_LINUX_EH_FRAME
+#define _FUTURE_LINUX_EH_FRAME
+
+/* From <linux/prctl.h>. */
+#define PR_REGISTER_EH_FRAME 82
+#define PR_UNREGISTER_EH_FRAME 83
+
+/* From <linux/eh_frame.h>. */
+struct eh_frame_setup {
+ __u64 eh_frame_hdr_start;
+ __u64 eh_frame_hdr_size;
+ __u64 text_start;
+ __u64 text_size;
+};
+
+#endif /* _FUTURE_LINUX_EH_FRAME */
/* _dl_map_segments ensures that any whole pages in gaps between segments
are filled in with PROT_NONE mappings. So we can just unmap the whole
@@ -29,6 +47,18 @@
static __always_inline void
_dl_unmap_segments (struct link_map *l)
{
+ if (l->l_eh_frame_start != 0)
+ {
+ struct eh_frame_setup data = {
+ .eh_frame_hdr_start = l->l_eh_frame_start,
+ .eh_frame_hdr_size = 0,
+ .text_start = 0,
+ .text_size = 0,
+ };
+
+ __prctl(PR_UNREGISTER_EH_FRAME, &data, sizeof(data), 0, 0);
+ }
+
__munmap ((void *) l->l_map_start, l->l_map_end - l->l_map_start);
}
diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
index 0dba7072d53b..83411c1aa396 100644
--- a/elf/setup-vdso.h
+++ b/elf/setup-vdso.h
@@ -16,6 +16,25 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <sys/prctl.h>
+
+#ifndef _FUTURE_LINUX_EH_FRAME
+#define _FUTURE_LINUX_EH_FRAME
+
+/* From <linux/prctl.h>. */
+#define PR_REGISTER_EH_FRAME 82
+#define PR_UNREGISTER_EH_FRAME 83
+
+/* From <linux/eh_frame.h>. */
+struct eh_frame_setup {
+ __u64 eh_frame_hdr_start;
+ __u64 eh_frame_hdr_size;
+ __u64 text_start;
+ __u64 text_size;
+};
+
+#endif /* _FUTURE_LINUX_EH_FRAME */
+
static inline void __attribute__ ((always_inline))
setup_vdso (struct link_map *main_map __attribute__ ((unused)),
struct link_map ***first_preload __attribute__ ((unused)))
@@ -56,6 +75,14 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
if (ph->p_vaddr + ph->p_memsz >= l->l_map_end)
l->l_map_end = ph->p_vaddr + ph->p_memsz;
}
+ else if (ph->p_type == PT_GNU_EH_FRAME)
+ {
+ if (! l->l_eh_frame_start)
+ {
+ l->l_eh_frame_start = ph->p_vaddr;
+ l->l_eh_frame_size = ph->p_memsz;
+ }
+ }
else
/* There must be no TLS segment. */
assert (ph->p_type != PT_TLS);
@@ -78,6 +105,19 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
l->l_local_scope[0]->r_nlist = 1;
l->l_local_scope[0]->r_list = &l->l_real;
+ if (l->l_eh_frame_start != 0)
+ {
+ l->l_eh_frame_start += l->l_addr;
+
+ struct eh_frame_setup data = {
+ .eh_frame_hdr_start = l->l_eh_frame_start,
+ .eh_frame_hdr_size = l->l_eh_frame_size,
+ .text_start = l->l_map_start,
+ .text_size = l->l_map_end - l->l_map_start,
+ };
+ __prctl(PR_REGISTER_EH_FRAME, &data, sizeof(data), 0, 0);
+ }
+
/* Now that we have the info handy, use the DSO image's soname
so this object can be looked up by name. */
{
diff --git a/include/link.h b/include/link.h
index 8f851d2212df..b9ee4674ac69 100644
--- a/include/link.h
+++ b/include/link.h
@@ -345,6 +345,9 @@ struct link_map
ElfW(Addr) l_relro_addr;
size_t l_relro_size;
+ ElfW(Addr) l_eh_frame_start;
+ size_t l_eh_frame_size;
+
unsigned long long int l_serial;
};
--
2.53.0
prev parent reply other threads:[~2026-08-19 8:36 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-18 14:49 [RFC PATCH v1 00/25] unwind_user: Implement .eh_frame handling Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 01/25] unwind_user: Add generic and arch-specific headers to MAINTAINERS Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 02/25] unwind_user: Stop when reaching an outermost frame Jens Remus
2026-08-18 14:56 ` sashiko-bot
2026-08-18 14:49 ` [RFC PATCH v1 03/25] unwind_user: Enable archs that pass RA in a register Jens Remus
2026-08-18 14:58 ` sashiko-bot
2026-08-18 14:49 ` [RFC PATCH v1 04/25] unwind_user: Flexible FP/RA recovery rules Jens Remus
2026-08-18 14:58 ` sashiko-bot
2026-08-18 14:49 ` [RFC PATCH v1 05/25] unwind_user: Flexible CFA " Jens Remus
2026-08-18 14:57 ` sashiko-bot
2026-08-18 14:49 ` [RFC PATCH v1 06/25] unwind_user: Enable archs that define CFA = SP_callsite + offset Jens Remus
2026-08-18 14:57 ` sashiko-bot
2026-08-18 14:49 ` [RFC PATCH v1 07/25] unwind_user/eh_frame: Add support for reading .eh_frame_hdr section Jens Remus
2026-08-18 15:02 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 08/25] unwind_user/eh_frame: Store .eh_frame_hdr section data in per-mm maple tree Jens Remus
2026-08-18 15:08 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 09/25] unwind_user/eh_frame: Add support for reading .eh_frame section Jens Remus
2026-08-18 15:05 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 10/25] unwind_user/eh_frame: Detect .eh_frame_hdr sections in executables Jens Remus
2026-08-18 15:18 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 11/25] unwind_user/eh_frame: Wire up unwind_user to eh_frame Jens Remus
2026-08-18 15:09 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 12/25] unwind_user/eh_frame: Remove .eh_frame[_hdr] section on detected corruption Jens Remus
2026-08-18 15:10 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 13/25] unwind_user/eh_frame: Show file name in debug output Jens Remus
2026-08-18 15:00 ` sashiko-bot
2026-08-18 14:49 ` [RFC PATCH v1 14/25] unwind_user/eh_frame: Add .eh_frame[_hdr] validation option Jens Remus
2026-08-18 15:08 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 15/25] unwind_user/eh_frame: Duplicate registered .eh_frame[_hdr] section data on clone/fork Jens Remus
2026-08-18 15:11 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 16/25] unwind_user/eh_frame: Add linear .eh_frame search fallback Jens Remus
2026-08-18 15:06 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 17/25] unwind_user/eh_frame: Ignore DW_CFA_GNU_args_size Jens Remus
2026-08-18 15:04 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 18/25] unwind_user/eh_frame: Add support for DWARF expressions Jens Remus
2026-08-18 15:13 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 19/25] x86/uaccess: Add unsafe_copy_from_user() implementation Jens Remus
2026-08-18 15:08 ` sashiko-bot
2026-08-18 14:49 ` [RFC PATCH v1 20/25] unwind_user/eh_frame/x86: Enable eh_frame unwinding on x86 Jens Remus
2026-08-18 15:04 ` sashiko-bot
2026-08-18 14:49 ` [RFC PATCH v1 21/25] unwind_user/eh_frame/x86: Handle PLT expressions Jens Remus
2026-08-18 15:10 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 22/25] unwind_user/eh_frame/x86: Handle DRAP expressions Jens Remus
2026-08-18 15:10 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 14:49 ` [RFC PATCH v1 23/25] s390/ptrace: Provide frame_pointer() Jens Remus
2026-08-18 15:06 ` sashiko-bot
2026-08-18 14:49 ` [RFC PATCH v1 24/25] unwind_user/eh_frame/s390: Enable eh_frame unwinding on s390 Jens Remus
2026-08-18 15:15 ` sashiko-bot
2026-08-18 14:49 ` [RFC PATCH v1 25/25] unwind_user/eh_frame: Add prctl() interface for (un)registering .eh_frame_hdr sections Jens Remus
2026-08-18 15:17 ` sashiko-bot
2026-08-21 19:41 ` Jens Remus
2026-08-18 17:21 ` [RFC PATCH v1 00/25] unwind_user: Implement .eh_frame handling Steven Rostedt
2026-08-21 19:51 ` Jens Remus
2026-08-19 8:35 ` Jens Remus [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=58c95510-a245-495f-8df6-bbd70d71e637@linux.ibm.com \
--to=jremus@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=andrii@kernel.org \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=hpa@zytor.com \
--cc=ibhagatgnu@gmail.com \
--cc=iii@linux.ibm.com \
--cc=jpoimboe@kernel.org \
--cc=kees@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=rostedt@kernel.org \
--cc=sam@gentoo.org \
--cc=tglx@kernel.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.