RISC-V: Fix ld relax failure with calls and align directives.
authorJim Wilson <jimw@sifive.com>
Tue, 12 Nov 2019 23:50:48 +0000 (15:50 -0800)
committerJim Wilson <jimw@sifive.com>
Tue, 12 Nov 2019 23:53:22 +0000 (15:53 -0800)
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
bfd/elfnn-riscv.c
ld/ChangeLog
ld/testsuite/ld-riscv-elf/call-relax-0.s [new file with mode: 0644]
ld/testsuite/ld-riscv-elf/call-relax-1.s [new file with mode: 0644]
ld/testsuite/ld-riscv-elf/call-relax-2.s [new file with mode: 0644]
ld/testsuite/ld-riscv-elf/call-relax-3.s [new file with mode: 0644]
ld/testsuite/ld-riscv-elf/call-relax.d [new file with mode: 0644]
ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp

index 07eb053c846cd294c37124bd6c417141546d272e..9370b7a8d04618d347b3ef2adb563fdcfde22f61 100644 (file)
@@ -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.
index 6be209e23989c62f85dcaaef11ae6ab05fba7b67..997f7866020ae5cdf5480bc964001312a71b3bd3 100644 (file)
@@ -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))
index ad7cfd5eada5abcc4c3c0c4e9c5fd98cad4521fb..39646cb1dc8ebbd4ed51fa3d220c93afba8cff7b 100644 (file)
@@ -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 (file)
index 0000000..4b18bf3
--- /dev/null
@@ -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 (file)
index 0000000..270aaad
--- /dev/null
@@ -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 (file)
index 0000000..2521d1c
--- /dev/null
@@ -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 (file)
index 0000000..3eb04d8
--- /dev/null
@@ -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 (file)
index 0000000..46d9c84
--- /dev/null
@@ -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
index 0a7ac5945e856f2f7bd65c70e94566f982772d5e..7aabbdd641cc338eef4fb54669e135cec2408267 100644 (file)
@@ -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"