[PATCH 2/2] elf: Use the effective lazy mode for the deferred IRELATIVE pass
Adhemerval Zanella <[email protected]> Sun, 2 Aug 2026 20:44:04 -0300
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Message-ID | <[email protected]> |
The 63b31c05a8a split relocation processing must agree for the lazy
flag, a mistamatch would change the .rel.plt handling.
This is not an issue for any port currently, but on hppa it may return
a different value: if hppa affs IFUNC support, the second pass would
route PLT entries to its empty lazy handler and leave the descriptors
unrelocated, silently.
Checked on x86_64-linux-gnu, and built for all supported architectures.
---
elf/dl-reloc-static-pie.c | 7 +++++--
elf/dl-reloc.c | 5 +++--
elf/dynamic-link.h | 21 ++++++++++++++-------
3 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
index 53260b57372..79aa2c24327 100644
--- a/elf/dl-reloc-static-pie.c
+++ b/elf/dl-reloc-static-pie.c
@@ -79,8 +79,11 @@ _dl_relocate_static_pie (void)
# endif
/* Relocate ourselves so we can do normal function calls and data access
- using the global offset table. IRELATIVE entries are deferred. */
- ELF_DYNAMIC_RELOCATE_NOIFUNC (main_map, NULL, 0, 0, 0);
+ using the global offset table. IRELATIVE entries are deferred.
+ Lazy binding is never used here, so edr_lazy comes back as 0 and the
+ deferred pass can hardcode the same value. */
+ int edr_lazy;
+ ELF_DYNAMIC_RELOCATE_NOIFUNC (main_map, NULL, 0, 0, 0, edr_lazy);
/* Initialize _r_debug_extended. */
struct r_debug *r = _dl_debug_initialize (0, LM_ID_BASE);
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 80cd7e25d16..01f16f9a3ae 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -278,8 +278,9 @@ _dl_relocate_object_no_relro (struct link_map *l, struct r_scope_elem *scope[],
IFUNC resolvers. Without this, a resolver would see the unrelocated
initialiser bytes that were placed into the slot by the early
_dl_allocate_tls_init. */
+ int edr_lazy;
ELF_DYNAMIC_RELOCATE_NOIFUNC (l, scope, lazy, consider_profiling,
- skip_ifunc);
+ skip_ifunc, edr_lazy);
#ifdef SHARED
/* Re-initialise the static TLS slot with the .tdata so the IRELATIVE
@@ -292,7 +293,7 @@ _dl_relocate_object_no_relro (struct link_map *l, struct r_scope_elem *scope[],
_dl_init_static_tls (l);
#endif
- ELF_DYNAMIC_RELOCATE_IFUNC (l, scope, lazy, skip_ifunc);
+ ELF_DYNAMIC_RELOCATE_IFUNC (l, scope, edr_lazy, skip_ifunc);
if ((consider_profiling || consider_symbind)
&& l->l_info[DT_PLTRELSZ] != NULL)
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 9baef6d7b84..0110ec56d3d 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -261,20 +261,27 @@ enum elf_dynamic_reloc_phase
/* Like ELF_DYNAMIC_RELOCATE but only processes the non-IRELATIVE pass.
The IRELATIVE pass must be completed later via ELF_DYNAMIC_RELOCATE_IFUNC.
Used by the static-pie startup so the TCB and stack-protector canary can
- be initialised between the two passes. */
+ be initialised between the two passes.
+
+ EDR_LAZY is an int which receives the effective lazy-binding mode picked
+ by elf_machine_runtime_setup. It can differ from LAZY (currently only
+ hppa), and elf_machine_runtime_setup has side effects so it must not be
+ called twice. The caller must pass the same value back to
+ ELF_DYNAMIC_RELOCATE_IFUNC. */
# define ELF_DYNAMIC_RELOCATE_NOIFUNC(map, scope, lazy, consider_profile, \
- skip_ifunc) \
+ skip_ifunc, edr_lazy) \
do { \
- int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy), \
- (consider_profile)); \
+ (edr_lazy) = elf_machine_runtime_setup ((map), (scope), (lazy), \
+ (consider_profile)); \
if (!is_rtld_link_map (map) || DO_RTLD_BOOTSTRAP) \
ELF_DYNAMIC_DO_RELR (map); \
- ELF_DYNAMIC_DO_REL_NOIFUNC ((map), (scope), edr_lazy, skip_ifunc); \
- ELF_DYNAMIC_DO_RELA_NOIFUNC ((map), (scope), edr_lazy, skip_ifunc); \
+ ELF_DYNAMIC_DO_REL_NOIFUNC ((map), (scope), (edr_lazy), skip_ifunc); \
+ ELF_DYNAMIC_DO_RELA_NOIFUNC ((map), (scope), (edr_lazy), skip_ifunc); \
ELF_DYNAMIC_AFTER_RELOC ((map), (edr_lazy)); \
} while (0)
-/* IRELATIVE-only companion to ELF_DYNAMIC_RELOCATE_NOIFUNC. */
+/* IRELATIVE-only companion to ELF_DYNAMIC_RELOCATE_NOIFUNC. LAZY must be the
+ EDR_LAZY value that call produced, not the mode originally requested. */
# define ELF_DYNAMIC_RELOCATE_IFUNC(map, scope, lazy, skip_ifunc) \
do { \
ELF_DYNAMIC_DO_REL_IFUNCONLY ((map), (scope), (lazy), skip_ifunc); \
--
2.53.0