This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[Commit]: AArch64: Refuse to link when unresolveable relocs are encountered
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sourceware dot org
- Date: Thu, 12 Oct 2017 13:36:38 +0100
- Subject: [Commit]: AArch64: Refuse to link when unresolveable relocs are encountered
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=nickc at redhat dot com
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com AA9B572AE1
Hi Guys,
I am checking in the patch below to fix a problem recently encountered
with the AArch64 linker. It would report unresolvable relocs but
then continue to produce a (non-working) binary with no error code.
The problem turns out to be the AArch64 final_link_relocate function,
which was reporting the error but then returning a value of FALSE.
Since the final_link_relocate functions return a bfd_reloc_status_type
and a value of 0 corresponds to bfd_reloc_ok, the generic parts of the
linker assumed that everything was OK.
As well as fixing this issue in the AArch64 backend I have also taken
the liberty of changing the starting value of the bfd_reloc_status
enum so that TRUE and FALSE are no longer valid members of this enum.
I could not find a way to have the compiler automatically detect and
report when these unsupported values were used, but maybe that will
come in the future.
Cheers
Nick
bfd/ChangeLog
2017-10-12 Nick Clifton <nickc@redhat.com>
* reloc.c (enum bfd_reloc_status): Start values at 2.
* bfd-in2.h: Regenerate.
* elfnn-arch64.c (aarch64_relocate): Invert sense of function, so
that a TRUE return indicates success. Compare the result of
calling _bfd_aarch64_elf_put_addend against bfd_reloc_ok.
(build_one_stub): Change sense of tests against aarch64_relocate
return value.
(elfNN_aarch64_tls_relax): Return bfd_reloc_notsupported, rather
than FALSE, when an error is detected.
(elfNN_aarch64_final_link_relocate): Likewise.
ld/Changelog
2017-10-12 Nick Clifton <nickc@redhat.com>
* testsuite/ld-aarch64/pcrel_pic_defined.d: Expect errors not
warnings. Expect errors about unsupported relocations.
* testsuite/ld-aarch64/pcrel_pic_undefined.d: Likewise.
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 92970561ee..5fd314dee2 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -2610,6 +2610,8 @@ elfNN_aarch64_link_hash_table_create (bfd *abfd)
return &ret->root.root;
}
+/* Perform relocation R_TYPE. Returns TRUE upon success, FALSE otherwise. */
+
static bfd_boolean
aarch64_relocate (unsigned int r_type, bfd *input_bfd, asection *input_section,
bfd_vma offset, bfd_vma value)
@@ -2625,7 +2627,7 @@ aarch64_relocate (unsigned int r_type, bfd *input_bfd, asection *input_section,
value = _bfd_aarch64_elf_resolve_relocation (r_type, place, value, 0, FALSE);
return _bfd_aarch64_elf_put_addend (input_bfd,
input_section->contents + offset, r_type,
- howto, value);
+ howto, value) == bfd_reloc_ok;
}
static enum elf_aarch64_stub_type
@@ -2965,22 +2967,22 @@ aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
switch (stub_entry->stub_type)
{
case aarch64_stub_adrp_branch:
- if (aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21), stub_bfd, stub_sec,
- stub_entry->stub_offset, sym_value))
+ if (!aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21), stub_bfd, stub_sec,
+ stub_entry->stub_offset, sym_value))
/* The stub would not have been relaxed if the offset was out
of range. */
BFD_FAIL ();
- if (aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC), stub_bfd, stub_sec,
- stub_entry->stub_offset + 4, sym_value))
+ if (!aarch64_relocate (AARCH64_R (ADD_ABS_LO12_NC), stub_bfd, stub_sec,
+ stub_entry->stub_offset + 4, sym_value))
BFD_FAIL ();
break;
case aarch64_stub_long_branch:
/* We want the value relative to the address 12 bytes back from the
value itself. */
- if (aarch64_relocate (AARCH64_R (PRELNN), stub_bfd, stub_sec,
- stub_entry->stub_offset + 16, sym_value + 12))
+ if (!aarch64_relocate (AARCH64_R (PRELNN), stub_bfd, stub_sec,
+ stub_entry->stub_offset + 16, sym_value + 12))
BFD_FAIL ();
break;
@@ -3001,8 +3003,8 @@ aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
break;
case aarch64_stub_erratum_843419_veneer:
- if (aarch64_relocate (AARCH64_R (JUMP26), stub_bfd, stub_sec,
- stub_entry->stub_offset + 4, sym_value + 4))
+ if (!aarch64_relocate (AARCH64_R (JUMP26), stub_bfd, stub_sec,
+ stub_entry->stub_offset + 4, sym_value + 4))
BFD_FAIL ();
break;
@@ -4998,7 +5000,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
(_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"),
input_bfd, input_section, rel->r_offset, howto->name, name);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return bfd_reloc_notsupported;
}
else if (h->plt.offset == (bfd_vma) -1)
goto bad_ifunc_reloc;
@@ -5022,7 +5024,7 @@ bad_ifunc_reloc:
"symbol `%s' isn't handled by %s"), input_bfd,
howto->name, name, __FUNCTION__);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return bfd_reloc_notsupported;
case BFD_RELOC_AARCH64_NN:
if (rel->r_addend != 0)
@@ -5038,7 +5040,7 @@ bad_ifunc_reloc:
"symbol `%s' has non-zero addend: %Ld"),
input_bfd, howto->name, name, rel->r_addend);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return bfd_reloc_notsupported;
}
/* Generate dynamic relocation only when there is a
@@ -5362,7 +5364,7 @@ bad_ifunc_reloc:
input_bfd, elfNN_aarch64_howto_table[howto_index].name,
h->root.root.string);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return bfd_reloc_notsupported;
}
/* Fall through. */
@@ -8766,7 +8768,8 @@ elf_aarch64_update_plt_entry (bfd *output_bfd,
{
reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (r_type);
- _bfd_aarch64_elf_put_addend (output_bfd, plt_entry, r_type, howto, value);
+ /* FIXME: We should check the return value from this function call. */
+ (void) _bfd_aarch64_elf_put_addend (output_bfd, plt_entry, r_type, howto, value);
}
static void
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 97a17f5147..b4d8584037 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -65,8 +65,9 @@ CODE_FRAGMENT
.
.typedef enum bfd_reloc_status
.{
-. {* No errors detected. *}
-. bfd_reloc_ok,
+. {* No errors detected. Note - the value 2 is used so that it
+. will not be mistaken for the boolean TRUE or FALSE values. *}
+. bfd_reloc_ok = 2,
.
. {* The relocation was performed, but there was an overflow. *}
. bfd_reloc_overflow,
diff --git a/ld/testsuite/ld-aarch64/pcrel_pic_defined.d b/ld/testsuite/ld-aarch64/pcrel_pic_defined.d
index 743e810b96..a611e313ff 100644
--- a/ld/testsuite/ld-aarch64/pcrel_pic_defined.d
+++ b/ld/testsuite/ld-aarch64/pcrel_pic_defined.d
@@ -1,10 +1,17 @@
#name: PC-Rel relocation against defined
#source: pcrel.s
#ld: -shared -e0 -defsym global_a=0x1000 -defsym global_b=0x2000
-#warning: .*: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_ADR_PREL_PG_HI21_NC against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_ADR_PREL_LO21 against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_LD_PREL_LO19 against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_PREL16 against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_PREL32 against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_PREL64 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_ADR_PREL_PG_HI21_NC against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_ADR_PREL_LO21 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_LD_PREL_LO19 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_PREL16 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_PREL32 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_PREL64 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
diff --git a/ld/testsuite/ld-aarch64/pcrel_pic_undefined.d b/ld/testsuite/ld-aarch64/pcrel_pic_undefined.d
index f7f048d9da..b5d6372235 100644
--- a/ld/testsuite/ld-aarch64/pcrel_pic_undefined.d
+++ b/ld/testsuite/ld-aarch64/pcrel_pic_undefined.d
@@ -1,10 +1,17 @@
#name: PC-Rel relocation against undefined
#source: pcrel.s
#ld: -shared -e0 -defsym global_b=0x2000
-#warning: .*: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_ADR_PREL_PG_HI21_NC against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_ADR_PREL_LO21 against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_LD_PREL_LO19 against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_PREL16 against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_PREL32 against symbol `global_a.*bind externally.*fPIC.*
-#warning: .*: relocation R_AARCH64_PREL64 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_ADR_PREL_PG_HI21_NC against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_ADR_PREL_LO21 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_LD_PREL_LO19 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_PREL16 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_PREL32 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation
+#error: .*: relocation R_AARCH64_PREL64 against symbol `global_a.*bind externally.*fPIC.*
+#error: .*: dangerous relocation: unsupported relocation