aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfnn-aarch64.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2016-02-09 09:56:21 +0000
committerNick Clifton <nickc@redhat.com>2016-02-09 09:56:21 +0000
commit2ea53e003163338a403d5afbb2046cafb8f3abe9 (patch)
tree4239dc30b45ff76536a55578194b080124302ec1 /bfd/elfnn-aarch64.c
parent24f5f69a8a1d09c317a5f28d324fca73a8a0b930 (diff)
downloadgdb-2ea53e003163338a403d5afbb2046cafb8f3abe9.zip
gdb-2ea53e003163338a403d5afbb2046cafb8f3abe9.tar.gz
gdb-2ea53e003163338a403d5afbb2046cafb8f3abe9.tar.bz2
Add a more helpful warning message to explain why some AArch64 relocations can overflow.
bfd * elfnn-aarch64.c (elfNN_aarch64_relocate_section): Add a more helpful warning message to explain why certain AArch64 relocs might overflow. ld * testsuite/ld-aarch64/reloc-overflow-bad.d: New test. * testsuite/ld-aarch64/reloc-overflow-1.s: New source file. * testsuite/ld-aarch64/reloc-overflow-2.s: New source file. * testsuite/ld-aarch64/aarch64-elf.exp: Run the new test.
Diffstat (limited to 'bfd/elfnn-aarch64.c')
-rw-r--r--bfd/elfnn-aarch64.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 292470df..99acab4 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -6405,10 +6405,6 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
break;
}
- if (!save_addend)
- addend = 0;
-
-
/* Dynamic relocs are not propagated for SEC_DEBUGGING sections
because such sections are not SEC_ALLOC and thus ld.so will
not process them. */
@@ -6448,6 +6444,34 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
name, input_bfd, input_section, rel->r_offset);
return FALSE;
}
+ /* Overflow can occur when a variable is referenced with a type
+ that has a larger alignment than the type with which it was
+ declared. eg:
+ file1.c: extern int foo; int a (void) { return foo; }
+ file2.c: char bar, foo, baz;
+ If the variable is placed into a data section at an offset
+ that is incompatible with the larger alignment requirement
+ overflow will occur. (Strictly speaking this is not overflow
+ but rather an alignment problem, but the bfd_reloc_ error
+ enum does not have a value to cover that situation).
+
+ Try to catch this situation here and provide a more helpful
+ error message to the user. */
+ if (addend & ((1 << howto->rightshift) - 1)
+ /* FIXME: Are we testing all of the appropriate reloc
+ types here ? */
+ && (real_r_type == BFD_RELOC_AARCH64_LD_LO19_PCREL
+ || real_r_type == BFD_RELOC_AARCH64_LDST16_LO12
+ || real_r_type == BFD_RELOC_AARCH64_LDST32_LO12
+ || real_r_type == BFD_RELOC_AARCH64_LDST64_LO12
+ || real_r_type == BFD_RELOC_AARCH64_LDST128_LO12))
+ {
+ info->callbacks->warning
+ (info, _("One possible cause of this error is that the \
+symbol is being referenced in the indicated code as if it had a larger \
+alignment than was declared where it was defined."),
+ name, input_bfd, input_section, rel->r_offset);
+ }
break;
case bfd_reloc_undefined:
@@ -6482,6 +6506,9 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
break;
}
}
+
+ if (!save_addend)
+ addend = 0;
}
return TRUE;