Fix accesses to the GOT for AARCH64 operating in 32-bit mode.
authorYury Norov <ynorov@caviumnetworks.com>
Thu, 1 Dec 2016 12:31:51 +0000 (12:31 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 1 Dec 2016 12:31:51 +0000 (12:31 +0000)
PR ld/20868
bfd * elfnn-aarch64.c (elfNN_aarch64_tls_relax): Use 32-bit accesses
to the GOT when operating in 32-bit mode.

ld * testsuite/ld-aarch64/tls-relax-gd-ie-ilp32.d: New test.
* testsuite/ld-aarch64/relocs-ilp32.ld: Linker script for the new
test.
* testsuite/ld-aarch64/aarch64-elf.exp: Run the new test.

bfd/ChangeLog
bfd/elfnn-aarch64.c
ld/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/relocs-ilp32.ld [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-relax-gd-ie-ilp32.d [new file with mode: 0644]

index fae51f3a2b4febbb4c8a5e92afba66d3958deaf3..68e5032488d79d97b0ec22d4363b8b627aeefd05 100644 (file)
@@ -1,3 +1,9 @@
+2016-12-01  Yury Norov  <ynorov@caviumnetworks.com>
+
+       PR ld/20868
+       * elfnn-aarch64.c (elfNN_aarch64_tls_relax): Use 32-bit accesses
+       to the GOT when operating in 32-bit mode.
+
 2016-12-01  Ma Jiang  <ma.jiang@zte.com.cn>
 
        PR ld/16720
index 99b2a04f153a688855d7c34c4a0a562a37e7e5d6..ffa8e6a9970317414bf2464f04b9dff25ce83d70 100644 (file)
@@ -5841,24 +5841,29 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
       else
        {
          /* GD->IE relaxation
-            ADD  x0, #:tlsgd_lo12:var  => ldr  x0, [x0, #:gottprel_lo12:var]
+            ADD  x0, #:tlsgd_lo12:var  => ldr  R0, [x0, #:gottprel_lo12:var]
             BL   __tls_get_addr        => mrs  x1, tpidr_el0
               R_AARCH64_CALL26
-            NOP                        => add  x0, x1, x0
-          */
+            NOP                        => add  R0, R1, R0
+
+            Where R is x for lp64 mode, and w for ilp32 mode.  */
 
          BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
 
          /* Remove the relocation on the BL instruction.  */
          rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
 
-         bfd_putl32 (0xf9400000, contents + rel->r_offset);
-
          /* We choose to fixup the BL and NOP instructions using the
             offset from the second relocation to allow flexibility in
             scheduling instructions between the ADD and BL.  */
-         bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
+#if ARCH_SIZE == 32
+         bfd_putl32 (0xb9400000, contents + rel->r_offset);
+         bfd_putl32 (0x0b000020, contents + rel[1].r_offset + 4);
+#else
+         bfd_putl32 (0xf9400000, contents + rel->r_offset);
          bfd_putl32 (0x8b000020, contents + rel[1].r_offset + 4);
+#endif
+         bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
          return bfd_reloc_continue;
        }
 
index 9484e74f7fd64ba19036dafce9df4afc7385e335..446a4afa9a31f20a615dc4659bbfa137dda9a44b 100644 (file)
@@ -1,3 +1,11 @@
+2016-12-01  Yury Norov  <ynorov@caviumnetworks.com>
+
+       PR ld/20868
+       * testsuite/ld-aarch64/tls-relax-gd-ie-ilp32.d: New test.
+       * testsuite/ld-aarch64/relocs-ilp32.ld: Linker script for the new
+       test.
+       * testsuite/ld-aarch64/aarch64-elf.exp: Run the new test.
+
 2016-11-28  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * emulparams/arclinux_prof.sh: Remove duplicate TEMPLATE_NAME.
index d4d7f5a0b8fa5626158eff4727b729d64398d206..8e425d214f82371155ff53b048d762a48dae8445 100644 (file)
@@ -189,6 +189,7 @@ run_dump_test "farcall-bl-section"
 run_dump_test "tls-relax-all"
 run_dump_test "tls-relax-gd-le"
 run_dump_test "tls-relax-gdesc-le"
+run_dump_test "tls-relax-gd-ie-ilp32"
 run_dump_test "tls-relax-gd-ie"
 run_dump_test "tls-relax-large-gd-ie"
 run_dump_test "tls-relax-large-gd-ie-be"
diff --git a/ld/testsuite/ld-aarch64/relocs-ilp32.ld b/ld/testsuite/ld-aarch64/relocs-ilp32.ld
new file mode 100644 (file)
index 0000000..7174aff
--- /dev/null
@@ -0,0 +1,19 @@
+/* Script for ld testsuite.  */
+OUTPUT_ARCH(aarch64:ilp32)
+ENTRY(_start)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment:  */
+  PROVIDE (__executable_start = 0x8000); . = 0x10000;
+  .text           :
+  {
+    *(.before)
+    *(.text)
+    *(.after)
+  } =0
+  . = 0x20000;
+  .got            : { *(.got) *(.got.plt)}
+  . = 0x12340000;
+  .far : { *(.far) }
+  .ARM.attributes 0 : { *(.ARM.atttributes) }
+}
diff --git a/ld/testsuite/ld-aarch64/tls-relax-gd-ie-ilp32.d b/ld/testsuite/ld-aarch64/tls-relax-gd-ie-ilp32.d
new file mode 100644 (file)
index 0000000..ab08c61
--- /dev/null
@@ -0,0 +1,10 @@
+#source: tls-relax-gd-ie.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+ +10000:       90000080        adrp    x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+ +10004:       b9400400        ldr     w0, \[x0, #4\]
+ +10008:       d53bd041        mrs     x1, tpidr_el0
+ +1000c:       0b000020        add     w0, w1, w0
+ +10010:       b9400000        ldr     w0, \[x0\]