mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-26 06:50:07 +00:00
Define elf_machine_rel_relative. Minor optimizations.
This commit is contained in:
parent
4435779790
commit
85bdccdbd2
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user