aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Wilson <jimw@sifive.com>2018-09-25 13:13:23 -0700
committerJim Wilson <jimw@sifive.com>2018-09-25 13:13:23 -0700
commit5ef237932919a19fe85f70fc37f7d3a0660b7665 (patch)
treefe23c77960e3c141b486b18c1474c64396254d1c
parent3d6e0c015aa832f00ccd4fe3f5f43b90357258e8 (diff)
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.
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/elfnn-riscv.c44
2 files changed, 46 insertions, 8 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e8e31952caf..62cf91decf9 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 f3e2cc7c377..c99bcff5f1b 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);