From c6261a00c3e70dd8e508062ea43a1bcb6d547621 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Tue, 12 Nov 2019 15:50:48 -0800 Subject: [PATCH] RISC-V: Fix ld relax failure with calls and align directives. Make _bfd_riscv_relax_call handle section alignment padding same as the _bfd_riscv_relax_lui and _bfd_riscv_relax_pc functions already do. Use the max section alignment if section boundaries are crossed, otherwise the alignment of the containing section. bfd/ PR 25181 * elfnn-riscv.c (_bfd_riscv_relax_call): Always add max_alignment to foff. If sym_sec->output_section and sec->output_section are the same and not *ABS* then set max_alignment to that section's alignment. ld/ PR 25181 * testsuite/ld-riscv-elf/call-relax-0.s: New file. * testsuite/ld-riscv-elf/call-relax-1.s: New file. * testsuite/ld-riscv-elf/call-relax-2.s: New file. * testsuite/ld-riscv-elf/call-relax-3.s: New file. * testsuite/ld-riscv-elf/call-relax.d: New test. * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Run call-relax test. Change-Id: Iaf65cee52345abf1955f36e8e72c4f6cc0db8d9a --- bfd/ChangeLog | 7 +++++++ bfd/elfnn-riscv.c | 13 ++++++++++--- ld/ChangeLog | 10 ++++++++++ ld/testsuite/ld-riscv-elf/call-relax-0.s | 9 +++++++++ ld/testsuite/ld-riscv-elf/call-relax-1.s | 6 ++++++ ld/testsuite/ld-riscv-elf/call-relax-2.s | 7 +++++++ ld/testsuite/ld-riscv-elf/call-relax-3.s | 9 +++++++++ ld/testsuite/ld-riscv-elf/call-relax.d | 9 +++++++++ ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 1 + 9 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 ld/testsuite/ld-riscv-elf/call-relax-0.s create mode 100644 ld/testsuite/ld-riscv-elf/call-relax-1.s create mode 100644 ld/testsuite/ld-riscv-elf/call-relax-2.s create mode 100644 ld/testsuite/ld-riscv-elf/call-relax-3.s create mode 100644 ld/testsuite/ld-riscv-elf/call-relax.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 07eb053c846..9370b7a8d04 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2019-11-12 Jim Wilson + + PR 25181 + * elfnn-riscv.c (_bfd_riscv_relax_call): Always add max_alignment to + foff. If sym_sec->output_section and sec->output_section are the same + and not *ABS* then set max_alignment to that section's alignment. + 2019-11-07 Alan Modra * cpu-cr16c.c: Delete. diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 6be209e2398..997f7866020 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -3494,9 +3494,16 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec, int rd, r_type, len = 4, rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC; /* If the call crosses section boundaries, an alignment directive could - cause the PC-relative offset to later increase. */ - if (VALID_UJTYPE_IMM (foff) && sym_sec->output_section != sec->output_section) - foff += (foff < 0 ? -max_alignment : max_alignment); + cause the PC-relative offset to later increase, so we need to add in the + max alignment of any section inclusive from the call to the target. + Otherwise, we only need to use the alignment of the current section. */ + if (VALID_UJTYPE_IMM (foff)) + { + if (sym_sec->output_section == sec->output_section + && sym_sec->output_section != bfd_abs_section_ptr) + max_alignment = (bfd_vma) 1 << sym_sec->output_section->alignment_power; + foff += (foff < 0 ? -max_alignment : max_alignment); + } /* See if this function call can be shortened. */ if (!VALID_UJTYPE_IMM (foff) && !(!bfd_link_pic (link_info) && near_zero)) diff --git a/ld/ChangeLog b/ld/ChangeLog index ad7cfd5eada..39646cb1dc8 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,13 @@ +2019-11-12 Jim Wilson + + PR 25181 + * testsuite/ld-riscv-elf/call-relax-0.s: New file. + * testsuite/ld-riscv-elf/call-relax-1.s: New file. + * testsuite/ld-riscv-elf/call-relax-2.s: New file. + * testsuite/ld-riscv-elf/call-relax-3.s: New file. + * testsuite/ld-riscv-elf/call-relax.d: New test. + * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Run call-relax test. + 2019-11-08 Alan Modra * emulparams/aarch64elf.sh: Revert 2019-11-05 change. diff --git a/ld/testsuite/ld-riscv-elf/call-relax-0.s b/ld/testsuite/ld-riscv-elf/call-relax-0.s new file mode 100644 index 00000000000..4b18bf338d3 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/call-relax-0.s @@ -0,0 +1,9 @@ +.globl _start + +.section .text.hot +_start: + call cc + +.text +ff: + call dd diff --git a/ld/testsuite/ld-riscv-elf/call-relax-1.s b/ld/testsuite/ld-riscv-elf/call-relax-1.s new file mode 100644 index 00000000000..270aaadd7fa --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/call-relax-1.s @@ -0,0 +1,6 @@ +.globl align1 + +.text +.balign 32 +align1: + csrr a0, sie diff --git a/ld/testsuite/ld-riscv-elf/call-relax-2.s b/ld/testsuite/ld-riscv-elf/call-relax-2.s new file mode 100644 index 00000000000..2521d1c97e1 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/call-relax-2.s @@ -0,0 +1,7 @@ +.globl align2 + +.text +.balign 4 +align2: + csrr a0, sie +.fill 0xfffb6 diff --git a/ld/testsuite/ld-riscv-elf/call-relax-3.s b/ld/testsuite/ld-riscv-elf/call-relax-3.s new file mode 100644 index 00000000000..3eb04d8b8f7 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/call-relax-3.s @@ -0,0 +1,9 @@ +.globl cc +.globl dd + +.text +cc: + csrr a0, sie + csrr a1, sie +dd: + ret diff --git a/ld/testsuite/ld-riscv-elf/call-relax.d b/ld/testsuite/ld-riscv-elf/call-relax.d new file mode 100644 index 00000000000..46d9c84f35f --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/call-relax.d @@ -0,0 +1,9 @@ +#name: call relaxation with alignment +#source: call-relax-0.s +#source: call-relax-1.s +#source: call-relax-2.s +#source: call-relax-3.s +#as: -march=rv32ic +#ld: -melf32lriscv +#objdump: -d +#pass diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index 0a7ac5945e8..7aabbdd641c 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -20,6 +20,7 @@ # if [istarget "riscv*-*-*"] { + run_dump_test "call-relax" run_dump_test "c-lui" run_dump_test "c-lui-2" run_dump_test "disas-jalr" -- 2.30.2