public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [RFC] RISC-V: Fix the 32-bit --enable-targets=all build breakage.
@ 2021-11-12  8:35 Nelson Chu
  2021-11-12  8:38 ` Nelson Chu
  0 siblings, 1 reply; 13+ messages in thread
From: Nelson Chu @ 2021-11-12  8:35 UTC (permalink / raw)
  To: binutils, amodra; +Cc: jimw, nelson.chu

This should be the same problem as the commit,
ba9b3ef5ee666467b67780e81f868c432f4fc56d.

Generally, the elfxx-* file should be compiled both for 32-bit and 64-bit
machine, since xx can be 32 and 64.  However, seems like the elfxx-riscv.c
and elf32-riscv.c are missing for BFD32_BACKENDS_CFILES.

This patch try to add the missing linker files for the BFD32_BACKENDS, but
the dst_mask of R_RISCV_CALL may be overflow for the host 32-bit machine.
Therefore, we rewrite the R_RISCV_CALL stuff in the perform_relocation, use
the two 32-bit bfd_vma values to encode it, since the R_RISCV_CALL should be
two instructions, rather than one address.

bfd/
	* Makefile.am: Added elfxx-riscv.* and elf32-riscv.* to
	BFD32_BACKENDS and BFD32_BACKENDS_CFILES.
	* Makefile.in: Regernated.
	* elfnn-riscv.c (perform_relocation): Relocate the R_RISCV_CALL and
	R_RISCV_CALL_PLT relocs by two bfd_vma values, since they are two
	insturctions in fact.  So that the rv32 riscv toolchain built on
	the host 32-bit machine should work.
	* elfxx-riscv.c (howto_table): Let elfnn-riscv.c:perform_relocation
	to handle the dst_mask of R_RISCV_CALL and R_RISCV_CALL_PLT specially.
	Set dst_mask to MINUS_ONE.
---
 bfd/Makefile.am   |  4 ++++
 bfd/Makefile.in   |  4 ++++
 bfd/elfnn-riscv.c | 24 +++++++++++++++++++++---
 bfd/elfxx-riscv.c |  6 ++----
 4 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 097177b..1a935d6 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -336,6 +336,8 @@ BFD32_BACKENDS = \
 	elf32-pj.lo \
 	elf32-ppc.lo \
 	elf32-pru.lo \
+	elf32-riscv.lo \
+	elfxx-riscv.lo \
 	elf32-rl78.lo \
 	elf32-rx.lo \
 	elf32-s390.lo \
@@ -469,6 +471,8 @@ BFD32_BACKENDS_CFILES = \
 	elf32-pj.c \
 	elf32-ppc.c \
 	elf32-pru.c \
+	elf32-riscv.c \
+	elfxx-riscv.c \
 	elf32-rl78.c \
 	elf32-rx.c \
 	elf32-s390.c \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index a76b653..3817167 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -762,6 +762,8 @@ BFD32_BACKENDS = \
 	elf32-pj.lo \
 	elf32-ppc.lo \
 	elf32-pru.lo \
+	elf32-riscv.lo \
+	elfxx-riscv.lo \
 	elf32-rl78.lo \
 	elf32-rx.lo \
 	elf32-s390.lo \
@@ -895,6 +897,8 @@ BFD32_BACKENDS_CFILES = \
 	elf32-pj.c \
 	elf32-ppc.c \
 	elf32-pru.c \
+	elf32-riscv.lo \
+	elfxx-riscv.c \
 	elf32-rl78.c \
 	elf32-rx.c \
 	elf32-s390.c \
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 36cbf1e..024dd32 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1607,6 +1607,9 @@ perform_relocation (const reloc_howto_type *howto,
 		    bfd *input_bfd,
 		    bfd_byte *contents)
 {
+  bool handle_call_special = false;
+  bfd_vma value_call_auipc, value_call_jalr;
+
   if (howto->pc_relative)
     value -= sec_addr (input_section) + rel->r_offset;
   value += rel->r_addend;
@@ -1644,8 +1647,9 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_CALL_PLT:
       if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
 	return bfd_reloc_overflow;
-      value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value))
-	      | (ENCODE_ITYPE_IMM (value) << 32);
+      value_call_auipc = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
+      value_call_jalr = ENCODE_ITYPE_IMM (value);
+      handle_call_special = true;
       break;
 
     case R_RISCV_JAL:
@@ -1717,6 +1721,21 @@ perform_relocation (const reloc_howto_type *howto,
       return bfd_reloc_notsupported;
     }
 
+  /* Handle R_RISCV_CALL and R_RISCV_CALL_PLT specially, in case the
+     host machine is 32-bit.  */
+  if (handle_call_special)
+    {
+      bfd_vma insn_auipc = riscv_get_insn (32, contents + rel->r_offset);
+      bfd_vma insn_jalr = riscv_get_insn (32, contents + rel->r_offset + 0x4);
+      bfd_vma dst_mask_auipc = ENCODE_UTYPE_IMM (-1U);
+      bfd_vma dst_mask_jalr = ENCODE_ITYPE_IMM (-1U);
+      insn_auipc = (insn_auipc & ~dst_mask_auipc) | (value_call_auipc & dst_mask_auipc);
+      insn_jalr = (insn_jalr & ~dst_mask_jalr) | (value_call_jalr & dst_mask_jalr);
+      riscv_put_insn (32, insn_auipc, contents + rel->r_offset);
+      riscv_put_insn (32, insn_jalr, contents + rel->r_offset + 0x4);
+      return bfd_reloc_ok;
+    }
+
   bfd_vma word;
   if (riscv_is_insn_reloc (howto))
     word = riscv_get_insn (howto->bitsize, contents + rel->r_offset);
@@ -1727,7 +1746,6 @@ perform_relocation (const reloc_howto_type *howto,
     riscv_put_insn (howto->bitsize, word, contents + rel->r_offset);
   else
     bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
-
   return bfd_reloc_ok;
 }
 
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 3ffbaad..858d29e 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -264,8 +264,7 @@ static reloc_howto_type howto_table[] =
 	 "R_RISCV_CALL",		/* name */
 	 false,				/* partial_inplace */
 	 0,				/* src_mask */
-	 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
-					/* dst_mask */
+	 MINUS_ONE,			/* dst_mask */
 	 true),				/* pcrel_offset */
 
   /* Like R_RISCV_CALL, but not locally binding.  */
@@ -280,8 +279,7 @@ static reloc_howto_type howto_table[] =
 	 "R_RISCV_CALL_PLT",		/* name */
 	 false,				/* partial_inplace */
 	 0,				/* src_mask */
-	 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
-					/* dst_mask */
+	 MINUS_ONE,			/* dst_mask */
 	 true),				/* pcrel_offset */
 
   /* High 20 bits of 32-bit PC-relative GOT access.  */
-- 
2.7.4


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2021-12-11  3:02 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-12  8:35 [RFC] RISC-V: Fix the 32-bit --enable-targets=all build breakage Nelson Chu
2021-11-12  8:38 ` Nelson Chu
2021-11-12  9:34   ` Alan Modra
2021-11-12  9:42     ` Nelson Chu
2021-12-01  9:52       ` Luis Machado
2021-12-10 10:40       ` Andrew Burgess
2021-12-10 12:36         ` Luis Machado
2021-12-10 14:57           ` Andrew Burgess
2021-12-10 15:09             ` Luis Machado
2021-12-11  3:01         ` Nelson Chu
2021-11-17 13:52     ` Luis Machado
2021-11-18  1:02       ` Alan Modra
2021-11-18  1:29         ` Mike Frysinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).