public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH][AArch64] Improve copy relocation support on four absolute relocation types
@ 2014-08-13 14:32 Jiong Wang
  2014-08-26 14:17 ` Nicholas Clifton
  0 siblings, 1 reply; 2+ messages in thread
From: Jiong Wang @ 2014-08-13 14:32 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 3016 bytes --]

aarch64 static linker fail linking unreasonably when trying to link executable from .o
written by handle assembly which contain access of global symbol and generated without -fPIC.

/usr/bin/ld: x.o(.text+0x8): unresolvable R_AARCH64_MOVW_UABS_G0_NC relocation against...
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status

I found the problem is caused by our incomplete support for calculating address of
global symbol by absolute relocation.

currently, if we calculating address by 32/64 bit absolute relocation, it's OK.

for example:

x.s
         
.8byte global_a
         
for .o, a ABS64 relocation created.

Relocation section '*.rela.text*' at offset 0x360 contains 1 entries:

R_AARCH64_ABS64        0000000000000000 global_a + 0
  
then if we:

   link into executable
   ============================
   copy relocation generated, and the original address in text section
   will point to .dynbss which this copy relocation will happen.

   *readelf -r x.exe*

   Relocation section '*.rela.dyn*' at offset 0x460 contains 9 entries:

     R_AARCH64_COPY         0000000000410830 stdout + 0

   link into shared library
   ========================
   R_AARCH64_ABS64 will be propagated to dynamic relocation section to let the
   runtime linker relocate on the text section directly.

   *readelf -r x.so*

   Relocation section '*.rela.dyn*' at offset 0x460 contains 9 entries:

     R_AARCH64_ABS64        0000000000000000 stdout + 0
   
while there is another way to form 64 bit address for global symbol by using
   
   movz x0,:abs_g0_nc:global_a (BFD_RELOC_AARCH64_MOVW_G0_NC)
   movk x0,:abs_g1_nc:global_a (BFD_RELOC_AARCH64_MOVW_G1_NC)
   movk x0,:abs_g2_nc:global_a (BFD_RELOC_AARCH64_MOVW_G2_NC)
   movk x0,:abs_g3:global_a    (BFD_RELOC_AARCH64_MOVW_G3)

to form the address from pieces instead of one single R_AARCH64_ABS64.

so for the above four relocation types, we need to support all those logic
AARCH64_ABS64 supported except when linking shared library to prevent
copy on write penalty.

  * for executable linking, generate copy relocation.
  * reject them when linking shared library.

this is also the approach arm32 adopted.

ok for trunk?

thanks.

-- Jiong

   bfd/
     * elfnn-aarch64.c (elfNN_aarch64_check_relocs): Initialize non_got_ref
     properly for MOVW_G0/1/2_NC and MOVW_G3. Reject them when linking
     shared library.
     (elfNN_aarch64_gc_sweep_hook): Add check on these relocs.

   ld/testsuite/
     * ld-aarch64/copy-relocs-so.s: New test file.
     * ld-aarch64/copy-relocs-exe.s: Likewise.
     * ld-aarch64/copy-relocs.d: New expectation file.
     * ld-aarch64/emit-relocs-264-bad.d: New test file.
     * ld-aarch64/emit-relocs-266-bad.d: Likewise.
     * ld-aarch64/emit-relocs-268-bad.d: Likewise.
     * ld-aarch64/emit-relocs-269-bad.d: Likewise.
     * ld-aarch64/aarch64-elf.exp: Run new added test.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: fix-copy-reloc.patch --]
[-- Type: text/x-patch; name=fix-copy-reloc.patch, Size: 6089 bytes --]

commit 755d9ef68978198eb3e022d6fad86e4a54f97f2b
Author: Jiong Wang <jiong.wang@arm.com>
Date:   Mon Aug 11 14:52:24 2014 +0100

    Fix

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 4dfb604..d7b3037 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -4766,16 +4766,6 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
 	    }
 	  break;
 
-	case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
-	case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
-	case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
-	  if (h != NULL && info->executable)
-	    {
-	      if (h->plt.refcount > 0)
-		h->plt.refcount -= 1;
-	    }
-	  break;
-
 	case BFD_RELOC_AARCH64_CALL26:
 	case BFD_RELOC_AARCH64_JUMP26:
 	  /* If this is a local symbol then we resolve it
@@ -4787,6 +4777,13 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
 	    h->plt.refcount -= 1;
 	  break;
 
+	case BFD_RELOC_AARCH64_MOVW_G0_NC:
+	case BFD_RELOC_AARCH64_MOVW_G1_NC:
+	case BFD_RELOC_AARCH64_MOVW_G2_NC:
+	case BFD_RELOC_AARCH64_MOVW_G3:
+	case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
+	case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+	case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
 	case BFD_RELOC_AARCH64_NN:
 	  if (h != NULL && info->executable)
 	    {
@@ -5283,6 +5280,22 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    break;
 	  }
 
+	case BFD_RELOC_AARCH64_MOVW_G0_NC:
+	case BFD_RELOC_AARCH64_MOVW_G1_NC:
+	case BFD_RELOC_AARCH64_MOVW_G2_NC:
+	case BFD_RELOC_AARCH64_MOVW_G3:
+	  if (info->shared)
+	    {
+	      int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
+	      (*_bfd_error_handler)
+		(_("%B: relocation %s against `%s' can not be used when making "
+		   "a shared object; recompile with -fPIC"),
+		 abfd, elfNN_aarch64_howto_table[howto_index].name,
+		 (h) ? h->root.root.string : "a local symbol");
+	      bfd_set_error (bfd_error_bad_value);
+	      return FALSE;
+	    }
+
 	case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
 	case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
 	case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 36babf3..b3f6eb5 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -51,11 +51,15 @@ run_dump_test "emit-relocs-260-be"
 run_dump_test "emit-relocs-262"
 run_dump_test "emit-relocs-263"
 run_dump_test "emit-relocs-264"
