aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfnn-riscv.c
diff options
context:
space:
mode:
authorJim Wilson <jimw@sifive.com>2018-09-24 14:05:32 -0700
committerJim Wilson <jimw@sifive.com>2018-09-24 14:05:32 -0700
commit551703cfd409faca433626a0af077a43011381b7 (patch)
tree8ef7b1c2a1592262b8bc2df357f92be83cbafe3b /bfd/elfnn-riscv.c
parentdb72737006fc383cb8838bf7f3dc8e641e60c38f (diff)
downloadgdb-551703cfd409faca433626a0af077a43011381b7.zip
gdb-551703cfd409faca433626a0af077a43011381b7.tar.gz
gdb-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.c28
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: