diff options
author | Maciej W. Rozycki <macro@imgtec.com> | 2016-06-21 21:22:39 +0100 |
---|---|---|
committer | Maciej W. Rozycki <macro@imgtec.com> | 2016-06-21 23:00:20 +0100 |
commit | 41947d9e38c4fd27b17843f328d58138193e4f19 (patch) | |
tree | ab440ef62ed51a22e1f7c1fd4214585e69afd8b9 /gas/config/tc-mips.c | |
parent | 717ba204e06d88ed68441e236da3688a92cf054c (diff) | |
download | gdb-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.c | 62 |
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: |