[LD][AARCH64]Add BFD_RELOC_AARCH64_LD64_GOTOFF_LO15 Support.
authorRenlin Li <renlin.li@arm.com>
Fri, 2 Oct 2015 13:51:26 +0000 (14:51 +0100)
committerRenlin Li <renlin.li@arm.com>
Fri, 2 Oct 2015 16:56:07 +0000 (17:56 +0100)
bfd/

2015-10-02  Renlin Li  <renlin.li@arm.com>

* elfnn-aarch64.c (aarch64_reloc_got_type): Add
BFD_RELOC_AARCH64_LD_64_GOTOFF_LO15 support.
(elfNN_aarch64_gc_sweep_hook): Likewise.
(elfNN_aarch64_check_relocs): Likewise
* elfxx-aarch64.c (_bfd_aarch64_elf_put_addend): Likewise.
(_bfd_aarch64_elf_resolve_relocation): Likewise
(elfNN_aarch64_final_link_relocate): Calculate offset within GOT.

ld/testsuite/

2015-10-02  Renlin Li  <renlin.li@arm.com>

* ld-aarch64/emit-relocs-310.d: New.
* ld-aarch64/emit-relocs-310.s: New.
* ld-aarch64/aarch64-elf.exp: Run the 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-310.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/emit-relocs-310.s [new file with mode: 0644]

index b33cb3c516465fb224c3cf15780371e7430e3252..1413d10491fb496650223888004b28cb8c21ac97 100644 (file)
@@ -1,3 +1,13 @@
+2015-10-02  Renlin Li  <renlin.li@arm.com>
+
+       * elfnn-aarch64.c (aarch64_reloc_got_type): Add
+       BFD_RELOC_AARCH64_LD_64_GOTOFF_LO15 support.
+       (elfNN_aarch64_gc_sweep_hook): Likewise.
+       (elfNN_aarch64_check_relocs): Likewise
+       * elfxx-aarch64.c (_bfd_aarch64_elf_put_addend): Likewise.
+       (_bfd_aarch64_elf_resolve_relocation): Likewise
+       (elfNN_aarch64_final_link_relocate): Calculate offset within GOT.
+
 2015-10-02  Renlin Li  <renlin.li@arm.com>
 
        * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Change if to
index 2157ccdfc7270338f5a76829a227ec55afff4b9f..adef278071dd68659b927119c8e42805664eb455 100644 (file)
@@ -4414,6 +4414,7 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
     case BFD_RELOC_AARCH64_GOT_LD_PREL19:
     case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+    case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
     case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
       return GOT_NORMAL;
@@ -4963,6 +4964,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
        case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
        case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
+       case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
          base_got = globals->root.sgot;
          off = h->got.offset;
@@ -5030,6 +5032,9 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
              addend = (globals->root.sgot->output_section->vma
                        + globals->root.sgot->output_offset);
              break;
+           case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
+             value = (value - globals->root.sgot->output_section->vma
+                      - globals->root.sgot->output_offset);
            default:
              break;
            }
@@ -5311,6 +5316,70 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 
       break;
 
+    case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
+      if (h != NULL)
+         value = aarch64_calculate_got_entry_vma (h, globals, info, value,
+                                                  output_bfd,
+                                                  unresolved_reloc_p);
+      else
+       {
+         struct elf_aarch64_local_symbol *locals
+           = elf_aarch64_locals (input_bfd);
+
+         if (locals == NULL)
+           {
+             int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
+             (*_bfd_error_handler)
+               (_("%B: Local symbol descriptor table be NULL when applying "
+                  "relocation %s against local symbol"),
+                input_bfd, elfNN_aarch64_howto_table[howto_index].name);
+             abort ();
+           }
+
+         off = symbol_got_offset (input_bfd, h, r_symndx);
+         base_got = globals->root.sgot;
+         if (base_got == NULL)
+           abort ();
+
+         bfd_vma got_entry_addr = (base_got->output_section->vma
+                                   + base_got->output_offset + off);
+
+         if (!symbol_got_offset_mark_p (input_bfd, h, r_symndx))
+           {
+             bfd_put_64 (output_bfd, value, base_got->contents + off);
+
+             if (bfd_link_pic (info))
+               {
+                 asection *s;
+                 Elf_Internal_Rela outrel;
+
+                 /* For local symbol, we have done absolute relocation in static
+                    linking stage.  While for share library, we need to update
+                    the content of GOT entry according to the share objects
+                    loading base address.  So we need to generate a
+                    R_AARCH64_RELATIVE reloc for dynamic linker.  */
+                 s = globals->root.srelgot;
+                 if (s == NULL)
+                   abort ();
+
+                 outrel.r_offset = got_entry_addr;
+                 outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
+                 outrel.r_addend = value;
+                 elf_append_rela (output_bfd, s, &outrel);
+               }
+
+             symbol_got_offset_mark (input_bfd, h, r_symndx);
+           }
+       }
+
+      /* Update the relocation value to GOT entry addr as we have transformed
+        the direct data access into indirect data access through GOT.  */
+      value = symbol_got_offset (input_bfd, h, r_symndx);
+      value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+                                                  0, weak_undef_p);
+      *unresolved_reloc_p = FALSE;
+      break;
+
     case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
@@ -6392,6 +6461,7 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
        case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+       case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
        case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
@@ -6746,6 +6816,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            case BFD_RELOC_AARCH64_JUMP26:
            case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
            case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+           case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
            case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
            case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
            case BFD_RELOC_AARCH64_NN:
@@ -6859,6 +6930,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
        case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+       case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
        case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
index 34bd1a690226690d6ad58668b8c56fb0821daed7..c831f600a9ae610a457768f81521c1f778b82695 100644 (file)
@@ -265,6 +265,7 @@ _bfd_aarch64_elf_put_addend (bfd *abfd,
 
     case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+    case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
     case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
     case BFD_RELOC_AARCH64_LDST128_LO12:
@@ -404,6 +405,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type,
 
     case BFD_RELOC_AARCH64_16:
     case BFD_RELOC_AARCH64_32:
+    case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
     case BFD_RELOC_AARCH64_MOVW_G0:
     case BFD_RELOC_AARCH64_MOVW_G0_NC:
     case BFD_RELOC_AARCH64_MOVW_G0_S:
index 41be8cd9c7a2d237875520597269fecd87732d49..d1446a7d76aa5cbda84586892ac15a1281dc8c64 100644 (file)
@@ -1,3 +1,9 @@
+2015-10-02  Renlin Li  <renlin.li@arm.com>
+
+       * ld-aarch64/emit-relocs-310.d: New.
+       * ld-aarch64/emit-relocs-310.s: New.
+       * ld-aarch64/aarch64-elf.exp: Run the test.
+
 2015-10-01  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/19031
index 6f00961db9f002ef31d59a2aa5e480764fd9b069..1f68c17d26b1d2e72eba6a6bfedb157bc03a6a0d 100644 (file)
@@ -121,7 +121,7 @@ run_dump_test "emit-relocs-309-up"
 run_dump_test "emit-relocs-309-low"
 run_dump_test "emit-relocs-309-up-bad"
 run_dump_test "emit-relocs-309-low-bad"
-# 310 not done yet
+run_dump_test "emit-relocs-310"
 run_dump_test "emit-relocs-311"
 run_dump_test "emit-relocs-312"
 run_dump_test "emit-relocs-313"
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-310.d b/ld/testsuite/ld-aarch64/emit-relocs-310.d
new file mode 100644 (file)
index 0000000..0baf451
--- /dev/null
@@ -0,0 +1,21 @@
+#source: emit-relocs-310.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:      580000c1        ldr     x1, 10018 <\.text\+0x18>
+   10004:      100000a2        adr     x2, 10018 <\.text\+0x18>
+   10008:      8b010041        add     x1, x2, x1
+   1000c:      f9400820        ldr     x0, \[x1,#16\]
+                       1000c: R_AARCH64_LD64_GOTOFF_LO15       globala
+   10010:      f9400c20        ldr     x0, \[x1,#24\]
+                       10010: R_AARCH64_LD64_GOTOFF_LO15       globalb
+   10014:      f9400420        ldr     x0, \[x1,#8\]
+                       10014: R_AARCH64_LD64_GOTOFF_LO15       globalc
+   10018:      0000ffe8        .word   0x0000ffe8
+                       10018: R_AARCH64_PREL64 _GLOBAL_OFFSET_TABLE_
+   1001c:      00000000        .word   0x00000000
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-310.s b/ld/testsuite/ld-aarch64/emit-relocs-310.s
new file mode 100644 (file)
index 0000000..abcbd34
--- /dev/null
@@ -0,0 +1,11 @@
+       .text
+       ldr     x1, .Lgot
+       adr     x2, .Lgot
+       add     x1, x2, x1
+
+       ldr     x0, [x1, #:gotoff_lo15:globala]
+       ldr     x0, [x1, #:gotoff_lo15:globalb]
+       ldr     x0, [x1, #:gotoff_lo15:globalc]
+
+.Lgot:
+       .dword _GLOBAL_OFFSET_TABLE_ - .