This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[AArch64] Improve PC-relative relocation check for shared library
- From: Jiong Wang <jiong dot wang at arm dot com>
- To: binutils at sourceware dot org
- Date: Thu, 16 Apr 2015 10:42:30 +0100
- Subject: [AArch64] Improve PC-relative relocation check for shared library
- Authentication-results: sourceware.org; auth=none
For PC relative relocation against external symbol, both defined &
undefined, we should reject them when building shared library, as we
don't propagate them to runtime, and AArch64 dynamic linker doesn't
support any of them. This is also what x86 backend is doing.
Currently, when generating .so, for PC-relative relocation against
external undefined symbol, we are silently generating wrong
binary. while when it's external symbol defined in other .so, we will
trigger unresolved_reloc_p check, while it's better to remind user to
rebuild the code with -fPIC explicitly
OK for trunk?
thanks.
2015-04-16 Jiong. Wang <jiong.wang@arm.com>
bfd/
* elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Reject
PC-relative relocation for external symbol.
ld/testsuite/
* ld-aarch64/pcrel.s: New testcase.
* ld-aarch64/pcrel_pic_defiend_local.d: New expect file.
* ld-aarch64/pcrel_pic_undefined.d: Ditto.
* ld-aarch64/aarch64-elf.exp: Run them.
--
Regards,
Jiong
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 37de7fa..e58c07e 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -4434,16 +4434,36 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
signed_addend, weak_undef_p);
break;
+ case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
+ case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+ case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
+ case BFD_RELOC_AARCH64_LD_LO19_PCREL:
+ case BFD_RELOC_AARCH64_16_PCREL:
+ case BFD_RELOC_AARCH64_32_PCREL:
+ case BFD_RELOC_AARCH64_64_PCREL:
+ if (info->shared
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (input_section->flags & SEC_READONLY) != 0
+ && h != NULL
+ && !h->def_regular)
+ {
+ int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
+
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against external symbol `%s' can not be used"
+ " when making a shared object; recompile with -fPIC"),
+ input_bfd, elfNN_aarch64_howto_table[howto_index].name,
+ h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
case BFD_RELOC_AARCH64_16:
#if ARCH_SIZE == 64
case BFD_RELOC_AARCH64_32:
#endif
case BFD_RELOC_AARCH64_ADD_LO12:
- case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
- case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
- case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
case BFD_RELOC_AARCH64_BRANCH19:
- case BFD_RELOC_AARCH64_LD_LO19_PCREL:
case BFD_RELOC_AARCH64_LDST8_LO12:
case BFD_RELOC_AARCH64_LDST16_LO12:
case BFD_RELOC_AARCH64_LDST32_LO12:
@@ -4459,9 +4479,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
case BFD_RELOC_AARCH64_MOVW_G2:
case BFD_RELOC_AARCH64_MOVW_G2_NC:
case BFD_RELOC_AARCH64_MOVW_G3:
- case BFD_RELOC_AARCH64_16_PCREL:
- case BFD_RELOC_AARCH64_32_PCREL:
- case BFD_RELOC_AARCH64_64_PCREL:
case BFD_RELOC_AARCH64_TSTBR14:
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
signed_addend, weak_undef_p);
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 4810d60..5e354a5 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -104,6 +104,10 @@ run_dump_test "emit-relocs-local-addend"
# test addend correctness when -r specified.
run_dump_test "local-addend-r"
+# test error handling on pcrel relocation for shared libraries.
+run_dump_test "pcrel_pic_undefined"
+run_dump_test "pcrel_pic_defined_local"
+
run_dump_test "limit-b"
run_dump_test "limit-bl"
run_dump_test "farcall-section"
diff --git a/ld/testsuite/ld-aarch64/pcrel.s b/ld/testsuite/ld-aarch64/pcrel.s
new file mode 100644
index 0000000..df542ef
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/pcrel.s
@@ -0,0 +1,20 @@
+ .text
+ .align 2
+main:
+ # R_AARCH64_ADR_PREL_PG_HI21
+ # R_AARCH64_ADR_PREL_PG_HI21_NC
+ # R_AARCH64_ADR_LO_21
+ adrp x0, :pg_hi21:global_a
+ adrp x1, :pg_hi21_nc:global_a
+ adr x2, global_a
+
+ #R_AARCH64_LD_PREL_LO19
+ ldr x3, global_a
+
+ # R_AARCH64_PREL16
+ # R_AARCH64_PREL32
+ # R_AARCH64_PREL64
+ .hword global_a - .
+ .word global_a - .
+ .xword global_a - .
+
diff --git a/ld/testsuite/ld-aarch64/pcrel_pic_defined_local.d b/ld/testsuite/ld-aarch64/pcrel_pic_defined_local.d
new file mode 100644
index 0000000..832652f
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/pcrel_pic_defined_local.d
@@ -0,0 +1,5 @@
+#name: PC-Rel relocation against defined
+#source: pcrel.s
+#objdump: -r
+#ld: -shared -e0 -defsym global_a=0x1000
+#...
diff --git a/ld/testsuite/ld-aarch64/pcrel_pic_undefined.d b/ld/testsuite/ld-aarch64/pcrel_pic_undefined.d
new file mode 100644
index 0000000..de7f020
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/pcrel_pic_undefined.d
@@ -0,0 +1,10 @@
+#name: PC-Rel relocation against undefined
+#source: pcrel.s
+#ld: -shared -e0
+#warning: .*: relocation R_AARCH64_ADR_PREL_PG_HI21 against external symbol.*fPIC.*
+#warning: .*: relocation R_AARCH64_ADR_PREL_PG_HI21_NC against external symbol.*fPIC.*
+#warning: .*: relocation R_AARCH64_ADR_PREL_LO21 against external symbol.*fPIC.*
+#warning: .*: relocation R_AARCH64_LD_PREL_LO19 against external symbol.*fPIC.*
+#warning: .*: relocation R_AARCH64_PREL16 against external symbol.*fPIC.*
+#warning: .*: relocation R_AARCH64_PREL32 against external symbol.*fPIC.*
+#warning: .*: relocation R_AARCH64_PREL64 against external symbol.*fPIC.*