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>
This commit is contained in:
Adhemerval Zanella 2022-01-13 17:58:00 -03:00
parent 8c8510ab27
commit 6628c742b2
25 changed files with 117 additions and 885 deletions

4
NEWS
View File

@ -13,7 +13,9 @@ Major new features:
Deprecated and removed features, and other changes affecting compatibility: 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: Changes to build and runtime requirements:

View File

@ -127,7 +127,6 @@ rtld-routines = \
$(all-dl-routines) \ $(all-dl-routines) \
dl-audit \ dl-audit \
dl-compat \ dl-compat \
dl-conflict \
dl-diagnostics \ dl-diagnostics \
dl-diagnostics-cpu \ dl-diagnostics-cpu \
dl-diagnostics-kernel \ dl-diagnostics-kernel \
@ -1103,14 +1102,6 @@ tests-special += $(objpfx)check-abi-ld.out
update-abi: update-abi-ld update-abi: update-abi-ld
update-all-abi: update-all-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 # The test requires shared _and_ PIE because the executable
# unit test driver must be able to link with the shared object # unit test driver must be able to link with the shared object
# that is going to eventually go into an installed DSO. # 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: \ $(objpfx)tst-tls-manydynamic.out: \
$(patsubst %,$(objpfx)%.so,$(tst-tls-many-dynamic-modules)) $(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 $(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh $(objpfx)ldconfig
$(SHELL) $< '$(common-objpfx)' '$(test-wrapper-env)' \ $(SHELL) $< '$(common-objpfx)' '$(test-wrapper-env)' \
'$(run-program-env)' > $@; \ '$(run-program-env)' > $@; \

View File

@ -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
}

View File

@ -68,22 +68,6 @@ openaux (void *a)
args->map->l_ns); 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 /* We use a very special kind of list to track the path
through the list of loaded shared objects. We have to through the list of loaded shared objects. We have to
produce a flat list with unique members of all involved objects. 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; 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. */ /* Maybe we can remove some relocation dependencies now. */
struct link_map_reldeps *l_reldeps = NULL; struct link_map_reldeps *l_reldeps = NULL;
if (map->l_reldeps != NULL) if (map->l_reldeps != NULL)

View File

