/* RISC-V-specific support for NN-bit ELF.
- Copyright (C) 2011-2019 Free Software Foundation, Inc.
+ Copyright (C) 2011-2020 Free Software Foundation, Inc.
Contributed by Andrew Waterman (andrew@sifive.com).
Based on TILE-Gx and MIPS targets.
int r_type = ELFNN_R_TYPE (rel->r_info), tls_type;
reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
const char *msg = NULL;
+ char *msg_buf = NULL;
bfd_boolean resolved_to_zero;
if (howto == NULL
break;
case R_RISCV_CALL:
+ case R_RISCV_CALL_PLT:
/* Handle a call to an undefined weak function. This won't be
relaxed, so we have to handle it here. */
if (h != NULL && h->root.type == bfd_link_hash_undefweak
- && h->plt.offset == MINUS_ONE)
+ && (!bfd_link_pic (info) || h->plt.offset == MINUS_ONE))
{
/* We can use x0 as the base register. */
bfd_vma insn = bfd_get_32 (input_bfd,
}
/* Fall through. */
- case R_RISCV_CALL_PLT:
case R_RISCV_JAL:
case R_RISCV_RVC_JUMP:
+ /* This line has to match the check in _bfd_riscv_relax_section. */
if (bfd_link_pic (info) && h != NULL && h->plt.offset != MINUS_ONE)
{
/* Refer to the PLT entry. */
|| (h != NULL && h->type == STT_SECTION))
&& rel->r_addend)
{
+ msg = _("%pcrel_lo section symbol with an addend");
r = bfd_reloc_dangerous;
break;
}
&& _bfd_elf_section_offset (output_bfd, info, input_section,
rel->r_offset) != (bfd_vma) -1)
{
- (*_bfd_error_handler)
- (_("%pB(%pA+%#" PRIx64 "): "
- "unresolvable %s relocation against symbol `%s'"),
- input_bfd,
- input_section,
- (uint64_t) rel->r_offset,
- howto->name,
- h->root.root.string);
-
- bfd_set_error (bfd_error_bad_value);
- ret = FALSE;
- goto out;
+ switch (r_type)
+ {
+ case R_RISCV_CALL:
+ case R_RISCV_JAL:
+ case R_RISCV_RVC_JUMP:
+ if (asprintf (&msg_buf,
+ _("%%X%%P: relocation %s against `%s' can "
+ "not be used when making a shared object; "
+ "recompile with -fPIC\n"),
+ howto->name,
+ h->root.root.string) == -1)
+ msg_buf = NULL;
+ break;
+
+ default:
+ if (asprintf (&msg_buf,
+ _("%%X%%P: unresolvable %s relocation against "
+ "symbol `%s'\n"),
+ howto->name,
+ h->root.root.string) == -1)
+ msg_buf = NULL;
+ break;
+ }
+
+ msg = msg_buf;
+ r = bfd_reloc_notsupported;
}
if (r == bfd_reloc_ok)
r = perform_relocation (howto, rel, relocation, input_section,
input_bfd, contents);
+ /* We should have already detected the error and set message before.
+ If the error message isn't set since the linker runs out of memory
+ or we don't set it before, then we should set the default message
+ with the "internal error" string here. */
switch (r)
{
case bfd_reloc_ok:
break;
case bfd_reloc_outofrange:
- msg = _("%X%P: internal error: out of range error\n");
+ if (msg == NULL)
+ msg = _("%X%P: internal error: out of range error\n");
break;
case bfd_reloc_notsupported:
- msg = _("%X%P: internal error: unsupported relocation error\n");
+ if (msg == NULL)
+ msg = _("%X%P: internal error: unsupported relocation error\n");
break;
case bfd_reloc_dangerous:
+ /* The error message should already be set. */
+ if (msg == NULL)
+ msg = _("dangerous relocation error");
info->callbacks->reloc_dangerous
- (info, "%pcrel_lo section symbol with an addend", input_bfd,
- input_section, rel->r_offset);
+ (info, msg, input_bfd, input_section, rel->r_offset);
break;
default:
break;
}
- if (msg)
+ /* Do not report error message for the dangerous relocation again. */
+ if (msg && r != bfd_reloc_dangerous)
info->callbacks->einfo (msg);
+ /* Free the unused `msg_buf` if needed. */
+ if (msg_buf)
+ free (msg_buf);
+
/* We already reported the error via a callback, so don't try to report
it again by returning false. That leads to spurious errors. */
ret = TRUE;
int rd, r_type, len = 4, rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC;
/* If the call crosses section boundaries, an alignment directive could
- cause the PC-relative offset to later increase. */
- if (VALID_UJTYPE_IMM (foff) && sym_sec->output_section != sec->output_section)
- foff += (foff < 0 ? -max_alignment : max_alignment);
+ cause the PC-relative offset to later increase, so we need to add in the
+ max alignment of any section inclusive from the call to the target.
+ Otherwise, we only need to use the alignment of the current section. */
+ if (VALID_UJTYPE_IMM (foff))
+ {
+ if (sym_sec->output_section == sec->output_section
+ && sym_sec->output_section != bfd_abs_section_ptr)
+ max_alignment = (bfd_vma) 1 << sym_sec->output_section->alignment_power;
+ foff += (foff < 0 ? -max_alignment : max_alignment);
+ }
/* See if this function call can be shortened. */
if (!VALID_UJTYPE_IMM (foff) && !(!bfd_link_pic (link_info) && near_zero))
undefined_weak = TRUE;
}
- if (h->plt.offset != MINUS_ONE)
+ /* This line has to match the check in riscv_elf_relocate_section
+ in the R_RISCV_CALL[_PLT] case. */
+ if (bfd_link_pic (info) && h->plt.offset != MINUS_ONE)
{
sym_sec = htab->elf.splt;
symval = h->plt.offset;