[AArch64] BFD Support BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
authorJiong Wang <jiong.wang@arm.com>
Mon, 1 Jun 2015 09:26:00 +0000 (10:26 +0100)
committerJiong Wang <jiong.wang@arm.com>
Mon, 1 Jun 2015 09:26:00 +0000 (10:26 +0100)
2015-06-01  Jiong Wang  <jiong.wang@arm.com>
bfd/
* elfnn-aarch64.c (aarch64_reloc_got_type): Support
BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15.
(elfNN_aarch64_final_link_relocate): Ditto.
(elfNN_aarch64_gc_swap_hook): Ditto.
(elfNN_aarch64_check_relocs): Ditto.
* elfxx-aarch64.c (_bfd_aarch64_elf_put_addend): Ditto.

ld/testsuite/
* ld-aarch64/emit-relocs-313.s: New test file.
* ld-aarch64/emit-relocs-313.d: Ditto.
* ld-aarch64/aarch64-elf.exp: Run new test.

bfd/ChangeLog
bfd/elfnn-aarch64.c
bfd/elfxx-aarch64.c
ld/testsuite/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/emit-relocs-313.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/emit-relocs-313.s [new file with mode: 0644]

index ccb2928..5ae71b2 100644 (file)
@@ -1,5 +1,14 @@
 2015-06-01  Jiong Wang  <jiong.wang@arm.com>
 
+       * elfnn-aarch64.c (aarch64_reloc_got_type): Support
+       BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15.
+       (elfNN_aarch64_final_link_relocate): Ditto.
+       (elfNN_aarch64_gc_swap_hook): Ditto.
+       (elfNN_aarch64_check_relocs): Ditto.
+       * elfxx-aarch64.c (_bfd_aarch64_elf_put_addend): Ditto.
+
+2015-06-01  Jiong Wang  <jiong.wang@arm.com>
+
        * reloc.c (BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15): New entry.
        * bfd-in2.h: Regenerate.
        * libbfd.h: Regenerate.
index 2615f24..bcb25fd 100644 (file)
@@ -4052,6 +4052,7 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
     case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
     case BFD_RELOC_AARCH64_GOT_LD_PREL19:
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+    case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
       return GOT_NORMAL;
 
@@ -4507,6 +4508,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     {
       asection *plt;
       const char *name;
+      bfd_vma addend = 0;
 
       if ((input_section->flags & SEC_ALLOC) == 0
          || h->plt.offset == (bfd_vma) -1)
@@ -4604,6 +4606,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
        case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+       case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
          base_got = globals->root.sgot;
          off = h->got.offset;
@@ -4663,8 +4666,11 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
            value = aarch64_calculate_got_entry_vma (h, globals, info,
                                                     value, output_bfd,
                                                     unresolved_reloc_p);
+         if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+           addend = (globals->root.sgot->output_section->vma
+                     + globals->root.sgot->output_offset);
          value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
-                                                      0, weak_undef_p);
+                                                      addend, weak_undef_p);
          return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type, howto, value);
        case BFD_RELOC_AARCH64_ADD_LO12:
        case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
@@ -4869,20 +4875,26 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
     case BFD_RELOC_AARCH64_GOT_LD_PREL19:
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+    case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
       if (globals->root.sgot == NULL)
        BFD_ASSERT (h != NULL);
 
       if (h != NULL)
        {
+         bfd_vma addend = 0;
          value = aarch64_calculate_got_entry_vma (h, globals, info, value,
                                                   output_bfd,
                                                   unresolved_reloc_p);
+         if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+           addend = (globals->root.sgot->output_section->vma
+                     + globals->root.sgot->output_offset);
          value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
-                                                      0, weak_undef_p);
+                                                      addend, weak_undef_p);
        }
       else
       {
+       bfd_vma addend = 0;
        struct elf_aarch64_local_symbol *locals
          = elf_aarch64_locals (input_bfd);
 
@@ -4931,6 +4943,12 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
        /* Update the relocation value to GOT entry addr as we have transformed
           the direct data access into indirect data access through GOT.  */
        value = got_entry_addr;
+
+       if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+         addend = base_got->output_section->vma + base_got->output_offset;
+
+       value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+                                                    addend, weak_undef_p);
       }
 
       break;
