(elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
== RISCV_ELF_DATA ? ((struct riscv_elf_link_hash_table *) ((p)->hash)) : NULL)
-static void
-riscv_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+static bfd_boolean
+riscv_info_to_howto_rela (bfd *abfd,
arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
- cache_ptr->howto = riscv_elf_rtype_to_howto (ELFNN_R_TYPE (dst->r_info));
+ cache_ptr->howto = riscv_elf_rtype_to_howto (abfd, ELFNN_R_TYPE (dst->r_info));
+ return cache_ptr->howto != NULL;
}
static void
static bfd_boolean
bad_static_reloc (bfd *abfd, unsigned r_type, struct elf_link_hash_entry *h)
{
+ reloc_howto_type * r = riscv_elf_rtype_to_howto (abfd, r_type);
+
(*_bfd_error_handler)
(_("%pB: relocation %s against `%s' can not be used when making a shared "
"object; recompile with -fPIC"),
- abfd, riscv_elf_rtype_to_howto (r_type)->name,
- h != NULL ? h->root.root.string : "a local symbol");
+ abfd, r ? r->name : _("<unknown>"),
+ h != NULL ? h->root.root.string : "a local symbol");
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
may need to keep relocations for symbols satisfied by a
dynamic library if we manage to avoid copy relocs for the
symbol. */
+ reloc_howto_type * r = riscv_elf_rtype_to_howto (abfd, r_type);
+
if ((bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
- && (! riscv_elf_rtype_to_howto (r_type)->pc_relative
+ && ((r != NULL && ! r->pc_relative)
|| (h != NULL
&& (! info->symbolic
|| h->root.type == bfd_link_hash_defweak
}
p->count += 1;
- p->pc_count += riscv_elf_rtype_to_howto (r_type)->pc_relative;
+ p->pc_count += r == NULL ? 0 : r->pc_relative;
}
break;
bfd_boolean unresolved_reloc, is_ie = FALSE;
bfd_vma pc = sec_addr (input_section) + rel->r_offset;
int r_type = ELFNN_R_TYPE (rel->r_info), tls_type;
- reloc_howto_type *howto = riscv_elf_rtype_to_howto (r_type);
+ reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
const char *msg = NULL;
- if (r_type == R_RISCV_GNU_VTINHERIT || r_type == R_RISCV_GNU_VTENTRY)
+ if (howto == NULL
+ || r_type == R_RISCV_GNU_VTINHERIT || r_type == R_RISCV_GNU_VTENTRY)
continue;
/* This is a final link. */
howto,
input_bfd);
r_type = ELFNN_R_TYPE (rel->r_info);
- howto = riscv_elf_rtype_to_howto (r_type);
- if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
- relocation, absolute))
+ howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
+ if (howto == NULL)
+ r = bfd_reloc_notsupported;
+ else if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
+ relocation, absolute))
r = bfd_reloc_overflow;
break;
howto,
input_bfd);
r_type = ELFNN_R_TYPE (rel->r_info);
- howto = riscv_elf_rtype_to_howto (r_type);
- if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
- relocation + rel->r_addend,
- absolute))
+ howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
+ if (howto == NULL)
+ r = bfd_reloc_notsupported;
+ else if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
+ relocation + rel->r_addend,
+ absolute))
r = bfd_reloc_overflow;
break;
rel->r_offset) != (bfd_vma) -1)
{
(*_bfd_error_handler)
- (_("%pB(%pA+%#Lx): unresolvable %s relocation against symbol `%s'"),
+ (_("%pB(%pA+%#" PRIx64 "): "
+ "unresolvable %s relocation against symbol `%s'"),
input_bfd,
input_section,
- rel->r_offset,
+ (uint64_t) rel->r_offset,
howto->name,
h->root.root.string);
continue;
/* If the symbol *spans* the bytes we just deleted (i.e. its
*end* is in the moved bytes but its *start* isn't), then we
- must adjust its size. */
- if (sym->st_value <= addr
- && sym->st_value + sym->st_size > addr
- && sym->st_value + sym->st_size <= toaddr)
+ must adjust its size.
+
+ This test needs to use the original value of st_value, otherwise
+ we might accidentally decrease size when deleting bytes right
+ before the symbol. But since deleted relocs can't span across
+ symbols, we can't have both a st_value and a st_size decrease,
+ so it is simpler to just use an else. */
+ else if (sym->st_value <= addr
+ && sym->st_value + sym->st_size > addr
+ && sym->st_value + sym->st_size <= toaddr)
sym->st_size -= count;
}
}
sym_hash->root.u.def.value -= count;
/* As above, adjust the size if needed. */
- if (sym_hash->root.u.def.value <= addr
- && sym_hash->root.u.def.value + sym_hash->size > addr
- && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
+ else if (sym_hash->root.u.def.value <= addr
+ && sym_hash->root.u.def.value + sym_hash->size > addr
+ && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
sym_hash->size -= count;
}
}
/* Make sure there are enough NOPs to actually achieve the alignment. */
if (rel->r_addend < nop_bytes)
{
- (*_bfd_error_handler)
- (_("%pB(%pA+0x%lx): %d bytes required for alignment "
- "to %d-byte boundary, but only %d present"),
- abfd, sym_sec, rel->r_offset, nop_bytes, alignment, rel->r_addend);
+ _bfd_error_handler
+ (_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment "
+ "to %" PRId64 "-byte boundary, but only %" PRId64 " present"),
+ abfd, sym_sec, (uint64_t) rel->r_offset,
+ (int64_t) nop_bytes, (int64_t) alignment, (int64_t) rel->r_addend);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
symval = hi_reloc.hi_addr;
sym_sec = hi_reloc.sym_sec;
if (!riscv_use_pcgp_hi_reloc(pcgp_relocs, hi->hi_sec_off))
- (*_bfd_error_handler)
- (_("%pB(%pA+0x%lx): Unable to clear RISCV_PCREL_HI20 reloc"
- "for cooresponding RISCV_PCREL_LO12 reloc"),
- abfd, sec, rel->r_offset);
+ _bfd_error_handler
+ (_("%pB(%pA+%#" PRIx64 "): Unable to clear RISCV_PCREL_HI20 reloc "
+ "for corresponding RISCV_PCREL_LO12 reloc"),
+ abfd, sec, (uint64_t) rel->r_offset);
}
break;