From bb0ddc2f1eca652aa8af56825b2ba3182498cc5a Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 2 Mar 2003 11:45:12 +0000 Subject: * sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_fixup_plt): Don't use weak_extern for dl_rtld_map. Instead check only if [SHARED]. (elf_machine_rela): Clean up. * sysdeps/powerpc/powerpc32/dl-machine.h (elf_machine_rela): Clean up. PowerPC TLS support contributed by Paul Mackerras . * sysdeps/powerpc/powerpc32/elf/configure.in: New file. * sysdeps/powerpc/powerpc32/elf/configure: New generated file. * elf/tls-macros.h [__powerpc__ && !__powerpc64__] (TLS_LE, TLS_IE, TLS_LD, TLS_GD): Define them. * sysdeps/powerpc/powerpc32/dl-machine.h (elf_machine_rela): Support new relocs for TLS. * sysdeps/powerpc/dl-tls.h (TLS_TP_OFFSET, TLS_DTV_OFFSET): Move these macros out of [SHARED]. (TLS_TPREL_VALUE, TLS_DTPREL_VALUE): New macros. * elf/elf.h: Define R_PPC_* relocs for TLS support. Clean up R_PPC64_* macro definition comments. --- sysdeps/powerpc/powerpc32/dl-machine.h | 117 +++++++++------ sysdeps/powerpc/powerpc32/elf/configure | 57 ++++++++ sysdeps/powerpc/powerpc32/elf/configure.in | 42 ++++++ sysdeps/powerpc/powerpc64/dl-machine.h | 220 +++++++++-------------------- 4 files changed, 242 insertions(+), 194 deletions(-) create mode 100755 sysdeps/powerpc/powerpc32/elf/configure create mode 100644 sysdeps/powerpc/powerpc32/elf/configure.in (limited to 'sysdeps') diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h index 88408a4287..39dbbb412c 100644 --- a/sysdeps/powerpc/powerpc32/dl-machine.h +++ b/sysdeps/powerpc/powerpc32/dl-machine.h @@ -23,6 +23,7 @@ #define ELF_MACHINE_NAME "powerpc" #include +#include /* Return nonzero iff ELF header is compatible with the running host. */ static inline int @@ -275,11 +276,22 @@ __elf_preferred_address(struct link_map *loader, size_t maplength, /* We never want to use a PLT entry as the destination of a reloc, when what is being relocated is a branch. This is partly for efficiency, but mostly so we avoid loops. */ +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#define elf_machine_type_class(type) \ + ((((type) == R_PPC_JMP_SLOT \ + || (type) == R_PPC_REL24 \ + || (type) == R_PPC_DTPMOD32 \ + || (type) == R_PPC_DTPREL32 \ + || (type) == R_PPC_TPREL32 \ + || (type) == R_PPC_ADDR24) * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_PPC_COPY) * ELF_RTYPE_CLASS_COPY)) +#else #define elf_machine_type_class(type) \ ((((type) == R_PPC_JMP_SLOT \ || (type) == R_PPC_REL24 \ || (type) == R_PPC_ADDR24) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_PPC_COPY) * ELF_RTYPE_CLASS_COPY)) +#endif /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ #define ELF_MACHINE_JMP_SLOT R_PPC_JMP_SLOT @@ -341,44 +353,29 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, Elf32_Addr *const reloc_addr) { const Elf32_Sym *const refsym = sym; - Elf32_Word finaladdr; - const int rinfo = ELF32_R_TYPE (reloc->r_info); - -#ifndef RESOLVE_CONFLICT_FIND_MAP - if (__builtin_expect (rinfo == R_PPC_NONE, 0)) - return; + Elf32_Addr value; + const int r_type = ELF32_R_TYPE (reloc->r_info); - /* The condition on the next two lines is a hack around a bug in Solaris - tools on Sparc. It's not clear whether it should really be here at all, - but if not the binutils need to be changed. */ - if (rinfo == R_PPC_RELATIVE - || (sym->st_shndx != SHN_UNDEF - && ELF32_ST_BIND (sym->st_info) == STB_LOCAL)) + if (r_type == R_PPC_RELATIVE) { - /* Has already been relocated. */ - Elf32_Word loadbase = map->l_addr; - finaladdr = loadbase + reloc->r_addend; - } - else - { - Elf32_Word loadbase - = (Elf32_Word) (char *) (RESOLVE (&sym, version, - ELF32_R_TYPE(reloc->r_info))); - if (sym == NULL) - { - /* Weak symbol that wasn't actually defined anywhere. */ - assert (loadbase == 0); - finaladdr = reloc->r_addend; - } - else - finaladdr = (loadbase + (Elf32_Word) (char *) sym->st_value - + reloc->r_addend); + *reloc_addr = map->l_addr + reloc->r_addend; + return; } + + if (__builtin_expect (r_type == R_PPC_NONE, 0)) + return; + +#if defined USE_TLS && !defined RTLD_BOOTSTRAP + struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); + value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; #else - finaladdr = reloc->r_addend; - if (rinfo == R_PPC_JMP_SLOT) - RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr); + value = RESOLVE (&sym, version, r_type); +# ifndef RTLD_BOOTSTRAP + if (sym != NULL) +# endif + value += sym->st_value; #endif + value += reloc->r_addend; /* A small amount of code is duplicated here for speed. In libc, more than 90% of the relocs are R_PPC_RELATIVE; in the X11 shared @@ -386,15 +383,55 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, R_PPC_ADDR32, and 16% are R_PPC_JMP_SLOT (which this routine wouldn't usually handle). As an bonus, doing this here allows the switch statement in __process_machine_rela to work. */ - if (rinfo == R_PPC_RELATIVE - || rinfo == R_PPC_GLOB_DAT - || rinfo == R_PPC_ADDR32) + switch (r_type) { - *reloc_addr = finaladdr; + case R_PPC_GLOB_DAT: + case R_PPC_ADDR32: + *reloc_addr = value; + break; + +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) + case R_PPC_DTPMOD32: +# ifdef RTLD_BOOTSTRAP + /* During startup the dynamic linker is always index 1. */ + *reloc_addr = 1; +# else + /* Get the information from the link map returned by the + RESOLVE_MAP function. */ + if (sym_map != NULL) + *reloc_addr = sym_map->l_tls_modid; +# endif + break; + case R_PPC_DTPREL32: + /* During relocation all TLS symbols are defined and used. + Therefore the offset is already correct. */ +# ifndef RTLD_BOOTSTRAP + *reloc_addr = TLS_DTPREL_VALUE (sym, reloc); +# endif + break; + case R_PPC_TPREL32: +# ifndef RTLD_BOOTSTRAP + if (sym_map) + { + CHECK_STATIC_TLS (map, sym_map); +# endif + *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc); +# ifndef RTLD_BOOTSTRAP + } +# endif + break; +#endif /* USE_TLS etc. */ + +#ifdef RESOLVE_CONFLICT_FIND_MAP + case R_PPC_JMP_SLOT: + RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr); + /* FALLTHROUGH */ +#endif + + default: + __process_machine_rela (map, reloc, sym, refsym, + reloc_addr, value, r_type); } - else - __process_machine_rela (map, reloc, sym, refsym, - reloc_addr, finaladdr, rinfo); } static inline void diff --git a/sysdeps/powerpc/powerpc32/elf/configure b/sysdeps/powerpc/powerpc32/elf/configure new file mode 100755 index 0000000000..c4bed2b8d5 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/elf/configure @@ -0,0 +1,57 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/powerpc32/elf. + +if test "$usetls" != no; then +# Check for support of thread-local storage handling in assembler and +# linker. +echo "$as_me:$LINENO: checking for powerpc32 TLS support" >&5 +echo $ECHO_N "checking for powerpc32 TLS support... $ECHO_C" >&6 +if test "${libc_cv_powerpc32_tls+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s <<\EOF + .section ".tdata","awT",@progbits +x: .long 1 +x1: .long 1 +x2: .long 1 + .text + addi 3,31,x@got@tlsgd + addi 3,31,x1@got@tlsld + addi 9,3,x1@dtprel + addis 9,3,x2@dtprel@ha + addi 9,9,x2@dtprel@l + lwz 0,x1@dtprel(3) + addis 9,3,x2@dtprel@ha + lwz 0,x2@dtprel@l(9) + lwz 9,x3@got@tprel(31) + add 9,9,x@tls + addi 9,2,x1@tprel + addis 9,2,x2@tprel@ha + addi 9,9,x2@tprel@l +EOF +if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + libc_cv_powerpc32_tls=yes +else + libc_cv_powerpc32_tls=no +fi +rm -f conftest* +fi +echo "$as_me:$LINENO: result: $libc_cv_powerpc32_tls" >&5 +echo "${ECHO_T}$libc_cv_powerpc32_tls" >&6 +if test $libc_cv_powerpc32_tls = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_TLS_SUPPORT 1 +_ACEOF + +fi +fi + +cat >>confdefs.h <<\_ACEOF +#define PI_STATIC_AND_HIDDEN 1 +_ACEOF + diff --git a/sysdeps/powerpc/powerpc32/elf/configure.in b/sysdeps/powerpc/powerpc32/elf/configure.in new file mode 100644 index 0000000000..97c300c20b --- /dev/null +++ b/sysdeps/powerpc/powerpc32/elf/configure.in @@ -0,0 +1,42 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/powerpc32/elf. + +if test "$usetls" != no; then +# Check for support of thread-local storage handling in assembler and +# linker. +AC_CACHE_CHECK(for powerpc32 TLS support, libc_cv_powerpc32_tls, [dnl +cat > conftest.s <<\EOF + .section ".tdata","awT",@progbits +x: .long 1 +x1: .long 1 +x2: .long 1 + .text + addi 3,31,x@got@tlsgd + addi 3,31,x1@got@tlsld + addi 9,3,x1@dtprel + addis 9,3,x2@dtprel@ha + addi 9,9,x2@dtprel@l + lwz 0,x1@dtprel(3) + addis 9,3,x2@dtprel@ha + lwz 0,x2@dtprel@l(9) + lwz 9,x3@got@tprel(31) + add 9,9,x@tls + addi 9,2,x1@tprel + addis 9,2,x2@tprel@ha + addi 9,9,x2@tprel@l +EOF +dnl +if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then + libc_cv_powerpc32_tls=yes +else + libc_cv_powerpc32_tls=no +fi +rm -f conftest*]) +if test $libc_cv_powerpc32_tls = yes; then + AC_DEFINE(HAVE_TLS_SUPPORT) +fi +fi + +dnl It is always possible to access static and hidden symbols in an +dnl position independent way. +AC_DEFINE(PI_STATIC_AND_HIDDEN) diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h index e9cb54b685..87982638ee 100644 --- a/sysdeps/powerpc/powerpc64/dl-machine.h +++ b/sysdeps/powerpc/powerpc64/dl-machine.h @@ -330,12 +330,12 @@ elf_machine_dynamic (void) of the main executable's symbols, as for a COPY reloc. */ #if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) -#define elf_machine_type_class(type) \ - ( (((type) == R_PPC64_DTPMOD64 \ - || (type) == R_PPC64_DTPREL64 \ - || (type) == R_PPC64_TPREL64 \ - || (type) == R_PPC64_ADDR24) * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY)) +#define elf_machine_type_class(type) \ + ((((type) == R_PPC64_DTPMOD64 \ + || (type) == R_PPC64_DTPREL64 \ + || (type) == R_PPC64_TPREL64 \ + || (type) == R_PPC64_ADDR24) * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY)) #else #define elf_machine_type_class(type) \ ((((type) == R_PPC64_ADDR24) * ELF_RTYPE_CLASS_PLT) \ @@ -472,9 +472,6 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map, Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr; Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr; Elf64_Addr offset = 0; -#ifndef RTLD_BOOTSTRAP - weak_extern (GL(dl_rtld_map)); -#endif /* If sym_map is NULL, it's a weak undefined sym; Leave the plt zero. */ if (sym_map == NULL) @@ -483,7 +480,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map, /* If the opd entry is not yet relocated (because it's from a shared object that hasn't been processed yet), then manually reloc it. */ if (map != sym_map && !sym_map->l_relocated -#ifndef RTLD_BOOTSTRAP +#if !defined RTLD_BOOTSTRAP && defined SHARED /* Bootstrap map doesn't have l_relocated set for it. */ && sym_map != &GL(dl_rtld_map) #endif @@ -528,7 +525,8 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, #define PPC_HIGHERA(v) PPC_HIGHER ((v) + 0x8000) #define PPC_HIGHEST(v) (((v) >> 48) & 0xffff) #define PPC_HIGHESTA(v) PPC_HIGHEST ((v) + 0x8000) -#define BIT_INSERT(old, val, mask) ((old & ~(Elf64_Addr) mask) | (val & mask)) +#define BIT_INSERT(var, val, mask) \ + ((var) = ((var) & ~(Elf64_Addr) (mask) | ((val) & (mask)))) #define dont_expect(X) __builtin_expect ((X), 0) @@ -555,9 +553,9 @@ elf_machine_rela (struct link_map *map, const struct r_found_version *version, Elf64_Addr *const reloc_addr) { - int r_type = ELF64_R_TYPE (reloc->r_info); + const int r_type = ELF64_R_TYPE (reloc->r_info); struct link_map *sym_map; - Elf64_Addr value, raw_value; + Elf64_Addr value; #ifndef RTLD_BOOTSTRAP const Elf64_Sym *const refsym = sym; #endif @@ -568,17 +566,23 @@ elf_machine_rela (struct link_map *map, return; } - if (r_type == R_PPC64_NONE) + if (__builtin_expect (r_type == R_PPC64_NONE, 0)) return; - sym_map = RESOLVE_MAP (&sym, version, r_type); - value = raw_value = reloc->r_addend; - if (sym_map) - { - raw_value += sym->st_value; - value = raw_value + sym_map->l_addr; - } +#if defined USE_TLS && !defined RTLD_BOOTSTRAP + struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); + value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; +#else + value = RESOLVE (&sym, version, r_type); +# ifndef RTLD_BOOTSTRAP + if (sym != NULL) +# endif + value += sym->st_value; +#endif + value += reloc->r_addend; + /* For relocs that don't edit code, return. + For relocs that might edit instructions, break from the switch. */ switch (r_type) { case R_PPC64_ADDR64: @@ -586,112 +590,63 @@ elf_machine_rela (struct link_map *map, *reloc_addr = value; return; -#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) + case R_PPC64_JMP_SLOT: +#ifdef RESOLVE_CONFLICT_FIND_MAP + RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr); +#endif + elf_machine_fixup_plt (map, sym_map, reloc, reloc_addr, value); + return; +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) case R_PPC64_DTPMOD64: -#ifdef RTLD_BOOTSTRAP +# ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always index 1. */ *reloc_addr = 1; -#else +# else /* Get the information from the link map returned by the resolve function. */ if (sym_map != NULL) *reloc_addr = sym_map->l_tls_modid; -#endif +# endif return; - case R_PPC64_TPREL64: -#ifdef RTLD_BOOTSTRAP - *reloc_addr = (sym_map->l_tls_offset - TLS_TCB_SIZE - + raw_value - TLS_TP_OFFSET); -#else + case R_PPC_DTPREL64: + /* During relocation all TLS symbols are defined and used. + Therefore the offset is already correct. */ +# ifndef RTLD_BOOTSTRAP + *reloc_addr = TLS_DTPREL_VALUE (sym, reloc); +# endif + break; + case R_PPC_TPREL64: +# ifndef RTLD_BOOTSTRAP if (sym_map) { CHECK_STATIC_TLS (map, sym_map); - *reloc_addr = (sym_map->l_tls_offset - TLS_TCB_SIZE - + raw_value - TLS_TP_OFFSET); +# endif + *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc); +# ifndef RTLD_BOOTSTRAP } -#endif - return; - - case R_PPC64_DTPREL64: -#ifndef RTLD_BOOTSTRAP - /* During relocation all TLS symbols are defined and used. - Therefore the offset is already correct. */ - *reloc_addr = raw_value - TLS_DTV_OFFSET; -#endif - return; -#endif - - case R_PPC64_JMP_SLOT: - - elf_machine_fixup_plt (map, sym_map, reloc, reloc_addr, value); - return; +# endif + break; +#endif /* USE_TLS etc. */ #ifndef RTLD_BOOTSTRAP /* None of the following appear in ld.so */ case R_PPC64_ADDR16_LO_DS: if (dont_expect ((value & 3) != 0)) _dl_reloc_overflow (map, "R_PPC64_ADDR16_LO_DS", reloc_addr, sym, refsym); - *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr, - value, 0xfffc); - break; - - case R_PPC64_TPREL16_LO_DS: - if (dont_expect ((value & 3) != 0)) - _dl_reloc_overflow (map, "R_PPC64_TPREL16_LO_DS", - reloc_addr, sym, refsym); - *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr, - value, 0xfffc); - break; - - case R_PPC64_DTPREL16_LO_DS: - if (dont_expect ((value & 3) != 0)) - _dl_reloc_overflow (map, "R_PPC64_DTPREL16_LO_DS", - reloc_addr, sym, refsym); - *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr, - value, 0xfffc); - break; - - case R_PPC64_GOT_TPREL16_LO_DS: - if (dont_expect ((value & 3) != 0)) - _dl_reloc_overflow (map, "R_PPC64_GOT_TPREL16_LO_DS", - reloc_addr, sym, refsym); - *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr, - value, 0xfffc); - break; - - case R_PPC64_GOT_DTPREL16_LO_DS: - if (dont_expect ((value & 3) != 0)) - _dl_reloc_overflow (map, "R_PPC64_GOT_DTPREL16_LO_DS", - reloc_addr, sym, refsym); - *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr, - value, 0xfffc); + BIT_INSERT (*(Elf64_Half *) reloc_addr, value, 0xfffc); break; case R_PPC64_ADDR16_LO: - case R_PPC64_TPREL16_LO: - case R_PPC64_DTPREL16_LO: - case R_PPC64_GOT_TLSGD16_LO: - case R_PPC64_GOT_TLSLD16_LO: *(Elf64_Half *) reloc_addr = PPC_LO (value); break; case R_PPC64_ADDR16_HI: - case R_PPC64_TPREL16_HI: - case R_PPC64_DTPREL16_HI: - case R_PPC64_GOT_TPREL16_HI: - case R_PPC64_GOT_DTPREL16_HI: - case R_PPC64_GOT_TLSGD16_HI: - case R_PPC64_GOT_TLSLD16_HI: *(Elf64_Half *) reloc_addr = PPC_HI (value); break; case R_PPC64_ADDR16_HA: - case R_PPC64_TPREL16_HA: - case R_PPC64_DTPREL16_HA: - case R_PPC64_GOT_TLSGD16_HA: - case R_PPC64_GOT_TLSLD16_HA: *(Elf64_Half *) reloc_addr = PPC_HA (value); break; @@ -700,8 +655,7 @@ elf_machine_rela (struct link_map *map, Elf64_Addr delta = value - (Elf64_Xword) reloc_addr; if (dont_expect ((delta + 0x2000000) >= 0x4000000 || (delta & 3) != 0)) _dl_reloc_overflow (map, "R_PPC64_REL24", reloc_addr, sym, refsym); - *(Elf64_Word *) reloc_addr = BIT_INSERT (*(Elf64_Word *) reloc_addr, - delta, 0x3fffffc); + BIT_INSERT (*(Elf64_Word *) reloc_addr, delta, 0x3fffffc); } break; @@ -747,8 +701,7 @@ elf_machine_rela (struct link_map *map, case R_PPC64_ADDR24: if (dont_expect ((value + 0x2000000) >= 0x4000000 || (value & 3) != 0)) _dl_reloc_overflow (map, "R_PPC64_ADDR24", reloc_addr, sym, refsym); - *(Elf64_Word *) reloc_addr = BIT_INSERT (*(Elf64_Word *) reloc_addr, - value, 0x3fffffc); + BIT_INSERT (*(Elf64_Word *) reloc_addr, value, 0x3fffffc); break; case R_PPC64_ADDR16: @@ -768,63 +721,22 @@ elf_machine_rela (struct link_map *map, case R_PPC64_ADDR16_DS: if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0)) _dl_reloc_overflow (map, "R_PPC64_ADDR16_DS", reloc_addr, sym, refsym); - *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr, - value, 0xfffc); - break; - - case R_PPC64_TPREL16_DS: - if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0)) - _dl_reloc_overflow (map, "R_PPC64_TPREL16_DS", reloc_addr, - sym, refsym); - *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr, - value, 0xfffc); - break; - - case R_PPC64_DTPREL16_DS: - if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0)) - _dl_reloc_overflow (map, "R_PPC64_DTPREL16_DS", reloc_addr, - sym, refsym); - *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr, - value, 0xfffc); - break; - - case R_PPC64_GOT_TPREL16_DS: - if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0)) - _dl_reloc_overflow (map, "R_PPC64_GOT_TPREL16_DS", reloc_addr, - sym, refsym); - *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr, - value, 0xfffc); - break; - - case R_PPC64_GOT_DTPREL16_DS: - if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0)) - _dl_reloc_overflow (map, "R_PPC64_GOT_DTPREL16_DS", - reloc_addr, sym, refsym); - *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr, - value, 0xfffc); + BIT_INSERT (*(Elf64_Half *) reloc_addr, value, 0xfffc); break; case R_PPC64_ADDR16_HIGHER: - case R_PPC64_TPREL16_HIGHER: - case R_PPC64_DTPREL16_HIGHER: *(Elf64_Half *) reloc_addr = PPC_HIGHER (value); break; case R_PPC64_ADDR16_HIGHEST: - case R_PPC64_TPREL16_HIGHEST: - case R_PPC64_DTPREL16_HIGHEST: *(Elf64_Half *) reloc_addr = PPC_HIGHEST (value); break; case R_PPC64_ADDR16_HIGHERA: - case R_PPC64_TPREL16_HIGHERA: - case R_PPC64_DTPREL16_HIGHERA: *(Elf64_Half *) reloc_addr = PPC_HIGHERA (value); break; case R_PPC64_ADDR16_HIGHESTA: - case R_PPC64_TPREL16_HIGHESTA: - case R_PPC64_DTPREL16_HIGHESTA: *(Elf64_Half *) reloc_addr = PPC_HIGHESTA (value); break; @@ -832,20 +744,20 @@ elf_machine_rela (struct link_map *map, case R_PPC64_ADDR14_BRTAKEN: case R_PPC64_ADDR14_BRNTAKEN: { - Elf64_Word insn; if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0)) - _dl_reloc_overflow (map, "R_PPC64_ADDR14", reloc_addr, sym, refsym); - insn = BIT_INSERT (*(Elf64_Word *) reloc_addr, value, 0xfffc); + _dl_reloc_overflow (map, "R_PPC64_ADDR14", reloc_addr, sym, refsym); + Elf64_Word insn = *(Elf64_Word *) reloc_addr; + BIT_INSERT (insn, value, 0xfffc); if (r_type != R_PPC64_ADDR14) - { - insn &= ~(1 << 21); - if (r_type == R_PPC64_ADDR14_BRTAKEN) - insn |= 1 << 21; - if ((insn & (0x14 << 21)) == (0x04 << 21)) - insn |= 0x02 << 21; - else if ((insn & (0x14 << 21)) == (0x10 << 21)) - insn |= 0x08 << 21; - } + { + insn &= ~(1 << 21); + if (r_type == R_PPC64_ADDR14_BRTAKEN) + insn |= 1 << 21; + if ((insn & (0x14 << 21)) == (0x04 << 21)) + insn |= 0x02 << 21; + else if ((insn & (0x14 << 21)) == (0x10 << 21)) + insn |= 0x08 << 21; + } *(Elf64_Word *) reloc_addr = insn; } break; -- cgit 1.4.1