mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 10:35:12 +08:00
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.
This commit is contained in:
parent
3d6e0c015a
commit
5ef2379329
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user