diff options
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | sysdeps/alpha/dl-machine.h | 21 | ||||
-rw-r--r-- | sysdeps/arm/dl-machine.h | 28 | ||||
-rw-r--r-- | sysdeps/cris/dl-machine.h | 41 | ||||
-rw-r--r-- | sysdeps/hppa/dl-machine.h | 7 | ||||
-rw-r--r-- | sysdeps/i386/dl-machine.h | 29 | ||||
-rw-r--r-- | sysdeps/ia64/dl-machine.h | 15 | ||||
-rw-r--r-- | sysdeps/m68k/dl-machine.h | 17 | ||||
-rw-r--r-- | sysdeps/mips/dl-machine.h | 15 | ||||
-rw-r--r-- | sysdeps/powerpc/dl-machine.h | 8 | ||||
-rw-r--r-- | sysdeps/s390/s390-32/dl-machine.h | 30 | ||||
-rw-r--r-- | sysdeps/s390/s390-64/dl-machine.h | 58 | ||||
-rw-r--r-- | sysdeps/sh/dl-machine.h | 23 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/dl-machine.h | 17 | ||||
-rw-r--r-- | sysdeps/sparc/sparc64/dl-machine.h | 37 |
15 files changed, 257 insertions, 110 deletions
diff --git a/ChangeLog b/ChangeLog index acd3afc10f..c174bf0d3e 100644 --- a/ChangeLog +++ b/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. diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h index 1634e96950..e16f046cb7 100644 --- a/sysdeps/alpha/dl-machine.h +++ b/sysdeps/alpha/dl-machine.h @@ -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 @@ -548,6 +548,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) { diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h index 24fe366784..7dfed999d0 100644 --- a/sysdeps/arm/dl-machine.h +++ b/sysdeps/arm/dl-machine.h @@ -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 */ diff --git a/sysdeps/cris/dl-machine.h b/sysdeps/cris/dl-machine.h index c6d2558e6f..0813f70ec6 100644 --- a/sysdeps/cris/dl-machine.h +++ b/sysdeps/cris/dl-machine.h @@ -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,7 +358,7 @@ 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 } @@ -378,15 +366,22 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, } 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 */ diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h index e8e2ab20a1..bc37986082 100644 --- a/sysdeps/hppa/dl-machine.h +++ b/sysdeps/hppa/dl-machine.h @@ -629,6 +629,13 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, } 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) { diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index bd6b57ae13..99576aeb5a 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -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,7 +370,7 @@ 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 } @@ -372,16 +378,23 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, } 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 */ diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h index a2192a1e2e..8123515a08 100644 --- a/sysdeps/ia64/dl-machine.h +++ b/sysdeps/ia64/dl-machine.h @@ -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 diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h index c4849b078c..e3a5a24586 100644 --- a/sysdeps/m68k/dl-machine.h +++ b/sysdeps/m68k/dl-machine.h @@ -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,13 +292,20 @@ 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) { diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h index 87d7cbb5d5..340cd1750a 100644 --- a/sysdeps/mips/dl-machine.h +++ b/sysdeps/mips/dl-machine.h @@ -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,12 +530,19 @@ 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) { diff --git a/sysdeps/powerpc/dl-machine.h b/sysdeps/powerpc/dl-machine.h index 5ea6c46b78..f528dcb9d4 100644 --- a/sysdeps/powerpc/dl-machine.h +++ b/sysdeps/powerpc/dl-machine.h @@ -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. */ diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h index 4f8952487c..7b9cb89889 100644 --- a/sysdeps/s390/s390-32/dl-machine.h +++ b/sysdeps/s390/s390-32/dl-machine.h @@ -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 */ diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h index 4020ff4b31..1f7fc2d540 100644 --- a/sysdeps/s390/s390-64/dl-machine.h +++ b/sysdeps/s390/s390-64/dl-machine.h @@ -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 */ diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h index 2a740b1c13..a082e6edca 100644 --- a/sysdeps/sh/dl-machine.h +++ b/sysdeps/sh/dl-machine.h @@ -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 } diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h index 460421d996..edeb20b931 100644 --- a/sysdeps/sparc/sparc32/dl-machine.h +++ b/sysdeps/sparc/sparc32/dl-machine.h @@ -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,7 +451,7 @@ 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 } @@ -457,6 +459,13 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, } 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) { diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h index b7f2d62c90..1e5e25b827 100644 --- a/sysdeps/sparc/sparc64/dl-machine.h +++ b/sysdeps/sparc/sparc64/dl-machine.h @@ -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,7 +360,7 @@ 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 } @@ -376,6 +368,13 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, } 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) { |