From 6628c742b2c16e785d3c884d9deeda5adb30ca12 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Thu, 13 Jan 2022 17:58:00 -0300 Subject: elf: Remove prelink support Prelinked binaries and libraries still work, the dynamic tags DT_GNU_PRELINKED, DT_GNU_LIBLIST, DT_GNU_CONFLICT just ignored (meaning the process is reallocated as default). The loader environment variable TRACE_PRELINKING is also removed, since it used solely on prelink. Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. Reviewed-by: Siddhesh Poyarekar --- NEWS | 4 +- elf/Makefile | 16 --- elf/dl-conflict.c | 77 ---------- elf/dl-deps.c | 66 --------- elf/dl-error-skeleton.c | 4 +- elf/dl-load.c | 3 +- elf/dl-lookup.c | 161 --------------------- elf/do-rel.h | 3 - elf/rtld.c | 250 +++++++-------------------------- elf/tst-prelink-cmp.c | 49 ------- elf/tst-prelink.c | 29 ---- include/link.h | 4 - sysdeps/alpha/dl-machine.h | 15 -- sysdeps/arm/dl-machine.h | 4 - sysdeps/generic/ldsodefs.h | 11 -- sysdeps/i386/dl-machine.h | 16 +-- sysdeps/or1k/dl-machine.h | 4 - sysdeps/powerpc/powerpc32/dl-machine.h | 31 ++-- sysdeps/powerpc/powerpc64/dl-machine.h | 37 ----- sysdeps/s390/s390-32/dl-machine.h | 22 ++- sysdeps/s390/s390-64/dl-machine.h | 22 ++- sysdeps/sh/dl-machine.h | 2 +- sysdeps/sparc/sparc32/dl-machine.h | 52 +------ sysdeps/sparc/sparc64/dl-machine.h | 72 +--------- sysdeps/x86_64/dl-machine.h | 48 +++---- 25 files changed, 117 insertions(+), 885 deletions(-) delete mode 100644 elf/dl-conflict.c delete mode 100644 elf/tst-prelink-cmp.c delete mode 100644 elf/tst-prelink.c diff --git a/NEWS b/NEWS index 7b8febcb72..9bef1058b5 100644 --- a/NEWS +++ b/NEWS @@ -13,7 +13,9 @@ Major new features: Deprecated and removed features, and other changes affecting compatibility: - [Add deprecations, removals and changes affecting compatibility here] +* Support for prelink will be removed in the next release; this includes + removal of the LD_TRACE_PRELINKING, and LD_USE_LOAD_BIAS, environment + variables and their functionality in the dynamic loader. Changes to build and runtime requirements: diff --git a/elf/Makefile b/elf/Makefile index b2bd03a9f6..bff94954c9 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -127,7 +127,6 @@ rtld-routines = \ $(all-dl-routines) \ dl-audit \ dl-compat \ - dl-conflict \ dl-diagnostics \ dl-diagnostics-cpu \ dl-diagnostics-kernel \ @@ -1103,14 +1102,6 @@ tests-special += $(objpfx)check-abi-ld.out update-abi: update-abi-ld update-all-abi: update-all-abi-ld -ifeq ($(have-glob-dat-reloc),yes) -tests += tst-prelink -tests-internal += tst-prelink-cmp -# Don't compile tst-prelink.c with PIE for GLOB_DAT relocation. -CFLAGS-tst-prelink.c += -fno-pie -tst-prelink-no-pie = yes -endif - # The test requires shared _and_ PIE because the executable # unit test driver must be able to link with the shared object # that is going to eventually go into an installed DSO. @@ -2285,13 +2276,6 @@ $(objpfx)tst-tls-manydynamic: $(shared-thread-library) $(objpfx)tst-tls-manydynamic.out: \ $(patsubst %,$(objpfx)%.so,$(tst-tls-many-dynamic-modules)) -tst-prelink-ENV = LD_TRACE_PRELINKING=1 - -$(objpfx)tst-prelink-conflict.out: $(objpfx)tst-prelink.out - grep stdout $< | grep conflict | $(AWK) '{ print $$10, $$11 }' > $@ - -$(objpfx)tst-prelink-cmp.out: $(objpfx)tst-prelink-conflict.out - $(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh $(objpfx)ldconfig $(SHELL) $< '$(common-objpfx)' '$(test-wrapper-env)' \ '$(run-program-env)' > $@; \ diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c deleted file mode 100644 index 769afd581b..0000000000 --- a/elf/dl-conflict.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Resolve conflicts against already prelinked libraries. - Copyright (C) 2001-2022 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dynamic-link.h" - -/* Used at loading time solely for prelink executable. It is not called - concurrently so it is be safe to defined as static. */ -static struct link_map *resolve_conflict_map __attribute__ ((__unused__)); - - /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ -#define RESOLVE_MAP(map, scope, ref, version, flags) (*ref = NULL, NULL) -#define RESOLVE(ref, version, flags) (*ref = NULL, 0) -#define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \ - do { \ - while ((resolve_conflict_map->l_map_end < (ElfW(Addr)) (r_offset)) \ - || (resolve_conflict_map->l_map_start > (ElfW(Addr)) (r_offset))) \ - resolve_conflict_map = resolve_conflict_map->l_next; \ - \ - (map) = resolve_conflict_map; \ - } while (0) - -#include "dynamic-link.h" - -void -_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, - ElfW(Rela) *conflictend) -{ -#if ! ELF_MACHINE_NO_RELA - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC)) - _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name)); - - { - /* Do the conflict relocation of the object and library GOT and other - data. */ - - /* Prelinking makes no sense for anything but the main namespace. */ - assert (l->l_ns == LM_ID_BASE); - resolve_conflict_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; - - /* Override these, defined in dynamic-link.h. */ -#undef CHECK_STATIC_TLS -#define CHECK_STATIC_TLS(ref_map, sym_map) ((void) 0) -#undef TRY_STATIC_TLS -#define TRY_STATIC_TLS(ref_map, sym_map) (0) - - GL(dl_num_cache_relocations) += conflictend - conflict; - - for (; conflict < conflictend; ++conflict) - elf_machine_rela (l, NULL, conflict, NULL, NULL, - (void *) conflict->r_offset, 0); - } -#endif -} diff --git a/elf/dl-deps.c b/elf/dl-deps.c index c8bab5cad5..a2fc278256 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -68,22 +68,6 @@ openaux (void *a) args->map->l_ns); } -static ptrdiff_t -_dl_build_local_scope (struct link_map **list, struct link_map *map) -{ - struct link_map **p = list; - struct link_map **q; - - *p++ = map; - map->l_reserved = 1; - if (map->l_initfini) - for (q = map->l_initfini + 1; *q; ++q) - if (! (*q)->l_reserved) - p += _dl_build_local_scope (p, *q); - return p - list; -} - - /* We use a very special kind of list to track the path through the list of loaded shared objects. We have to produce a flat list with unique members of all involved objects. @@ -504,56 +488,6 @@ _dl_map_object_deps (struct link_map *map, runp->map->l_reserved = 0; } - if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0 - && map == GL(dl_ns)[LM_ID_BASE]._ns_loaded) - { - /* If we are to compute conflicts, we have to build local scope - for each library, not just the ultimate loader. */ - for (i = 0; i < nlist; ++i) - { - struct link_map *l = map->l_searchlist.r_list[i]; - unsigned int j, cnt; - - /* The local scope has been already computed. */ - if (l == map - || (l->l_local_scope[0] - && l->l_local_scope[0]->r_nlist) != 0) - continue; - - if (l->l_info[AUXTAG] || l->l_info[FILTERTAG]) - { - /* As current DT_AUXILIARY/DT_FILTER implementation needs to be - rewritten, no need to bother with prelinking the old - implementation. */ - _dl_signal_error (EINVAL, l->l_name, NULL, N_("\ -Filters not supported with LD_TRACE_PRELINKING")); - } - - cnt = _dl_build_local_scope (l_initfini, l); - assert (cnt <= nlist); - for (j = 0; j < cnt; j++) - { - l_initfini[j]->l_reserved = 0; - if (j && __builtin_expect (l_initfini[j]->l_info[DT_SYMBOLIC] - != NULL, 0)) - l->l_symbolic_in_local_scope = true; - } - - l->l_local_scope[0] = - (struct r_scope_elem *) malloc (sizeof (struct r_scope_elem) - + (cnt - * sizeof (struct link_map *))); - if (l->l_local_scope[0] == NULL) - _dl_signal_error (ENOMEM, map->l_name, NULL, - N_("cannot allocate symbol search list")); - l->l_local_scope[0]->r_nlist = cnt; - l->l_local_scope[0]->r_list = - (struct link_map **) (l->l_local_scope[0] + 1); - memcpy (l->l_local_scope[0]->r_list, l_initfini, - cnt * sizeof (struct link_map *)); - } - } - /* Maybe we can remove some relocation dependencies now. */ struct link_map_reldeps *l_reldeps = NULL; if (map->l_reldeps != NULL) diff --git a/elf/dl-error-skeleton.c b/elf/dl-error-skeleton.c index b4213ea3db..8abf437f87 100644 --- a/elf/dl-error-skeleton.c +++ b/elf/dl-error-skeleton.c @@ -132,7 +132,7 @@ _dl_signal_cexception (int errcode, struct dl_exception *exception, const char *occasion) { if (__builtin_expect (GLRO(dl_debug_mask) - & ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0)) + & ~(DL_DEBUG_STATISTICS), 0)) _dl_debug_printf ("%s: error: %s: %s (%s)\n", exception->objname, occasion, exception->errstring, receiver ? "continued" : "fatal"); @@ -153,7 +153,7 @@ _dl_signal_cerror (int errcode, const char *objname, const char *occation, const char *errstring) { if (__builtin_expect (GLRO(dl_debug_mask) - & ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0)) + & ~(DL_DEBUG_STATISTICS), 0)) _dl_debug_printf ("%s: error: %s: %s (%s)\n", objname, occation, errstring, receiver ? "continued" : "fatal"); diff --git a/elf/dl-load.c b/elf/dl-load.c index 5b0ff41ee1..892e8ef2f6 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -2263,8 +2263,7 @@ _dl_map_object (struct link_map *loader, const char *name, if (__glibc_unlikely (fd == -1)) { - if (trace_mode - && __glibc_likely ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) == 0)) + if (trace_mode) { /* We haven't found an appropriate library. But since we are only interested in the list of libraries this isn't diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index cbf46fda62..7b2a6622be 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -296,19 +296,6 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, assert (!RTLD_CHECK_FOREIGN_CALL); #endif -#ifdef SHARED - /* If tab->entries is NULL, but tab->size is not, it means - this is the second, conflict finding, lookup for - LD_TRACE_PRELINKING in _dl_debug_bindings. Don't - allocate anything and don't enter anything into the - hash table. */ - if (__glibc_unlikely (tab->size)) - { - assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK); - goto success; - } -#endif - #define INITIAL_NUNIQUE_SYM_TABLE 31 size = INITIAL_NUNIQUE_SYM_TABLE; entries = calloc (sizeof (struct unique_sym), size); @@ -341,9 +328,6 @@ marking %s [%lu] as NODELETE due to unique symbol\n", } ++tab->n_elements; -#ifdef SHARED - success: -#endif __rtld_lock_unlock_recursive (tab->lock); result->s = sym; @@ -818,12 +802,6 @@ marking %s [%lu] as NODELETE due to memory allocation failure\n", goto out; } -static void -_dl_debug_bindings (const char *undef_name, struct link_map *undef_map, - const ElfW(Sym) **ref, struct sym_val *value, - const struct r_found_version *version, int type_class, - int protected); - /* Search loaded objects' symbol tables for a definition of the symbol UNDEF_NAME, perhaps with a requested version for the symbol. @@ -943,145 +921,6 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, if (__glibc_unlikely (current_value.m->l_used == 0)) current_value.m->l_used = 1; - if (__glibc_unlikely (GLRO(dl_debug_mask) - & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK))) - _dl_debug_bindings (undef_name, undef_map, ref, - ¤t_value, version, type_class, protected); - *ref = current_value.s; return LOOKUP_VALUE (current_value.m); } - - -static void -_dl_debug_bindings (const char *undef_name, struct link_map *undef_map, - const ElfW(Sym) **ref, struct sym_val *value, - const struct r_found_version *version, int type_class, - int protected) -{ - const char *reference_name = undef_map->l_name; - - if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS) - { - _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'", - DSO_FILENAME (reference_name), - undef_map->l_ns, - DSO_FILENAME (value->m->l_name), - value->m->l_ns, - protected ? "protected" : "normal", undef_name); - if (version) - _dl_debug_printf_c (" [%s]\n", version->name); - else - _dl_debug_printf_c ("\n"); - } -#ifdef SHARED - if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) - { -/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with - LD_TRACE_PRELINKING. */ -#define RTYPE_CLASS_VALID 8 -#define RTYPE_CLASS_PLT (8|1) -#define RTYPE_CLASS_COPY (8|2) -#define RTYPE_CLASS_TLS (8|4) -#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1 -# error ELF_RTYPE_CLASS_PLT must be 0 or 1! -#endif -#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2 -# error ELF_RTYPE_CLASS_COPY must be 0 or 2! -#endif - int conflict = 0; - struct sym_val val = { NULL, NULL }; - - if ((GLRO(dl_trace_prelink_map) == NULL - || GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded) - && undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded) - { - const uint_fast32_t new_hash = dl_new_hash (undef_name); - unsigned long int old_hash = 0xffffffff; - struct unique_sym *saved_entries - = GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries; - - GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = NULL; - do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val, - undef_map->l_local_scope[0], 0, version, 0, NULL, - type_class, undef_map); - if (val.s != value->s || val.m != value->m) - conflict = 1; - else if (__glibc_unlikely (undef_map->l_symbolic_in_local_scope) - && val.s - && __glibc_unlikely (ELFW(ST_BIND) (val.s->st_info) - == STB_GNU_UNIQUE)) - { - /* If it is STB_GNU_UNIQUE and undef_map's l_local_scope - contains any DT_SYMBOLIC libraries, unfortunately there - can be conflicts even if the above is equal. As symbol - resolution goes from the last library to the first and - if a STB_GNU_UNIQUE symbol is found in some late DT_SYMBOLIC - library, it would be the one that is looked up. */ - struct sym_val val2 = { NULL, NULL }; - size_t n; - struct r_scope_elem *scope = undef_map->l_local_scope[0]; - - for (n = 0; n < scope->r_nlist; n++) - if (scope->r_list[n] == val.m) - break; - - for (n++; n < scope->r_nlist; n++) - if (scope->r_list[n]->l_info[DT_SYMBOLIC] != NULL - && do_lookup_x (undef_name, new_hash, &old_hash, *ref, - &val2, - &scope->r_list[n]->l_symbolic_searchlist, - 0, version, 0, NULL, type_class, - undef_map) > 0) - { - conflict = 1; - val = val2; - break; - } - } - GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = saved_entries; - } - - if (value->s) - { - /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY - bits since since prelink only uses them. */ - type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY; - if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info) - == STT_TLS)) - /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS. */ - type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID; - else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info) - == STT_GNU_IFUNC)) - /* Set the RTYPE_CLASS_VALID bit. */ - type_class |= RTYPE_CLASS_VALID; - } - - if (conflict - || GLRO(dl_trace_prelink_map) == undef_map - || GLRO(dl_trace_prelink_map) == NULL - || type_class >= 4) - { - _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ", - conflict ? "conflict" : "lookup", - (int) sizeof (ElfW(Addr)) * 2, - (size_t) undef_map->l_map_start, - (int) sizeof (ElfW(Addr)) * 2, - (size_t) (((ElfW(Addr)) *ref) - undef_map->l_map_start), - (int) sizeof (ElfW(Addr)) * 2, - (size_t) (value->s ? value->m->l_map_start : 0), - (int) sizeof (ElfW(Addr)) * 2, - (size_t) (value->s ? value->s->st_value : 0)); - - if (conflict) - _dl_printf ("x 0x%0*Zx 0x%0*Zx ", - (int) sizeof (ElfW(Addr)) * 2, - (size_t) (val.s ? val.m->l_map_start : 0), - (int) sizeof (ElfW(Addr)) * 2, - (size_t) (val.s ? val.s->st_value : 0)); - - _dl_printf ("/%x %s\n", type_class, undef_name); - } - } -#endif -} diff --git a/elf/do-rel.h b/elf/do-rel.h index 60d5dce8f2..d3e022267b 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -105,9 +105,6 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], relocations or rela relocations if they are computed as memory_loc += l_addr... */ if (l_addr != 0) -# else - /* ...or we know the object has been prelinked. */ - if (l_addr != 0 || ! map->l_info[VALIDX(DT_GNU_PRELINKED)]) # endif #endif for (; relative < r; ++relative) diff --git a/elf/rtld.c b/elf/rtld.c index 8dafaf61f4..5f089038e1 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -565,7 +565,7 @@ _dl_start (void *arg) ELF_MACHINE_BEFORE_RTLD_RELOC (&bootstrap_map, bootstrap_map.l_info); #endif - if (bootstrap_map.l_addr || ! bootstrap_map.l_info[VALIDX(DT_GNU_PRELINKED)]) + if (bootstrap_map.l_addr) { /* Relocate ourselves so we can do normal function calls and data access using the global offset table. */ @@ -1322,7 +1322,6 @@ dl_main (const ElfW(Phdr) *phdr, size_t file_size; char *file; unsigned int i; - bool prelinked = false; bool rtld_is_main = false; void *tcbp = NULL; @@ -2055,37 +2054,7 @@ dl_main (const ElfW(Phdr) *phdr, after relocation. */ struct link_map *l; - if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) - { - struct r_scope_elem *scope = &main_map->l_searchlist; - - for (i = 0; i < scope->r_nlist; i++) - { - l = scope->r_list [i]; - if (l->l_faked) - { - _dl_printf ("\t%s => not found\n", l->l_libname->name); - continue; - } - if (_dl_name_match_p (GLRO(dl_trace_prelink), l)) - GLRO(dl_trace_prelink_map) = l; - _dl_printf ("\t%s => %s (0x%0*Zx, 0x%0*Zx)", - DSO_FILENAME (l->l_libname->name), - DSO_FILENAME (l->l_name), - (int) sizeof l->l_map_start * 2, - (size_t) l->l_map_start, - (int) sizeof l->l_addr * 2, - (size_t) l->l_addr); - - if (l->l_tls_modid) - _dl_printf (" TLS(0x%Zx, 0x%0*Zx)\n", l->l_tls_modid, - (int) sizeof l->l_tls_offset * 2, - (size_t) l->l_tls_offset); - else - _dl_printf ("\n"); - } - } - else if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) + if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) { /* Look through the dependencies of the main executable and determine which of them is not actually @@ -2193,14 +2162,6 @@ dl_main (const ElfW(Phdr) *phdr, } } - if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) - && rtld_multiple_ref) - { - /* Mark the link map as not yet relocated again. */ - GL(dl_rtld_map).l_relocated = 0; - _dl_relocate_object (&GL(dl_rtld_map), - main_map->l_scope, __RTLD_NOIFUNC, 0); - } } #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)) if (state.version_info) @@ -2277,61 +2238,6 @@ dl_main (const ElfW(Phdr) *phdr, _exit (0); } - if (main_map->l_info[ADDRIDX (DT_GNU_LIBLIST)] - && ! __builtin_expect (GLRO(dl_profile) != NULL, 0) - && ! __builtin_expect (GLRO(dl_dynamic_weak), 0)) - { - ElfW(Lib) *liblist, *liblistend; - struct link_map **r_list, **r_listend, *l; - const char *strtab = (const void *) D_PTR (main_map, l_info[DT_STRTAB]); - - assert (main_map->l_info[VALIDX (DT_GNU_LIBLISTSZ)] != NULL); - liblist = (ElfW(Lib) *) - main_map->l_info[ADDRIDX (DT_GNU_LIBLIST)]->d_un.d_ptr; - liblistend = (ElfW(Lib) *) - ((char *) liblist - + main_map->l_info[VALIDX (DT_GNU_LIBLISTSZ)]->d_un.d_val); - r_list = main_map->l_searchlist.r_list; - r_listend = r_list + main_map->l_searchlist.r_nlist; - - for (; r_list < r_listend && liblist < liblistend; r_list++) - { - l = *r_list; - - if (l == main_map) - continue; - - /* If the library is not mapped where it should, fail. */ - if (l->l_addr) - break; - - /* Next, check if checksum matches. */ - if (l->l_info [VALIDX(DT_CHECKSUM)] == NULL - || l->l_info [VALIDX(DT_CHECKSUM)]->d_un.d_val - != liblist->l_checksum) - break; - - if (l->l_info [VALIDX(DT_GNU_PRELINKED)] == NULL - || l->l_info [VALIDX(DT_GNU_PRELINKED)]->d_un.d_val - != liblist->l_time_stamp) - break; - - if (! _dl_name_match_p (strtab + liblist->l_name, l)) - break; - - ++liblist; - } - - - if (r_list == r_listend && liblist == liblistend) - prelinked = true; - - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) - _dl_debug_printf ("\nprelink checking: %s\n", - prelinked ? "ok" : "failed"); - } - - /* Now set up the variable which helps the assembler startup code. */ GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist = &main_map->l_searchlist; @@ -2356,103 +2262,59 @@ dl_main (const ElfW(Phdr) *phdr, _rtld_main_check (main_map, _dl_argv[0]); - if (prelinked) - { - if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL) - { - ElfW(Rela) *conflict, *conflictend; + /* Now we have all the objects loaded. Relocate them all except for + the dynamic linker itself. We do this in reverse order so that copy + relocs of earlier objects overwrite the data written by later + objects. We do not re-relocate the dynamic linker itself in this + loop because that could result in the GOT entries for functions we + call being changed, and that would break us. It is safe to relocate + the dynamic linker out of order because it has no copy relocs (we + know that because it is self-contained). */ - RTLD_TIMING_VAR (start); - rtld_timer_start (&start); + int consider_profiling = GLRO(dl_profile) != NULL; - assert (main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL); - conflict = (ElfW(Rela) *) - main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr; - conflictend = (ElfW(Rela) *) - ((char *) conflict - + main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val); - _dl_resolve_conflicts (main_map, conflict, conflictend); - - rtld_timer_stop (&relocate_time, start); - } + /* If we are profiling we also must do lazy reloaction. */ + GLRO(dl_lazy) |= consider_profiling; - /* Set up the object lookup structures. */ - _dl_find_object_init (); - - /* The library defining malloc has already been relocated due to - prelinking. Resolve the malloc symbols for the dynamic - loader. */ - __rtld_malloc_init_real (main_map); - - /* Likewise for the locking implementation. */ - __rtld_mutex_init (); - - /* Mark all the objects so we know they have been already relocated. */ - for (struct link_map *l = main_map; l != NULL; l = l->l_next) - { - l->l_relocated = 1; - if (l->l_relro_size) - _dl_protect_relro (l); - - /* Add object to slot information data if necessasy. */ - if (l->l_tls_blocksize != 0 && tls_init_tp_called) - _dl_add_to_slotinfo (l, true); - } - } - else - { - /* Now we have all the objects loaded. Relocate them all except for - the dynamic linker itself. We do this in reverse order so that copy - relocs of earlier objects overwrite the data written by later - objects. We do not re-relocate the dynamic linker itself in this - loop because that could result in the GOT entries for functions we - call being changed, and that would break us. It is safe to relocate - the dynamic linker out of order because it has no copy relocs (we - know that because it is self-contained). */ - - int consider_profiling = GLRO(dl_profile) != NULL; - - /* If we are profiling we also must do lazy reloaction. */ - GLRO(dl_lazy) |= consider_profiling; + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); + { + unsigned i = main_map->l_searchlist.r_nlist; + while (i-- > 0) + { + struct link_map *l = main_map->l_initfini[i]; - RTLD_TIMING_VAR (start); - rtld_timer_start (&start); - unsigned i = main_map->l_searchlist.r_nlist; - while (i-- > 0) - { - struct link_map *l = main_map->l_initfini[i]; + /* While we are at it, help the memory handling a bit. We have to + mark some data structures as allocated with the fake malloc() + implementation in ld.so. */ + struct libname_list *lnp = l->l_libname->next; - /* While we are at it, help the memory handling a bit. We have to - mark some data structures as allocated with the fake malloc() - implementation in ld.so. */ - struct libname_list *lnp = l->l_libname->next; + while (__builtin_expect (lnp != NULL, 0)) + { + lnp->dont_free = 1; + lnp = lnp->next; + } + /* Also allocated with the fake malloc(). */ + l->l_free_initfini = 0; - while (__builtin_expect (lnp != NULL, 0)) - { - lnp->dont_free = 1; - lnp = lnp->next; - } - /* Also allocated with the fake malloc(). */ - l->l_free_initfini = 0; + if (l != &GL(dl_rtld_map)) + _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0, + consider_profiling); - if (l != &GL(dl_rtld_map)) - _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0, - consider_profiling); + /* Add object to slot information data if necessasy. */ + if (l->l_tls_blocksize != 0 && tls_init_tp_called) + _dl_add_to_slotinfo (l, true); + } + } + rtld_timer_stop (&relocate_time, start); - /* Add object to slot information data if necessasy. */ - if (l->l_tls_blocksize != 0 && tls_init_tp_called) - _dl_add_to_slotinfo (l, true); - } - rtld_timer_stop (&relocate_time, start); - - /* Now enable profiling if needed. Like the previous call, - this has to go here because the calls it makes should use the - rtld versions of the functions (particularly calloc()), but it - needs to have _dl_profile_map set up by the relocator. */ - if (__glibc_unlikely (GL(dl_profile_map) != NULL)) - /* We must prepare the profiling. */ - _dl_start_profile (); - } + /* Now enable profiling if needed. Like the previous call, + this has to go here because the calls it makes should use the + rtld versions of the functions (particularly calloc()), but it + needs to have _dl_profile_map set up by the relocator. */ + if (__glibc_unlikely (GL(dl_profile_map) != NULL)) + /* We must prepare the profiling. */ + _dl_start_profile (); if ((!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0) || count_modids != _dl_count_modids ()) @@ -2478,7 +2340,7 @@ dl_main (const ElfW(Phdr) *phdr, /* Make sure no new search directories have been added. */ assert (GLRO(dl_init_all_dirs) == GL(dl_all_dirs)); - if (! prelinked && rtld_multiple_ref) + if (rtld_multiple_ref) { /* There was an explicit ref to the dynamic linker as a shared lib. Re-relocate ourselves with user-controlled symbol definitions. @@ -2811,17 +2673,6 @@ process_envvars (struct dl_main_state *state) GLRO(dl_profile_output) = &envline[15]; break; - case 16: - /* The mode of the dynamic linker can be set. */ - if (memcmp (envline, "TRACE_PRELINKING", 16) == 0) - { - state->mode = rtld_mode_trace; - GLRO(dl_verbose) = 1; - GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK; - GLRO(dl_trace_prelink) = &envline[17]; - } - break; - case 20: /* The mode of the dynamic linker can be set. */ if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0) @@ -2955,9 +2806,8 @@ print_statistics (const hp_timing_t *rtld_total_timep) += l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val; #ifndef ELF_MACHINE_REL_RELATIVE /* Relative relocations are processed on these architectures if - library is loaded to different address than p_vaddr or - if not prelinked. */ - if ((l->l_addr != 0 || !l->l_info[VALIDX(DT_GNU_PRELINKED)]) + library is loaded to different address than p_vaddr. */ + if ((l->l_addr != 0) && l->l_info[VERSYMIDX (DT_RELACOUNT)]) #else /* On e.g. IA-64 or Alpha, relative relocations are processed diff --git a/elf/tst-prelink-cmp.c b/elf/tst-prelink-cmp.c deleted file mode 100644 index 43f2299f37..0000000000 --- a/elf/tst-prelink-cmp.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Test the output from the environment variable, LD_TRACE_PRELINKING, - for prelink. - Copyright (C) 2021-2022 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include - -static int -do_test (void) -{ -#ifndef DL_EXTERN_PROTECTED_DATA - return EXIT_UNSUPPORTED; -#else - char *src = xasprintf ("%s/elf/tst-prelink-conflict.out", - support_objdir_root); - FILE *f = xfopen (src,"r"); - size_t buffer_length = 0; - char *buffer = NULL; - - const char *expected = "/0 stdout\n"; - - xgetline (&buffer, &buffer_length, f); - TEST_COMPARE_STRING (expected, buffer); - - free (buffer); - xfclose (f); - return 0; -#endif -} - -#include diff --git a/elf/tst-prelink.c b/elf/tst-prelink.c deleted file mode 100644 index 7ec49adc0f..0000000000 --- a/elf/tst-prelink.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Test the output from the environment variable, LD_TRACE_PRELINKING, - for prelink. - Copyright (C) 2015-2022 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include - -static int -do_test (void) -{ - fprintf (stdout, "hello\n"); - return 0; -} - -#include diff --git a/include/link.h b/include/link.h index bef2820b40..03db14c7b0 100644 --- a/include/link.h +++ b/include/link.h @@ -203,10 +203,6 @@ struct link_map unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are mprotected or if no holes are present at all. */ - unsigned int l_symbolic_in_local_scope:1; /* Nonzero if l_local_scope - during LD_TRACE_PRELINKING=1 - contains any DT_SYMBOLIC - libraries. */ unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be freed, ie. not allocated with the dummy malloc in ld.so. */ diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h index 47cfefdc31..30fc790e88 100644 --- a/sysdeps/alpha/dl-machine.h +++ b/sysdeps/alpha/dl-machine.h @@ -423,23 +423,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], if (r_type == R_ALPHA_GLOB_DAT) *reloc_addr = sym_value; -#ifdef RESOLVE_CONFLICT_FIND_MAP - /* In .gnu.conflict section, R_ALPHA_JMP_SLOT relocations have - R_ALPHA_JMP_SLOT in lower 8 bits and the remaining 24 bits - are .rela.plt index. */ - else if ((r_type & 0xff) == R_ALPHA_JMP_SLOT) - { - /* elf_machine_fixup_plt needs the map reloc_addr points into, - while in _dl_resolve_conflicts map is _dl_loaded. */ - RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr); - reloc = ((const Elf64_Rela *) D_PTR (map, l_info[DT_JMPREL])) - + (r_type >> 8); - elf_machine_fixup_plt (map, 0, 0, 0, reloc, reloc_addr, sym_value); - } -#else else if (r_type == R_ALPHA_JMP_SLOT) elf_machine_fixup_plt (map, 0, 0, 0, reloc, reloc_addr, sym_value); -#endif #ifndef RTLD_BOOTSTRAP else if (r_type == R_ALPHA_REFQUAD) { diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h index 68dcb96d9d..94f41c65cb 100644 --- a/sysdeps/arm/dl-machine.h +++ b/sysdeps/arm/dl-machine.h @@ -521,9 +521,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], return; else { -# ifndef RESOLVE_CONFLICT_FIND_MAP const Elf32_Sym *const refsym = sym; -# endif struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); @@ -535,7 +533,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], switch (r_type) { -# ifndef RESOLVE_CONFLICT_FIND_MAP /* Not needed for dl-conflict.c. */ case R_ARM_COPY: if (sym == NULL) @@ -555,7 +552,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], memcpy (reloc_addr_arg, (void *) value, MIN (sym->st_size, refsym->st_size)); break; -# endif /* !RESOLVE_CONFLICT_FIND_MAP */ case R_ARM_GLOB_DAT: case R_ARM_JUMP_SLOT: case R_ARM_ABS32: diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 2ebe7901c0..d1c6cd902b 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -562,7 +562,6 @@ struct rtld_global_ro #define DL_DEBUG_SCOPES (1 << 9) /* These two are used only internally. */ #define DL_DEBUG_HELP (1 << 10) -#define DL_DEBUG_PRELINK (1 << 11) /* OS version. */ EXTERN unsigned int _dl_osversion; @@ -649,10 +648,6 @@ struct rtld_global_ro EXTERN const char *_dl_profile; /* Filename of the output file. */ EXTERN const char *_dl_profile_output; - /* Name of the object we want to trace the prelinking. */ - EXTERN const char *_dl_trace_prelink; - /* Map of shared object to be prelink traced. */ - EXTERN struct link_map *_dl_trace_prelink_map; /* All search directories defined at startup. This is assigned a non-NULL pointer by the ld.so startup code (after initialization @@ -1096,12 +1091,6 @@ extern void _dl_reloc_bad_type (struct link_map *map, unsigned int type, int plt) attribute_hidden __attribute__ ((__noreturn__)); -/* Resolve conflicts if prelinking. */ -extern void _dl_resolve_conflicts (struct link_map *l, - ElfW(Rela) *conflict, - ElfW(Rela) *conflictend) - attribute_hidden; - /* Check the version dependencies of all objects available through MAP. If VERBOSE print some more diagnostics. */ extern int _dl_check_all_versions (struct link_map *map, int verbose, diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 6182b45ed3..3ffd0b4e31 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -479,9 +479,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], *reloc_addr = map->l_addr + reloc->r_addend; else if (r_type != R_386_NONE) { -# ifndef RESOLVE_CONFLICT_FIND_MAP const Elf32_Sym *const refsym = sym; -# endif struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); @@ -503,7 +501,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], case R_386_32: *reloc_addr = value + reloc->r_addend; break; -# ifndef RESOLVE_CONFLICT_FIND_MAP /* Not needed for dl-conflict.c. */ case R_386_PC32: *reloc_addr = (value + reloc->r_addend - (Elf32_Addr) reloc_addr); @@ -525,19 +522,19 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], struct tlsdesc volatile *td = (struct tlsdesc volatile *)reloc_addr; -# ifndef RTLD_BOOTSTRAP +# ifndef RTLD_BOOTSTRAP if (!sym) { td->arg = (void*)reloc->r_addend; td->entry = _dl_tlsdesc_undefweak; } else -# endif +# endif { -# ifndef RTLD_BOOTSTRAP -# ifndef SHARED +# ifndef RTLD_BOOTSTRAP +# ifndef SHARED CHECK_STATIC_TLS (map, sym_map); -# else +# else if (!TRY_STATIC_TLS (map, sym_map)) { td->arg = _dl_make_tlsdesc_dynamic @@ -545,8 +542,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], td->entry = _dl_tlsdesc_dynamic; } else -# endif # endif +# endif { td->arg = (void*)(sym->st_value - sym_map->l_tls_offset + reloc->r_addend); @@ -599,7 +596,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], memcpy (reloc_addr_arg, (void *) value, MIN (sym->st_size, refsym->st_size)); break; -# endif /* !RESOLVE_CONFLICT_FIND_MAP */ case R_386_IRELATIVE: value = map->l_addr + reloc->r_addend; if (__glibc_likely (!skip_ifunc)) diff --git a/sysdeps/or1k/dl-machine.h b/sysdeps/or1k/dl-machine.h index 35329a60f6..849763a36e 100644 --- a/sysdeps/or1k/dl-machine.h +++ b/sysdeps/or1k/dl-machine.h @@ -189,9 +189,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], return; else { -# ifndef RESOLVE_CONFLICT_FIND_MAP const Elf32_Sym *const refsym = sym; -# endif struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); @@ -204,7 +202,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], switch (r_type) { -# ifndef RESOLVE_CONFLICT_FIND_MAP case R_OR1K_COPY: if (sym == NULL) /* This can happen in trace mode if an object could not be @@ -225,7 +222,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], memcpy (reloc_addr_arg, (void *) value, MIN (sym->st_size, refsym->st_size)); break; -# endif /* !RESOLVE_CONFLICT_FIND_MAP */ case R_OR1K_32: /* Support relocations on mis-aligned offsets. */ value += reloc->r_addend; diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h index 70961b4b78..7583b491f9 100644 --- a/sysdeps/powerpc/powerpc32/dl-machine.h +++ b/sysdeps/powerpc/powerpc32/dl-machine.h @@ -294,7 +294,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], const int r_type = ELF32_R_TYPE (reloc->r_info); struct link_map *sym_map = NULL; -#ifndef RESOLVE_CONFLICT_FIND_MAP if (r_type == R_PPC_RELATIVE) { *reloc_addr = map->l_addr + reloc->r_addend; @@ -318,9 +317,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], value = SYMBOL_ADDRESS (sym_map, sym, true); } value += reloc->r_addend; -#else - value = reloc->r_addend; -#endif if (sym != NULL && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0) @@ -341,12 +337,11 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], *reloc_addr = value; break; -#ifndef RESOLVE_CONFLICT_FIND_MAP -# ifdef RTLD_BOOTSTRAP -# define NOT_BOOTSTRAP 0 -# else -# define NOT_BOOTSTRAP 1 -# endif +#ifdef RTLD_BOOTSTRAP +# define NOT_BOOTSTRAP 0 +#else +# define NOT_BOOTSTRAP 1 +#endif case R_PPC_DTPMOD32: if (map->l_info[DT_PPC(OPT)] @@ -361,11 +356,11 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], } else if (sym_map != NULL) { -# ifndef SHARED +#ifndef SHARED CHECK_STATIC_TLS (map, sym_map); -# else +#else if (TRY_STATIC_TLS (map, sym_map)) -# endif +#endif { reloc_addr[0] = 0; /* Set up for local dynamic. */ @@ -395,11 +390,11 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], else if (sym_map != NULL) { /* This reloc is always preceded by R_PPC_DTPMOD32. */ -# ifndef SHARED +#ifndef SHARED assert (HAVE_STATIC_TLS (map, sym_map)); -# else +#else if (HAVE_STATIC_TLS (map, sym_map)) -# endif +#endif { *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc); break; @@ -419,12 +414,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc); } break; -#endif case R_PPC_JMP_SLOT: -#ifdef RESOLVE_CONFLICT_FIND_MAP - RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr); -#endif if (map->l_info[DT_PPC(GOT)] != 0) { *reloc_addr = value; diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h index a505998351..5da5de7a0a 100644 --- a/sysdeps/powerpc/powerpc64/dl-machine.h +++ b/sysdeps/powerpc/powerpc64/dl-machine.h @@ -537,36 +537,6 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map, return finaladdr; } -static inline void __attribute__ ((always_inline)) -elf_machine_plt_conflict (struct link_map *map, lookup_t sym_map, - const ElfW(Sym) *refsym, const ElfW(Sym) *sym, - const Elf64_Rela *reloc, - Elf64_Addr *reloc_addr, Elf64_Addr finaladdr) -{ -#if _CALL_ELF != 2 - Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr; - Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr; - Elf64_FuncDesc zero_fd = {0, 0, 0}; - - if (sym_map == NULL) - finaladdr = 0; - - if (finaladdr == 0) - rel = &zero_fd; - - plt->fd_func = rel->fd_func; - plt->fd_aux = rel->fd_aux; - plt->fd_toc = rel->fd_toc; - PPC_DCBST (&plt->fd_func); - PPC_DCBST (&plt->fd_aux); - PPC_DCBST (&plt->fd_toc); - PPC_SYNC; -#else - finaladdr += ppc64_local_entry_offset (map, sym_map, refsym, sym); - *reloc_addr = finaladdr; -#endif -} - /* Return the final value of a plt relocation. */ static inline Elf64_Addr elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, @@ -639,7 +609,6 @@ resolve_ifunc (Elf64_Addr value, const struct link_map *map, const struct link_map *sym_map) { #if _CALL_ELF != 2 -#ifndef RESOLVE_CONFLICT_FIND_MAP /* The function we are calling may not yet have its opd entry relocated. */ Elf64_FuncDesc opd; if (map != sym_map @@ -657,7 +626,6 @@ resolve_ifunc (Elf64_Addr value, dependency. */ asm ("" : "=r" (value) : "0" (&opd), "X" (opd)); } -#endif #endif return ((Elf64_Addr (*) (unsigned long int)) value) (GLRO(dl_hwcap)); } @@ -722,13 +690,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], value = resolve_ifunc (value, map, sym_map); /* Fall thru */ case R_PPC64_JMP_SLOT: -#ifdef RESOLVE_CONFLICT_FIND_MAP - elf_machine_plt_conflict (map, sym_map, refsym, sym, - reloc, reloc_addr, value); -#else elf_machine_fixup_plt (map, sym_map, refsym, sym, reloc, reloc_addr, value); -#endif return; case R_PPC64_DTPMOD64: diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h index 5178d8c68c..4e6229e945 100644 --- a/sysdeps/s390/s390-32/dl-machine.h +++ b/sysdeps/s390/s390-32/dl-machine.h @@ -352,7 +352,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], return; else { -#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP +#if !defined RTLD_BOOTSTRAP /* Only needed for R_390_COPY below. */ const Elf32_Sym *const refsym = sym; #endif @@ -380,34 +380,33 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], *reloc_addr = value + reloc->r_addend; break; -#ifndef RESOLVE_CONFLICT_FIND_MAP case R_390_TLS_DTPMOD: -# ifdef RTLD_BOOTSTRAP +#ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always the module with index 1. XXX If this relocation is necessary move before RESOLVE call. */ *reloc_addr = 1; -# else +#else /* Get the information from the link map returned by the resolv function. */ if (sym_map != NULL) *reloc_addr = sym_map->l_tls_modid; -# endif +#endif break; case R_390_TLS_DTPOFF: -# ifndef RTLD_BOOTSTRAP +#ifndef RTLD_BOOTSTRAP /* During relocation all TLS symbols are defined and used. Therefore the offset is already correct. */ if (sym != NULL) *reloc_addr = sym->st_value + reloc->r_addend; -# endif +#endif break; case R_390_TLS_TPOFF: /* The offset is negative, forward from the thread pointer. */ -# ifdef RTLD_BOOTSTRAP +#ifdef RTLD_BOOTSTRAP *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset; -# else +#else /* We know the offset of the object the symbol is contained in. It is a negative value which will be added to the thread pointer. */ @@ -419,10 +418,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], } #endif break; -#endif /* use TLS */ #ifndef RTLD_BOOTSTRAP -# ifndef RESOLVE_CONFLICT_FIND_MAP /* Not needed in dl-conflict.c. */ case R_390_COPY: if (sym == NULL) @@ -443,7 +440,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], memcpy (reloc_addr_arg, (void *) value, MIN (sym->st_size, refsym->st_size)); break; -# endif case R_390_32: *reloc_addr = value + reloc->r_addend; break; @@ -453,7 +449,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], case R_390_8: *(char *) reloc_addr = value + reloc->r_addend; break; -# ifndef RESOLVE_CONFLICT_FIND_MAP case R_390_PC32: *reloc_addr = value + reloc->r_addend - (Elf32_Addr) reloc_addr; break; @@ -471,7 +466,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], break; case R_390_NONE: break; -# endif #endif #if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG) default: diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h index 9c0d247e60..4bd97f5645 100644 --- a/sysdeps/s390/s390-64/dl-machine.h +++ b/sysdeps/s390/s390-64/dl-machine.h @@ -299,7 +299,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], return; else { -#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP +#if !defined RTLD_BOOTSTRAP /* Only needed for R_390_COPY below. */ const Elf64_Sym *const refsym = sym; #endif @@ -327,34 +327,33 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], *reloc_addr = value + reloc->r_addend; break; -#ifndef RESOLVE_CONFLICT_FIND_MAP case R_390_TLS_DTPMOD: -# ifdef RTLD_BOOTSTRAP +#ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always the module with index 1. XXX If this relocation is necessary move before RESOLVE call. */ *reloc_addr = 1; -# else +#else /* Get the information from the link map returned by the resolv function. */ if (sym_map != NULL) *reloc_addr = sym_map->l_tls_modid; -# endif +#endif break; case R_390_TLS_DTPOFF: -# ifndef RTLD_BOOTSTRAP +#ifndef RTLD_BOOTSTRAP /* During relocation all TLS symbols are defined and used. Therefore the offset is already correct. */ if (sym != NULL) *reloc_addr = sym->st_value + reloc->r_addend; -# endif +#endif break; case R_390_TLS_TPOFF: /* The offset is negative, forward from the thread pointer. */ -# ifdef RTLD_BOOTSTRAP +#ifdef RTLD_BOOTSTRAP *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset; -# else +#else /* We know the offset of the object the symbol is contained in. It is a negative value which will be added to the thread pointer. */ @@ -366,10 +365,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], } #endif break; -#endif /* use TLS */ #ifndef RTLD_BOOTSTRAP -# ifndef RESOLVE_CONFLICT_FIND_MAP /* Not needed for dl-conflict.c. */ case R_390_COPY: if (sym == NULL) @@ -390,7 +387,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], memcpy (reloc_addr_arg, (void *) value, MIN (sym->st_size, refsym->st_size)); break; -# endif case R_390_64: *reloc_addr = value + reloc->r_addend; break; @@ -403,7 +399,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], case R_390_8: *(char *) reloc_addr = value + reloc->r_addend; break; -# ifndef RESOLVE_CONFLICT_FIND_MAP case R_390_PC64: *reloc_addr = value +reloc->r_addend - (Elf64_Addr) reloc_addr; break; @@ -425,7 +420,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], break; case R_390_NONE: break; -# endif #endif #if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG) default: diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h index c99ad2054d..8b08a1fc47 100644 --- a/sysdeps/sh/dl-machine.h +++ b/sysdeps/sh/dl-machine.h @@ -391,7 +391,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], break; case R_SH_DIR32: { -#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP +#if !defined RTLD_BOOTSTRAP /* This is defined in rtld.c, but nowhere in the static libc.a; make the reference weak so static programs can still link. This declaration cannot be done when diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h index 35e680c255..e8d208a080 100644 --- a/sysdeps/sparc/sparc32/dl-machine.h +++ b/sysdeps/sparc/sparc32/dl-machine.h @@ -142,44 +142,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], plt[1] = 0x85c0a000 | (rfunc & 0x3ff); plt[2] = OPCODE_NOP; /* Fill call delay slot. */ plt[3] = (Elf32_Addr) l; - if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0) - || __builtin_expect (l->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL, 0)) - { - /* Need to reinitialize .plt to undo prelinking. */ - Elf32_Rela *rela = (Elf32_Rela *) D_PTR (l, l_info[DT_JMPREL]); - Elf32_Rela *relaend - = (Elf32_Rela *) ((char *) rela - + l->l_info[DT_PLTRELSZ]->d_un.d_val); -#if !defined RTLD_BOOTSTRAP && !defined __sparc_v9__ - /* Note that we don't mask the hwcap here, as the flush is - essential to functionality on those cpu's that implement it. - For sparcv9 we can assume flush is present. */ - const int do_flush = GLRO(dl_hwcap) & HWCAP_SPARC_FLUSH; -#else - const int do_flush = 1; -#endif - - /* prelink must ensure there are no R_SPARC_NONE relocs left - in .rela.plt. */ - while (rela < relaend) - { - *(unsigned int *) (rela->r_offset + l->l_addr) - = OPCODE_SETHI_G1 | (rela->r_offset + l->l_addr - - (Elf32_Addr) plt); - *(unsigned int *) (rela->r_offset + l->l_addr + 4) - = OPCODE_BA | ((((Elf32_Addr) plt - - rela->r_offset - l->l_addr - 4) >> 2) - & 0x3fffff); - if (do_flush) - { - __asm __volatile ("flush %0" : : "r" (rela->r_offset - + l->l_addr)); - __asm __volatile ("flush %0+4" : : "r" (rela->r_offset - + l->l_addr)); - } - ++rela; - } - } } return lazy; @@ -334,14 +296,12 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], void *const reloc_addr_arg, int skip_ifunc) { Elf32_Addr *const reloc_addr = reloc_addr_arg; -#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP +#if !defined RTLD_BOOTSTRAP const Elf32_Sym *const refsym = sym; #endif Elf32_Addr value; const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); -#if !defined RESOLVE_CONFLICT_FIND_MAP struct link_map *sym_map = NULL; -#endif #if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC /* This is defined in rtld.c, but nowhere in the static libc.a; make the @@ -372,7 +332,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], } #endif -#ifndef RESOLVE_CONFLICT_FIND_MAP if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0) && sym->st_shndx != SHN_UNDEF) { @@ -384,9 +343,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); value = SYMBOL_ADDRESS (sym_map, sym, true); } -#else - value = 0; -#endif value += reloc->r_addend; /* Assume copy relocs have zero addend. */ @@ -400,7 +356,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], switch (r_type) { -#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP +#if !defined RTLD_BOOTSTRAP case R_SPARC_COPY: if (sym == NULL) /* This can happen in trace mode if an object could not be @@ -450,7 +406,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], sparc_fixup_plt (reloc, reloc_addr, value, 0, do_flush); } break; -#ifndef RESOLVE_CONFLICT_FIND_MAP case R_SPARC_TLS_DTPMOD32: /* Get the information from the link map returned by the resolv function. */ @@ -474,7 +429,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], + reloc->r_addend; } break; -# ifndef RTLD_BOOTSTRAP +#ifndef RTLD_BOOTSTRAP case R_SPARC_TLS_LE_HIX22: case R_SPARC_TLS_LE_LOX10: if (sym != NULL) @@ -489,7 +444,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], | 0x1c00; } break; -# endif #endif #ifndef RTLD_BOOTSTRAP case R_SPARC_8: diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h index b6b36db240..dc24dbc305 100644 --- a/sysdeps/sparc/sparc64/dl-machine.h +++ b/sysdeps/sparc/sparc64/dl-machine.h @@ -196,50 +196,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], /* Now put the magic cookie at the beginning of .PLT2 Entry .PLT3 is unused by this implementation. */ *((struct link_map **)(&plt[16])) = l; - - if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0) - || __builtin_expect (l->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL, 0)) - { - /* Need to reinitialize .plt to undo prelinking. */ - Elf64_Rela *rela = (Elf64_Rela *) D_PTR (l, l_info[DT_JMPREL]); - Elf64_Rela *relaend - = (Elf64_Rela *) ((char *) rela - + l->l_info[DT_PLTRELSZ]->d_un.d_val); - - /* prelink must ensure there are no R_SPARC_NONE relocs left - in .rela.plt. */ - while (rela < relaend) - { - if (__builtin_expect (rela->r_addend, 0) != 0) - { - Elf64_Addr slot = ((rela->r_offset + l->l_addr + 0x400 - - (Elf64_Addr) plt) - / 0x1400) * 0x1400 - + (Elf64_Addr) plt - 0x400; - /* ldx [%o7 + X], %g1 */ - unsigned int first_ldx = *(unsigned int *)(slot + 12); - Elf64_Addr ptr = slot + (first_ldx & 0xfff) + 4; - - *(Elf64_Addr *) (rela->r_offset + l->l_addr) - = (Elf64_Addr) plt - - (slot + ((rela->r_offset + l->l_addr - ptr) / 8) * 24 - + 4); - ++rela; - continue; - } - - *(unsigned int *) (rela->r_offset + l->l_addr) - = 0x03000000 | (rela->r_offset + l->l_addr - (Elf64_Addr) plt); - *(unsigned int *) (rela->r_offset + l->l_addr + 4) - = 0x30680000 | ((((Elf64_Addr) plt + 32 - rela->r_offset - - l->l_addr - 4) >> 2) & 0x7ffff); - __asm __volatile ("flush %0" : : "r" (rela->r_offset - + l->l_addr)); - __asm __volatile ("flush %0+4" : : "r" (rela->r_offset - + l->l_addr)); - ++rela; - } - } } return lazy; @@ -361,14 +317,12 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], void *const reloc_addr_arg, int skip_ifunc) { Elf64_Addr *const reloc_addr = reloc_addr_arg; -#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP +#if !defined RTLD_BOOTSTRAP const Elf64_Sym *const refsym = sym; #endif Elf64_Addr value; const unsigned long int r_type = ELF64_R_TYPE_ID (reloc->r_info); -#if !defined RESOLVE_CONFLICT_FIND_MAP struct link_map *sym_map = NULL; -#endif #if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC /* This is defined in rtld.c, but nowhere in the static libc.a; make the @@ -399,7 +353,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], } #endif -#ifndef RESOLVE_CONFLICT_FIND_MAP if (__builtin_expect (ELF64_ST_BIND (sym->st_info) == STB_LOCAL, 0) && sym->st_shndx != SHN_UNDEF) { @@ -411,9 +364,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); value = SYMBOL_ADDRESS (sym_map, sym, true); } -#else - value = 0; -#endif value += reloc->r_addend; /* Assume copy relocs have zero addend. */ @@ -425,7 +375,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], switch (r_type) { -#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP +#if !defined RTLD_BOOTSTRAP case R_SPARC_COPY: if (sym == NULL) /* This can happen in trace mode if an object could not be @@ -459,26 +409,11 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], value = ((Elf64_Addr (*) (int)) value) (GLRO(dl_hwcap)); /* 'high' is always zero, for large PLT entries the linker emits an R_SPARC_IRELATIVE. */ -#ifdef RESOLVE_CONFLICT_FIND_MAP - sparc64_fixup_plt (NULL, reloc, reloc_addr, value, 0, 0); -#else sparc64_fixup_plt (map, reloc, reloc_addr, value, 0, 0); -#endif break; case R_SPARC_JMP_SLOT: -#ifdef RESOLVE_CONFLICT_FIND_MAP - /* R_SPARC_JMP_SLOT conflicts against .plt[32768+] - relocs should be turned into R_SPARC_64 relocs - in .gnu.conflict section. - r_addend non-zero does not mean it is a .plt[32768+] - reloc, instead it is the actual address of the function - to call. */ - sparc64_fixup_plt (NULL, reloc, reloc_addr, value, 0, 0); -#else sparc64_fixup_plt (map, reloc, reloc_addr, value, reloc->r_addend, 0); -#endif break; -#ifndef RESOLVE_CONFLICT_FIND_MAP case R_SPARC_TLS_DTPMOD64: /* Get the information from the link map returned by the resolv function. */ @@ -502,7 +437,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], + reloc->r_addend; } break; -# ifndef RTLD_BOOTSTRAP +#ifndef RTLD_BOOTSTRAP case R_SPARC_TLS_LE_HIX22: case R_SPARC_TLS_LE_LOX10: if (sym != NULL) @@ -520,7 +455,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], | 0x1c00); } break; -# endif #endif #ifndef RTLD_BOOTSTRAP case R_SPARC_8: diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index 155ca36bd5..6a6187490b 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -346,59 +346,58 @@ and creates an unsatisfiable circular dependency.\n", *reloc_addr = value + reloc->r_addend; break; -# ifndef RESOLVE_CONFLICT_FIND_MAP case R_X86_64_DTPMOD64: -# ifdef RTLD_BOOTSTRAP +# ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always the module with index 1. XXX If this relocation is necessary move before RESOLVE call. */ *reloc_addr = 1; -# else +# else /* Get the information from the link map returned by the resolve function. */ if (sym_map != NULL) *reloc_addr = sym_map->l_tls_modid; -# endif +# endif break; case R_X86_64_DTPOFF64: -# ifndef RTLD_BOOTSTRAP +# ifndef RTLD_BOOTSTRAP /* During relocation all TLS symbols are defined and used. Therefore the offset is already correct. */ if (sym != NULL) { value = sym->st_value + reloc->r_addend; -# ifdef __ILP32__ +# ifdef __ILP32__ /* This relocation type computes a signed offset that is usually negative. The symbol and addend values are 32 bits but the GOT entry is 64 bits wide and the whole 64-bit entry is used as a signed quantity, so we need to sign-extend the computed value to 64 bits. */ *(Elf64_Sxword *) reloc_addr = (Elf64_Sxword) (Elf32_Sword) value; -# else +# else *reloc_addr = value; -# endif - } # endif + } +# endif break; case R_X86_64_TLSDESC: { struct tlsdesc volatile *td = (struct tlsdesc volatile *)reloc_addr; -# ifndef RTLD_BOOTSTRAP +# ifndef RTLD_BOOTSTRAP if (! sym) { td->arg = (void*)reloc->r_addend; td->entry = _dl_tlsdesc_undefweak; } else -# endif +# endif { -# ifndef RTLD_BOOTSTRAP -# ifndef SHARED +# ifndef RTLD_BOOTSTRAP +# ifndef SHARED CHECK_STATIC_TLS (map, sym_map); -# else +# else if (!TRY_STATIC_TLS (map, sym_map)) { td->arg = _dl_make_tlsdesc_dynamic @@ -406,8 +405,8 @@ and creates an unsatisfiable circular dependency.\n", td->entry = _dl_tlsdesc_dynamic; } else -# endif # endif +# endif { td->arg = (void*)(sym->st_value - sym_map->l_tls_offset + reloc->r_addend); @@ -418,30 +417,29 @@ and creates an unsatisfiable circular dependency.\n", } case R_X86_64_TPOFF64: /* The offset is negative, forward from the thread pointer. */ -# ifndef RTLD_BOOTSTRAP +# ifndef RTLD_BOOTSTRAP if (sym != NULL) -# endif +# endif { -# ifndef RTLD_BOOTSTRAP +# ifndef RTLD_BOOTSTRAP CHECK_STATIC_TLS (map, sym_map); -# endif +# endif /* We know the offset of the object the symbol is contained in. It is a negative value which will be added to the thread pointer. */ value = (sym->st_value + reloc->r_addend - sym_map->l_tls_offset); -# ifdef __ILP32__ +# ifdef __ILP32__ /* The symbol and addend values are 32 bits but the GOT entry is 64 bits wide and the whole 64-bit entry is used as a signed quantity, so we need to sign-extend the computed value to 64 bits. */ *(Elf64_Sxword *) reloc_addr = (Elf64_Sxword) (Elf32_Sword) value; -# else +# else *reloc_addr = value; -# endif +# endif } break; -# endif # ifndef RTLD_BOOTSTRAP case R_X86_64_64: @@ -466,15 +464,12 @@ and creates an unsatisfiable circular dependency.\n", fmt = "\ %s: Symbol `%s' causes overflow in R_X86_64_32 relocation\n"; -# ifndef RESOLVE_CONFLICT_FIND_MAP print_err: -# endif strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]); _dl_error_printf (fmt, RTLD_PROGNAME, strtab + refsym->st_name); } break; -# ifndef RESOLVE_CONFLICT_FIND_MAP /* Not needed for dl-conflict.c. */ case R_X86_64_PC32: value += reloc->r_addend - (ElfW(Addr)) reloc_addr; @@ -502,7 +497,6 @@ and creates an unsatisfiable circular dependency.\n", goto print_err; } break; -# endif case R_X86_64_IRELATIVE: value = map->l_addr + reloc->r_addend; if (__glibc_likely (!skip_ifunc)) -- cgit v1.2.3