+run_dump_test "emit-relocs-264-bad"
 run_dump_test "emit-relocs-265"
 run_dump_test "emit-relocs-266"
+run_dump_test "emit-relocs-266-bad"
 run_dump_test "emit-relocs-267"
 run_dump_test "emit-relocs-268"
+run_dump_test "emit-relocs-268-bad"
 run_dump_test "emit-relocs-269"
+run_dump_test "emit-relocs-269-bad"
 run_dump_test "emit-relocs-270"
 run_dump_test "emit-relocs-270-bad"
 run_dump_test "emit-relocs-271"
@@ -163,3 +167,12 @@ run_dump_test "ifunc-21"
 run_dump_test "ifunc-22"
 
 run_dump_test "relasz"
+
+set aarch64elflinktests {
+  {"ld-aarch64/so with global symbol" "-shared" "" "" {copy-reloc-so.s}
+  {} "copy-reloc-so.so"}
+  {"ld-aarch64/exe with copy relocation" "-e0 tmpdir/copy-reloc-so.so" "" ""
+  {copy-reloc-exe.s} {{objdump -R copy-reloc.d}} "copy-reloc"}
+}
+
+run_ld_link_tests $aarch64elflinktests
diff --git a/ld/testsuite/ld-aarch64/copy-reloc-exe.s b/ld/testsuite/ld-aarch64/copy-reloc-exe.s
new file mode 100644
index 0000000..cafc700
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/copy-reloc-exe.s
@@ -0,0 +1,7 @@
+	.text
+	.global main
+main:
+	movz x0,:abs_g0_nc:global_a
+	movk x0,:abs_g1_nc:global_a
+	movk x0,:abs_g2_nc:global_a
+	movk x0,:abs_g3:global_a
diff --git a/ld/testsuite/ld-aarch64/copy-reloc-so.s b/ld/testsuite/ld-aarch64/copy-reloc-so.s
new file mode 100644
index 0000000..07ec44a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/copy-reloc-so.s
@@ -0,0 +1,6 @@
+	.global global_a
+	.type	global_a, %object
+	.size	global_a, 4
+	.data
+global_a:
+	.word 0xcafedead
diff --git a/ld/testsuite/ld-aarch64/copy-reloc.d b/ld/testsuite/ld-aarch64/copy-reloc.d
new file mode 100644
index 0000000..c4eed84
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/copy-reloc.d
@@ -0,0 +1,4 @@
+.*
+DYNAMIC RELOCATION RECORDS
+OFFSET.*TYPE.*VALUE.*
+.*R_AARCH64_COPY.*global_a
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-264-bad.d b/ld/testsuite/ld-aarch64/emit-relocs-264-bad.d
new file mode 100644
index 0000000..22718ca
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-264-bad.d
@@ -0,0 +1,3 @@
+#source: emit-relocs-264.s
+#ld: -T relocs.ld --defsym tempy=0x11000 --defsym tempy2=0x45000 --defsym tempy3=0x1234  -e0 -shared
+#error: .*relocation R_AARCH64_MOVW_UABS_G0_NC.*can not.*shared object.*fPIC
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-266-bad.d b/ld/testsuite/ld-aarch64/emit-relocs-266-bad.d
new file mode 100644
index 0000000..886494d
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-266-bad.d
@@ -0,0 +1,3 @@
+#source: emit-relocs-266.s
+#ld: -T relocs.ld --defsym tempy=0x11000 --defsym tempy2=0x45000 --defsym tempy3=0x1234  -e0 -shared
+#error: .*relocation R_AARCH64_MOVW_UABS_G1_NC.*can not.*shared object.*fPIC
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-268-bad.d b/ld/testsuite/ld-aarch64/emit-relocs-268-bad.d
new file mode 100644
index 0000000..ea97541
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-268-bad.d
@@ -0,0 +1,3 @@
+#source: emit-relocs-268.s
+#ld: -T relocs.ld --defsym tempy=0x11000 --defsym tempy2=0x45000 --defsym tempy3=0x1234  -e0 -shared
+#error: .*relocation R_AARCH64_MOVW_UABS_G2_NC.*can not.*shared object.*fPIC
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-269-bad.d b/ld/testsuite/ld-aarch64/emit-relocs-269-bad.d
new file mode 100644
index 0000000..9292855
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-269-bad.d
@@ -0,0 +1,3 @@
+#source: emit-relocs-269.s
+#ld: -T relocs.ld --defsym tempy=0x11000 --defsym tempy2=0x45000 --defsym tempy3=0x1234  -e0 -shared
+#error: .*relocation R_AARCH64_MOVW_UABS_G3.*can not.*shared object.*fPIC

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH][AArch64] Improve copy relocation support on four absolute relocation types
  2014-08-13 14:32 [PATCH][AArch64] Improve copy relocation support on four absolute relocation types Jiong Wang
