This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PR20402][LD][AARCH64]Don't emit RELATIVE relocation for absolute symbols which are resolved at static linking time.
- From: Renlin Li <renlin dot li at foss dot arm dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>, Nicholas Clifton <nickc at redhat dot com>, Ramana Radhakrishnan <Ramana dot Radhakrishnan at arm dot com>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>, ard dot biesheuvel at linaro dot org
- Date: Tue, 6 Feb 2018 13:16:52 +0000
- Subject: [PR20402][LD][AARCH64]Don't emit RELATIVE relocation for absolute symbols which are resolved at static linking time.
- Authentication-results: sourceware.org; auth=none
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.
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