This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] RISC-V: Fix ld relax failure with calls and align directives.
- From: Jim Wilson <jimw at sifive dot com>
- To: binutils at sourceware dot org
- Cc: Jim Wilson <jimw at sifive dot com>
- Date: Tue, 12 Nov 2019 15:54:30 -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.
Tested with riscv{32,64}-{elf,linux} cross binutils build and make check,
and cross gcc builds and check for riscv32-elf and riscv64-linux. There
were no regressions. The new test fails without the patch and works with
the patch.
Committed.
Jim
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: I727ddb4714f32bcd34089c3183944f17d407a386
---
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 07eb053c84..9370b7a8d0 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 6be209e239..997f786602 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 ad7cfd5ead..39646cb1dc 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,13 @@
+2019-11-12 Jim Wilson <jimw@sifive.com>
+
+ 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 <amodra@gmail.com>
* 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 0000000000..4b18bf338d
--- /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 0000000000..270aaadd7f
--- /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 0000000000..2521d1c97e
--- /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 0000000000..3eb04d8b8f
--- /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 0000000000..46d9c84f35
--- /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 0a7ac5945e..7aabbdd641 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.17.1