From 17c6c3b99156fe82c1e637e1a5fd9f163ac788c8 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 7 May 2021 12:05:12 +0200 Subject: [PATCH] x86-64/ELF: clear src_mask for all reloc types x86-64 uses rela relocations. The comment next to the field's declaration says "Non-zero values for ELF USE_RELA targets should be viewed with suspicion ..." And indeed the fields being non-zero causes section contents to be accumulated into the final relocated values in addition to the relocations' addends, which is contrary to the ELF spec. --- bfd/ChangeLog | 5 ++ bfd/elf64-x86-64.c | 132 +++++++++++++++--------------- gas/ChangeLog | 5 ++ gas/testsuite/gas/i386/i386.exp | 1 + gas/testsuite/gas/i386/rela.d | 13 +++ gas/testsuite/gas/i386/rela.s | 14 ++++ ld/ChangeLog | 5 ++ ld/testsuite/ld-x86-64/rela.d | 10 +++ ld/testsuite/ld-x86-64/x86-64.exp | 1 + 9 files changed, 119 insertions(+), 67 deletions(-) create mode 100644 gas/testsuite/gas/i386/rela.d create mode 100644 gas/testsuite/gas/i386/rela.s create mode 100644 ld/testsuite/ld-x86-64/rela.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 0b1e3d4c51d..dd517a9d810 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2021-05-07 Jan Beulich + + * elf64-x86-64.c (x86_64_elf_howto_table): Set src_mask fields + to zero. + 2021-05-07 Alan Modra * bfd-in2.h: Regenerate. diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 83a749e6ddc..d0c994e570a 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -45,133 +45,131 @@ static reloc_howto_type x86_64_elf_howto_table[] = { HOWTO(R_X86_64_NONE, 0, 3, 0, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_NONE", false, 0x00000000, 0x00000000, + bfd_elf_generic_reloc, "R_X86_64_NONE", false, 0, 0x00000000, false), HOWTO(R_X86_64_64, 0, 4, 64, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_64", false, MINUS_ONE, MINUS_ONE, + bfd_elf_generic_reloc, "R_X86_64_64", false, 0, MINUS_ONE, false), HOWTO(R_X86_64_PC32, 0, 2, 32, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_PC32", false, 0xffffffff, 0xffffffff, + bfd_elf_generic_reloc, "R_X86_64_PC32", false, 0, 0xffffffff, true), HOWTO(R_X86_64_GOT32, 0, 2, 32, false, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOT32", false, 0xffffffff, 0xffffffff, + bfd_elf_generic_reloc, "R_X86_64_GOT32", false, 0, 0xffffffff, false), HOWTO(R_X86_64_PLT32, 0, 2, 32, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_PLT32", false, 0xffffffff, 0xffffffff, + bfd_elf_generic_reloc, "R_X86_64_PLT32", false, 0, 0xffffffff, true), HOWTO(R_X86_64_COPY, 0, 2, 32, false, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_COPY", false, 0xffffffff, 0xffffffff, + bfd_elf_generic_reloc, "R_X86_64_COPY", false, 0, 0xffffffff, false), HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", false, MINUS_ONE, - MINUS_ONE, false), + bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", false, 0, MINUS_ONE, + false), HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", false, MINUS_ONE, - MINUS_ONE, false), + bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", false, 0, MINUS_ONE, + false), HOWTO(R_X86_64_RELATIVE, 0, 4, 64, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_RELATIVE", false, MINUS_ONE, - MINUS_ONE, false), + bfd_elf_generic_reloc, "R_X86_64_RELATIVE", false, 0, MINUS_ONE, + false), HOWTO(R_X86_64_GOTPCREL, 0, 2, 32, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", false, 0xffffffff, - 0xffffffff, true), + bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", false, 0, 0xffffffff, + true), HOWTO(R_X86_64_32, 0, 2, 32, false, 0, complain_overflow_unsigned, - bfd_elf_generic_reloc, "R_X86_64_32", false, 0xffffffff, 0xffffffff, + bfd_elf_generic_reloc, "R_X86_64_32", false, 0, 0xffffffff, false), HOWTO(R_X86_64_32S, 0, 2, 32, false, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_32S", false, 0xffffffff, 0xffffffff, + bfd_elf_generic_reloc, "R_X86_64_32S", false, 0, 0xffffffff, false), HOWTO(R_X86_64_16, 0, 1, 16, false, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_16", false, 0xffff, 0xffff, false), + bfd_elf_generic_reloc, "R_X86_64_16", false, 0, 0xffff, false), HOWTO(R_X86_64_PC16, 0, 1, 16, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_PC16", false, 0xffff, 0xffff, true), + bfd_elf_generic_reloc, "R_X86_64_PC16", false, 0, 0xffff, true), HOWTO(R_X86_64_8, 0, 0, 8, false, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_8", false, 0xff, 0xff, false), + bfd_elf_generic_reloc, "R_X86_64_8", false, 0, 0xff, false), HOWTO(R_X86_64_PC8, 0, 0, 8, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_PC8", false, 0xff, 0xff, true), + bfd_elf_generic_reloc, "R_X86_64_PC8", false, 0, 0xff, true), HOWTO(R_X86_64_DTPMOD64, 0, 4, 64, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_DTPMOD64", false, MINUS_ONE, - MINUS_ONE, false), + bfd_elf_generic_reloc, "R_X86_64_DTPMOD64", false, 0, MINUS_ONE, + false), HOWTO(R_X86_64_DTPOFF64, 0, 4, 64, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_DTPOFF64", false, MINUS_ONE, - MINUS_ONE, false), + bfd_elf_generic_reloc, "R_X86_64_DTPOFF64", false, 0, MINUS_ONE, + false), HOWTO(R_X86_64_TPOFF64, 0, 4, 64, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_TPOFF64", false, MINUS_ONE, - MINUS_ONE, false), + bfd_elf_generic_reloc, "R_X86_64_TPOFF64", false, 0, MINUS_ONE, + false), HOWTO(R_X86_64_TLSGD, 0, 2, 32, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_TLSGD", false, 0xffffffff, - 0xffffffff, true), + bfd_elf_generic_reloc, "R_X86_64_TLSGD", false, 0, 0xffffffff, + true), HOWTO(R_X86_64_TLSLD, 0, 2, 32, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_TLSLD", false, 0xffffffff, - 0xffffffff, true), + bfd_elf_generic_reloc, "R_X86_64_TLSLD", false, 0, 0xffffffff, + true), HOWTO(R_X86_64_DTPOFF32, 0, 2, 32, false, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_DTPOFF32", false, 0xffffffff, - 0xffffffff, false), + bfd_elf_generic_reloc, "R_X86_64_DTPOFF32", false, 0, 0xffffffff, + false), HOWTO(R_X86_64_GOTTPOFF, 0, 2, 32, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTTPOFF", false, 0xffffffff, - 0xffffffff, true), + bfd_elf_generic_reloc, "R_X86_64_GOTTPOFF", false, 0, 0xffffffff, + true), HOWTO(R_X86_64_TPOFF32, 0, 2, 32, false, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_TPOFF32", false, 0xffffffff, - 0xffffffff, false), + bfd_elf_generic_reloc, "R_X86_64_TPOFF32", false, 0, 0xffffffff, + false), HOWTO(R_X86_64_PC64, 0, 4, 64, true, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_PC64", false, MINUS_ONE, MINUS_ONE, + bfd_elf_generic_reloc, "R_X86_64_PC64", false, 0, MINUS_ONE, true), HOWTO(R_X86_64_GOTOFF64, 0, 4, 64, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_GOTOFF64", - false, MINUS_ONE, MINUS_ONE, false), + bfd_elf_generic_reloc, "R_X86_64_GOTOFF64", false, 0, MINUS_ONE, + false), HOWTO(R_X86_64_GOTPC32, 0, 2, 32, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTPC32", - false, 0xffffffff, 0xffffffff, true), + bfd_elf_generic_reloc, "R_X86_64_GOTPC32", false, 0, 0xffffffff, + true), HOWTO(R_X86_64_GOT64, 0, 4, 64, false, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOT64", false, MINUS_ONE, MINUS_ONE, + bfd_elf_generic_reloc, "R_X86_64_GOT64", false, 0, MINUS_ONE, false), HOWTO(R_X86_64_GOTPCREL64, 0, 4, 64, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTPCREL64", false, MINUS_ONE, - MINUS_ONE, true), + bfd_elf_generic_reloc, "R_X86_64_GOTPCREL64", false, 0, MINUS_ONE, + true), HOWTO(R_X86_64_GOTPC64, 0, 4, 64, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTPC64", - false, MINUS_ONE, MINUS_ONE, true), + bfd_elf_generic_reloc, "R_X86_64_GOTPC64", false, 0, MINUS_ONE, + true), HOWTO(R_X86_64_GOTPLT64, 0, 4, 64, false, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTPLT64", false, MINUS_ONE, - MINUS_ONE, false), + bfd_elf_generic_reloc, "R_X86_64_GOTPLT64", false, 0, MINUS_ONE, + false), HOWTO(R_X86_64_PLTOFF64, 0, 4, 64, false, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_PLTOFF64", false, MINUS_ONE, - MINUS_ONE, false), + bfd_elf_generic_reloc, "R_X86_64_PLTOFF64", false, 0, MINUS_ONE, + false), HOWTO(R_X86_64_SIZE32, 0, 2, 32, false, 0, complain_overflow_unsigned, - bfd_elf_generic_reloc, "R_X86_64_SIZE32", false, 0xffffffff, 0xffffffff, + bfd_elf_generic_reloc, "R_X86_64_SIZE32", false, 0, 0xffffffff, false), HOWTO(R_X86_64_SIZE64, 0, 4, 64, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_SIZE64", false, MINUS_ONE, MINUS_ONE, + bfd_elf_generic_reloc, "R_X86_64_SIZE64", false, 0, MINUS_ONE, false), HOWTO(R_X86_64_GOTPC32_TLSDESC, 0, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, - "R_X86_64_GOTPC32_TLSDESC", - false, 0xffffffff, 0xffffffff, true), + "R_X86_64_GOTPC32_TLSDESC", false, 0, 0xffffffff, true), HOWTO(R_X86_64_TLSDESC_CALL, 0, 3, 0, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_X86_64_TLSDESC_CALL", false, 0, 0, false), HOWTO(R_X86_64_TLSDESC, 0, 4, 64, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, - "R_X86_64_TLSDESC", - false, MINUS_ONE, MINUS_ONE, false), + "R_X86_64_TLSDESC", false, 0, MINUS_ONE, false), HOWTO(R_X86_64_IRELATIVE, 0, 4, 64, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", false, MINUS_ONE, - MINUS_ONE, false), + bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", false, 0, MINUS_ONE, + false), HOWTO(R_X86_64_RELATIVE64, 0, 4, 64, false, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_RELATIVE64", false, MINUS_ONE, - MINUS_ONE, false), + bfd_elf_generic_reloc, "R_X86_64_RELATIVE64", false, 0, MINUS_ONE, + false), HOWTO(R_X86_64_PC32_BND, 0, 2, 32, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_PC32_BND", false, 0xffffffff, 0xffffffff, + bfd_elf_generic_reloc, "R_X86_64_PC32_BND", false, 0, 0xffffffff, true), HOWTO(R_X86_64_PLT32_BND, 0, 2, 32, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_PLT32_BND", false, 0xffffffff, 0xffffffff, + bfd_elf_generic_reloc, "R_X86_64_PLT32_BND", false, 0, 0xffffffff, true), HOWTO(R_X86_64_GOTPCRELX, 0, 2, 32, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTPCRELX", false, 0xffffffff, - 0xffffffff, true), + bfd_elf_generic_reloc, "R_X86_64_GOTPCRELX", false, 0, 0xffffffff, + true), HOWTO(R_X86_64_REX_GOTPCRELX, 0, 2, 32, true, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_REX_GOTPCRELX", false, 0xffffffff, - 0xffffffff, true), + bfd_elf_generic_reloc, "R_X86_64_REX_GOTPCRELX", false, 0, 0xffffffff, + true), /* We have a gap in the reloc numbers here. R_X86_64_standard counts the number up to this point, and @@ -191,7 +189,7 @@ static reloc_howto_type x86_64_elf_howto_table[] = /* Use complain_overflow_bitfield on R_X86_64_32 for x32. */ HOWTO(R_X86_64_32, 0, 2, 32, false, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_32", false, 0xffffffff, 0xffffffff, + bfd_elf_generic_reloc, "R_X86_64_32", false, 0, 0xffffffff, false) }; diff --git a/gas/ChangeLog b/gas/ChangeLog index b3a2cfc9650..b04a764f2a8 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2021-05-07 Jan Beulich + + * testsuite/gas/i386/rela.s, testsuite/gas/i386/rela.d: New. + * testsuite/gas/i386/i386.exp: Run new test. + 2021-05-07 Jan Beulich * config/tc-i386.c (output_disp): Use disps field instead of diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 234438e5d85..39010bdd500 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -1246,6 +1246,7 @@ if [gas_64_check] then { run_dump_test "reloc64" run_list_test "reloc64" "--defsym _bad_=1" run_dump_test "mixed-mode-reloc64" + run_dump_test "rela" run_dump_test "x86-64-ifunc" run_dump_test "x86-64-opcode-inval" run_dump_test "x86-64-opcode-inval-intel" diff --git a/gas/testsuite/gas/i386/rela.d b/gas/testsuite/gas/i386/rela.d new file mode 100644 index 00000000000..198f71238c9 --- /dev/null +++ b/gas/testsuite/gas/i386/rela.d @@ -0,0 +1,13 @@ +#name: x86-64 rela relocs w/ non-zero relocated fields +#objdump: -rsj .data + +.*: +file format .* + +RELOCATION RECORDS FOR \[\.data\]: + +OFFSET +TYPE +VALUE * +0*0 R_X86_64_64 *q +0*8 R_X86_64_32 *l + +Contents of section .data: + 0+0 11 ?11 ?11 ?11 22 ?22 ?22 ?22 33 ?33 ?33 ?33 44 ?44 ?44 ?44 .* diff --git a/gas/testsuite/gas/i386/rela.s b/gas/testsuite/gas/i386/rela.s new file mode 100644 index 00000000000..28269fe3683 --- /dev/null +++ b/gas/testsuite/gas/i386/rela.s @@ -0,0 +1,14 @@ +# Note: This file is also used by an ld test case. + + .text + .global _start +_start: + ret + + .data + .p2align 4 +l: .long 0x11111111, 0x22222222 +q: .quad 0x4444444433333333 + + .reloc l, BFD_RELOC_64, q + .reloc q, BFD_RELOC_32, l diff --git a/ld/ChangeLog b/ld/ChangeLog index 998c403382e..d78c706da74 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2021-05-07 Jan Beulich + + * testsuite/ld-x86-64/rela.d: New. + * testsuite/ld-x86-64/x86-64.exp: Run new test. + 2021-05-07 Nick Clifton * ldelfgen.c (compare_link_order): Ignore section size when diff --git a/ld/testsuite/ld-x86-64/rela.d b/ld/testsuite/ld-x86-64/rela.d new file mode 100644 index 00000000000..ac91834e4c4 --- /dev/null +++ b/ld/testsuite/ld-x86-64/rela.d @@ -0,0 +1,10 @@ +#name: x86-64 rela relocs w/ non-zero relocated fields +#as: --64 +#source: ${srcdir}/../../../gas/testsuite/gas/i386/rela.s +#ld: -melf_x86_64 +#objdump: -sj .data + +.*: +file format .* + +Contents of section .data: + *[0-9a-f]*0 08 ?.. ?.. ?.. 00 ?00 ?00 ?00 00 ?.. ?.. ?.. 44 ?44 ?44 ?44 .* diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 269f70d05b2..17fd10ee121 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -262,6 +262,7 @@ run_dump_test "apic" run_dump_test "pcrel8" run_dump_test "pcrel16" run_dump_test "pcrel16-2" +run_dump_test "rela" run_dump_test "tlsgd2" run_dump_test "tlsgd3" run_dump_test "tlsgd12" -- 2.30.2