diff options
| author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2022-01-13 17:58:00 -0300 |
|---|---|---|
| committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2022-02-10 09:16:12 -0300 |
| commit | 6628c742b2c16e785d3c884d9deeda5adb30ca12 (patch) | |
| tree | 493580e40aef171896584e1d3d32bbe14c15140b | |
| parent | 8c8510ab2790039e58995ef3a22309582413d3ff (diff) | |
| download | glibc-6628c742b2c16e785d3c884d9deeda5adb30ca12.tar.xz glibc-6628c742b2c16e785d3c884d9deeda5adb30ca12.zip | |
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 <siddhesh@sourceware.org>
| -rw-r--r-- | NEWS | 4 | ||||
| -rw-r--r-- | elf/Makefile | 16 | ||||
| -rw-r--r-- | elf/dl-conflict.c | 77 | ||||
| -rw-r--r-- | elf/dl-deps.c | 66 | ||||
| -rw-r--r-- | elf/dl-error-skeleton.c | 4 | ||||
| -rw-r--r-- | elf/dl-load.c | 3 | ||||
| -rw-r--r-- | elf/dl-lookup.c | 161 | ||||
| -rw-r--r-- | elf/do-rel.h | 3 | ||||
| -rw-r--r-- | elf/rtld.c | 250 | ||||
| -rw-r--r-- | elf/tst-prelink-cmp.c | 49 | ||||
| -rw-r--r-- | elf/tst-prelink.c | 29 | ||||
| -rw-r--r-- | include/link.h | 4 | ||||
| -rw-r--r-- | sysdeps/alpha/dl-machine.h | 15 | ||||
| -rw-r--r-- | sysdeps/arm/dl-machine.h | 4 | ||||
| -rw-r--r-- | sysdeps/generic/ldsodefs.h | 11 | ||||
| -rw-r--r-- | sysdeps/i386/dl-machine.h | 16 | ||||
| -rw-r--r-- | sysdeps/or1k/dl-machine.h | 4 | ||||
| -rw-r--r-- | sysdeps/powerpc/powerpc32/dl-machine.h | 31 | ||||
| -rw-r--r-- | sysdeps/powerpc/powerpc64/dl-machine.h | 37 | ||||
| -rw-r--r-- | sysdeps/s390/s390-32/dl-machine.h | 22 | ||||
| -rw-r--r-- | sysdeps/s390/s390-64/dl-machine.h | 22 | ||||
| -rw-r--r-- | sysdeps/sh/dl-machine.h | 2 | ||||
| -rw-r--r-- | sysdeps/sparc/sparc32/dl-machine.h | 52 | ||||
| -rw-r--r-- | sysdeps/sparc/sparc64/dl-machine.h | 72 | ||||
| -rw-r--r-- | sysdeps/x86_64/dl-machine.h | 48 |
25 files changed, 117 insertions, 885 deletions
@@ -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 <https://www.gnu.org/licenses/>. */ - -#include <assert.h> -#include <errno.h> -#include <libintl.h> -#include <stdlib.h> -#include <unistd.h> -#include <ldsodefs.h> -#include <sys/mman.h> -#include <sys/param.h> -#include <sys/types.h> -#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(d |
