Upstream commit: fffc2df8a3e2c8cda2991063d23086360268b777 - i386: Provide GLIBC_ABI_GNU_TLS symbol version [BZ #33221] - i386: Update ___tls_get_addr to preserve vector registers - Extend struct r_debug to support multiple namespaces (RHEL-101985) - Fix a potential crash in the dynamic loader when processing specific symbol versions (RHEL-109683) - Signal la_objopen for ld.so with dlmopen (RHEL-109693) - Switch to main malloc after final ld.so self-relocation (RHEL-109703) - Prevent ld.so from asserting and crashing during audited library loads (RHEL-109702) - x86-64: Provide GLIBC_ABI_DT_X86_64_PLT symbol version (RHEL-109621) - x86-64, i386: Provide GLIBC_ABI_GNU2_TLS symbol version (RHEL-109625) - Ensure fallback initialization of ctype TLS data pointers to fix segfaults in programs using dlmopen or auditors (RHEL-72018) - Handle load segment gaps in _dl_find_object (RHEL-104854) - AArch64: Improve codegen in SVE log1p - AArch64: Optimize inverse trig functions - AArch64: Avoid memset ifunc in cpu-features.c [BZ #33112] Resolves: RHEL-109536 Resolves: RHEL-72018 Resolves: RHEL-101985 Resolves: RHEL-104854 Resolves: RHEL-109621 Resolves: RHEL-109625 Resolves: RHEL-109683 Resolves: RHEL-109693 Resolves: RHEL-109702 Resolves: RHEL-109703
150 lines
5.7 KiB
Diff
150 lines
5.7 KiB
Diff
commit 97017da5ef946c6d38c252f56c8cb7c205b732fa
|
|
Author: Florian Weimer <fweimer@redhat.com>
|
|
Date: Fri Jul 4 21:46:16 2025 +0200
|
|
|
|
elf: Introduce _dl_debug_change_state
|
|
|
|
It combines updating r_state with the debugger notification.
|
|
|
|
The second change to _dl_open introduces an additional debugger
|
|
notification for dlmopen, but debuggers are expected to ignore it.
|
|
|
|
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
|
(cherry picked from commit 8329939a37f483a16013dd8af8303cbcb86d92cb)
|
|
|
|
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
|
index 4c963097f4dc8d79..fb27a1231c1c5b66 100644
|
|
--- a/elf/dl-close.c
|
|
+++ b/elf/dl-close.c
|
|
@@ -433,8 +433,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
|
/* Notify the debugger we are about to remove some loaded objects.
|
|
LA_ACT_DELETE has already been signalled above for !unload_any. */
|
|
struct r_debug *r = _dl_debug_update (nsid);
|
|
- r->r_state = RT_DELETE;
|
|
- _dl_debug_state ();
|
|
+ _dl_debug_change_state (r, RT_DELETE);
|
|
LIBC_PROBE (unmap_start, 2, nsid, r);
|
|
|
|
if (unload_global)
|
|
@@ -726,8 +725,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
|
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
|
|
|
|
/* Notify the debugger those objects are finalized and gone. */
|
|
- r->r_state = RT_CONSISTENT;
|
|
- _dl_debug_state ();
|
|
+ _dl_debug_change_state (r, RT_CONSISTENT);
|
|
LIBC_PROBE (unmap_complete, 2, nsid, r);
|
|
|
|
#ifdef SHARED
|
|
diff --git a/elf/dl-debug.c b/elf/dl-debug.c
|
|
index 5c49fa847e91bd81..b3777ffc136469cf 100644
|
|
--- a/elf/dl-debug.c
|
|
+++ b/elf/dl-debug.c
|
|
@@ -67,6 +67,13 @@ _dl_debug_update (Lmid_t ns)
|
|
return &r->base;
|
|
}
|
|
|
|
+void
|
|
+_dl_debug_change_state (struct r_debug *r, int state)
|
|
+{
|
|
+ atomic_store_release (&r->r_state, state);
|
|
+ _dl_debug_state ();
|
|
+}
|
|
+
|
|
/* Initialize _r_debug_extended for the namespace NS. LDBASE is the
|
|
run-time load address of the dynamic linker, to be put in
|
|
_r_debug_extended.r_ldbase. Return the address of _r_debug. */
|
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
|
index 75a7187c649e0202..8b0890499d66f67a 100644
|
|
--- a/elf/dl-load.c
|
|
+++ b/elf/dl-load.c
|
|
@@ -947,8 +947,7 @@ _dl_notify_new_object (int mode, Lmid_t nsid, struct link_map *l)
|
|
/* Notify the debugger we have added some objects. We need to
|
|
call _dl_debug_initialize in a static program in case dynamic
|
|
linking has not been used before. */
|
|
- r->r_state = RT_ADD;
|
|
- _dl_debug_state ();
|
|
+ _dl_debug_change_state (r, RT_ADD);
|
|
LIBC_PROBE (map_start, 2, nsid, r);
|
|
}
|
|
else
|
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
|
index 80f084d5c838fc1c..6f6d3ddbf94c764c 100644
|
|
--- a/elf/dl-open.c
|
|
+++ b/elf/dl-open.c
|
|
@@ -792,8 +792,7 @@ dl_open_worker (void *a)
|
|
#ifdef SHARED
|
|
bool was_not_consistent = r->r_state != RT_CONSISTENT;
|
|
#endif
|
|
- r->r_state = RT_CONSISTENT;
|
|
- _dl_debug_state ();
|
|
+ _dl_debug_change_state (r, RT_CONSISTENT);
|
|
LIBC_PROBE (map_complete, 3, nsid, r, args->map);
|
|
|
|
#ifdef SHARED
|
|
@@ -871,7 +870,7 @@ no more namespaces available for dlmopen()"));
|
|
}
|
|
|
|
GL(dl_ns)[nsid].libc_map = NULL;
|
|
- _dl_debug_update (nsid)->r_state = RT_CONSISTENT;
|
|
+ _dl_debug_change_state (_dl_debug_update (nsid), RT_CONSISTENT);
|
|
}
|
|
/* Never allow loading a DSO in a namespace which is empty. Such
|
|
direct placements is only causing problems. Also don't allow
|
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
|
index 809fc807989b285e..43bfc7378afc6cc7 100644
|
|
--- a/elf/rtld.c
|
|
+++ b/elf/rtld.c
|
|
@@ -1850,8 +1850,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
|
elf_setup_debug_entry (main_map, r);
|
|
|
|
/* We start adding objects. */
|
|
- r->r_state = RT_ADD;
|
|
- _dl_debug_state ();
|
|
+ _dl_debug_change_state (r, RT_ADD);
|
|
LIBC_PROBE (init_start, 2, LM_ID_BASE, r);
|
|
|
|
/* Auditing checkpoint: we are ready to signal that the initial map
|
|
@@ -2402,8 +2401,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
|
/* Notify the debugger all new objects are now ready to go. We must re-get
|
|
the address since by now the variable might be in another object. */
|
|
r = _dl_debug_update (LM_ID_BASE);
|
|
- r->r_state = RT_CONSISTENT;
|
|
- _dl_debug_state ();
|
|
+ _dl_debug_change_state (r, RT_CONSISTENT);
|
|
LIBC_PROBE (init_complete, 2, LM_ID_BASE, r);
|
|
|
|
/* Auditing checkpoint: we have added all objects. */
|
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
|
index 8b9ae3783056a29f..017406e7fa93c941 100644
|
|
--- a/sysdeps/generic/ldsodefs.h
|
|
+++ b/sysdeps/generic/ldsodefs.h
|
|
@@ -1067,8 +1067,14 @@ extern void _dl_debug_state (void);
|
|
rtld_hidden_proto (_dl_debug_state)
|
|
|
|
/* Initialize `struct r_debug_extended' for the namespace NS. LDBASE
|
|
- is the run-time load address of the dynamic linker, to be put in the
|
|
- `r_ldbase' member. Return the address of the structure. */
|
|
+ is the run-time load address of the dynamic linker, to be put in
|
|
+ the `r_ldbase' member.
|
|
+
|
|
+ Return the address of the r_debug structure for the namespace.
|
|
+ This is not merely a convenience or optimization, but it is
|
|
+ necessary for the LIBC_PROBE Systemtap/debugger probes to work
|
|
+ reliably: direct variable access can create probes that tools
|
|
+ cannot consume. */
|
|
extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns)
|
|
attribute_hidden;
|
|
|
|
@@ -1076,6 +1082,10 @@ extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns)
|
|
of the namespace NS. */
|
|
extern struct r_debug *_dl_debug_update (Lmid_t ns) attribute_hidden;
|
|
|
|
+/* Update R->r_state to STATE and notify the debugger by calling
|
|
+ _dl_debug_state. */
|
|
+void _dl_debug_change_state (struct r_debug *r, int state) attribute_hidden;
|
|
+
|
|
/* Initialize the basic data structure for the search paths. SOURCE
|
|
is either "LD_LIBRARY_PATH" or "--library-path".
|
|
GLIBC_HWCAPS_PREPEND adds additional glibc-hwcaps subdirectories to
|