aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2022-01-13 17:58:00 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2022-02-10 09:16:12 -0300
commit6628c742b2c16e785d3c884d9deeda5adb30ca12 (patch)
tree493580e40aef171896584e1d3d32bbe14c15140b
parent8c8510ab2790039e58995ef3a22309582413d3ff (diff)
downloadglibc-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--NEWS4
-rw-r--r--elf/Makefile16
-rw-r--r--elf/dl-conflict.c77
-rw-r--r--elf/dl-deps.c66
-rw-r--r--elf/dl-error-skeleton.c4
-rw-r--r--elf/dl-load.c3
-rw-r--r--elf/dl-lookup.c161
-rw-r--r--elf/do-rel.h3
-rw-r--r--elf/rtld.c250
-rw-r--r--elf/tst-prelink-cmp.c49
-rw-r--r--elf/tst-prelink.c29
-rw-r--r--include/link.h4
-rw-r--r--sysdeps/alpha/dl-machine.h15
-rw-r--r--sysdeps/arm/dl-machine.h4
-rw-r--r--sysdeps/generic/ldsodefs.h11
-rw-r--r--sysdeps/i386/dl-machine.h16
-rw-r--r--sysdeps/or1k/dl-machine.h4
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.h31
-rw-r--r--sysdeps/powerpc/powerpc64/dl-machine.h37
-rw-r--r--sysdeps/s390/s390-32/dl-machine.h22
-rw-r--r--sysdeps/s390/s390-64/dl-machine.h22
-rw-r--r--sysdeps/sh/dl-machine.h2
-rw-r--r--sysdeps/sparc/sparc32/dl-machine.h52
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h72
-rw-r--r--sysdeps/x86_64/dl-machine.h48
25 files changed, 117 insertions, 885 deletions
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 <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,
- &current_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