diff options
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elf32-xtensa.c | 26 | ||||
-rw-r--r-- | ld/ChangeLog | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/relax-diff1.d | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/relax-diff1.s | 18 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/relax-ndiff.d | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/relax-ndiff.s | 20 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/xtensa.exp | 2 |
8 files changed, 83 insertions, 11 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 31e8526..25453b3 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2020-04-29 Max Filippov <jcmvbkbc@gmail.com> + + * elf32-xtensa.c (relax_section): Don't negate diff_value for + XTENSA_NDIFF relocations. Don't add sign bits whe diff_value + equals 0. Report overflow when the result has negative sign but + all significant bits are zero. + 2020-04-29 Gunther Nikl <gnikl@justmail.de> * aoutx.h (swap_std_reloc_out): Special case 64 bit relocations. diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index fded42d..4327b02 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -9670,37 +9670,44 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) switch (r_type) { case R_XTENSA_DIFF8: + diff_mask = 0x7f; diff_value = bfd_get_signed_8 (abfd, &contents[old_source_offset]); break; case R_XTENSA_DIFF16: + diff_mask = 0x7fff; diff_value = bfd_get_signed_16 (abfd, &contents[old_source_offset]); break; case R_XTENSA_DIFF32: + diff_mask = 0x7fffffff; diff_value = bfd_get_signed_32 (abfd, &contents[old_source_offset]); break; case R_XTENSA_PDIFF8: case R_XTENSA_NDIFF8: + diff_mask = 0xff; diff_value = bfd_get_8 (abfd, &contents[old_source_offset]); break; case R_XTENSA_PDIFF16: case R_XTENSA_NDIFF16: + diff_mask = 0xffff; diff_value = bfd_get_16 (abfd, &contents[old_source_offset]); break; case R_XTENSA_PDIFF32: case R_XTENSA_NDIFF32: + diff_mask = 0xffffffff; diff_value = bfd_get_32 (abfd, &contents[old_source_offset]); break; } if (r_type >= R_XTENSA_NDIFF8 - && r_type <= R_XTENSA_NDIFF32) - diff_value = -diff_value; + && r_type <= R_XTENSA_NDIFF32 + && diff_value) + diff_value |= ~diff_mask; new_end_offset = offset_with_removed_text_map (&target_relax_info->action_list, @@ -9710,43 +9717,40 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) switch (r_type) { case R_XTENSA_DIFF8: - diff_mask = 0x7f; bfd_put_signed_8 (abfd, diff_value, &contents[old_source_offset]); break; case R_XTENSA_DIFF16: - diff_mask = 0x7fff; bfd_put_signed_16 (abfd, diff_value, &contents[old_source_offset]); break; case R_XTENSA_DIFF32: - diff_mask = 0x7fffffff; bfd_put_signed_32 (abfd, diff_value, &contents[old_source_offset]); break; case R_XTENSA_PDIFF8: case R_XTENSA_NDIFF8: - diff_mask = 0xff; bfd_put_8 (abfd, diff_value, &contents[old_source_offset]); break; case R_XTENSA_PDIFF16: case R_XTENSA_NDIFF16: - diff_mask = 0xffff; bfd_put_16 (abfd, diff_value, &contents[old_source_offset]); break; case R_XTENSA_PDIFF32: case R_XTENSA_NDIFF32: - diff_mask = 0xffffffff; bfd_put_32 (abfd, diff_value, &contents[old_source_offset]); break; } - /* Check for overflow. Sign bits must be all zeroes or all ones */ - if ((diff_value & ~diff_mask) != 0 && - (diff_value & ~diff_mask) != (-1 & ~diff_mask)) + /* Check for overflow. Sign bits must be all zeroes or + all ones. When sign bits are all ones diff_value + may not be zero. */ + if (((diff_value & ~diff_mask) != 0 + && (diff_value & ~diff_mask) != ~diff_mask) + || (diff_value && (bfd_vma) diff_value == ~diff_mask)) { (*link_info->callbacks->reloc_dangerous) (link_info, _("overflow after relaxation"), diff --git a/ld/ChangeLog b/ld/ChangeLog index ae587df..43825ee 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,12 @@ +2020-04-29 Max Filippov <jcmvbkbc@gmail.com> + + * testsuite/ld-xtensa/relax-diff1.d: New test definition. + * testsuite/ld-xtensa/relax-diff1.s: New test source. + * testsuite/ld-xtensa/relax-ndiff.d: New test definition. + * testsuite/ld-xtensa/relax-ndiff.s: New test source. + * testsuite/ld-xtensa/xtensa.exp: (relax-diff1) + (relax-ndiff): New tests. + 2020-04-29 Stephen Casner <casner@acm.org> PR 25829 diff --git a/ld/testsuite/ld-xtensa/relax-diff1.d b/ld/testsuite/ld-xtensa/relax-diff1.d new file mode 100644 index 0000000..900b55b --- /dev/null +++ b/ld/testsuite/ld-xtensa/relax-diff1.d @@ -0,0 +1,6 @@ +#as: --text-section-literals +#ld: +#objdump: -s +#... + 410154 06fa0006 fffa.* +#... diff --git a/ld/testsuite/ld-xtensa/relax-diff1.s b/ld/testsuite/ld-xtensa/relax-diff1.s new file mode 100644 index 0000000..6cc8e2b --- /dev/null +++ b/ld/testsuite/ld-xtensa/relax-diff1.s @@ -0,0 +1,18 @@ + .globl _start + .globl _ResetVector + .text +_ResetVector: +_start: + .literal_position + movi a2, 0x12345678 + movi a2, 0x12345678 +1: + .space 250 +2: + .space 65530 +3: + .align 4 + .byte 1b - 2b + .byte 2b - 1b + .short 2b - 3b + .short 3b - 2b diff --git a/ld/testsuite/ld-xtensa/relax-ndiff.d b/ld/testsuite/ld-xtensa/relax-ndiff.d new file mode 100644 index 0000000..2a1cfd3 --- /dev/null +++ b/ld/testsuite/ld-xtensa/relax-ndiff.d @@ -0,0 +1,6 @@ +#as: --text-section-literals +#ld: +#objdump: -s +#... + 400074 fffffff6 0000000a fff6000a f60a.* +#... diff --git a/ld/testsuite/ld-xtensa/relax-ndiff.s b/ld/testsuite/ld-xtensa/relax-ndiff.s new file mode 100644 index 0000000..4e4176b --- /dev/null +++ b/ld/testsuite/ld-xtensa/relax-ndiff.s @@ -0,0 +1,20 @@ + .globl _start + .globl _ResetVector + .text +_ResetVector: +_start: + .literal_position + movi a2, 0x12345678 + movi a2, 0x12345678 +1: + .space 10 +2: + .space 10 +3: + .align 4 + .word 1b - 2b + .word 3b - 2b + .short 1b - 2b + .short 3b - 2b + .byte 1b - 2b + .byte 3b - 2b diff --git a/ld/testsuite/ld-xtensa/xtensa.exp b/ld/testsuite/ld-xtensa/xtensa.exp index de39887..5334bc6 100644 --- a/ld/testsuite/ld-xtensa/xtensa.exp +++ b/ld/testsuite/ld-xtensa/xtensa.exp @@ -27,7 +27,9 @@ run_dump_test "call_overflow" run_dump_test "coalesce" run_dump_test "diff_overflow" run_dump_test "lcall" +run_dump_test "relax-diff1" run_dump_test "relax-loc" +run_dump_test "relax-ndiff" run_dump_test "relax-static-pie" run_dump_test "relax-static-local-pie" |