const char *prefix, asection *s, bfd_vma value,
bfd_vma size)
{
+ bfd_boolean micromips_p = ELF_ST_IS_MICROMIPS (h->root.other);
struct bfd_link_hash_entry *bh;
struct elf_link_hash_entry *elfh;
char *name;
bfd_boolean res;
- if (ELF_ST_IS_MICROMIPS (h->root.other))
+ if (micromips_p)
value |= 1;
/* Create a new symbol. */
elfh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
elfh->size = size;
elfh->forced_local = 1;
+ if (micromips_p)
+ elfh->other = ELF_ST_SET_MICROMIPS (elfh->other);
return TRUE;
}
|| h->root.root.type == bfd_link_hash_defweak)
&& h->root.def_regular
&& !bfd_is_abs_section (h->root.root.u.def.section)
+ && !bfd_is_und_section (h->root.root.u.def.section)
&& (!ELF_ST_IS_MIPS16 (h->root.other)
|| (h->fn_stub && h->need_fn_stub))
&& (PIC_OBJECT_P (h->root.root.u.def.section->owner)
/* Prefer to use LUI/ADDIU stubs if the function is at the beginning
of the section and if we would need no more than 2 nops. */
value = mips_elf_get_la25_target (stub, &s);
+ if (ELF_ST_IS_MICROMIPS (stub->h->root.other))
+ value &= ~1;
use_trampoline_p = (value != 0 || s->alignment_power > 4);
h->la25_stub = stub;
All we need to do here is shuffle the bits appropriately.
As above, the two 16-bit halves must be swapped on a
- little-endian system. */
+ little-endian system.
+
+ Finally R_MIPS16_PC16_S1 corresponds to R_MIPS_PC16, however the
+ relocatable field is shifted by 1 rather than 2 and the same bit
+ shuffling is done as with the relocations above. */
static inline bfd_boolean
mips16_reloc_p (int r_type)
case R_MIPS16_TLS_GOTTPREL:
case R_MIPS16_TLS_TPREL_HI16:
case R_MIPS16_TLS_TPREL_LO16:
+ case R_MIPS16_PC16_S1:
return TRUE;
default:
|| r_type == R_MICROMIPS_26_S1);
}
+static inline bfd_boolean
+b_reloc_p (int r_type)
+{
+ return (r_type == R_MIPS_PC26_S2
+ || r_type == R_MIPS_PC21_S2
+ || r_type == R_MIPS_PC16
+ || r_type == R_MIPS_GNU_REL16_S2
+ || r_type == R_MIPS16_PC16_S1
+ || r_type == R_MICROMIPS_PC16_S1
+ || r_type == R_MICROMIPS_PC10_S1
+ || r_type == R_MICROMIPS_PC7_S1);
+}
+
static inline bfd_boolean
aligned_pcrel_reloc_p (int r_type)
{
|| r_type == R_MIPS_PC19_S2);
}
+static inline bfd_boolean
+branch_reloc_p (int r_type)
+{
+ return (r_type == R_MIPS_26
+ || r_type == R_MIPS_PC26_S2
+ || r_type == R_MIPS_PC21_S2
+ || r_type == R_MIPS_PC16
+ || r_type == R_MIPS_GNU_REL16_S2);
+}
+
+static inline bfd_boolean
+mips16_branch_reloc_p (int r_type)
+{
+ return (r_type == R_MIPS16_26
+ || r_type == R_MIPS16_PC16_S1);
+}
+
static inline bfd_boolean
micromips_branch_reloc_p (int r_type)
{
if (g->assigned_low_gotno > g->assigned_high_gotno)
{
/* We didn't allocate enough space in the GOT. */
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("not enough GOT space for local GOT entries"));
bfd_set_error (bfd_error_bad_value);
return NULL;
/* TRUE if the symbol referred to by this relocation is a local
symbol. */
bfd_boolean local_p, was_local_p;
+ /* TRUE if the symbol referred to by this relocation is a section
+ symbol. */
+ bfd_boolean section_p = FALSE;
/* TRUE if the symbol referred to by this relocation is "_gp_disp". */
bfd_boolean gp_disp_p = FALSE;
/* TRUE if the symbol referred to by this relocation is
/* Figure out the value of the symbol. */
if (local_p)
{
+ bfd_boolean micromips_p = MICROMIPS_P (abfd);
Elf_Internal_Sym *sym;
sym = local_syms + r_symndx;
sec = local_sections[r_symndx];
+ section_p = ELF_ST_TYPE (sym->st_info) == STT_SECTION;
+
symbol = sec->output_section->vma + sec->output_offset;
- if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
- || (sec->flags & SEC_MERGE))
+ if (!section_p || (sec->flags & SEC_MERGE))
symbol += sym->st_value;
- if ((sec->flags & SEC_MERGE)
- && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ if ((sec->flags & SEC_MERGE) && section_p)
{
addend = _bfd_elf_rel_local_sym (abfd, sym, &sec, addend);
addend -= symbol;
*namep = bfd_elf_string_from_elf_section (input_bfd,
symtab_hdr->sh_link,
sym->st_name);
- if (*namep == '\0')
+ if (*namep == NULL || **namep == '\0')
*namep = bfd_section_name (input_bfd, sec);
- target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (sym->st_other);
- target_is_micromips_code_p = ELF_ST_IS_MICROMIPS (sym->st_other);
+ /* For relocations against a section symbol and ones against no
+ symbol (absolute relocations) infer the ISA mode from the addend. */
+ if (section_p || r_symndx == STN_UNDEF)
+ {
+ target_is_16_bit_code_p = (addend & 1) && !micromips_p;
+ target_is_micromips_code_p = (addend & 1) && micromips_p;
+ }
+ /* For relocations against an absolute symbol infer the ISA mode
+ from the value of the symbol plus addend. */
+ else if (bfd_is_abs_section (sec))
+ {
+ target_is_16_bit_code_p = ((symbol + addend) & 1) && !micromips_p;
+ target_is_micromips_code_p = ((symbol + addend) & 1) && micromips_p;
+ }
+ /* Otherwise just use the regular symbol annotation available. */
+ else
+ {
+ target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (sym->st_other);
+ target_is_micromips_code_p = ELF_ST_IS_MICROMIPS (sym->st_other);
+ }
}
else
{
http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf */
symbol = 0;
}
- else if ((*info->callbacks->undefined_symbol)
- (info, h->root.root.root.string, input_bfd,
- input_section, relocation->r_offset,
- (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
- || ELF_ST_VISIBILITY (h->root.other)))
- {
- return bfd_reloc_undefined;
- }
else
{
- return bfd_reloc_notsupported;
+ (*info->callbacks->undefined_symbol)
+ (info, h->root.root.root.string, input_bfd,
+ input_section, relocation->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
+ || ELF_ST_VISIBILITY (h->root.other));
+ return bfd_reloc_undefined;
}
target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (h->root.other);
else if (h != NULL && h->la25_stub
&& mips_elf_relocation_needs_la25_stub (input_bfd, r_type,
target_is_16_bit_code_p))
- symbol = (h->la25_stub->stub_section->output_section->vma
- + h->la25_stub->stub_section->output_offset
- + h->la25_stub->offset);
+ {
+ symbol = (h->la25_stub->stub_section->output_section->vma
+ + h->la25_stub->stub_section->output_offset
+ + h->la25_stub->offset);
+ if (ELF_ST_IS_MICROMIPS (h->root.other))
+ symbol |= 1;
+ }
/* For direct MIPS16 and microMIPS calls make sure the compressed PLT
entry is used if a standard PLT entry has also been made. In this
case the symbol will have been set by mips_elf_set_plt_sym_value
to point to the standard PLT entry, so redirect to the compressed
one. */
- else if ((r_type == R_MIPS16_26 || r_type == R_MICROMIPS_26_S1)
+ else if ((mips16_branch_reloc_p (r_type)
+ || micromips_branch_reloc_p (r_type))
&& !bfd_link_relocatable (info)
&& h != NULL
&& h->use_plt_entry
}
/* Make sure MIPS16 and microMIPS are not used together. */
- if ((r_type == R_MIPS16_26 && target_is_micromips_code_p)
+ if ((mips16_branch_reloc_p (r_type) && target_is_micromips_code_p)
|| (micromips_branch_reloc_p (r_type) && target_is_16_bit_code_p))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("MIPS16 and microMIPS functions cannot call each other"));
return bfd_reloc_notsupported;
}
acceptable. */
*cross_mode_jump_p = (!bfd_link_relocatable (info)
&& !(h && h->root.root.type == bfd_link_hash_undefweak)
- && ((r_type == R_MIPS16_26 && !target_is_16_bit_code_p)
- || (r_type == R_MICROMIPS_26_S1
+ && ((mips16_branch_reloc_p (r_type)
+ && !target_is_16_bit_code_p)
+ || (micromips_branch_reloc_p (r_type)
&& !target_is_micromips_code_p)
- || ((r_type == R_MIPS_26 || r_type == R_MIPS_JALR)
+ || ((branch_reloc_p (r_type)
+ || r_type == R_MIPS_JALR)
&& (target_is_16_bit_code_p
|| target_is_micromips_code_p))));
{
unsigned int shift;
- /* Make sure the target of JALX is word-aligned. Bit 0 must be
- the correct ISA mode selector and bit 1 must be 0. */
- if (*cross_mode_jump_p && (symbol & 3) != (r_type == R_MIPS_26))
- return bfd_reloc_outofrange;
-
/* Shift is 2, unusually, for microMIPS JALX. */
shift = (!*cross_mode_jump_p && r_type == R_MICROMIPS_26_S1) ? 1 : 2;
- if (was_local_p)
- value = addend | ((p + 4) & (0xfc000000 << shift));
- else if (howto->partial_inplace)
+ if (howto->partial_inplace && !section_p)
value = _bfd_mips_elf_sign_extend (addend, 26 + shift);
else
value = addend;
- value = (value + symbol) >> shift;
- if (!was_local_p && h->root.root.type != bfd_link_hash_undefweak)
+ value += symbol;
+
+ /* Make sure the target of a jump is suitably aligned. Bit 0 must
+ be the correct ISA mode selector except for weak undefined
+ symbols. */
+ if ((was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ && (*cross_mode_jump_p
+ ? (value & 3) != (r_type == R_MIPS_26)
+ : (value & ((1 << shift) - 1)) != (r_type != R_MIPS_26)))
+ return bfd_reloc_outofrange;
+
+ value >>= shift;
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
overflowed_p = (value >> 26) != ((p + 4) >> (26 + shift));
value &= howto->dst_mask;
}
if (howto->partial_inplace)
addend = _bfd_mips_elf_sign_extend (addend, 18);
- if ((symbol + addend) & 3)
+ /* No need to exclude weak undefined symbols here as they resolve
+ to 0 and never set `*cross_mode_jump_p', so this alignment check
+ will never trigger for them. */
+ if (*cross_mode_jump_p
+ ? ((symbol + addend) & 3) != 1
+ : ((symbol + addend) & 3) != 0)
return bfd_reloc_outofrange;
value = symbol + addend - p;
value &= howto->dst_mask;
break;
+ case R_MIPS16_PC16_S1:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 17);
+
+ if ((was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ && (*cross_mode_jump_p
+ ? ((symbol + addend) & 3) != 0
+ : ((symbol + addend) & 1) == 0))
+ return bfd_reloc_outofrange;
+
+ value = symbol + addend - p;
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 17);
+ value >>= howto->rightshift;
+ value &= howto->dst_mask;
+ break;
+
case R_MIPS_PC21_S2:
if (howto->partial_inplace)
addend = _bfd_mips_elf_sign_extend (addend, 23);
case R_MICROMIPS_PC7_S1:
if (howto->partial_inplace)
addend = _bfd_mips_elf_sign_extend (addend, 8);
+
+ if ((was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ && (*cross_mode_jump_p
+ ? ((symbol + addend + 2) & 3) != 0
+ : ((symbol + addend + 2) & 1) == 0))
+ return bfd_reloc_outofrange;
+
value = symbol + addend - p;
if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
overflowed_p = mips_elf_overflow_p (value, 8);
case R_MICROMIPS_PC10_S1:
if (howto->partial_inplace)
addend = _bfd_mips_elf_sign_extend (addend, 11);
+
+ if ((was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ && (*cross_mode_jump_p
+ ? ((symbol + addend + 2) & 3) != 0
+ : ((symbol + addend + 2) & 1) == 0))
+ return bfd_reloc_outofrange;
+
value = symbol + addend - p;
if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
overflowed_p = mips_elf_overflow_p (value, 11);
case R_MICROMIPS_PC16_S1:
if (howto->partial_inplace)
addend = _bfd_mips_elf_sign_extend (addend, 17);
+
+ if ((was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ && (*cross_mode_jump_p
+ ? ((symbol + addend) & 3) != 0
+ : ((symbol + addend) & 1) == 0))
+ return bfd_reloc_outofrange;
+
value = symbol + addend - p;
if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
overflowed_p = mips_elf_overflow_p (value, 17);
/* Set the field. */
x |= (value & howto->dst_mask);
- /* If required, turn JAL into JALX. */
+ /* Detect incorrect JALX usage. If required, turn JAL or BAL into JALX. */
+ if (!cross_mode_jump_p && jal_reloc_p (r_type))
+ {
+ bfd_vma opcode = x >> 26;
+
+ if (r_type == R_MIPS16_26 ? opcode == 0x7
+ : r_type == R_MICROMIPS_26_S1 ? opcode == 0x3c
+ : opcode == 0x1d)
+ {
+ info->callbacks->einfo
+ (_("%X%H: Unsupported JALX to the same ISA mode\n"),
+ input_bfd, input_section, relocation->r_offset);
+ return TRUE;
+ }
+ }
if (cross_mode_jump_p && jal_reloc_p (r_type))
{
bfd_boolean ok;
convert J or JALS to JALX. */
if (!ok)
{
- (*_bfd_error_handler)
- (_("%B: %A+0x%lx: Unsupported jump between ISA modes; consider recompiling with interlinking enabled."),
- input_bfd,
- input_section,
- (unsigned long) relocation->r_offset);
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ info->callbacks->einfo
+ (_("%X%H: Unsupported jump between ISA modes; "
+ "consider recompiling with interlinking enabled\n"),
+ input_bfd, input_section, relocation->r_offset);
+ return TRUE;
}
/* Make this the JALX opcode. */
x = (x & ~(0x3f << 26)) | (jalx_opcode << 26);
}
+ else if (cross_mode_jump_p && b_reloc_p (r_type))
+ {
+ bfd_boolean ok = FALSE;
+ bfd_vma opcode = x >> 16;
+ bfd_vma jalx_opcode = 0;
+ bfd_vma addr;
+ bfd_vma dest;
+
+ if (r_type == R_MICROMIPS_PC16_S1)
+ {
+ ok = opcode == 0x4060;
+ jalx_opcode = 0x3c;
+ value <<= 1;
+ }
+ else if (r_type == R_MIPS_PC16 || r_type == R_MIPS_GNU_REL16_S2)
+ {
+ ok = opcode == 0x411;
+ jalx_opcode = 0x1d;
+ value <<= 2;
+ }
+
+ if (bfd_link_pic (info) || !ok)
+ {
+ info->callbacks->einfo
+ (_("%X%H: Unsupported branch between ISA modes\n"),
+ input_bfd, input_section, relocation->r_offset);
+ return TRUE;
+ }
+
+ addr = (input_section->output_section->vma
+ + input_section->output_offset
+ + relocation->r_offset
+ + 4);
+ dest = addr + (((value & 0x3ffff) ^ 0x20000) - 0x20000);
+
+ if ((addr >> 28) << 28 != (dest >> 28) << 28)
+ {
+ info->callbacks->einfo
+ (_("%X%H: Cannot convert branch between ISA modes "
+ "to JALX: relocation out of range\n"),
+ input_bfd, input_section, relocation->r_offset);
+ return TRUE;
+ }
+
+ /* Make this the JALX opcode. */
+ x = ((dest >> 2) & 0x3ffffff) | jalx_opcode << 26;
+ }
/* Try converting JAL to BAL and J(AL)R to B(AL), if the target is in
range. */
&intopt);
if (intopt.size < sizeof (Elf_External_Options))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: Warning: bad `%s' option size %u smaller than its header"),
abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size);
break;
&intopt);
if (intopt.size < sizeof (Elf_External_Options))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: Warning: bad `%s' option size %u smaller than its header"),
abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size);
break;
r_symndx = mips16_stub_symndx (bed, sec, relocs, rel_end);
if (r_symndx == 0)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: Warning: cannot determine the target function for"
" stub section `%s'"),
abfd, name);
r_symndx = mips16_stub_symndx (bed, sec, relocs, rel_end);
if (r_symndx == 0)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: Warning: cannot determine the target function for"
" stub section `%s'"),
abfd, name);
h = NULL;
else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: Malformed reloc detected for section %s"),
abfd, name);
bfd_set_error (bfd_error_bad_value);
return FALSE;
if (htab->is_vxworks && !bfd_link_pic (info))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: GOT reloc at 0x%lx not expected in executables"),
abfd, (unsigned long) rel->r_offset);
bfd_set_error (bfd_error_bad_value);
case R_MIPS_PC21_S2:
case R_MIPS_PC26_S2:
case R_MIPS16_26:
+ case R_MIPS16_PC16_S1:
case R_MICROMIPS_26_S1:
case R_MICROMIPS_PC7_S1:
case R_MICROMIPS_PC10_S1:
case R_MICROMIPS_CALL16:
if (h == NULL)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: CALL16 reloc at 0x%lx not against global symbol"),
abfd, (unsigned long) rel->r_offset);
bfd_set_error (bfd_error_bad_value);
a PLT entry is not created because the symbol is satisfied
locally. */
if (h != NULL
- && jal_reloc_p (r_type)
+ && (branch_reloc_p (r_type)
+ || mips16_branch_reloc_p (r_type)
+ || micromips_branch_reloc_p (r_type))
&& !SYMBOL_CALLS_LOCAL (info, h))
{
if (h->plt.plist == NULL)
if (h->plt.plist == NULL)
return FALSE;
- if (r_type == R_MIPS_26)
+ if (branch_reloc_p (r_type))
h->plt.plist->need_mips = TRUE;
else
h->plt.plist->need_comp = TRUE;
case R_MIPS_26:
case R_MICROMIPS_26_S1:
howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, r_type, FALSE);
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
abfd, howto->name,
(h) ? h->root.root.string : "a local symbol");
some that we can't convert. */
if (!htab->use_plts_and_copy_relocs || bfd_link_pic (info))
{
- (*_bfd_error_handler) (_("non-dynamic relocations refer to "
- "dynamic symbol %s"),
- h->root.root.string);
+ _bfd_error_handler (_("non-dynamic relocations refer to "
+ "dynamic symbol %s"),
+ h->root.root.string);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
name = bfd_elf_sym_name (input_bfd, symtab_hdr,
local_syms + r_symndx,
sec);
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"),
input_bfd, input_section, name, howto->name,
rel->r_offset);
htab->small_data_overflow_reported = TRUE;
(*info->callbacks->einfo) ("%P: %s\n", msg);
}
- if (! ((*info->callbacks->reloc_overflow)
- (info, NULL, name, howto->name, (bfd_vma) 0,
- input_bfd, input_section, rel->r_offset)))
- return FALSE;
+ (*info->callbacks->reloc_overflow)
+ (info, NULL, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset);
}
break;
case bfd_reloc_outofrange:
msg = NULL;
if (jal_reloc_p (howto->type))
- msg = _("JALX to a non-word-aligned address");
+ msg = (cross_mode_jump_p
+ ? _("Cannot convert a jump to JALX "
+ "for a non-word-aligned address")
+ : (howto->type == R_MIPS16_26
+ ? _("Jump to a non-word-aligned address")
+ : _("Jump to a non-instruction-aligned address")));
+ else if (b_reloc_p (howto->type))
+ msg = (cross_mode_jump_p
+ ? _("Cannot convert a branch to JALX "
+ "for a non-word-aligned address")
+ : _("Branch to a non-instruction-aligned address"));
else if (aligned_pcrel_reloc_p (howto->type))
msg = _("PC-relative load from unaligned address");
if (msg)
{
- info->callbacks->warning
- (info, msg, name, input_bfd, input_section, rel->r_offset);
- return FALSE;
+ info->callbacks->einfo
+ ("%X%H: %s\n", input_bfd, input_section, rel->r_offset, msg);
+ break;
}
/* Fall through. */
/* ADDIUPC has a span of +/-16MB, check we're in range. */
if (gotpc_offset + 0x1000000 >= 0x2000000)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: `%A' offset of %ld from `%A' "
"beyond the range of ADDIUPC"),
output_bfd,
/* ADDIUPC has a span of +/-16MB, check we're in range. */
if (gotpc_offset + 0x1000000 >= 0x2000000)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: `%A' offset of %ld from `%A' beyond the range of ADDIUPC"),
output_bfd,
htab->sgotplt->output_section,
}
/* In case if we don't have global got symbols we default
to setting DT_MIPS_GOTSYM to the same value as
- DT_MIPS_SYMTABNO, so we just fall through. */
+ DT_MIPS_SYMTABNO. */
+ /* Fall through. */
case DT_MIPS_SYMTABNO:
name = ".dynsym";
switch (r)
{
case bfd_reloc_undefined:
- if (!((*link_info->callbacks->undefined_symbol)
- (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
- input_bfd, input_section, (*parent)->address, TRUE)))
- goto error_return;
+ (*link_info->callbacks->undefined_symbol)
+ (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+ input_bfd, input_section, (*parent)->address, TRUE);
break;
case bfd_reloc_dangerous:
BFD_ASSERT (error_message != NULL);
- if (!((*link_info->callbacks->reloc_dangerous)
- (link_info, error_message, input_bfd, input_section,
- (*parent)->address)))
- goto error_return;
+ (*link_info->callbacks->reloc_dangerous)
+ (link_info, error_message,
+ input_bfd, input_section, (*parent)->address);
break;
case bfd_reloc_overflow:
- if (!((*link_info->callbacks->reloc_overflow)
- (link_info, NULL,
- bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
- (*parent)->howto->name, (*parent)->addend,
- input_bfd, input_section, (*parent)->address)))
- goto error_return;
+ (*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+ (*parent)->howto->name, (*parent)->addend,
+ input_bfd, input_section, (*parent)->address);
break;
case bfd_reloc_outofrange:
default:
case E_MIPS_ARCH_64R2: new_isa = LEVEL_REV (64, 2); break;
case E_MIPS_ARCH_64R6: new_isa = LEVEL_REV (64, 6); break;
default:
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: Unknown architecture %s"),
abfd, bfd_printable_name (abfd));
}
gptab_bss_sec = o;
else
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%s: illegal section name `%s'"),
bfd_get_filename (abfd), o->name);
bfd_set_error (bfd_error_nonrepresentable_section);
if there are conflicting settings. */
static bfd_boolean
-mips_elf_merge_obj_e_flags (bfd *ibfd, bfd *obfd)
+mips_elf_merge_obj_e_flags (bfd *ibfd, struct bfd_link_info *info)
{
+ bfd *obfd = info->output_bfd;
struct mips_elf_obj_tdata *out_tdata = mips_elf_tdata (obfd);
flagword old_flags;
flagword new_flags;
if (((new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0)
!= ((old_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: warning: linking abicalls files with non-abicalls files"),
ibfd);
ok = TRUE;
/* Compare the ISAs. */
if (mips_32bit_flags_p (old_flags) != mips_32bit_flags_p (new_flags))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: linking 32-bit code with 64-bit code"),
ibfd);
ok = FALSE;
else
{
/* The ISAs aren't compatible. */
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: linking %s module with previous %s modules"),
ibfd,
bfd_printable_name (ibfd),
|| (elf_elfheader (ibfd)->e_ident[EI_CLASS]
!= elf_elfheader (obfd)->e_ident[EI_CLASS]))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: ABI mismatch: linking %s module with previous %s modules"),
ibfd,
elf_mips_abi_name (ibfd),
if (m16_mis || micro_mis)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: ASE mismatch: linking %s module with previous %s modules"),
ibfd,
m16_mis ? "MIPS16" : "microMIPS",
/* Compare NaN encodings. */
if ((new_flags & EF_MIPS_NAN2008) != (old_flags & EF_MIPS_NAN2008))
{
+ /* xgettext:c-format */
_bfd_error_handler (_("%B: linking %s module with previous %s modules"),
ibfd,
(new_flags & EF_MIPS_NAN2008
/* Compare FP64 state. */
if ((new_flags & EF_MIPS_FP64) != (old_flags & EF_MIPS_FP64))
{
+ /* xgettext:c-format */
_bfd_error_handler (_("%B: linking %s module with previous %s modules"),
ibfd,
(new_flags & EF_MIPS_FP64
/* Warn about any other mismatches */
if (new_flags != old_flags)
{
- (*_bfd_error_handler)
+ /* xgettext:c-format */
+ _bfd_error_handler
(_("%B: uses different e_flags (0x%lx) fields than previous modules "
"(0x%lx)"),
ibfd, (unsigned long) new_flags,
/* Merge object attributes from IBFD into OBFD. Raise an error if
there are conflicting attributes. */
static bfd_boolean
-mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
+mips_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
{
+ bfd *obfd = info->output_bfd;
obj_attribute *in_attr;
obj_attribute *out_attr;
bfd *abi_fp_bfd;
in_string = _bfd_mips_fp_abi_string (in_fp);
/* First warn about cases involving unrecognised ABIs. */
if (!out_string && !in_string)
+ /* xgettext:c-format */
_bfd_error_handler
(_("Warning: %B uses unknown floating point ABI %d "
"(set by %B), %B uses unknown floating point ABI %d"),
obfd, abi_fp_bfd, ibfd, out_fp, in_fp);
else if (!out_string)
_bfd_error_handler
+ /* xgettext:c-format */
(_("Warning: %B uses unknown floating point ABI %d "
"(set by %B), %B uses %s"),
obfd, abi_fp_bfd, ibfd, out_fp, in_string);
else if (!in_string)
_bfd_error_handler
+ /* xgettext:c-format */
(_("Warning: %B uses %s (set by %B), "
"%B uses unknown floating point ABI %d"),
obfd, abi_fp_bfd, ibfd, out_string, in_fp);
else if (out_fp == Val_GNU_MIPS_ABI_FP_SOFT)
in_string = "-mhard-float";
_bfd_error_handler
+ /* xgettext:c-format */
(_("Warning: %B uses %s (set by %B), %B uses %s"),
obfd, abi_fp_bfd, ibfd, out_string, in_string);
}
{
case Val_GNU_MIPS_ABI_MSA_128:
_bfd_error_handler
+ /* xgettext:c-format */
(_("Warning: %B uses %s (set by %B), "
"%B uses unknown MSA ABI %d"),
obfd, abi_msa_bfd, ibfd,
{
case Val_GNU_MIPS_ABI_MSA_128:
_bfd_error_handler
+ /* xgettext:c-format */
(_("Warning: %B uses unknown MSA ABI %d "
"(set by %B), %B uses %s"),
obfd, abi_msa_bfd, ibfd,
default:
_bfd_error_handler
+ /* xgettext:c-format */
(_("Warning: %B uses unknown MSA ABI %d "
"(set by %B), %B uses unknown MSA ABI %d"),
obfd, abi_msa_bfd, ibfd,
}
/* Merge Tag_compatibility attributes and any common GNU ones. */
- return _bfd_elf_merge_object_attributes (ibfd, obfd);
+ return _bfd_elf_merge_object_attributes (ibfd, info);
}
/* Merge object ABI flags from IBFD into OBFD. Raise an error if
object file when linking. */
bfd_boolean
-_bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+_bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
+ bfd *obfd = info->output_bfd;
struct mips_elf_obj_tdata *out_tdata;
struct mips_elf_obj_tdata *in_tdata;
bfd_boolean null_input_bfd = TRUE;
bfd_boolean ok;
/* Check if we have the same endianness. */
- if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ if (! _bfd_generic_verify_endian_match (ibfd, info))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: endianness incompatible with that of the selected emulation"),
ibfd);
return FALSE;
if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: ABI is incompatible with that of the selected emulation"),
ibfd);
return FALSE;
if (LEVEL_REV (in_abiflags.isa_level, in_abiflags.isa_rev)
< LEVEL_REV (abiflags.isa_level, abiflags.isa_rev))
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: warning: Inconsistent ISA between e_flags and "
".MIPS.abiflags"), ibfd);
if (abiflags.fp_abi != Val_GNU_MIPS_ABI_FP_ANY
&& in_abiflags.fp_abi != abiflags.fp_abi)
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: warning: Inconsistent FP ABI between .gnu.attributes and "
".MIPS.abiflags"), ibfd);
if ((in_abiflags.ases & abiflags.ases) != abiflags.ases)
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: warning: Inconsistent ASEs between e_flags and "
".MIPS.abiflags"), ibfd);
/* The isa_ext is allowed to be an extension of what can be inferred
from e_flags. */
if (!mips_mach_extends_p (bfd_mips_isa_ext_mach (abiflags.isa_ext),
bfd_mips_isa_ext_mach (in_abiflags.isa_ext)))
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: warning: Inconsistent ISA extensions between e_flags and "
".MIPS.abiflags"), ibfd);
if (in_abiflags.flags2 != 0)
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: warning: Unexpected flag in the flags2 field of "
".MIPS.abiflags (0x%lx)"), ibfd,
(unsigned long) in_abiflags.flags2);
ok = TRUE;
}
else
- ok = mips_elf_merge_obj_e_flags (ibfd, obfd);
+ ok = mips_elf_merge_obj_e_flags (ibfd, info);
- ok = mips_elf_merge_obj_attributes (ibfd, obfd) && ok;
+ ok = mips_elf_merge_obj_attributes (ibfd, info) && ok;
ok = mips_elf_merge_obj_abiflags (ibfd, obfd) && ok;