@ -132,7 +132,7 @@ _dl_signal_cexception (int errcode, struct dl_exception *exception,
const char *occasion) const char *occasion)
{ {
if (__builtin_expect (GLRO(dl_debug_mask) 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", _dl_debug_printf ("%s: error: %s: %s (%s)\n",
exception->objname, occasion, exception->objname, occasion,
exception->errstring, receiver ? "continued" : "fatal"); exception->errstring, receiver ? "continued" : "fatal");
@ -153,7 +153,7 @@ _dl_signal_cerror (int errcode, const char *objname, const char *occation,
const char *errstring) const char *errstring)
{ {
if (__builtin_expect (GLRO(dl_debug_mask) 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, _dl_debug_printf ("%s: error: %s: %s (%s)\n", objname, occation,
errstring, receiver ? "continued" : "fatal"); errstring, receiver ? "continued" : "fatal");

View File

@ -2263,8 +2263,7 @@ _dl_map_object (struct link_map *loader, const char *name,
if (__glibc_unlikely (fd == -1)) if (__glibc_unlikely (fd == -1))
{ {
if (trace_mode if (trace_mode)
&& __glibc_likely ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) == 0))
{ {
/* We haven't found an appropriate library. But since we /* We haven't found an appropriate library. But since we
are only interested in the list of libraries this isn't are only interested in the list of libraries this isn't

View File

@ -296,19 +296,6 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash,
assert (!RTLD_CHECK_FOREIGN_CALL); assert (!RTLD_CHECK_FOREIGN_CALL);
#endif #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 #define INITIAL_NUNIQUE_SYM_TABLE 31
size = INITIAL_NUNIQUE_SYM_TABLE; size = INITIAL_NUNIQUE_SYM_TABLE;
entries = calloc (sizeof (struct unique_sym), size); entries = calloc (sizeof (struct unique_sym), size);
@ -341,9 +328,6 @@ marking %s [%lu] as NODELETE due to unique symbol\n",
} }
++tab->n_elements; ++tab->n_elements;
#ifdef SHARED
success:
#endif
__rtld_lock_unlock_recursive (tab->lock); __rtld_lock_unlock_recursive (tab->lock);
result->s = sym; result->s = sym;
@ -818,12 +802,6 @@ marking %s [%lu] as NODELETE due to memory allocation failure\n",
goto out; 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 /* Search loaded objects' symbol tables for a definition of the symbol
UNDEF_NAME, perhaps with a requested version for 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)) if (__glibc_unlikely (current_value.m->l_used == 0))
current_value.m->l_used = 1; 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; *ref = current_value.s;
return LOOKUP_VALUE (current_value.m); 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
}

View File

@ -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 relocations or rela relocations if they are computed as
memory_loc += l_addr... */ memory_loc += l_addr... */
if (l_addr != 0) 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
#endif #endif
for (; relative < r; ++relative) for (; relative < r; ++relative)

View File

@ -565,7 +565,7 @@ _dl_start (void *arg)
ELF_MACHINE_BEFORE_RTLD_RELOC (&bootstrap_map, bootstrap_map.l_info); ELF_MACHINE_BEFORE_RTLD_RELOC (&bootstrap_map, bootstrap_map.l_info);
#endif #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 /* Relocate ourselves so we can do normal function calls and
data access using the global offset table. */ data access using the global offset table. */
@ -1322,7 +1322,6 @@ dl_main (const ElfW(Phdr) *phdr,
size_t file_size; size_t file_size;
char *file; char *file;
unsigned int i; unsigned int i;
bool prelinked = false;
bool rtld_is_main = false; bool rtld_is_main = false;
void *tcbp = NULL; void *tcbp = NULL;
@ -2055,37 +2054,7 @@ dl_main (const ElfW(Phdr) *phdr,
after relocation. */ after relocation. */
struct link_map *l; struct link_map *l;
if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
{
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)
{ {
/* Look through the dependencies of the main executable /* Look through the dependencies of the main executable
and determine which of them is not actually 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)) #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
if (state.version_info) if (state.version_info)
@ -2277,61 +2238,6 @@ dl_main (const ElfW(Phdr) *phdr,
_exit (0); _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. */ /* Now set up the variable which helps the assembler startup code. */
GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist = &main_map->l_searchlist; 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]); _rtld_main_check (main_map, _dl_argv[0]);
if (prelinked) /* 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
if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL) relocs of earlier objects overwrite the data written by later
{ objects. We do not re-relocate the dynamic linker itself in this
ElfW(Rela) *conflict, *conflictend; 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); int consider_profiling = GLRO(dl_profile) != NULL;
rtld_timer_start (&start);
assert (main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL); /* If we are profiling we also must do lazy reloaction. */
conflict = (ElfW(Rela) *) GLRO(dl_lazy) |= consider_profiling;
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); 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];
/* Set up the object lookup structures. */ /* While we are at it, help the memory handling a bit. We have to
_dl_find_object_init (); mark some data structures as allocated with the fake malloc()
implementation in ld.so. */
struct libname_list *lnp = l->l_libname->next;
/* The library defining malloc has already been relocated due to while (__builtin_expect (lnp != NULL, 0))
prelinking. Resolve the malloc symbols for the dynamic {
loader. */ lnp->dont_free = 1;
__rtld_malloc_init_real (main_map); lnp = lnp->next;
}
/* Also allocated with the fake malloc(). */
l->l_free_initfini = 0;
/* Likewise for the locking implementation. */ if (l != &GL(dl_rtld_map))
__rtld_mutex_init (); _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0,
consider_profiling);
/* Mark all the objects so we know they have been already relocated. */ /* Add object to slot information data if necessasy. */
for (struct link_map *l = main_map; l != NULL; l = l->l_next) if (l->l_tls_blocksize != 0 && tls_init_tp_called)
{ _dl_add_to_slotinfo (l, true);
l->l_relocated = 1; }
if (l->l_relro_size) }
_dl_protect_relro (l); rtld_timer_stop (&relocate_time, start);
/* Add object to slot information data if necessasy. */ /* Now enable profiling if needed. Like the previous call,
if (l->l_tls_blocksize != 0 && tls_init_tp_called) this has to go here because the calls it makes should use the
_dl_add_to_slotinfo (l, true); 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))
else /* We must prepare the profiling. */
{ _dl_start_profile ();
/* 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];
/* 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;
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);
/* 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) if ((!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0)
|| count_modids != _dl_count_modids ()) || count_modids != _dl_count_modids ())
@ -2478,7 +2340,7 @@ dl_main (const ElfW(Phdr) *phdr,
/* Make sure no new search directories have been added. */ /* Make sure no new search directories have been added. */
assert (GLRO(dl_init_all_dirs) == GL(dl_all_dirs)); 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. /* There was an explicit ref to the dynamic linker as a shared lib.
Re-relocate ourselves with user-controlled symbol definitions. 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]; GLRO(dl_profile_output) = &envline[15];
break; 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: case 20:
/* The mode of the dynamic linker can be set. */ /* The mode of the dynamic linker can be set. */
if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0) 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; += l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val;
#ifndef ELF_MACHINE_REL_RELATIVE #ifndef ELF_MACHINE_REL_RELATIVE
/* Relative relocations are processed on these architectures if /* Relative relocations are processed on these architectures if
library is loaded to different address than p_vaddr or library is loaded to different address than p_vaddr. */
if not prelinked. */ if ((l->l_addr != 0)
if ((l->l_addr != 0 || !l->l_info[VALIDX(DT_GNU_PRELINKED)])
&& l->l_info[VERSYMIDX (DT_RELACOUNT)]) && l->l_info[VERSYMIDX (DT_RELACOUNT)])
#else #else
/* On e.g. IA-64 or Alpha, relative relocations are processed /* On e.g. IA-64 or Alpha, relative relocations are processed

View File

@ -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
<https://www.gnu.org/licenses/>. */
#include <ldsodefs.h>
#include <support/check.h>
#include <support/xstdio.h>
#include <support/support.h>
#include <support/test-driver.h>
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 <support/test-driver.c>

View File

@ -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
<https://www.gnu.org/licenses/>. */
#include <stdio.h>
static int
do_test (void)
{
fprintf (stdout, "hello\n");
return 0;
}
#include <support/test-driver.c>

View File

@ -203,10 +203,6 @@ struct link_map
unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are
mprotected or if no holes are present at mprotected or if no holes are present at
all. */ 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 unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be
freed, ie. not allocated with freed, ie. not allocated with
the dummy malloc in ld.so. */ the dummy malloc in ld.so. */

View File

@ -423,23 +423,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
if (r_type == R_ALPHA_GLOB_DAT) if (r_type == R_ALPHA_GLOB_DAT)
*reloc_addr = sym_value; *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) else if (r_type == R_ALPHA_JMP_SLOT)
elf_machine_fixup_plt (map, 0, 0, 0, reloc, reloc_addr, sym_value); elf_machine_fixup_plt (map, 0, 0, 0, reloc, reloc_addr, sym_value);
#endif
#ifndef RTLD_BOOTSTRAP #ifndef RTLD_BOOTSTRAP
else if (r_type == R_ALPHA_REFQUAD) else if (r_type == R_ALPHA_REFQUAD)
{ {

View File

@ -521,9 +521,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
return; return;
else else
{ {
# ifndef RESOLVE_CONFLICT_FIND_MAP
const Elf32_Sym *const refsym = sym; const Elf32_Sym *const refsym = sym;
# endif
struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); 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) switch (r_type)
{ {
# ifndef RESOLVE_CONFLICT_FIND_MAP
/* Not needed for dl-conflict.c. */ /* Not needed for dl-conflict.c. */
case R_ARM_COPY: case R_ARM_COPY:
if (sym == NULL) 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, memcpy (reloc_addr_arg, (void *) value,
MIN (sym->st_size, refsym->st_size)); MIN (sym->st_size, refsym->st_size));
break; break;
# endif /* !RESOLVE_CONFLICT_FIND_MAP */
case R_ARM_GLOB_DAT: case R_ARM_GLOB_DAT:
case R_ARM_JUMP_SLOT: case R_ARM_JUMP_SLOT:
case R_ARM_ABS32: case R_ARM_ABS32:

View File

@ -562,7 +562,6 @@ struct rtld_global_ro
#define DL_DEBUG_SCOPES (1 << 9) #define DL_DEBUG_SCOPES (1 << 9)
/* These two are used only internally. */ /* These two are used only internally. */
#define DL_DEBUG_HELP (1 << 10) #define DL_DEBUG_HELP (1 << 10)
#define DL_DEBUG_PRELINK (1 << 11)
/* OS version. */ /* OS version. */
EXTERN unsigned int _dl_osversion; EXTERN unsigned int _dl_osversion;
@ -649,10 +648,6 @@ struct rtld_global_ro
EXTERN const char *_dl_profile; EXTERN const char *_dl_profile;
/* Filename of the output file. */ /* Filename of the output file. */
EXTERN const char *_dl_profile_output; 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 /* All search directories defined at startup. This is assigned a
non-NULL pointer by the ld.so startup code (after initialization 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) unsigned int type, int plt)
attribute_hidden __attribute__ ((__noreturn__)); 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 /* Check the version dependencies of all objects available through
MAP. If VERBOSE print some more diagnostics. */ MAP. If VERBOSE print some more diagnostics. */
extern int _dl_check_all_versions (struct link_map *map, int verbose, extern int _dl_check_all_versions (struct link_map *map, int verbose,

View File

@ -479,9 +479,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
*reloc_addr = map->l_addr + reloc->r_addend; *reloc_addr = map->l_addr + reloc->r_addend;
else if (r_type != R_386_NONE) else if (r_type != R_386_NONE)
{ {
# ifndef RESOLVE_CONFLICT_FIND_MAP
const Elf32_Sym *const refsym = sym; const Elf32_Sym *const refsym = sym;
# endif
struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
r_type); r_type);
Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); 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: case R_386_32:
*reloc_addr = value + reloc->r_addend; *reloc_addr = value + reloc->r_addend;
break; break;
# ifndef RESOLVE_CONFLICT_FIND_MAP
/* Not needed for dl-conflict.c. */ /* Not needed for dl-conflict.c. */
case R_386_PC32: case R_386_PC32:
*reloc_addr = (value + reloc->r_addend - (Elf32_Addr) reloc_addr); *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 *td =
(struct tlsdesc volatile *)reloc_addr; (struct tlsdesc volatile *)reloc_addr;
# ifndef RTLD_BOOTSTRAP # ifndef RTLD_BOOTSTRAP
if (!sym) if (!sym)
{ {
td->arg = (void*)reloc->r_addend; td->arg = (void*)reloc->r_addend;
td->entry = _dl_tlsdesc_undefweak; td->entry = _dl_tlsdesc_undefweak;
} }
else else
# endif # endif
{ {
# ifndef RTLD_BOOTSTRAP # ifndef RTLD_BOOTSTRAP
# ifndef SHARED # ifndef SHARED
CHECK_STATIC_TLS (map, sym_map); CHECK_STATIC_TLS (map, sym_map);
# else # else
if (!TRY_STATIC_TLS (map, sym_map)) if (!TRY_STATIC_TLS (map, sym_map))
{ {
td->arg = _dl_make_tlsdesc_dynamic 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; td->entry = _dl_tlsdesc_dynamic;
} }
else else
# endif
# endif # endif
# endif
{ {
td->arg = (void*)(sym->st_value - sym_map->l_tls_offset td->arg = (void*)(sym->st_value - sym_map->l_tls_offset
+ reloc->r_addend); + 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, memcpy (reloc_addr_arg, (void *) value,
MIN (sym->st_size, refsym->st_size)); MIN (sym->st_size, refsym->st_size));
break; break;
# endif /* !RESOLVE_CONFLICT_FIND_MAP */
case R_386_IRELATIVE: case R_386_IRELATIVE:
value = map->l_addr + reloc->r_addend; value = map->l_addr + reloc->r_addend;
if (__glibc_likely (!skip_ifunc)) if (__glibc_likely (!skip_ifunc))

View File

@ -189,9 +189,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
return; return;
else else
{ {
# ifndef RESOLVE_CONFLICT_FIND_MAP
const Elf32_Sym *const refsym = sym; const Elf32_Sym *const refsym = sym;
# endif
struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
r_type); r_type);
Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); 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) switch (r_type)
{ {
# ifndef RESOLVE_CONFLICT_FIND_MAP
case R_OR1K_COPY: case R_OR1K_COPY:
if (sym == NULL) if (sym == NULL)
/* This can happen in trace mode if an object could not be /* 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, memcpy (reloc_addr_arg, (void *) value,
MIN (sym->st_size, refsym->st_size)); MIN (sym->st_size, refsym->st_size));
break; break;
# endif /* !RESOLVE_CONFLICT_FIND_MAP */
case R_OR1K_32: case R_OR1K_32:
/* Support relocations on mis-aligned offsets. */ /* Support relocations on mis-aligned offsets. */
value += reloc->r_addend; value += reloc->r_addend;

View File

@ -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); const int r_type = ELF32_R_TYPE (reloc->r_info);
struct link_map *sym_map = NULL; struct link_map *sym_map = NULL;
#ifndef RESOLVE_CONFLICT_FIND_MAP
if (r_type == R_PPC_RELATIVE) if (r_type == R_PPC_RELATIVE)
{ {
*reloc_addr = map->l_addr + reloc->r_addend; *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 = SYMBOL_ADDRESS (sym_map, sym, true);
} }
value += reloc->r_addend; value += reloc->r_addend;
#else
value = reloc->r_addend;
#endif
if (sym != NULL if (sym != NULL
&& __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0) && __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; *reloc_addr = value;
break; break;
#ifndef RESOLVE_CONFLICT_FIND_MAP #ifdef RTLD_BOOTSTRAP
# ifdef RTLD_BOOTSTRAP # define NOT_BOOTSTRAP 0
# define NOT_BOOTSTRAP 0 #else
# else # define NOT_BOOTSTRAP 1
# define NOT_BOOTSTRAP 1 #endif
# endif
case R_PPC_DTPMOD32: case R_PPC_DTPMOD32:
if (map->l_info[DT_PPC(OPT)] 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) else if (sym_map != NULL)
{ {
# ifndef SHARED #ifndef SHARED
CHECK_STATIC_TLS (map, sym_map); CHECK_STATIC_TLS (map, sym_map);
# else #else
if (TRY_STATIC_TLS (map, sym_map)) if (TRY_STATIC_TLS (map, sym_map))
# endif #endif
{ {
reloc_addr[0] = 0; reloc_addr[0] = 0;
/* Set up for local dynamic. */ /* 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) else if (sym_map != NULL)
{ {
/* This reloc is always preceded by R_PPC_DTPMOD32. */ /* This reloc is always preceded by R_PPC_DTPMOD32. */
# ifndef SHARED #ifndef SHARED
assert (HAVE_STATIC_TLS (map, sym_map)); assert (HAVE_STATIC_TLS (map, sym_map));
# else #else
if (HAVE_STATIC_TLS (map, sym_map)) if (HAVE_STATIC_TLS (map, sym_map))
# endif #endif
{ {
*reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc); *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
break; 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); *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
} }
break; break;
#endif
case R_PPC_JMP_SLOT: 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) if (map->l_info[DT_PPC(GOT)] != 0)
{ {
*reloc_addr = value; *reloc_addr = value;

View File

@ -537,36 +537,6 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
return finaladdr; 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. */ /* Return the final value of a plt relocation. */
static inline Elf64_Addr static inline Elf64_Addr
elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, 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) const struct link_map *map, const struct link_map *sym_map)
{ {
#if _CALL_ELF != 2 #if _CALL_ELF != 2
#ifndef RESOLVE_CONFLICT_FIND_MAP
/* The function we are calling may not yet have its opd entry relocated. */ /* The function we are calling may not yet have its opd entry relocated. */
Elf64_FuncDesc opd; Elf64_FuncDesc opd;
if (map != sym_map if (map != sym_map
@ -657,7 +626,6 @@ resolve_ifunc (Elf64_Addr value,
dependency. */ dependency. */
asm ("" : "=r" (value) : "0" (&opd), "X" (opd)); asm ("" : "=r" (value) : "0" (&opd), "X" (opd));
} }
#endif
#endif #endif
return ((Elf64_Addr (*) (unsigned long int)) value) (GLRO(dl_hwcap)); 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); value = resolve_ifunc (value, map, sym_map);
/* Fall thru */ /* Fall thru */
case R_PPC64_JMP_SLOT: 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, elf_machine_fixup_plt (map, sym_map, refsym, sym,
reloc, reloc_addr, value); reloc, reloc_addr, value);
#endif
return; return;
case R_PPC64_DTPMOD64: case R_PPC64_DTPMOD64:

View File

@ -352,7 +352,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
return; return;
else else
{ {
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP #if !defined RTLD_BOOTSTRAP
/* Only needed for R_390_COPY below. */ /* Only needed for R_390_COPY below. */
const Elf32_Sym *const refsym = sym; const Elf32_Sym *const refsym = sym;
#endif #endif
@ -380,34 +380,33 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
*reloc_addr = value + reloc->r_addend; *reloc_addr = value + reloc->r_addend;
break; break;
#ifndef RESOLVE_CONFLICT_FIND_MAP
case R_390_TLS_DTPMOD: case R_390_TLS_DTPMOD:
# ifdef RTLD_BOOTSTRAP #ifdef RTLD_BOOTSTRAP
/* During startup the dynamic linker is always the module /* During startup the dynamic linker is always the module
with index 1. with index 1.
XXX If this relocation is necessary move before RESOLVE XXX If this relocation is necessary move before RESOLVE
call. */ call. */
*reloc_addr = 1; *reloc_addr = 1;
# else #else
/* Get the information from the link map returned by the /* Get the information from the link map returned by the
resolv function. */ resolv function. */
if (sym_map != NULL) if (sym_map != NULL)
*reloc_addr = sym_map->l_tls_modid; *reloc_addr = sym_map->l_tls_modid;
# endif #endif
break; break;
case R_390_TLS_DTPOFF: case R_390_TLS_DTPOFF:
# ifndef RTLD_BOOTSTRAP #ifndef RTLD_BOOTSTRAP
/* During relocation all TLS symbols are defined and used. /* During relocation all TLS symbols are defined and used.
Therefore the offset is already correct. */ Therefore the offset is already correct. */
if (sym != NULL) if (sym != NULL)
*reloc_addr = sym->st_value + reloc->r_addend; *reloc_addr = sym->st_value + reloc->r_addend;
# endif #endif
break; break;
case R_390_TLS_TPOFF: case R_390_TLS_TPOFF:
/* The offset is negative, forward from the thread pointer. */ /* 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; *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. /* We know the offset of the object the symbol is contained in.
It is a negative value which will be added to the It is a negative value which will be added to the
thread pointer. */ thread pointer. */
@ -419,10 +418,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
} }
#endif #endif
break; break;
#endif /* use TLS */
#ifndef RTLD_BOOTSTRAP #ifndef RTLD_BOOTSTRAP
# ifndef RESOLVE_CONFLICT_FIND_MAP
/* Not needed in dl-conflict.c. */ /* Not needed in dl-conflict.c. */
case R_390_COPY: case R_390_COPY:
if (sym == NULL) 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, memcpy (reloc_addr_arg, (void *) value,
MIN (sym->st_size, refsym->st_size)); MIN (sym->st_size, refsym->st_size));
break; break;
# endif
case R_390_32: case R_390_32:
*reloc_addr = value + reloc->r_addend; *reloc_addr = value + reloc->r_addend;
break; break;
@ -453,7 +449,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
case R_390_8: case R_390_8:
*(char *) reloc_addr = value + reloc->r_addend; *(char *) reloc_addr = value + reloc->r_addend;
break; break;
# ifndef RESOLVE_CONFLICT_FIND_MAP
case R_390_PC32: case R_390_PC32:
*reloc_addr = value + reloc->r_addend - (Elf32_Addr) reloc_addr; *reloc_addr = value + reloc->r_addend - (Elf32_Addr) reloc_addr;
break; break;
@ -471,7 +466,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
break; break;
case R_390_NONE: case R_390_NONE:
break; break;
# endif
#endif #endif
#if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG) #if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG)
default: default:

View File

@ -299,7 +299,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
return; return;
else else
{ {
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP #if !defined RTLD_BOOTSTRAP
/* Only needed for R_390_COPY below. */ /* Only needed for R_390_COPY below. */
const Elf64_Sym *const refsym = sym; const Elf64_Sym *const refsym = sym;
#endif #endif
@ -327,34 +327,33 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
*reloc_addr = value + reloc->r_addend; *reloc_addr = value + reloc->r_addend;
break; break;
#ifndef RESOLVE_CONFLICT_FIND_MAP
case R_390_TLS_DTPMOD: case R_390_TLS_DTPMOD:
# ifdef RTLD_BOOTSTRAP #ifdef RTLD_BOOTSTRAP
/* During startup the dynamic linker is always the module /* During startup the dynamic linker is always the module
with index 1. with index 1.
XXX If this relocation is necessary move before RESOLVE XXX If this relocation is necessary move before RESOLVE
call. */ call. */
*reloc_addr = 1; *reloc_addr = 1;
# else #else
/* Get the information from the link map returned by the /* Get the information from the link map returned by the
resolv function. */ resolv function. */
if (sym_map != NULL) if (sym_map != NULL)
*reloc_addr = sym_map->l_tls_modid; *reloc_addr = sym_map->l_tls_modid;
# endif #endif
break; break;
case R_390_TLS_DTPOFF: case R_390_TLS_DTPOFF:
# ifndef RTLD_BOOTSTRAP #ifndef RTLD_BOOTSTRAP
/* During relocation all TLS symbols are defined and used. /* During relocation all TLS symbols are defined and used.
Therefore the offset is already correct. */ Therefore the offset is already correct. */
if (sym != NULL) if (sym != NULL)
*reloc_addr = sym->st_value + reloc->r_addend; *reloc_addr = sym->st_value + reloc->r_addend;
# endif #endif
break; break;
case R_390_TLS_TPOFF: case R_390_TLS_TPOFF:
/* The offset is negative, forward from the thread pointer. */ /* 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; *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. /* We know the offset of the object the symbol is contained in.
It is a negative value which will be added to the It is a negative value which will be added to the
thread pointer. */ thread pointer. */
@ -366,10 +365,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
} }
#endif #endif
break; break;
#endif /* use TLS */
#ifndef RTLD_BOOTSTRAP #ifndef RTLD_BOOTSTRAP
# ifndef RESOLVE_CONFLICT_FIND_MAP
/* Not needed for dl-conflict.c. */ /* Not needed for dl-conflict.c. */
case R_390_COPY: case R_390_COPY:
if (sym == NULL) 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, memcpy (reloc_addr_arg, (void *) value,
MIN (sym->st_size, refsym->st_size)); MIN (sym->st_size, refsym->st_size));
break; break;
# endif
case R_390_64: case R_390_64:
*reloc_addr = value + reloc->r_addend; *reloc_addr = value + reloc->r_addend;
break; break;
@ -403,7 +399,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
case R_390_8: case R_390_8:
*(char *) reloc_addr = value + reloc->r_addend; *(char *) reloc_addr = value + reloc->r_addend;
break; break;
# ifndef RESOLVE_CONFLICT_FIND_MAP
case R_390_PC64: case R_390_PC64:
*reloc_addr = value +reloc->r_addend - (Elf64_Addr) reloc_addr; *reloc_addr = value +reloc->r_addend - (Elf64_Addr) reloc_addr;
break; break;
@ -425,7 +420,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
break; break;
case R_390_NONE: case R_390_NONE:
break; break;
# endif
#endif #endif
#if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG) #if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG)
default: default:

View File

@ -391,7 +391,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
break; break;
case R_SH_DIR32: 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 /* This is defined in rtld.c, but nowhere in the static
libc.a; make the reference weak so static programs can libc.a; make the reference weak so static programs can
still link. This declaration cannot be done when still link. This declaration cannot be done when

View File

@ -142,44 +142,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
plt[1] = 0x85c0a000 | (rfunc & 0x3ff); plt[1] = 0x85c0a000 | (rfunc & 0x3ff);
plt[2] = OPCODE_NOP; /* Fill call delay slot. */ plt[2] = OPCODE_NOP; /* Fill call delay slot. */
plt[3] = (Elf32_Addr) l; 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; 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) void *const reloc_addr_arg, int skip_ifunc)
{ {
Elf32_Addr *const reloc_addr = reloc_addr_arg; 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; const Elf32_Sym *const refsym = sym;
#endif #endif
Elf32_Addr value; Elf32_Addr value;
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
#if !defined RESOLVE_CONFLICT_FIND_MAP
struct link_map *sym_map = NULL; struct link_map *sym_map = NULL;
#endif
#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC #if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
/* This is defined in rtld.c, but nowhere in the static libc.a; make the /* 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 #endif
#ifndef RESOLVE_CONFLICT_FIND_MAP
if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0) if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0)
&& sym->st_shndx != SHN_UNDEF) && 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); sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
value = SYMBOL_ADDRESS (sym_map, sym, true); value = SYMBOL_ADDRESS (sym_map, sym, true);
} }
#else
value = 0;
#endif
value += reloc->r_addend; /* Assume copy relocs have zero addend. */ 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) switch (r_type)
{ {
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP #if !defined RTLD_BOOTSTRAP
case R_SPARC_COPY: case R_SPARC_COPY:
if (sym == NULL) if (sym == NULL)
/* This can happen in trace mode if an object could not be /* 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); sparc_fixup_plt (reloc, reloc_addr, value, 0, do_flush);
} }
break; break;
#ifndef RESOLVE_CONFLICT_FIND_MAP
case R_SPARC_TLS_DTPMOD32: case R_SPARC_TLS_DTPMOD32:
/* Get the information from the link map returned by the /* Get the information from the link map returned by the
resolv function. */ resolv function. */
@ -474,7 +429,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+ reloc->r_addend; + reloc->r_addend;
} }
break; break;
# ifndef RTLD_BOOTSTRAP #ifndef RTLD_BOOTSTRAP
case R_SPARC_TLS_LE_HIX22: case R_SPARC_TLS_LE_HIX22:
case R_SPARC_TLS_LE_LOX10: case R_SPARC_TLS_LE_LOX10:
if (sym != NULL) if (sym != NULL)
@ -489,7 +444,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
| 0x1c00; | 0x1c00;
} }
break; break;
# endif
#endif #endif
#ifndef RTLD_BOOTSTRAP #ifndef RTLD_BOOTSTRAP
case R_SPARC_8: case R_SPARC_8:

View File

@ -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 /* Now put the magic cookie at the beginning of .PLT2
Entry .PLT3 is unused by this implementation. */ Entry .PLT3 is unused by this implementation. */
*((struct link_map **)(&plt[16])) = l; *((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; 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) void *const reloc_addr_arg, int skip_ifunc)
{ {
Elf64_Addr *const reloc_addr = reloc_addr_arg; 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; const Elf64_Sym *const refsym = sym;
#endif #endif
Elf64_Addr value; Elf64_Addr value;
const unsigned long int r_type = ELF64_R_TYPE_ID (reloc->r_info); 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; struct link_map *sym_map = NULL;
#endif
#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC #if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
/* This is defined in rtld.c, but nowhere in the static libc.a; make the /* 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 #endif
#ifndef RESOLVE_CONFLICT_FIND_MAP
if (__builtin_expect (ELF64_ST_BIND (sym->st_info) == STB_LOCAL, 0) if (__builtin_expect (ELF64_ST_BIND (sym->st_info) == STB_LOCAL, 0)
&& sym->st_shndx != SHN_UNDEF) && 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); sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
value = SYMBOL_ADDRESS (sym_map, sym, true); value = SYMBOL_ADDRESS (sym_map, sym, true);
} }
#else
value = 0;
#endif
value += reloc->r_addend; /* Assume copy relocs have zero addend. */ 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) switch (r_type)
{ {
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP #if !defined RTLD_BOOTSTRAP
case R_SPARC_COPY: case R_SPARC_COPY:
if (sym == NULL) if (sym == NULL)
/* This can happen in trace mode if an object could not be /* 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)); value = ((Elf64_Addr (*) (int)) value) (GLRO(dl_hwcap));
/* 'high' is always zero, for large PLT entries the linker /* 'high' is always zero, for large PLT entries the linker
emits an R_SPARC_IRELATIVE. */ 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); sparc64_fixup_plt (map, reloc, reloc_addr, value, 0, 0);
#endif
break; break;
case R_SPARC_JMP_SLOT: 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); sparc64_fixup_plt (map, reloc, reloc_addr, value, reloc->r_addend, 0);
#endif
break; break;
#ifndef RESOLVE_CONFLICT_FIND_MAP
case R_SPARC_TLS_DTPMOD64: case R_SPARC_TLS_DTPMOD64:
/* Get the information from the link map returned by the /* Get the information from the link map returned by the
resolv function. */ resolv function. */
@ -502,7 +437,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+ reloc->r_addend; + reloc->r_addend;
} }
break; break;
# ifndef RTLD_BOOTSTRAP #ifndef RTLD_BOOTSTRAP
case R_SPARC_TLS_LE_HIX22: case R_SPARC_TLS_LE_HIX22:
case R_SPARC_TLS_LE_LOX10: case R_SPARC_TLS_LE_LOX10:
if (sym != NULL) if (sym != NULL)
@ -520,7 +455,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
| 0x1c00); | 0x1c00);
} }
break; break;
# endif
#endif #endif
#ifndef RTLD_BOOTSTRAP #ifndef RTLD_BOOTSTRAP
case R_SPARC_8: case R_SPARC_8:

View File

@ -346,59 +346,58 @@ and creates an unsatisfiable circular dependency.\n",
*reloc_addr = value + reloc->r_addend; *reloc_addr = value + reloc->r_addend;
break; break;
# ifndef RESOLVE_CONFLICT_FIND_MAP
case R_X86_64_DTPMOD64: case R_X86_64_DTPMOD64:
# ifdef RTLD_BOOTSTRAP # ifdef RTLD_BOOTSTRAP
/* During startup the dynamic linker is always the module /* During startup the dynamic linker is always the module
with index 1. with index 1.
XXX If this relocation is necessary move before RESOLVE XXX If this relocation is necessary move before RESOLVE
call. */ call. */
*reloc_addr = 1; *reloc_addr = 1;
# else # else
/* Get the information from the link map returned by the /* Get the information from the link map returned by the
resolve function. */ resolve function. */
if (sym_map != NULL) if (sym_map != NULL)
*reloc_addr = sym_map->l_tls_modid; *reloc_addr = sym_map->l_tls_modid;
# endif # endif
break; break;
case R_X86_64_DTPOFF64: case R_X86_64_DTPOFF64:
# ifndef RTLD_BOOTSTRAP # ifndef RTLD_BOOTSTRAP
/* During relocation all TLS symbols are defined and used. /* During relocation all TLS symbols are defined and used.
Therefore the offset is already correct. */ Therefore the offset is already correct. */
if (sym != NULL) if (sym != NULL)
{ {
value = sym->st_value + reloc->r_addend; value = sym->st_value + reloc->r_addend;
# ifdef __ILP32__ # ifdef __ILP32__
/* This relocation type computes a signed offset that is /* This relocation type computes a signed offset that is
usually negative. The symbol and addend values are 32 usually negative. The symbol and addend values are 32
bits but the GOT entry is 64 bits wide and the whole bits but the GOT entry is 64 bits wide and the whole
64-bit entry is used as a signed quantity, so we need 64-bit entry is used as a signed quantity, so we need
to sign-extend the computed value to 64 bits. */ to sign-extend the computed value to 64 bits. */
*(Elf64_Sxword *) reloc_addr = (Elf64_Sxword) (Elf32_Sword) value; *(Elf64_Sxword *) reloc_addr = (Elf64_Sxword) (Elf32_Sword) value;
# else # else
*reloc_addr = value; *reloc_addr = value;
# endif
}
# endif # endif
}
# endif
break; break;
case R_X86_64_TLSDESC: case R_X86_64_TLSDESC:
{ {
struct tlsdesc volatile *td = struct tlsdesc volatile *td =
(struct tlsdesc volatile *)reloc_addr; (struct tlsdesc volatile *)reloc_addr;
# ifndef RTLD_BOOTSTRAP # ifndef RTLD_BOOTSTRAP
if (! sym) if (! sym)
{ {
td->arg = (void*)reloc->r_addend; td->arg = (void*)reloc->r_addend;
td->entry = _dl_tlsdesc_undefweak; td->entry = _dl_tlsdesc_undefweak;
} }
else else
# endif # endif
{ {
# ifndef RTLD_BOOTSTRAP # ifndef RTLD_BOOTSTRAP
# ifndef SHARED # ifndef SHARED
CHECK_STATIC_TLS (map, sym_map); CHECK_STATIC_TLS (map, sym_map);
# else # else
if (!TRY_STATIC_TLS (map, sym_map)) if (!TRY_STATIC_TLS (map, sym_map))
{ {
td->arg = _dl_make_tlsdesc_dynamic td->arg = _dl_make_tlsdesc_dynamic
@ -406,8 +405,8 @@ and creates an unsatisfiable circular dependency.\n",
td->entry = _dl_tlsdesc_dynamic; td->entry = _dl_tlsdesc_dynamic;
} }
else else
# endif
# endif # endif
# endif
{ {
td->arg = (void*)(sym->st_value - sym_map->l_tls_offset td->arg = (void*)(sym->st_value - sym_map->l_tls_offset
+ reloc->r_addend); + reloc->r_addend);
@ -418,30 +417,29 @@ and creates an unsatisfiable circular dependency.\n",
} }
case R_X86_64_TPOFF64: case R_X86_64_TPOFF64:
/* The offset is negative, forward from the thread pointer. */ /* The offset is negative, forward from the thread pointer. */
# ifndef RTLD_BOOTSTRAP # ifndef RTLD_BOOTSTRAP
if (sym != NULL) if (sym != NULL)
# endif # endif
{ {
# ifndef RTLD_BOOTSTRAP # ifndef RTLD_BOOTSTRAP
CHECK_STATIC_TLS (map, sym_map); CHECK_STATIC_TLS (map, sym_map);
# endif # endif
/* We know the offset of the object the symbol is contained in. /* We know the offset of the object the symbol is contained in.
It is a negative value which will be added to the It is a negative value which will be added to the
thread pointer. */ thread pointer. */
value = (sym->st_value + reloc->r_addend value = (sym->st_value + reloc->r_addend
- sym_map->l_tls_offset); - sym_map->l_tls_offset);
# ifdef __ILP32__ # ifdef __ILP32__
/* The symbol and addend values are 32 bits but the GOT /* The symbol and addend values are 32 bits but the GOT
entry is 64 bits wide and the whole 64-bit entry is used entry is 64 bits wide and the whole 64-bit entry is used
as a signed quantity, so we need to sign-extend the as a signed quantity, so we need to sign-extend the
computed value to 64 bits. */ computed value to 64 bits. */
*(Elf64_Sxword *) reloc_addr = (Elf64_Sxword) (Elf32_Sword) value; *(Elf64_Sxword *) reloc_addr = (Elf64_Sxword) (Elf32_Sword) value;
# else # else
*reloc_addr = value; *reloc_addr = value;
# endif # endif
} }
break; break;
# endif
# ifndef RTLD_BOOTSTRAP # ifndef RTLD_BOOTSTRAP
case R_X86_64_64: case R_X86_64_64:
@ -466,15 +464,12 @@ and creates an unsatisfiable circular dependency.\n",
fmt = "\ fmt = "\
%s: Symbol `%s' causes overflow in R_X86_64_32 relocation\n"; %s: Symbol `%s' causes overflow in R_X86_64_32 relocation\n";
# ifndef RESOLVE_CONFLICT_FIND_MAP
print_err: print_err:
# endif
strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]); strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
_dl_error_printf (fmt, RTLD_PROGNAME, strtab + refsym->st_name); _dl_error_printf (fmt, RTLD_PROGNAME, strtab + refsym->st_name);
} }
break; break;
# ifndef RESOLVE_CONFLICT_FIND_MAP
/* Not needed for dl-conflict.c. */ /* Not needed for dl-conflict.c. */
case R_X86_64_PC32: case R_X86_64_PC32:
value += reloc->r_addend - (ElfW(Addr)) reloc_addr; value += reloc->r_addend - (ElfW(Addr)) reloc_addr;
@ -502,7 +497,6 @@ and creates an unsatisfiable circular dependency.\n",
goto print_err; goto print_err;
} }
break; break;
# endif
case R_X86_64_IRELATIVE: case R_X86_64_IRELATIVE:
value = map->l_addr + reloc->r_addend; value = map->l_addr + reloc->r_addend;
if (__glibc_likely (!skip_ifunc)) if (__glibc_likely (!skip_ifunc))