From bc27bb0573a5e1ce1a6365fc06aeab9bd891fc3a Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 27 May 2016 20:43:05 +0100 Subject: [PATCH] MIPS/BFD: Include the addend in JALX's target alignment verification On RELA targets the addend can affect JALX target's alignment, so only verify it once the whole relocation calculation has completed. bfd/ * elfxx-mips.c (mips_elf_calculate_relocation) : Include the addend in JALX's target alignment verification. ld/ * testsuite/ld-mips-elf/unaligned-jalx-addend-0.d: New test. * testsuite/ld-mips-elf/unaligned-jalx-addend-1.d: New test. * testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-0.d: New test. * testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d: New test. * testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-0.d: New test. * testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d: New test. * testsuite/ld-mips-elf/unaligned-jalx-addend-0.s: New test source. * testsuite/ld-mips-elf/unaligned-jalx-addend-1.s: New test source. * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests. --- bfd/ChangeLog | 6 +++++ bfd/elfxx-mips.c | 14 +++++----- ld/ChangeLog | 18 +++++++++++++ ld/testsuite/ld-mips-elf/mips-elf.exp | 15 +++++++++++ ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.d | 27 +++++++++++++++++++ ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.s | 14 ++++++++++ ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.d | 29 +++++++++++++++++++++ ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.s | 22 ++++++++++++++++ .../unaligned-jalx-addend-micromips-0.d | 27 +++++++++++++++++++ .../unaligned-jalx-addend-micromips-1.d | 30 ++++++++++++++++++++++ .../ld-mips-elf/unaligned-jalx-addend-mips16-0.d | 27 +++++++++++++++++++ .../ld-mips-elf/unaligned-jalx-addend-mips16-1.d | 30 ++++++++++++++++++++++ 12 files changed, 253 insertions(+), 6 deletions(-) create mode 100644 ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.d create mode 100644 ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.s create mode 100644 ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.d create mode 100644 ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.s create mode 100644 ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-0.d create mode 100644 ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d create mode 100644 ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-0.d create mode 100644 ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5bace1e..cefe44a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,11 @@ 2016-05-27 Maciej W. Rozycki + * elfxx-mips.c (mips_elf_calculate_relocation) + : Include the addend in JALX's + target alignment verification. + +2016-05-27 Maciej W. Rozycki + * elfxx-mips.c (mips_elf_calculate_relocation): Also use the section name if `bfd_elf_string_from_elf_section' returns an empty string. diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 2fff306..c2c1290 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -5773,11 +5773,6 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, { unsigned int shift; - /* Make sure the target of JALX is word-aligned. Bit 0 must be - the correct ISA mode selector and bit 1 must be 0. */ - if (*cross_mode_jump_p && (symbol & 3) != (r_type == R_MIPS_26)) - return bfd_reloc_outofrange; - /* Shift is 2, unusually, for microMIPS JALX. */ shift = (!*cross_mode_jump_p && r_type == R_MICROMIPS_26_S1) ? 1 : 2; @@ -5787,7 +5782,14 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, value = _bfd_mips_elf_sign_extend (addend, 26 + shift); else value = addend; - value = (value + symbol) >> shift; + value += symbol; + + /* Make sure the target of JALX is word-aligned. Bit 0 must be + the correct ISA mode selector and bit 1 must be 0. */ + if (*cross_mode_jump_p && (value & 3) != (r_type == R_MIPS_26)) + return bfd_reloc_outofrange; + + value >>= shift; if (!was_local_p && h->root.root.type != bfd_link_hash_undefweak) overflowed_p = (value >> 26) != ((p + 4) >> (26 + shift)); value &= howto->dst_mask; diff --git a/ld/ChangeLog b/ld/ChangeLog index 1d683ac..6827732 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,23 @@ 2016-05-27 Maciej W. Rozycki + * testsuite/ld-mips-elf/unaligned-jalx-addend-0.d: New test. + * testsuite/ld-mips-elf/unaligned-jalx-addend-1.d: New test. + * testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-0.d: New + test. + * testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d: New + test. + * testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-0.d: New + test. + * testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d: New + test. + * testsuite/ld-mips-elf/unaligned-jalx-addend-0.s: New test + source. + * testsuite/ld-mips-elf/unaligned-jalx-addend-1.s: New test + source. + * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests. + +2016-05-27 Maciej W. Rozycki + * testsuite/ld-mips-elf/reloc-local-overflow.d: New test. * testsuite/ld-mips-elf/reloc-local-overflow.s: Source for the new test. diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp index 0c2a93b..3fa151a 100644 --- a/ld/testsuite/ld-mips-elf/mips-elf.exp +++ b/ld/testsuite/ld-mips-elf/mips-elf.exp @@ -184,6 +184,21 @@ run_dump_test "unaligned-jalx-mips16-1" [list [list ld $abi_ldflags(o32)]] run_dump_test "unaligned-jalx-micromips-0" [list [list ld $abi_ldflags(o32)]] run_dump_test "unaligned-jalx-micromips-1" [list [list ld $abi_ldflags(o32)]] +if $has_newabi { + run_dump_test "unaligned-jalx-addend-0" \ + [list [list ld $abi_ldflags(n32)]] + run_dump_test "unaligned-jalx-addend-1" \ + [list [list ld $abi_ldflags(n32)]] + run_dump_test "unaligned-jalx-addend-mips16-0" \ + [list [list ld $abi_ldflags(n32)]] + run_dump_test "unaligned-jalx-addend-mips16-1" \ + [list [list ld $abi_ldflags(n32)]] + run_dump_test "unaligned-jalx-addend-micromips-0" \ + [list [list ld $abi_ldflags(n32)]] + run_dump_test "unaligned-jalx-addend-micromips-1" \ + [list [list ld $abi_ldflags(n32)]] +} + run_dump_test "unaligned-lwpc-0" [list [list ld $abi_ldflags(o32)]] run_dump_test "unaligned-lwpc-1" [list [list ld $abi_ldflags(o32)]] run_dump_test "unaligned-ldpc-0" [list [list ld $abi_ldflags(o32)]] diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.d new file mode 100644 index 0000000..094277b --- /dev/null +++ b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.d @@ -0,0 +1,27 @@ +#name: MIPS JALX to unaligned symbol with addend 0 +#source: unaligned-jalx-addend-0.s +#source: unaligned-insn.s -mips16 +#as: -EB -n32 -march=from-abi +#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 +#objdump: -dr --prefix-addresses --show-raw-insn + +.*: +file format .*mips.* + +Disassembly of section \.text: +[0-9a-f]+ <[^>]*> 7700000d jalx 1c000034 +[0-9a-f]+ <[^>]*> 00000000 nop +[0-9a-f]+ <[^>]*> 7700000c jalx 1c000030 +[0-9a-f]+ <[^>]*> 00000000 nop +[0-9a-f]+ <[^>]*> 7700000c jalx 1c000030 +[0-9a-f]+ <[^>]*> 00000000 nop +[0-9a-f]+ <[^>]*> 7700000e jalx 1c000038 +[0-9a-f]+ <[^>]*> 00000000 nop + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.s b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.s new file mode 100644 index 0000000..417d69a --- /dev/null +++ b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.s @@ -0,0 +1,14 @@ + .text + .align 4 + .globl foo + .ent foo +foo: + jal bar0 + 4 + jal bar1 - 2 + jal bar2 - 4 + jal bar3 + 2 + .end foo + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16 diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.d new file mode 100644 index 0000000..befac09 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.d @@ -0,0 +1,29 @@ +#name: MIPS JALX to unaligned symbol with addend 1 +#source: unaligned-jalx-addend-1.s +#source: unaligned-insn.s -mips16 +#as: -EB -n32 -march=from-abi +#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 +#error: \A[^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\Z diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.s b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.s new file mode 100644 index 0000000..9e95bf9 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.s @@ -0,0 +1,22 @@ + .text + .align 4 + .globl foo + .ent foo +foo: + jal bar0 + 1 + jal bar0 + 2 + jal bar0 + 3 + jal bar1 + 1 + jal bar1 + 3 + jal bar1 + 4 + jal bar2 - 1 + jal bar2 - 2 + jal bar2 - 3 + jal bar3 - 1 + jal bar3 - 3 + jal bar3 - 4 + .end foo + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16 diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-0.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-0.d new file mode 100644 index 0000000..5a4eafc --- /dev/null +++ b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-0.d @@ -0,0 +1,27 @@ +#name: microMIPS JALX to unaligned symbol with addend 0 +#source: unaligned-jalx-addend-0.s -mmicromips +#source: unaligned-insn.s +#as: -EB -n32 -march=from-abi +#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 +#objdump: -dr --prefix-addresses --show-raw-insn + +.*: +file format .*mips.* + +Disassembly of section \.text: +[0-9a-f]+ <[^>]*> f300 000d jalx 1c000034 +[0-9a-f]+ <[^>]*> 0000 0000 nop +[0-9a-f]+ <[^>]*> f300 000c jalx 1c000030 +[0-9a-f]+ <[^>]*> 0000 0000 nop +[0-9a-f]+ <[^>]*> f300 000c jalx 1c000030 +[0-9a-f]+ <[^>]*> 0000 0000 nop +[0-9a-f]+ <[^>]*> f300 000e jalx 1c000038 +[0-9a-f]+ <[^>]*> 0000 0000 nop + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d new file mode 100644 index 0000000..038e46e --- /dev/null +++ b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d @@ -0,0 +1,30 @@ +#name: microMIPS JALX to unaligned symbol with addend 1 +#source: unaligned-jalx-addend-1.s -mmicromips +#source: unaligned-insn.s +#as: -EB -n32 -march=from-abi +#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 +#objdump: -dr --prefix-addresses --show-raw-insn +#error: \A[^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\Z diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-0.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-0.d new file mode 100644 index 0000000..3e7ac16 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-0.d @@ -0,0 +1,27 @@ +#name: MIPS16 JALX to unaligned symbol with addend 0 +#source: unaligned-jalx-addend-0.s -mips16 +#source: unaligned-insn.s +#as: -EB -n32 -march=from-abi +#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 +#objdump: -dr --prefix-addresses --show-raw-insn + +.*: +file format .*mips.* + +Disassembly of section \.text: +[0-9a-f]+ <[^>]*> 1c18 000d jalx 1c000034 +[0-9a-f]+ <[^>]*> 6500 nop +[0-9a-f]+ <[^>]*> 1c18 000c jalx 1c000030 +[0-9a-f]+ <[^>]*> 6500 nop +[0-9a-f]+ <[^>]*> 1c18 000c jalx 1c000030 +[0-9a-f]+ <[^>]*> 6500 nop +[0-9a-f]+ <[^>]*> 1c18 000e jalx 1c000038 +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. + \.\.\. diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d new file mode 100644 index 0000000..0bd81d8 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d @@ -0,0 +1,30 @@ +#name: MIPS16 JALX to unaligned symbol with addend 1 +#source: unaligned-jalx-addend-1.s -mips16 +#source: unaligned-insn.s +#as: -EB -n32 -march=from-abi +#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 +#objdump: -dr --prefix-addresses --show-raw-insn +#error: \A[^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n +#error: [^\n]*: In function `foo':\n +#error: \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\Z -- 2.7.4