[binutils-gdb] RISC-V: Give error for RVE PLTs.

Jim Wilson wilson@sourceware.org
Tue Sep 25 20:14:00 GMT 2018


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5ef237932919a19fe85f70fc37f7d3a0660b7665

commit 5ef237932919a19fe85f70fc37f7d3a0660b7665
Author: Jim Wilson <jimw@sifive.com>
Date:   Tue Sep 25 13:13:23 2018 -0700

    RISC-V: Give error for RVE PLTs.
    
    	bfd/
    	* elfnn-riscv.c (riscv_make_plt_header): New arg output_bfd.  Change
    	return type to bfd_boolean.  If	EF_RISCV_RVE call _bfd_error_handler
    	and return FALSE.  Return TRUE at end.
    	(riscv_make_plt_entry): Likewise.
    	(riscv_elf_finish_dynamic_symbol): Update call to riscv_make_plt_entry.
    	(riscv_elf_finish_dynamic_sections): Update call to
    	riscv_make_plt_header.

Diff:
---
 bfd/ChangeLog     | 10 ++++++++++
 bfd/elfnn-riscv.c | 44 ++++++++++++++++++++++++++++++++++++--------
 2 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e8e3195..62cf91d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,13 @@
+2018-09-25  Jim Wilson  <jimw@sifive.com>
+
+	* elfnn-riscv.c (riscv_make_plt_header): New arg output_bfd.  Change
+	return type to bfd_boolean.  If	EF_RISCV_RVE call _bfd_error_handler
+	and return FALSE.  Return TRUE at end.
+	(riscv_make_plt_entry): Likewise.
+	(riscv_elf_finish_dynamic_symbol): Update call to riscv_make_plt_entry.
+	(riscv_elf_finish_dynamic_sections): Update call to
+	riscv_make_plt_header.
+
 2018-09-24  Jim Wilson  <jimw@sifive.com>
 
 	* elfnn-riscv.c (_bfd_riscv_relax_pc) <R_RISCV_PCREL_LO12_I>: New local
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index f3e2cc7..c99bcff 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -169,12 +169,21 @@ riscv_elf_got_plt_val (bfd_vma plt_index, struct bfd_link_info *info)
 
 /* Generate a PLT header.  */
 
-static void
-riscv_make_plt_header (bfd_vma gotplt_addr, bfd_vma addr, uint32_t *entry)
+static bfd_boolean
+riscv_make_plt_header (bfd *output_bfd, bfd_vma gotplt_addr, bfd_vma addr,
+		       uint32_t *entry)
 {
   bfd_vma gotplt_offset_high = RISCV_PCREL_HIGH_PART (gotplt_addr, addr);
   bfd_vma gotplt_offset_low = RISCV_PCREL_LOW_PART (gotplt_addr, addr);
 
+  /* RVE has no t3 register, so this won't work, and is not supported.  */
+  if (elf_elfheader (output_bfd)->e_flags & EF_RISCV_RVE)
+    {
+      _bfd_error_handler (_("%pB: warning: RVE PLT generation not supported"),
+			  output_bfd);
+      return FALSE;
+    }
+
   /* auipc  t2, %hi(.got.plt)
      sub    t1, t1, t3		     # shifted .got.plt offset + hdr size + 12
      l[w|d] t3, %lo(.got.plt)(t2)    # _dl_runtime_resolve
@@ -192,13 +201,24 @@ riscv_make_plt_header (bfd_vma gotplt_addr, bfd_vma addr, uint32_t *entry)
   entry[5] = RISCV_ITYPE (SRLI, X_T1, X_T1, 4 - RISCV_ELF_LOG_WORD_BYTES);
   entry[6] = RISCV_ITYPE (LREG, X_T0, X_T0, RISCV_ELF_WORD_BYTES);
   entry[7] = RISCV_ITYPE (JALR, 0, X_T3, 0);
+
+  return TRUE;
 }
 
 /* Generate a PLT entry.  */
 
-static void
-riscv_make_plt_entry (bfd_vma got, bfd_vma addr, uint32_t *entry)
+static bfd_boolean
+riscv_make_plt_entry (bfd *output_bfd, bfd_vma got, bfd_vma addr,
+		      uint32_t *entry)
 {
+  /* RVE has no t3 register, so this won't work, and is not supported.  */
+  if (elf_elfheader (output_bfd)->e_flags & EF_RISCV_RVE)
+    {
+      _bfd_error_handler (_("%pB: warning: RVE PLT generation not supported"),
+			  output_bfd);
+      return FALSE;
+    }
+
   /* auipc  t3, %hi(.got.plt entry)
      l[w|d] t3, %lo(.got.plt entry)(t3)
      jalr   t1, t3
@@ -208,6 +228,8 @@ riscv_make_plt_entry (bfd_vma got, bfd_vma addr, uint32_t *entry)
   entry[1] = RISCV_ITYPE (LREG,  X_T3, X_T3, RISCV_PCREL_LOW_PART (got, addr));
   entry[2] = RISCV_ITYPE (JALR, X_T1, X_T3, 0);
   entry[3] = RISCV_NOP;
+
+  return TRUE;
 }
 
 /* Create an entry in an RISC-V ELF linker hash table.  */
@@ -2353,8 +2375,11 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
       loc = htab->elf.splt->contents + h->plt.offset;
 
       /* Fill in the PLT entry itself.  */
-      riscv_make_plt_entry (got_address, header_address + h->plt.offset,
-			    plt_entry);
+      if (! riscv_make_plt_entry (output_bfd, got_address,
+				  header_address + h->plt.offset,
+				  plt_entry))
+	return FALSE;
+
       for (i = 0; i < PLT_ENTRY_INSNS; i++)
 	bfd_put_32 (output_bfd, plt_entry[i], loc + 4*i);
 
@@ -2529,8 +2554,11 @@ riscv_elf_finish_dynamic_sections (bfd *output_bfd,
 	{
 	  int i;
 	  uint32_t plt_header[PLT_HEADER_INSNS];
-	  riscv_make_plt_header (sec_addr (htab->elf.sgotplt),
-				 sec_addr (splt), plt_header);
+	  ret = riscv_make_plt_header (output_bfd,
+				       sec_addr (htab->elf.sgotplt),
+				       sec_addr (splt), plt_header);
+	  if (!ret)
+	    return ret;
 
 	  for (i = 0; i < PLT_HEADER_INSNS; i++)
 	    bfd_put_32 (output_bfd, plt_header[i], splt->contents + 4*i);



More information about the Binutils-cvs mailing list