1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-12-24 17:51:17 +03:00
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

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