From c6261a00c3e70dd8e508062ea43a1bcb6d547621 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Tue, 12 Nov 2019 15:50:48 -0800 Subject: 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/elfnn-riscv.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'bfd/elfnn-riscv.c') diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 6be209e..997f786 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)) -- cgit v1.1