aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-x86-64.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-05-10 03:25:17 +0000
committerH.J. Lu <hjl.tools@gmail.com>2012-05-10 03:25:17 +0000
commit8cf0d2dd210b73dff4a2d63d60c49e42b86565a7 (patch)
treec73a06cc9dcf7ab583730ab2273ced526febf4cd /bfd/elf64-x86-64.c
parent968bf8f19d1668f5ad2b6cd6c7c251e72ed09756 (diff)
downloadgdb-8cf0d2dd210b73dff4a2d63d60c49e42b86565a7.zip
gdb-8cf0d2dd210b73dff4a2d63d60c49e42b86565a7.tar.gz
gdb-8cf0d2dd210b73dff4a2d63d60c49e42b86565a7.tar.bz2
Check 64-bit relocation addend overflow for x32
bfd/ * elf64-x86-64.c (elf_x86_64_relocate_section): Check addend overflow for R_X86_64_RELATIVE64. gas/ * config/tc-i386.c (tc_gen_reloc): Check x32 addend overflow for BFD_RELOC_64. gas/testsuite/ * gas/i386/ilp32/ilp32.exp: Run reloc64-inval. * gas/i386/ilp32/reloc64.s: Add tests for ".quad". * gas/i386/ilp32/reloc64.d: Updated. * gas/i386/ilp32/reloc64-inval.l: New file. * gas/i386/ilp32/reloc64-inval.s: Likewise. ld/testsuite/ * ld-x86-64/ilp32-11.d: New file. * ld-x86-64/ilp32-11.s: Likewise. * ld-x86-64/x86-64.exp: Run ilp32-11.
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r--bfd/elf64-x86-64.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index de7fd6f..8eafbf0 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -3681,6 +3681,27 @@ elf_x86_64_relocate_section (bfd *output_bfd,
outrel.r_info = htab->r_info (0,
R_X86_64_RELATIVE64);
outrel.r_addend = relocation + rel->r_addend;
+ /* Check addend overflow. */
+ if ((outrel.r_addend & 0x80000000)
+ != (rel->r_addend & 0x80000000))
+ {
+ const char *name;
+ if (h && h->root.root.string)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr,
+ sym, NULL);
+ (*_bfd_error_handler)
+ (_("%B: addend %ld in relocation %s against "
+ "symbol `%s' at 0x%lx in section `%A' is "
+ "out of range"),
+ input_bfd, input_section,
+ (long) rel->r_addend,
+ x86_64_elf_howto_table[r_type].name,
+ name, (unsigned long) rel->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
}
else
{