mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-02 11:01:35 +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:
@ -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>
|
2018-09-24 Jim Wilson <jimw@sifive.com>
|
||||||
|
|
||||||
* elfnn-riscv.c (_bfd_riscv_relax_pc) <R_RISCV_PCREL_LO12_I>: New local
|
* 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. */
|
/* Generate a PLT header. */
|
||||||
|
|
||||||
static void
|
static bfd_boolean
|
||||||
riscv_make_plt_header (bfd_vma gotplt_addr, bfd_vma addr, uint32_t *entry)
|
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_high = RISCV_PCREL_HIGH_PART (gotplt_addr, addr);
|
||||||
bfd_vma gotplt_offset_low = RISCV_PCREL_LOW_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)
|
/* auipc t2, %hi(.got.plt)
|
||||||
sub t1, t1, t3 # shifted .got.plt offset + hdr size + 12
|
sub t1, t1, t3 # shifted .got.plt offset + hdr size + 12
|
||||||
l[w|d] t3, %lo(.got.plt)(t2) # _dl_runtime_resolve
|
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[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[6] = RISCV_ITYPE (LREG, X_T0, X_T0, RISCV_ELF_WORD_BYTES);
|
||||||
entry[7] = RISCV_ITYPE (JALR, 0, X_T3, 0);
|
entry[7] = RISCV_ITYPE (JALR, 0, X_T3, 0);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate a PLT entry. */
|
/* Generate a PLT entry. */
|
||||||
|
|
||||||
static void
|
static bfd_boolean
|
||||||
riscv_make_plt_entry (bfd_vma got, bfd_vma addr, uint32_t *entry)
|
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)
|
/* auipc t3, %hi(.got.plt entry)
|
||||||
l[w|d] t3, %lo(.got.plt entry)(t3)
|
l[w|d] t3, %lo(.got.plt entry)(t3)
|
||||||
jalr t1, 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[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[2] = RISCV_ITYPE (JALR, X_T1, X_T3, 0);
|
||||||
entry[3] = RISCV_NOP;
|
entry[3] = RISCV_NOP;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create an entry in an RISC-V ELF linker hash table. */
|
/* 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;
|
loc = htab->elf.splt->contents + h->plt.offset;
|
||||||
|
|
||||||
/* Fill in the PLT entry itself. */
|
/* Fill in the PLT entry itself. */
|
||||||
riscv_make_plt_entry (got_address, header_address + h->plt.offset,
|
if (! riscv_make_plt_entry (output_bfd, got_address,
|
||||||
plt_entry);
|
header_address + h->plt.offset,
|
||||||
|
plt_entry))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
for (i = 0; i < PLT_ENTRY_INSNS; i++)
|
for (i = 0; i < PLT_ENTRY_INSNS; i++)
|
||||||
bfd_put_32 (output_bfd, plt_entry[i], loc + 4*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;
|
int i;
|
||||||
uint32_t plt_header[PLT_HEADER_INSNS];
|
uint32_t plt_header[PLT_HEADER_INSNS];
|
||||||
riscv_make_plt_header (sec_addr (htab->elf.sgotplt),
|
ret = riscv_make_plt_header (output_bfd,
|
||||||
sec_addr (splt), plt_header);
|
sec_addr (htab->elf.sgotplt),
|
||||||
|
sec_addr (splt), plt_header);
|
||||||
|
if (!ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
for (i = 0; i < PLT_HEADER_INSNS; i++)
|
for (i = 0; i < PLT_HEADER_INSNS; i++)
|
||||||
bfd_put_32 (output_bfd, plt_header[i], splt->contents + 4*i);
|
bfd_put_32 (output_bfd, plt_header[i], splt->contents + 4*i);
|
||||||
|
Reference in New Issue
Block a user