@@ -5926,6 +5944,7 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
        case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+       case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
@@ -6283,6 +6302,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            case BFD_RELOC_AARCH64_GOT_LD_PREL19:
            case BFD_RELOC_AARCH64_JUMP26:
            case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+           case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
            case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
            case BFD_RELOC_AARCH64_NN:
              if (htab->root.dynobj == NULL)
@@ -6394,6 +6414,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+       case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
index 576df78..889b0d0 100644 (file)
@@ -258,6 +258,7 @@ _bfd_aarch64_elf_put_addend (bfd *abfd,
       break;
 
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+    case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
     case BFD_RELOC_AARCH64_LDST128_LO12:
     case BFD_RELOC_AARCH64_LDST16_LO12:
@@ -413,6 +414,11 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type,
       value = PG (value + addend) - PG (place);
       break;
 
+    case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
+      /* Caller must make sure addend is the base address of .got section.  */
+      value = value - PG (addend);
+      break;
+
     case BFD_RELOC_AARCH64_ADD_LO12:
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
index 483baa7..9857040 100644 (file)
@@ -1,3 +1,9 @@
+2015-06-01  Jiong Wang  <jiong.wang@arm.com>
+
+       * ld-aarch64/emit-relocs-313.s: New test file.
+       * ld-aarch64/emit-relocs-313.d: Ditto.
+       * ld-aarch64/aarch64-elf.exp: Run new test.
+
 2015-05-29  Stephen Kitt  <steve@sk2.org>
 
        * ld-pe/pe-run2.exp (test_direct2_link_dll): Add $CFLAGS to the
index bfbbe24..79b5a3e 100644 (file)
@@ -99,6 +99,7 @@ run_dump_test "emit-relocs-309-low-bad"
 # 310 not done yet
 run_dump_test "emit-relocs-311"
 run_dump_test "emit-relocs-312"
+run_dump_test "emit-relocs-313"
 
 # test addend correctness when --emit-relocs specified for non-relocatable obj.
 run_dump_test "emit-relocs-local-addend"
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-313.d b/ld/testsuite/ld-aarch64/emit-relocs-313.d
new file mode 100644 (file)
index 0000000..0a7b5d1
--- /dev/null
@@ -0,0 +1,18 @@
+#source: emit-relocs-313.s
+#ld: -T relocs.ld --defsym globala=0x11000 --defsym globalb=0x45000 --defsym globalc=0x1234  -e0 --emit-relocs
+#objdump: -dr
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0000000000010000 <\.text>:
+   10000:      90000082        adrp    x2, 20000 <_GLOBAL_OFFSET_TABLE_>
+                       10000: R_AARCH64_ADR_PREL_PG_HI21       _GLOBAL_OFFSET_TABLE_
+   10004:      f9400840        ldr     x0, \[x2,#16\]
+                       10004: R_AARCH64_LD64_GOTPAGE_LO15      globala
+   10008:      f9400c40        ldr     x0, \[x2,#24\]
+                       10008: R_AARCH64_LD64_GOTPAGE_LO15      globalb
+   1000c:      f9400440        ldr     x0, \[x2,#8\]
+                       1000c: R_AARCH64_LD64_GOTPAGE_LO15      globalc
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-313.s b/ld/testsuite/ld-aarch64/emit-relocs-313.s
new file mode 100644 (file)
index 0000000..b13a0e5
--- /dev/null
@@ -0,0 +1,5 @@
+       .text
+       adrp  x2, _GLOBAL_OFFSET_TABLE_
+       ldr     x0, [x2, #:gotpage_lo14:globala]
+       ldr     x0, [x2, #:gotpage_lo14:globalb]
+       ldr     x0, [x2, #:gotpage_lo14:globalc]