diff options
author | Jim Wilson <jimw@sifive.com> | 2018-09-24 14:05:32 -0700 |
---|---|---|
committer | Jim Wilson <jimw@sifive.com> | 2018-09-24 14:05:32 -0700 |
commit | 551703cfd409faca433626a0af077a43011381b7 (patch) | |
tree | 8ef7b1c2a1592262b8bc2df357f92be83cbafe3b /bfd/elfnn-riscv.c | |
parent | db72737006fc383cb8838bf7f3dc8e641e60c38f (diff) | |
download | binutils-551703cfd409faca433626a0af077a43011381b7.zip binutils-551703cfd409faca433626a0af077a43011381b7.tar.gz binutils-551703cfd409faca433626a0af077a43011381b7.tar.bz2 |
RISC-V: Allow pcrel_lo addends, error on addend overflow.
bfd/
* elfnn-riscv.c (riscv_resolve_pcrel_lo_relocs): Add check for reloc
overflow with addend. Use reloc_dangerous instead of reloc_overflow.
Add strings for the two errors handled here.
(riscv_elf_relocate_section) In case R_RISCV_PCREL_LO12_I, rewrite
comment. Only give error with addend when used with section symbol.
In case bfd_reloc_dangerous, update error string.
ld/
* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Run pcrel-lo-addend-2.
* testsuite/ld-riscv/elf/ld-riscv-elf/pcrel-lo-addend-2.d: New.
* testsuite/ld-riscv/elf/ld-riscv-elf/pcrel-lo-addend-2.s: New.
* testsuite/ld-riscv/elf/ld-riscv-elf/pcrel-lo-addend.d: Update name
and error string.
Diffstat (limited to 'bfd/elfnn-riscv.c')
-rw-r--r-- | bfd/elfnn-riscv.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 4be3ece..63ff07e 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -1651,11 +1651,16 @@ riscv_resolve_pcrel_lo_relocs (riscv_pcrel_relocs *p) riscv_pcrel_hi_reloc search = {r->addr, 0}; riscv_pcrel_hi_reloc *entry = htab_find (p->hi_relocs, &search); - if (entry == NULL) + if (entry == NULL + /* Check for overflow into bit 11 when adding reloc addend. */ + || (! (entry->value & 0x800) + && ((entry->value + r->reloc->r_addend) & 0x800))) { - ((*r->info->callbacks->reloc_overflow) - (r->info, NULL, r->name, r->howto->name, (bfd_vma) 0, - input_bfd, r->input_section, r->reloc->r_offset)); + char *string = (entry == NULL + ? "%pcrel_lo missing matching %pcrel_hi" + : "%pcrel_lo overflow with an addend"); + (*r->info->callbacks->reloc_dangerous) + (r->info, string, input_bfd, r->input_section, r->reloc->r_offset); return TRUE; } @@ -2026,11 +2031,12 @@ riscv_elf_relocate_section (bfd *output_bfd, case R_RISCV_PCREL_LO12_I: case R_RISCV_PCREL_LO12_S: - /* Addends are not allowed, because then riscv_relax_delete_bytes - would have to search through all relocs to update the addends. - Also, riscv_resolve_pcrel_lo_relocs does not support addends - when searching for a matching hi reloc. */ - if (rel->r_addend) + /* We don't allow section symbols plus addends as the auipc address, + because then riscv_relax_delete_bytes would have to search through + all relocs to update these addends. This is also ambiguous, as + we do allow offsets to be added to the target address, which are + not to be used to find the auipc address. */ + if ((ELF_ST_TYPE (sym->st_info) == STT_SECTION) && rel->r_addend) { r = bfd_reloc_dangerous; break; @@ -2288,8 +2294,8 @@ riscv_elf_relocate_section (bfd *output_bfd, case bfd_reloc_dangerous: info->callbacks->reloc_dangerous - (info, "%pcrel_lo with addend", input_bfd, input_section, - rel->r_offset); + (info, "%pcrel_lo section symbol with an addend", input_bfd, + input_section, rel->r_offset); break; default: |