From: Alan Modra Date: Thu, 29 Jan 2015 10:03:26 +0000 (+1030) Subject: Correct GOLD PowerPC64 local-dynamic TLS linker optimization X-Git-Tag: binutils-2_25_1~223 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8e5ffad188dc9480e04e2952a96e1682c1470643;p=thirdparty%2Fbinutils-gdb.git Correct GOLD PowerPC64 local-dynamic TLS linker optimization Similar to b86ac8e3 * powerpc.cc (Target_powerpc::Relocate::relocate): Correct GOT_TLSLD and GOT_TLSGD to LE optimization. --- diff --git a/gold/ChangeLog b/gold/ChangeLog index b7b2d9a78e6..2c4a8c3c007 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,6 +1,10 @@ 2015-02-11 Alan Modra Apply from master + 2015-01-29 Alan Modra + * powerpc.cc (Target_powerpc::Relocate::relocate): Correct GOT_TLSLD + and GOT_TLSGD to LE optimization. + 2015-01-22 Alan Modra * powerpc.cc (Target_powerpc::Scan::local ): Correct condition for need of ifunc plt entry. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 707acda8b67..264bbd82b50 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -3092,8 +3092,6 @@ static const uint32_t addi_11_11 = 0x396b0000; static const uint32_t addi_12_12 = 0x398c0000; static const uint32_t addis_0_2 = 0x3c020000; static const uint32_t addis_0_13 = 0x3c0d0000; -static const uint32_t addis_3_2 = 0x3c620000; -static const uint32_t addis_3_13 = 0x3c6d0000; static const uint32_t addis_11_2 = 0x3d620000; static const uint32_t addis_11_11 = 0x3d6b0000; static const uint32_t addis_11_30 = 0x3d7e0000; @@ -6921,9 +6919,12 @@ Target_powerpc::Relocate::relocate( || r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO) { Insn* iview = reinterpret_cast(view - 2 * big_endian); - Insn insn = addis_3_13; + Insn insn = elfcpp::Swap<32, big_endian>::readval(iview); + insn &= (1 << 26) - (1 << 21); // extract rt if (size == 32) - insn = addis_3_2; + insn |= addis_0_2; + else + insn |= addis_0_13; elfcpp::Swap<32, big_endian>::writeval(iview, insn); r_type = elfcpp::R_POWERPC_TPREL16_HA; value = psymval->value(object, rela.get_r_addend()); @@ -6956,9 +6957,12 @@ Target_powerpc::Relocate::relocate( || r_type == elfcpp::R_POWERPC_GOT_TLSLD16_LO) { Insn* iview = reinterpret_cast(view - 2 * big_endian); - Insn insn = addis_3_13; + Insn insn = elfcpp::Swap<32, big_endian>::readval(iview); + insn &= (1 << 26) - (1 << 21); // extract rt if (size == 32) - insn = addis_3_2; + insn |= addis_0_2; + else + insn |= addis_0_13; elfcpp::Swap<32, big_endian>::writeval(iview, insn); r_type = elfcpp::R_POWERPC_TPREL16_HA; value = dtp_offset;