aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRenlin Li <renlin.li@arm.com>2015-10-02 14:51:26 +0100
committerRenlin Li <renlin.li@arm.com>2015-10-02 17:56:07 +0100
commita2e1db00c76bcad0594654d78af76d0e12a217ee (patch)
tree44f2ded06b6a254bf0817cb8c8271c36da07b297
parenta0becb8948afaf3dcb7c39884464a51aa35a9cd9 (diff)
downloadfsf-binutils-gdb-a2e1db00c76bcad0594654d78af76d0e12a217ee.zip
fsf-binutils-gdb-a2e1db00c76bcad0594654d78af76d0e12a217ee.tar.gz
fsf-binutils-gdb-a2e1db00c76bcad0594654d78af76d0e12a217ee.tar.bz2
[LD][AARCH64]Add BFD_RELOC_AARCH64_LD64_GOTOFF_LO15 Support.
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.
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/elfnn-aarch64.c72
-rw-r--r--bfd/elfxx-aarch64.c2
-rw-r--r--ld/testsuite/ChangeLog6
-rw-r--r--ld/testsuite/ld-aarch64/aarch64-elf.exp2
-rw-r--r--ld/testsuite/ld-aarch64/emit-relocs-310.d21
-rw-r--r--ld/testsuite/ld-aarch64/emit-relocs-310.s11
7 files changed, 123 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b33cb3c..1413d10 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,15 @@
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
switch statement.
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 2157ccd..adef278 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -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:
diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c
index 34bd1a6..c831f60 100644
--- a/bfd/elfxx-aarch64.c
+++ b/bfd/elfxx-aarch64.c
@@ -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:
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 41be8cd..d1446a7 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -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
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 6f00961..1f68c17 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -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
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_ - .