diff options
author | Jim Wilson <jimw@sifive.com> | 2019-11-12 15:50:48 -0800 |
---|---|---|
committer | Jim Wilson <jimw@sifive.com> | 2019-11-12 15:53:22 -0800 |
commit | c6261a00c3e70dd8e508062ea43a1bcb6d547621 (patch) | |
tree | b7267edb54f7535ff9913d2394ad867d14717b3b /bfd | |
parent | gdb: Support printf 'z' size modifier (diff) | |
download | binutils-gdb-c6261a00c3e70dd8e508062ea43a1bcb6d547621.tar.gz binutils-gdb-c6261a00c3e70dd8e508062ea43a1bcb6d547621.tar.bz2 binutils-gdb-c6261a00c3e70dd8e508062ea43a1bcb6d547621.zip |
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
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elfnn-riscv.c | 13 |
2 files changed, 17 insertions, 3 deletions
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 <jimw@sifive.com> + + 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 <amodra@gmail.com> * 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)) |