From: H.J. Lu Date: Thu, 10 May 2012 03:25:17 +0000 (+0000) Subject: Check 64-bit relocation addend overflow for x32 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8cf0d2dd210b73dff4a2d63d60c49e42b86565a7;p=binutils-gdb.git 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4c49cf9b59d..ee2c264a5bd 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2012-05-09 H.J. Lu + + * elf64-x86-64.c (elf_x86_64_relocate_section): Check addend + overflow for R_X86_64_RELATIVE64. + 2012-05-08 Ben Cheng * bfd/elf.c: Preserve the original p_align and p_flags if they are diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index de7fd6f957f..8eafbf084c2 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 { diff --git a/gas/ChangeLog b/gas/ChangeLog index 2cc6360525c..3b43ecd06e8 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2012-05-09 H.J. Lu + + * config/tc-i386.c (tc_gen_reloc): Check x32 addend overflow + for BFD_RELOC_64. + 2012-05-08 Alan Modra * Makefile.am (check_DEJAGNU): Export LC_ALL=C in place of other diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index ccf54bcae54..06f9764e228 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -9173,6 +9173,17 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) if (disallow_64bit_reloc) switch (code) { + case BFD_RELOC_64: + /* Check addend overflow. */ + if ((long long) fixp->fx_offset > 0x7fffffffLL + || (long long) fixp->fx_offset < -0x80000000LL) + { + as_bad_where (fixp->fx_file, fixp->fx_line, + _("cannot represent relocation %s with addend %lld in x32 mode"), + bfd_get_reloc_code_name (code), + (long long) fixp->fx_offset); + } + break; case BFD_RELOC_X86_64_DTPOFF64: case BFD_RELOC_X86_64_TPOFF64: case BFD_RELOC_64_PCREL: diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index e9c7bc771ce..7559561993c 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2012-05-09 H.J. Lu + + * 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. + 2012-05-08 Alan Modra * lib/gas-defs.exp (run_dump_test): Don't set LC_ALL here. diff --git a/gas/testsuite/gas/i386/ilp32/ilp32.exp b/gas/testsuite/gas/i386/ilp32/ilp32.exp index de43bf25ed7..95f3a2d69d4 100644 --- a/gas/testsuite/gas/i386/ilp32/ilp32.exp +++ b/gas/testsuite/gas/i386/ilp32/ilp32.exp @@ -26,6 +26,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check] && } run_list_test "reloc64" "--defsym _bad_=1" + run_list_test "reloc64-inval" set ASFLAGS "$old_ASFLAGS" } diff --git a/gas/testsuite/gas/i386/ilp32/reloc64-inval.l b/gas/testsuite/gas/i386/ilp32/reloc64-inval.l new file mode 100644 index 00000000000..13282371d46 --- /dev/null +++ b/gas/testsuite/gas/i386/ilp32/reloc64-inval.l @@ -0,0 +1,3 @@ +.*: Assembler messages: +.*:2: Error: .* +.*:3: Error: .* diff --git a/gas/testsuite/gas/i386/ilp32/reloc64-inval.s b/gas/testsuite/gas/i386/ilp32/reloc64-inval.s new file mode 100644 index 00000000000..14134aaf5dd --- /dev/null +++ b/gas/testsuite/gas/i386/ilp32/reloc64-inval.s @@ -0,0 +1,3 @@ + .data + .quad xtrn + 0x80000000 + .quad xtrn - 0x80000001 diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.d b/gas/testsuite/gas/i386/ilp32/reloc64.d index 08c15e41857..140f24d781b 100644 --- a/gas/testsuite/gas/i386/ilp32/reloc64.d +++ b/gas/testsuite/gas/i386/ilp32/reloc64.d @@ -90,3 +90,6 @@ Disassembly of section \.data: .*[ ]+R_X86_64_PC16[ ]+xtrn .*[ ]+R_X86_64_8[ ]+xtrn .*[ ]+R_X86_64_PC8[ ]+xtrn +.*[ ]+R_X86_64_64[ ]+xtrn +.*[ ]+R_X86_64_64[ ]+xtrn\+0x7fffffff +.*[ ]+R_X86_64_64[ ]+xtrn\+0x80000000 diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.s b/gas/testsuite/gas/i386/ilp32/reloc64.s index 3f18d04b025..3a2dbb87495 100644 --- a/gas/testsuite/gas/i386/ilp32/reloc64.s +++ b/gas/testsuite/gas/i386/ilp32/reloc64.s @@ -178,3 +178,8 @@ bad .byte xtrn@tpoff .text mov xtrn@tpoff (%rbx), %eax + + .data + .quad xtrn + .quad xtrn + 0x7fffffff + .quad xtrn - 0x80000000 diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index ae46fd0c5da..34e8d62aacd 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2012-05-09 H.J. Lu + + * ld-x86-64/ilp32-11.d: New file. + * ld-x86-64/ilp32-11.s: Likewise. + + * ld-x86-64/x86-64.exp: Run ilp32-11. + 2012-05-05 H.J. Lu PR ld/14052 diff --git a/ld/testsuite/ld-x86-64/ilp32-11.d b/ld/testsuite/ld-x86-64/ilp32-11.d new file mode 100644 index 00000000000..7240c5805e4 --- /dev/null +++ b/ld/testsuite/ld-x86-64/ilp32-11.d @@ -0,0 +1,3 @@ +#as: --x32 +#ld: -shared -melf32_x86_64 +#error: .*addend 2147483647 in relocation R_X86_64_64 against symbol `.text' at 0x0 in section `.data.rel.local' is out of range diff --git a/ld/testsuite/ld-x86-64/ilp32-11.s b/ld/testsuite/ld-x86-64/ilp32-11.s new file mode 100644 index 00000000000..2c853850f86 --- /dev/null +++ b/ld/testsuite/ld-x86-64/ilp32-11.s @@ -0,0 +1,9 @@ + .section .data.rel.local,"aw",@progbits + .align 8 +.Ljmp: + .quad func + 0x7fffffff + + .text + .type func, @function +func: + ret diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 27174d50946..e8afbc291f4 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -253,6 +253,7 @@ run_dump_test "ilp32-7" run_dump_test "ilp32-8" run_dump_test "ilp32-9" run_dump_test "ilp32-10" +run_dump_test "ilp32-11" run_dump_test "ia32-1" run_dump_test "ia32-2" run_dump_test "ia32-3"