2001-08-24  Ulrich Drepper  <drepper@redhat.com>

	* elf/do-rel.h (elf_dynamic_do_rel): If not relocating lazily, don't
	call elf_machine_rel for the last DT_RELCOUNT relocations but instead
	elf_machine_rel_relative.
	* sysdeps/alpha/dl-machine.h: Define elf_machine_rel_relative.
	Minor optimizations.
	* sysdeps/arm/dl-machine.h: Likewise.
	* sysdeps/cris/dl-machine.h: Likewise.
	* sysdeps/hppa/dl-machine.h: Likewise.
	* sysdeps/i386/dl-machine.h: Likewise.
	* sysdeps/ia64/dl-machine.h: Likewise.
	* sysdeps/m68k/dl-machine.h: Likewise.
	* sysdeps/mips/dl-machine.h: Likewise.
	* sysdeps/powerpc/dl-machine.h: Likewise.
	* sysdeps/s390/s390-32/dl-machine.h: Likewise.
	* sysdeps/s390/s390-64/dl-machine.h: Likewise.
	* sysdeps/sh/dl-machine.h: Likewise.
	* sysdeps/sparc/sparc32/dl-machine.h: Likewise.
	* sysdeps/sparc/sparc64/dl-machine.h: Likewise.
This commit is contained in:
Ulrich Drepper 2001-08-24 08:53:35 +00:00
parent c65c9d8ba0
commit 1721af3f96
15 changed files with 257 additions and 110 deletions

View File

@ -1,3 +1,24 @@
2001-08-24 Ulrich Drepper <drepper@redhat.com>
* elf/do-rel.h (elf_dynamic_do_rel): If not relocating lazily, don't
call elf_machine_rel for the last DT_RELCOUNT relocations but instead
elf_machine_rel_relative.
* sysdeps/alpha/dl-machine.h: Define elf_machine_rel_relative.
Minor optimizations.
* sysdeps/arm/dl-machine.h: Likewise.
* sysdeps/cris/dl-machine.h: Likewise.
* sysdeps/hppa/dl-machine.h: Likewise.
* sysdeps/i386/dl-machine.h: Likewise.
* sysdeps/ia64/dl-machine.h: Likewise.
* sysdeps/m68k/dl-machine.h: Likewise.
* sysdeps/mips/dl-machine.h: Likewise.
* sysdeps/powerpc/dl-machine.h: Likewise.
* sysdeps/s390/s390-32/dl-machine.h: Likewise.
* sysdeps/s390/s390-64/dl-machine.h: Likewise.
* sysdeps/sh/dl-machine.h: Likewise.
* sysdeps/sparc/sparc32/dl-machine.h: Likewise.
* sysdeps/sparc/sparc64/dl-machine.h: Likewise.
2001-08-23 Roland McGrath <roland@frob.com>
* rt/tst-aio4.c [! SIGRTMIN] (SIGRTMIN, SIGRTMAX): Define as -1.

View File

@ -480,7 +480,7 @@ elf_machine_rela (struct link_map *map,
/* We cannot use a switch here because we cannot locate the switch
jump table until we've self-relocated. */
if (r_type == R_ALPHA_RELATIVE)
if (__builtin_expect (r_type == R_ALPHA_RELATIVE, 0))
{
#ifndef RTLD_BOOTSTRAP
/* Already done in dynamic linker. */
@ -501,7 +501,7 @@ elf_machine_rela (struct link_map *map,
}
}
#ifndef RTLD_BOOTSTRAP
else if (r_type == R_ALPHA_NONE)
else if (__builtin_expect (r_type == R_ALPHA_NONE, 0))
return;
#endif
else
@ -547,6 +547,23 @@ elf_machine_rela (struct link_map *map,
}
}
static inline void
elf_machine_rel_relative (Elf64_Addr l_addr, const Elf64_Rel *reloc,
Elf64_Addr *const reloc_addr)
{
/* XXX Make some timings. Maybe it's preverable to test for
unaligned access and only do it the complex way if necessary. */
void *reloc_addr_1 = reloc_addr;
Elf64_Addr reloc_addr_val;
/* Load value without causing unaligned trap. */
memcpy (&reloc_addr_val, reloc_addr_1, 8);
reloc_addr_val += l_addr;
/* Store value without causing unaligned trap. */
memcpy (reloc_addr_1, &reloc_addr_val, 8);
}
static inline void
elf_machine_lazy_rel (struct link_map *map,
Elf64_Addr l_addr, const Elf64_Rela *reloc)

View File

@ -412,21 +412,27 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
const Elf32_Sym *sym, const struct r_found_version *version,
Elf32_Addr *const reloc_addr)
{
if (ELF32_R_TYPE (reloc->r_info) == R_ARM_RELATIVE)
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
if (__builtin_expect (r_type == R_ARM_RELATIVE, 0))
{
#ifndef RTLD_BOOTSTRAP
if (map != &_dl_rtld_map) /* Already done in rtld itself. */
#endif
*reloc_addr += map->l_addr;
}
else if (ELF32_R_TYPE (reloc->r_info) != R_ARM_NONE)
#ifndef RTLD_BOOTSTRAP
else if (__builtin_expect (r_type == R_ARM_NONE, 0))
return;
#endif
else
{
const Elf32_Sym *const refsym = sym;
Elf32_Addr value = RESOLVE (&sym, version, ELF32_R_TYPE (reloc->r_info));
Elf32_Addr value = RESOLVE (&sym, version, reloc->r_type);
if (sym)
value += sym->st_value;
switch (ELF32_R_TYPE (reloc->r_info))
switch (r_type)
{
case R_ARM_COPY:
if (sym == NULL)
@ -505,22 +511,30 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
}
break;
default:
_dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 0);
_dl_reloc_bad_type (map, r_type, 0);
break;
}
}
}
static inline void
elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
Elf32_Addr *const reloc_addr)
{
*reloc_addr += l_addr;
}
static inline void
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rel *reloc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
/* Check for unexpected PLT reloc type. */
if (ELF32_R_TYPE (reloc->r_info) == R_ARM_JUMP_SLOT)
if (__builtin_expect (r_type == R_ARM_JUMP_SLOT, 1))
*reloc_addr += l_addr;
else
_dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 1);
_dl_reloc_bad_type (map, r_type, 1);
}
#endif /* RESOLVE */

View File

@ -284,40 +284,28 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
const Elf32_Sym *sym, const struct r_found_version *version,
Elf32_Addr *const reloc_addr)
{
#ifndef RTLD_BOOTSTRAP
/* This is defined in rtld.c, but nowhere in the static libc.a; make the
reference weak so static programs can still link. This declaration
cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
because rtld.c contains the common defn for _dl_rtld_map, which is
incompatible with a weak decl in the same file. */
weak_extern (_dl_rtld_map);
#endif
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
if (ELF32_R_TYPE (reloc->r_info) == R_CRIS_RELATIVE)
{
#ifndef RTLD_BOOTSTRAP
if (map != &_dl_rtld_map) /* Already done in rtld itself. */
#endif
*reloc_addr = map->l_addr + reloc->r_addend;
}
if (__builtin_expect (r_type == R_CRIS_RELATIVE, 0))
*reloc_addr = map->l_addr + reloc->r_addend;
else
{
#ifndef RTLD_BOOTSTRAP
const Elf32_Sym *const refsym = sym;
#endif
Elf32_Addr value;
if (sym->st_shndx != SHN_UNDEF &&
ELF32_ST_BIND (sym->st_info) == STB_LOCAL)
if (sym->st_shndx != SHN_UNDEF
&& ELF32_ST_BIND (sym->st_info) == STB_LOCAL)
value = map->l_addr;
else
{
value = RESOLVE (&sym, version, ELF32_R_TYPE (reloc->r_info));
value = RESOLVE (&sym, version, r_type);
if (sym)
value += sym->st_value;
}
value += reloc->r_addend; /* Assume copy relocs have zero addend. */
switch (ELF32_R_TYPE (reloc->r_info))
switch (r_type)
{
#ifndef RTLD_BOOTSTRAP
case R_CRIS_COPY:
@ -370,23 +358,30 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
break;
#if !defined RTLD_BOOTSTRAP || defined _NDEBUG
default:
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 0);
_dl_reloc_bad_type (map, r_type, 0);
break;
#endif
}
}
}
static inline void
elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
Elf32_Addr *const reloc_addr)
{
*reloc_addr = l_addr + reloc->r_addend;
}
static inline void
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
if (__builtin_expect (ELF32_R_TYPE (reloc->r_info), R_CRIS_JUMP_SLOT)
== R_CRIS_JUMP_SLOT)
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
if (__builtin_expect (r_type == R_CRIS_JUMP_SLOT, 1))
*reloc_addr += l_addr;
else
_dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 1);
_dl_reloc_bad_type (map, r_type, 1);
}
#endif /* RESOLVE */

View File

@ -628,6 +628,13 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
*reloc_addr = value;
}
static inline void
elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
Elf32_Addr *const reloc_addr)
{
/* XXX Nothing to do. There is no relative relocation, right? */
}
static inline void
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc)

View File

@ -303,7 +303,9 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
const Elf32_Sym *sym, const struct r_found_version *version,
Elf32_Addr *const reloc_addr)
{
if (ELF32_R_TYPE (reloc->r_info) == R_386_RELATIVE)
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
if (__builtin_expect (r_type == R_386_RELATIVE, 0))
{
#ifndef RTLD_BOOTSTRAP
/* This is defined in rtld.c, but nowhere in the static libc.a;
@ -317,16 +319,20 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
#endif
*reloc_addr += map->l_addr;
}
else if (ELF32_R_TYPE (reloc->r_info) != R_386_NONE)
#ifndef RTLD_BOOTSTRAP
else if (__builtin_expect (r_type == R_386_NONE, 1))
return;
#endif
else
{
#ifndef RTLD_BOOTSTRAP
const Elf32_Sym *const refsym = sym;
#endif
Elf32_Addr value = RESOLVE (&sym, version, ELF32_R_TYPE (reloc->r_info));
Elf32_Addr value = RESOLVE (&sym, version, r_type);
if (sym)
value += sym->st_value;
switch (ELF32_R_TYPE (reloc->r_info))
switch (r_type)
{
case R_386_GLOB_DAT:
case R_386_JMP_SLOT:
@ -364,24 +370,31 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
default:
/* We add these checks in the version to relocate ld.so only
if we are still debugging. */
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 0);
_dl_reloc_bad_type (map, r_type, 0);
break;
#endif
}
}
}
static inline void
elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
Elf32_Addr *const reloc_addr)
{
*reloc_addr += l_addr;
}
static inline void
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rel *reloc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
/* Check for unexpected PLT reloc type. */
if (__builtin_expect (ELF32_R_TYPE (reloc->r_info), R_386_JMP_SLOT)
== R_386_JMP_SLOT)
if (__builtin_expect (r_type == R_386_JMP_SLOT, 1))
*reloc_addr += l_addr;
else
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 1);
_dl_reloc_bad_type (map, r_type, 1);
}
#endif /* RESOLVE */

View File

@ -520,8 +520,10 @@ elf_machine_rela (struct link_map *map,
/* We cannot use a switch here because we cannot locate the switch
jump table until we've self-relocated. */
if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_REL64LSB))
if (__builtin_expect (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_REL64LSB),
0))
{
assert (ELF64_R_TYPE (reloc->r_info) == R_IA64_REL64LSB);
value = *reloc_addr;
#ifndef RTLD_BOOTSTRAP
/* Already done in dynamic linker. */
@ -529,8 +531,10 @@ elf_machine_rela (struct link_map *map,
#endif
value += map->l_addr;
}
#ifndef RTLD_BOOTSTRAP
else if (r_type == R_IA64_NONE)
return;
#endif
else
{
struct link_map *sym_map;
@ -575,6 +579,15 @@ elf_machine_rela (struct link_map *map,
assert (! "unexpected dynamic reloc format");
}
static inline void
elf_machine_rel_relative (Elf64_Addr l_addr, const Elf64_Rel *reloc,
Elf64_Addr *const reloc_addr)
{
/* ??? Ignore MSB and Instruction format for now. */
assert (ELF64_R_TYPE (reloc->r_info) == R_IA64_REL64LSB);
*reloc_addr += l_addr;
}
/* Perform a RELATIVE reloc on the .got entry that transfers to the .plt. */
static inline void

View File

@ -232,16 +232,18 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
const Elf32_Sym *sym, const struct r_found_version *version,
Elf32_Addr *const reloc_addr)
{
if (ELF32_R_TYPE (reloc->r_info) == R_68K_RELATIVE)
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
if (__builtin_expect (r_type == R_68K_RELATIVE, 0))
*reloc_addr = map->l_addr + reloc->r_addend;
else
{
const Elf32_Sym *const refsym = sym;
Elf32_Addr value = RESOLVE (&sym, version, ELF32_R_TYPE (reloc->r_info));
Elf32_Addr value = RESOLVE (&sym, version, r_type);
if (sym)
value += sym->st_value;
switch (ELF32_R_TYPE (reloc->r_info))
switch (r_type)
{
case R_68K_COPY:
if (sym == NULL)
@ -290,12 +292,19 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
case R_68K_NONE: /* Alright, Wilbur. */
break;
default:
_dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 0);
_dl_reloc_bad_type (map, r_type, 0);
break;
}
}
}
static inline void
elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
Elf32_Addr *const reloc_addr)
{
*reloc_addr = l_addr + reloc->r_addend;
}
static inline void
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc)

View File

@ -1,5 +1,5 @@
/* Machine-dependent ELF dynamic relocation inline functions. MIPS version.
Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>.
@ -477,6 +477,8 @@ elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
const ElfW(Sym) *sym, const struct r_found_version *version,
ElfW(Addr) *const reloc_addr)
{
const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
#ifndef RTLD_BOOTSTRAP
/* This is defined in rtld.c, but nowhere in the static libc.a;
make the reference weak so static programs can still link. This
@ -487,7 +489,7 @@ elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
weak_extern (_dl_rtld_map);
#endif
switch (ELFW(R_TYPE) (reloc->r_info))
switch (r_type)
{
case R_MIPS_REL32:
{
@ -528,11 +530,18 @@ elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
case R_MIPS_NONE: /* Alright, Wilbur. */
break;
default:
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 0);
_dl_reloc_bad_type (map, r_type, 0);
break;
}
}
static inline void
elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
Elf32_Addr *const reloc_addr)
{
/* XXX Nothing to do. There is no relative relocation, right? */
}
static inline void
elf_machine_lazy_rel (struct link_map *map,
ElfW(Addr) l_addr, const ElfW(Rel) *reloc)

View File

@ -347,7 +347,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
Elf32_Word loadbase, finaladdr;
const int rinfo = ELF32_R_TYPE (reloc->r_info);
if (rinfo == R_PPC_NONE)
if (__builtin_expect (rinfo == R_PPC_NONE, 0))
return;
/* The condition on the next two lines is a hack around a bug in Solaris
@ -393,6 +393,12 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
reloc_addr, finaladdr, rinfo);
}
static inline void
elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
Elf32_Addr *const reloc_addr)
{
*reloc_addr = l_addr + reloc->r_addend;
}
/* The SVR4 ABI specifies that the JMPREL relocs must be inside the
DT_RELA table. */

View File

@ -364,20 +364,22 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
const Elf32_Sym *sym, const struct r_found_version *version,
Elf32_Addr *const reloc_addr)
{
if (ELF32_R_TYPE (reloc->r_info) == R_390_RELATIVE) {
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
if (__builtin_expect (r_type == R_390_RELATIVE, 0))
*reloc_addr = map->l_addr + reloc->r_addend;
#ifndef RTLD_BOOTSTRAP
if (map != &_dl_rtld_map) /* Already done in rtld itself. */
else if (__builtin_expect (r_type == R_390_NONE, 0))
return;
#endif
*reloc_addr = map->l_addr + reloc->r_addend;
}
else if (ELF32_R_TYPE (reloc->r_info) != R_390_NONE)
else
{
const Elf32_Sym *const refsym = sym;
Elf32_Addr value = RESOLVE (&sym, version, ELF32_R_TYPE (reloc->r_info));
Elf32_Addr value = RESOLVE (&sym, version, r_type);
if (sym)
value += sym->st_value;
switch (ELF32_R_TYPE (reloc->r_info))
switch (r_type)
{
case R_390_COPY:
if (sym == NULL)
@ -431,24 +433,30 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
case R_390_NONE:
break;
default:
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 0);
_dl_reloc_bad_type (map, r_type, 0);
break;
}
}
}
static inline void
elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
Elf32_Addr *const reloc_addr)
{
*reloc_addr = l_addr + reloc->r_addend;
}
static inline void
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc)
{
Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
/* Check for unexpected PLT reloc type. */
if (__builtin_expect (ELF32_R_TYPE (reloc->r_info), R_390_JMP_SLOT)
== R_390_JMP_SLOT)
if (__builtin_expect (r_type == R_390_JMP_SLOT, 1)))
*reloc_addr += l_addr;
else
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 1);
_dl_reloc_bad_type (map, r_type, 1);
}
#endif /* RESOLVE */

View File

@ -21,7 +21,7 @@
#ifndef dl_machine_h
#define dl_machine_h
#define ELF_MACHINE_NAME "s390x"
#include <sys/param.h>
@ -77,7 +77,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
extern void _dl_runtime_resolve (Elf64_Word);
extern void _dl_runtime_profile (Elf64_Word);
if (l->l_info[DT_JMPREL] && lazy)
if (l->l_info[DT_JMPREL] && lazy)
{
/* The GOT entries for functions in the PLT have not yet been filled
in. Their initial contents will arrange when called to push an
@ -96,7 +96,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
if (__builtin_expect (profile, 0))
{
got[2] = (Elf64_Addr) &_dl_runtime_profile;
if (_dl_name_match_p (_dl_profile, l))
/* This is the object we are looking for. Say that we really
want profiling and the timers are started. */
@ -203,7 +203,7 @@ _dl_runtime_profile:\n\
.size _dl_runtime_resolve, .-_dl_runtime_resolve\n\
.size _dl_runtime_profile, .-_dl_runtime_profile\n\
");
#endif
#endif
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
@ -282,10 +282,10 @@ _dl_start_user:\n\
/* Nonzero iff TYPE describes relocation of a PLT entry, so
PLT entries should not be allowed to define the value. */
#define elf_machine_lookup_noplt_p(type) ((type) == R_390_JMP_SLOT)
#define elf_machine_lookup_noplt_p(type) ((type) == R_390_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT
#define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT
/* The 64 bit S/390 never uses Elf64_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
@ -318,9 +318,9 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
Elf64_Addr value)
{
return value;
}
}
#endif /* !dl_machine_h */
#endif /* !dl_machine_h */
#ifdef RESOLVE
@ -332,21 +332,22 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
const Elf64_Sym *sym, const struct r_found_version *version,
Elf64_Addr *const reloc_addr)
{
if (ELF64_R_TYPE (reloc->r_info) == R_390_RELATIVE) {
const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
if (__builtin_expect (r_type == R_390_RELATIVE, 0))
*reloc_addr = map->l_addr + reloc->r_addend;
#ifndef RTLD_BOOTSTRAP
weak_extern (_dl_rtld_map);
if (map != &_dl_rtld_map) /* Already done in rtld itself. */
else if (__builtin_expect (r_type == R_390_NONE, 0))
return;
#endif
*reloc_addr = map->l_addr + reloc->r_addend;
}
else if (ELF64_R_TYPE (reloc->r_info) != R_390_NONE)
else
{
const Elf64_Sym *const refsym = sym;
Elf64_Addr value = RESOLVE (&sym, version, ELF64_R_TYPE (reloc->r_info));
Elf64_Addr value = RESOLVE (&sym, version, r_type);
if (sym)
value += sym->st_value;
switch (ELF64_R_TYPE (reloc->r_info))
switch (r_type)
{
case R_390_GLOB_DAT:
case R_390_JMP_SLOT:
@ -372,7 +373,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
}
memcpy (reloc_addr, (void *) value, MIN (sym->st_size,
refsym->st_size));
break;
break;
case R_390_64:
*reloc_addr = value + reloc->r_addend;
break;
@ -394,7 +395,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
((int) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1);
break;
case R_390_PC32:
*(unsigned int *) reloc_addr =
*(unsigned int *) reloc_addr =
value + reloc->r_addend - (Elf64_Addr) reloc_addr;
break;
case R_390_PC16DBL:
@ -403,7 +404,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
((short) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1);
break;
case R_390_PC16:
*(unsigned short *) reloc_addr =
*(unsigned short *) reloc_addr =
value + reloc->r_addend - (Elf64_Addr) reloc_addr;
break;
#endif
@ -411,24 +412,31 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
default:
/* We add these checks in the version to relocate ld.so only
if we are still debugging. */
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 0);
_dl_reloc_bad_type (map, r_type, 0);
break;
#endif
}
}
}
}
static inline void
elf_machine_rel_relative (Elf64_Addr l_addr, const Elf64_Rel *reloc,
Elf64_Addr *const reloc_addr)
{
*reloc_addr = l_addr + reloc->r_addend;
}
static inline void
elf_machine_lazy_rel (struct link_map *map,
Elf64_Addr l_addr, const Elf64_Rela *reloc)
{
Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
/* Check for unexpected PLT reloc type. */
if (__builtin_expect (ELF64_R_TYPE (reloc->r_info), R_390_JMP_SLOT)
== R_390_JMP_SLOT)
if (__builtin_expect (r_type == R_390_JMP_SLOT, 1))
*reloc_addr += l_addr;
else
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 1);
_dl_reloc_bad_type (map, r_type, 1);
}
#endif /* RESOLVE */

View File

@ -446,6 +446,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
const Elf32_Sym *sym, const struct r_found_version *version,
Elf32_Addr *const reloc_addr)
{
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
Elf32_Addr value;
#define COPY_UNALIGNED_WORD(sw, tw, align) \
@ -469,7 +470,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
} \
}
if (ELF32_R_TYPE (reloc->r_info) == R_SH_RELATIVE)
if (__builtin_expect (r_type == R_SH_RELATIVE, 0))
{
#ifndef RTLD_BOOTSTRAP
if (map != &_dl_rtld_map) /* Already done in rtld itself. */
@ -485,7 +486,11 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
COPY_UNALIGNED_WORD (value, *reloc_addr, (int) reloc_addr & 3);
}
}
else if (ELF32_R_TYPE (reloc->r_info) != R_SH_NONE)
#ifndef RTLD_BOOTSTRAP
else if (__builtin_expect (r_type 1= R_SH_NONE, 0))
return;
#endif
else
{
const Elf32_Sym *const refsym = sym;
@ -550,6 +555,20 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
break;
}
}
}
static inline void
elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
Elf32_Addr *const reloc_addr)
{
if (reloc->r_addend)
value = l_addr + reloc->r_addend;
else
{
COPY_UNALIGNED_WORD (*reloc_addr, value, (int) reloc_addr & 3);
value += l_addr;
}
COPY_UNALIGNED_WORD (value, *reloc_addr, (int) reloc_addr & 3);
#undef COPY_UNALIGNED_WORD
}

View File

@ -344,6 +344,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
const Elf32_Sym *sym, const struct r_found_version *version,
Elf32_Addr *const reloc_addr)
{
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
#ifndef RTLD_BOOTSTRAP
/* This is defined in rtld.c, but nowhere in the static libc.a; make the
reference weak so static programs can still link. This declaration
@ -353,7 +355,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
weak_extern (_dl_rtld_map);
#endif
if (ELF32_R_TYPE (reloc->r_info) == R_SPARC_RELATIVE)
if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0))
{
#ifndef RTLD_BOOTSTRAP
if (map != &_dl_rtld_map) /* Already done in rtld itself. */
@ -371,13 +373,13 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
value = map->l_addr;
else
{
value = RESOLVE (&sym, version, ELF32_R_TYPE (reloc->r_info));
value = RESOLVE (&sym, version, r_type);
if (sym)
value += sym->st_value;
}
value += reloc->r_addend; /* Assume copy relocs have zero addend. */
switch (ELF32_R_TYPE (reloc->r_info))
switch (r_type)
{
#ifndef RTLD_BOOTSTRAP
case R_SPARC_COPY:
@ -449,13 +451,20 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
break;
#if !defined RTLD_BOOTSTRAP || defined _NDEBUG
default:
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 0);
_dl_reloc_bad_type (map, r_type, 0);
break;
#endif
}
}
}
static inline void
elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
Elf32_Addr *const reloc_addr)
{
*reloc_addr += l_addr + reloc->r_addend;
}
static inline void
elf_machine_lazy_rel (struct link_map *map,
Elf32_Addr l_addr, const Elf32_Rela *reloc)

View File

@ -64,12 +64,12 @@ elf_machine_load_address (void)
: "=r"(pc), "=r"(la));
return pc - *(Elf64_Addr *)(elf_pic_register + la);
Unfortunately as binutils tries to work around Solaris
dynamic linker bug which resolves R_SPARC_RELATIVE as X += B + A
instead of X = B + A this does not work any longer, since ld
clears it.
The following method relies on the fact that sparcv9 ABI maximal
page length is 1MB and all ELF segments on sparc64 are aligned
to 1MB. Also, it relies on _DYNAMIC coming after _GLOBAL_OFFSET_TABLE_
@ -197,23 +197,15 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
const Elf64_Sym *sym, const struct r_found_version *version,
Elf64_Addr *const reloc_addr)
{
#ifndef RTLD_BOOTSTRAP
/* This is defined in rtld.c, but nowhere in the static libc.a; make the
reference weak so static programs can still link. This declaration
cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
because rtld.c contains the common defn for _dl_rtld_map, which is
incompatible with a weak decl in the same file. */
weak_extern (_dl_rtld_map);
#endif
const unsigned long int r_type = ELF64_R_TYPE_ID (reloc->r_info);
if (ELF64_R_TYPE_ID (reloc->r_info) == R_SPARC_RELATIVE)
{
if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0))
*reloc_addr = map->l_addr + reloc->r_addend;
#ifndef RTLD_BOOTSTRAP
if (map != &_dl_rtld_map) /* Already done in rtld itself. */
else if (r_type == R_SPARC_NONE) /* Who is Wilbur? */
return;
#endif
*reloc_addr = map->l_addr + reloc->r_addend;
}
else if (ELF64_R_TYPE_ID (reloc->r_info) != R_SPARC_NONE) /* Who is Wilbur? */
else
{
#ifndef RTLD_BOOTSTRAP
const Elf64_Sym *const refsym = sym;
@ -224,13 +216,13 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
value = map->l_addr;
else
{
value = RESOLVE (&sym, version, ELF64_R_TYPE_ID (reloc->r_info));
value = RESOLVE (&sym, version, r_type);
if (sym)
value += sym->st_value;
}
value += reloc->r_addend; /* Assume copy relocs have zero addend. */
switch (ELF64_R_TYPE_ID (reloc->r_info))
switch (r_type)
{
#ifndef RTLD_BOOTSTRAP
case R_SPARC_COPY:
@ -368,13 +360,20 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
#endif
#if !defined RTLD_BOOTSTRAP || defined _NDEBUG
default:
_dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 0);
_dl_reloc_bad_type (map, r_type, 0);
break;
#endif
}
}
}
static inline void
elf_machine_rel_relative (Elf64_Addr l_addr, const Elf64_Rel *reloc,
Elf64_Addr *const reloc_addr)
{
*reloc_addr = l_addr + reloc->r_addend;
}
static inline void
elf_machine_lazy_rel (struct link_map *map,
Elf64_Addr l_addr, const Elf64_Rela *reloc)