[gold][aarch64]Patch to fix a tlsdesc gd-to-ie relaxation bug

Jing Yu jingyu@google.com
Wed Nov 26 07:03:00 GMT 2014


Hi Cary,

When linking the following tlsdesc access sequence into an executable with -pie,

        adrp    x0, :tlsdesc:tls_gd
        ldr     x1, [x0, #:tlsdesc_lo12:tls_gd]
        add     x0, x0, :tlsdesc_lo12:tls_gd
        .tlsdesccall    tls_gd
        blr     x1
        mrs     x1, tpidr_el0
        add     x0, x1, x0
        ldr     w0, [x0]

current gold-aarch64 backend does tls-desc-gd-to-ie relaxation, into

       adrp    x0, 1000 <__FRAME_END__+0x720>
       ldr     x1, [x0,#4064]     ;; <=== the target register should be x0
       nop
       nop
        mrs     x1, tpidr_el0
        add     x0, x1, x0
        ldr     w0, [x0]

This code is wrong. Gold should change ldr target register into x0.

Here goes the patch to fix this bug.

Tested:
On aarch64 box,
$../binutils-gdb/configure --enable-plugins --disable-multilib
--disable-nls --enable-threads --enable-gold=default
--enable-targets=all

ok for trunk?

Thanks,
Jing

gold/ChangeLog:

2014-11-25  Jing Yu  <jingyu@google.com>

        * aarch64.cc (Relocate::tls_desc_gd_to_ie): Set ldr target
register to be x0 when to relax TLSDESC_LD64_LO12.


diff --git a/gold/aarch64.cc b/gold/aarch64.cc
index 125953a..8697ee5 100644
--- a/gold/aarch64.cc
+++ b/gold/aarch64.cc
@@ -6536,6 +6536,11 @@ Target_aarch64<size,
big_endian>::Relocate::tls_desc_gd_to_ie(
     case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
       {
+        // Set ldr target register to be x0.
+        Insntype insn = elfcpp::Swap<32, big_endian>::readval(ip);
+        insn &= 0xffffffe0;
+        elfcpp::Swap<32, big_endian>::writeval(ip, insn);
+        // Do relocation.
         const AArch64_reloc_property* reloc_property =
             aarch64_reloc_property_table->get_reloc_property(
               elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC);



More information about the Binutils mailing list