Update.
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:
parent
c65c9d8ba0
commit
1721af3f96
21
ChangeLog
21
ChangeLog
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user