aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-mips.c
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@imgtec.com>2016-06-21 21:22:39 +0100
committerMaciej W. Rozycki <macro@imgtec.com>2016-06-21 23:00:20 +0100
commit41947d9e38c4fd27b17843f328d58138193e4f19 (patch)
treeab440ef62ed51a22e1f7c1fd4214585e69afd8b9 /gas/config/tc-mips.c
parent717ba204e06d88ed68441e236da3688a92cf054c (diff)
downloadgdb-41947d9e38c4fd27b17843f328d58138193e4f19.zip
gdb-41947d9e38c4fd27b17843f328d58138193e4f19.tar.gz
gdb-41947d9e38c4fd27b17843f328d58138193e4f19.tar.bz2
MIPS/GAS: Handle resolved R6 PC-relative relocations
Complement commit 7361da2c952e ("Add support for MIPS R6.") and fix internal errors like: foo.s: Assembler messages: foo.s: Internal error! Assertion failure in md_apply_fix at .../gas/config/tc-mips.c:15028. Please report this bug. triggered by resolved R6 PC-relative relocations in sources containing R6 code fragments wrapped into ISA override blocks embedded within code otherwise assembled for an older ISA. gas/ * config/tc-mips.c (calculate_reloc) <BFD_RELOC_HI16_S_PCREL> <BFD_RELOC_LO16_PCREL>: New switch cases. (md_apply_fix) <BFD_RELOC_HI16_S_PCREL, BFD_RELOC_LO16_PCREL>: Move switch cases along `BFD_RELOC_MIPS_JMP'. <BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2> <BFD_RELOC_MIPS_18_PCREL_S3, BFD_RELOC_MIPS_19_PCREL_S2>: Handle the resolved case. * testsuite/gas/mips/pcrel-reloc-4.d: New test. * testsuite/gas/mips/pcrel-reloc-4-r6.d: New test. * testsuite/gas/mips/pcrel-reloc-5.d: New test. * testsuite/gas/mips/pcrel-reloc-5-r6.d: New test. * testsuite/gas/mips/pcrel-reloc-6.d: New test. * testsuite/gas/mips/pcrel-reloc-6.l: New list test. * testsuite/gas/mips/pcrel-reloc-4.s: New test source. * testsuite/gas/mips/pcrel-reloc-6.s: New test source. * testsuite/gas/mips/mips.exp: Run the new tests.
Diffstat (limited to 'gas/config/tc-mips.c')
-rw-r--r--gas/config/tc-mips.c62
1 files changed, 54 insertions, 8 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index c598806..6891508 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -6972,6 +6972,7 @@ calculate_reloc (bfd_reloc_code_real_type reloc, offsetT operand,
return TRUE;
case BFD_RELOC_HI16_S:
+ case BFD_RELOC_HI16_S_PCREL:
case BFD_RELOC_MICROMIPS_HI16_S:
case BFD_RELOC_MIPS16_HI16_S:
*result = ((operand + 0x8000) >> 16) & 0xffff;
@@ -6984,6 +6985,7 @@ calculate_reloc (bfd_reloc_code_real_type reloc, offsetT operand,
return TRUE;
case BFD_RELOC_LO16:
+ case BFD_RELOC_LO16_PCREL:
case BFD_RELOC_MICROMIPS_LO16:
case BFD_RELOC_MIPS16_LO16:
*result = operand & 0xffff;
@@ -14944,6 +14946,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_MIPS_GOT_LO16:
case BFD_RELOC_MIPS_CALL_HI16:
case BFD_RELOC_MIPS_CALL_LO16:
+ case BFD_RELOC_HI16_S_PCREL:
+ case BFD_RELOC_LO16_PCREL:
case BFD_RELOC_MIPS16_GPREL:
case BFD_RELOC_MIPS16_GOT16:
case BFD_RELOC_MIPS16_CALL16:
@@ -15025,12 +15029,39 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
break;
case BFD_RELOC_MIPS_21_PCREL_S2:
+ if ((*valP & 0x3) != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("branch to misaligned address (%lx)"), (long) *valP);
+ if (!fixP->fx_done)
+ break;
+
+ if (*valP + 0x400000 <= 0x7fffff)
+ {
+ insn = read_insn (buf);
+ insn |= (*valP >> 2) & 0x1fffff;
+ write_insn (buf, insn);
+ }
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("branch out of range"));
+ break;
+
case BFD_RELOC_MIPS_26_PCREL_S2:
if ((*valP & 0x3) != 0)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("branch to misaligned address (%lx)"), (long) *valP);
+ if (!fixP->fx_done)
+ break;
- gas_assert (!fixP->fx_done);
+ if (*valP + 0x8000000 <= 0xfffffff)
+ {
+ insn = read_insn (buf);
+ insn |= (*valP >> 2) & 0x3ffffff;
+ write_insn (buf, insn);
+ }
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("branch out of range"));
break;
case BFD_RELOC_MIPS_18_PCREL_S3:
@@ -15042,8 +15073,18 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("PC-relative access using misaligned offset (%lx)"),
(long) fixP->fx_offset);
+ if (!fixP->fx_done)
+ break;
- gas_assert (!fixP->fx_done);
+ if (*valP + 0x100000 <= 0x1fffff)
+ {
+ insn = read_insn (buf);
+ insn |= (*valP >> 3) & 0x3ffff;
+ write_insn (buf, insn);
+ }
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("PC-relative access out of range"));
break;
case BFD_RELOC_MIPS_19_PCREL_S2:
@@ -15051,13 +15092,18 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("PC-relative access to misaligned address (%lx)"),
(long) *valP);
+ if (!fixP->fx_done)
+ break;
- gas_assert (!fixP->fx_done);
- break;
-
- case BFD_RELOC_HI16_S_PCREL:
- case BFD_RELOC_LO16_PCREL:
- gas_assert (!fixP->fx_done);
+ if (*valP + 0x100000 <= 0x1fffff)
+ {
+ insn = read_insn (buf);
+ insn |= (*valP >> 2) & 0x7ffff;
+ write_insn (buf, insn);
+ }
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("PC-relative access out of range"));
break;
case BFD_RELOC_16_PCREL_S2: