This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[2/16][binutils][AARCH64]Add relocation support for large memory model. [LD]Add BFD_RELOC_AARCH64_LD64_GOTOFF_LO15 Support.


Hi all,

This patch adds LD support for BFD_RELOC_AARCH64_LD64_GOTOFF_LO15 relocation. This is used in large memory model.

A dedicated register (gp) is used to hold GOT start address. And the offset into the GOT is represented by this symbol. The final address of symbol is the add result of the offset and gp.

ld regression test done without issues. Okay to commit?

bfd/ChangeLog:

2015-09-08  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/ChangeLog:

2015-09-08  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.
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index c61d1e3..19a94ad 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -4166,6 +4166,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;
@@ -4715,6 +4716,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;
@@ -4782,6 +4784,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;
 	    }
@@ -5063,6 +5068,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:
@@ -6084,6 +6153,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:
@@ -6438,6 +6508,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:
@@ -6551,6 +6622,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:
diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c
index 69dac6d..9f10f55 100644
--- a/bfd/elfxx-aarch64.c
+++ b/bfd/elfxx-aarch64.c
@@ -263,6 +263,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:
@@ -389,6 +390,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:
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 15247dc..0094af2 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -114,7 +114,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
index 0000000..0baf451
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-310.d
@@ -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
index 0000000..abcbd34
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-310.s
@@ -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_ - .

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]