[PR20402,LD,AARCH64] Don't emit RELATIVE relocation for absolute symbols which are resolved at static linking time.

Message ID 84986e33-3d6f-3ca4-25c4-684e57cd6ff4@foss.arm.com
State New
Headers show
Series
  • [PR20402,LD,AARCH64] Don't emit RELATIVE relocation for absolute symbols which are resolved at static linking time.
Related show

Commit Message

Renlin Li Feb. 6, 2018, 1:16 p.m.
Hi all,

For absolute symbols which are forced local or not dynamic, the ABS relocation
should be resolved at static linking time.

Originally, an RELATIVE/ABS relocation will be generated even for absolution symbols
for the dynamic linker to resolve.

For the testcase with the patch, before the change, two R_AARCH64_RELATIV relocations
will be generated.

The relocation will be changed into R_AARCH64_NONE.  It is not possible to
remove the relocations totally.
At the time of allocating dynamic relocs space, the symbol information is not
finalized. It is not safe to not allocating space for the relocation with the
information available at that time.

For example, symbol agasint '.' will be initially defined in ABS section, but
later updated as section relative symbol. A relocation is needed for this case.

For _GLOBAL_OFFSET_TABLE_ and _DYNAMIC symbols, they are initially created as section relative
and forced local. So for those two symbol, a RELATIVE relocation will be generated.
They are later marked as absolute. This behavior is not changed with the patch here.

aarch64 binutils cross/native regression test Okay. Linux kernel link Okay.
Okay to commit?

Regards,
Renlin

bfd/ChangeLog:

2018-02-06  Renlin Li  <renlin.li@arm.com>

         PR ld/20402
	* elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Check absolute symbol,
         and don't emit relocation in specific case.

ld/ChangeLog:

2018-02-06  Renlin Li  <renlin.li@arm.com>

         PR ld/20402
	* testsuite/ld-aarch64/aarch64-elf.exp: Run new test.
	* testsuite/ld-aarch64/pr20402.s: New.
	* testsuite/ld-aarch64/pr20402.d: New.

Comments

Nick Clifton Feb. 9, 2018, 9:35 a.m. | #1
Hi Renlin,

> bfd/ChangeLog:

> 

> 2018-02-06  Renlin Li  <renlin.li@arm.com>

> 

>         PR ld/20402

>     * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Check absolute symbol,

>         and don't emit relocation in specific case.

> 

> ld/ChangeLog:

> 

> 2018-02-06  Renlin Li  <renlin.li@arm.com>

> 

>         PR ld/20402

>     * testsuite/ld-aarch64/aarch64-elf.exp: Run new test.

>     * testsuite/ld-aarch64/pr20402.s: New.

>     * testsuite/ld-aarch64/pr20402.d: New.


Approved - please apply.

Cheers
  Nick

Patch

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 973188220ba17bbb88eb19f850f2a482a56050cb..b6540201c3569cdff1cc5d60f6aacfd65040fd47 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -4954,6 +4954,7 @@  elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
   asection *base_got;
   bfd_vma orig_value = value;
   bfd_boolean resolved_to_zero;
+  bfd_boolean abs_symbol_p;
 
   globals = elf_aarch64_hash_table (info);
 
@@ -4973,6 +4974,9 @@  elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 
   weak_undef_p = (h ? h->root.type == bfd_link_hash_undefweak
 		  : bfd_is_und_section (sym_sec));
+  abs_symbol_p = (h !=NULL && h->root.type == bfd_link_hash_defined
+		  && bfd_is_abs_section (h->root.u.def.section));
+
 
   /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
      it here if it is defined in a non-shared object.  */
@@ -5238,6 +5242,12 @@  bad_ifunc_reloc:
 	      skip = TRUE;
 	      relocate = TRUE;
 	    }
+	  else if (abs_symbol_p)
+	    {
+	      /* Local absolute symbol.  */
+	      skip = (h->forced_local || (h->dynindx == -1));
+	      relocate = skip;
+	    }
 
 	  outrel.r_offset += (input_section->output_section->vma
 			      + input_section->output_offset);
@@ -5249,7 +5259,8 @@  bad_ifunc_reloc:
 		   && (!bfd_link_pic (info)
 		       || !(bfd_link_pie (info)
 			    || SYMBOLIC_BIND (info, h))
-		       || !h->def_regular))
+		       || !h->def_regular
+		       || abs_symbol_p))
 	    outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
 	  else
 	    {
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index d766f3736bc53467b560d8194a2eda154801df95..8fbb31a88976a2186c7533a0eb99aaec65c89616 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -276,6 +276,7 @@  run_dump_test_lp64 "tprel_g2_overflow"
 run_dump_test "tprel_add_lo12_overflow"
 run_dump_test "protected-data"
 run_dump_test_lp64 "pr22764"
+run_dump_test_lp64 "pr20402"
 
 # ifunc tests
 run_dump_test "ifunc-1"
diff --git a/ld/testsuite/ld-aarch64/pr20402.d b/ld/testsuite/ld-aarch64/pr20402.d
new file mode 100644
index 0000000000000000000000000000000000000000..9cfeeb76dd3a8ed475a845d6fdf9d0c452610a58
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/pr20402.d
@@ -0,0 +1,7 @@ 
+#ld: -pie -defsym foo=0x1 -defsym bar=0x2
+#readelf: -r
+
+Relocation section '\.rela\.dyn' at offset .* contains 2 entries:
+  Offset          Info           Type           Sym\. Value    Sym\. Name \+ Addend
+000000000000  000000000000 R_AARCH64_NONE                       0
+000000000000  000000000000 R_AARCH64_NONE                       0
diff --git a/ld/testsuite/ld-aarch64/pr20402.s b/ld/testsuite/ld-aarch64/pr20402.s
new file mode 100644
index 0000000000000000000000000000000000000000..b18c5e700ec0da74f205d7515d66dcc34b7f8053
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/pr20402.s
@@ -0,0 +1,6 @@ 
+  .text
+  .global _start
+  .hidden foo
+_start:
+  .xword foo
+  .xword bar