@ 2014-08-26 14:17 ` Nicholas Clifton
  0 siblings, 0 replies; 2+ messages in thread
From: Nicholas Clifton @ 2014-08-26 14:17 UTC (permalink / raw)
  To: Jiong Wang, binutils

Hi Jiong,

>    bfd/
>      * elfnn-aarch64.c (elfNN_aarch64_check_relocs): Initialize non_got_ref
>      properly for MOVW_G0/1/2_NC and MOVW_G3. Reject them when linking
>      shared library.
>      (elfNN_aarch64_gc_sweep_hook): Add check on these relocs.
>
>    ld/testsuite/
>      * ld-aarch64/copy-relocs-so.s: New test file.
>      * ld-aarch64/copy-relocs-exe.s: Likewise.
>      * ld-aarch64/copy-relocs.d: New expectation file.
>      * ld-aarch64/emit-relocs-264-bad.d: New test file.
>      * ld-aarch64/emit-relocs-266-bad.d: Likewise.
>      * ld-aarch64/emit-relocs-268-bad.d: Likewise.
>      * ld-aarch64/emit-relocs-269-bad.d: Likewise.
>      * ld-aarch64/aarch64-elf.exp: Run new added test.

Approved - please apply.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-08-26 14:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-13 14:32 [PATCH][AArch64] Improve copy relocation support on four absolute relocation types Jiong Wang
2014-08-26 14:17 ` Nicholas Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).