* config/tc-mips.h (DIFF_EXPR_OK, CFI_DIFF_EXPR_OK): Define.
	* config/tc-mips.c (md_pcrel_from): Remove error message.
	(md_apply_fix): Convert PC-relative BFD_RELOC_32s to
	BFD_RELOC_32_PCREL.  Report a specific error message for unhandled
	PC-relative expressions.  Handle BFD_RELOC_8.

gas/testsuite/
	* gas/all/gas.exp: Remove XFAIL of forward.d for MIPS.
	* gas/mips/pcrel-1.s, gas/mips/pcrel-1.d, gas/mips/pcrel-2.s,
	gas/mips/pcrel-2.d, gas/mips/pcrel-3.s, gas/mips/pcrel-3.l,
	gas/mips/pcrel-4.s, gas/mips/pcrel-4-32.d, gas/mips/pcrel-4-n32.d,
	gas/mips/pcrel-4-64.d: New tests.
	* gas/mips/mips.exp: Run them.
	* gas/mips/lui-2.l: Tweak error message for line 7.

ld/testsuite/
	* ld-elf/merge.d: Remove MIPS XFAIL.
This commit is contained in:
Richard Sandiford
2014-03-20 21:18:43 +00:00
parent 1bff71c325
commit d56a8dda6d
19 changed files with 187 additions and 21 deletions

View File

@@ -14057,15 +14057,7 @@ md_pcrel_from (fixS *fixP)
/* Return the address of the delay slot. */
return addr + 4;
case BFD_RELOC_32_PCREL:
return addr;
default:
/* We have no relocation type for PC relative MIPS16 instructions. */
if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != now_seg)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("PC relative MIPS16 instruction references"
" a different section"));
return addr;
}
}
@@ -14262,13 +14254,38 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
unsigned long insn;
reloc_howto_type *howto;
/* We ignore generic BFD relocations we don't know about. */
howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
if (! howto)
return;
if (fixP->fx_pcrel)
switch (fixP->fx_r_type)
{
case BFD_RELOC_16_PCREL_S2:
case BFD_RELOC_MICROMIPS_7_PCREL_S1:
case BFD_RELOC_MICROMIPS_10_PCREL_S1:
case BFD_RELOC_MICROMIPS_16_PCREL_S1:
case BFD_RELOC_32_PCREL:
break;
case BFD_RELOC_32:
fixP->fx_r_type = BFD_RELOC_32_PCREL;
break;
default:
as_bad_where (fixP->fx_file, fixP->fx_line,
_("PC-relative reference to a different section"));
break;
}
/* Handle BFD_RELOC_8, since it's easy. Punt on other bfd relocations
that have no MIPS ELF equivalent. */
if (fixP->fx_r_type != BFD_RELOC_8)
{
howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
if (!howto)
return;
}
gas_assert (fixP->fx_size == 2
|| fixP->fx_size == 4
|| fixP->fx_r_type == BFD_RELOC_8
|| fixP->fx_r_type == BFD_RELOC_16
|| fixP->fx_r_type == BFD_RELOC_64
|| fixP->fx_r_type == BFD_RELOC_CTOR
@@ -14280,12 +14297,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
buf = fixP->fx_frag->fr_literal + fixP->fx_where;
gas_assert (!fixP->fx_pcrel || fixP->fx_r_type == BFD_RELOC_16_PCREL_S2
|| fixP->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1
|| fixP->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1
|| fixP->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1
|| fixP->fx_r_type == BFD_RELOC_32_PCREL);
/* Don't treat parts of a composite relocation as done. There are two
reasons for this:
@@ -14435,6 +14446,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_32:
case BFD_RELOC_32_PCREL:
case BFD_RELOC_16:
case BFD_RELOC_8:
/* If we are deleting this reloc entry, we must fill in the
value now. This can happen if we have a .word which is not
resolved when it appears but is later defined. */