This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] MIPS/GAS: Correct the handling of %hi/%lo with subtraction
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: "Maciej W. Rozycki" <macro at codesourcery dot com>
- Cc: <binutils at sourceware dot org>
- Date: Sun, 23 Sep 2012 12:16:06 +0100
- Subject: Re: [PATCH] MIPS/GAS: Correct the handling of %hi/%lo with subtraction
- References: <alpine.DEB.1.10.1209211726270.28358@tp.orcam.me.uk>
"Maciej W. Rozycki" <macro@codesourcery.com> writes:
> Issues #1-3 are handled by the patch below. I have removed any range
> checks for the LO16 relocation and added further code to handle the MIPS16
> case right. I have added complementing code for HI16 relocations, that is
> similar to that for LO16, but I've decided not to obfuscate it too much
> and didn't factor it out.
I'm not buying that :-) The relocation value we want to install
doesn't depend on the current contents of the instruction, so I don't
think that:
install_reloc (...(*valP + 0x8000) >> 16...);
(for hi) and:
install_reloc (...*valP...);
(for lo) is any less obfuscated than cut-&-pasting all the insn reading
and writing bits.
IMO, the problem with the current code is lack of factoring. It's no
harder to resolve relocations at md_apply_fix time than at md_assemble
time, but at the moment they use two separate pieces of code.
If we use a common routine for both then...
> Issue #5 is fixed simply by checking for the condition and reporting an
> error -- GAS shouldn't silently produce wrong code, but such usage is
> currently unknown. It may well be that it'll trigger somewhere and some
> further cases may have to be implemented. I have deliberately disregarded
> the cases of HIGHER and HIGHEST relocs that are relevant to the original
> scenario reported in the issue where the n64 ABI is used -- for them to
> have any significance the distance between the symbols would have to be
> greater than 2GB and 128TB respectively. I have therefore concluded that
> implementing any handling would be a wasted effort at this time. Sent
> separately.
...the HIGHER and HIGHEST bits come out in the wash.
As with the jump relocs discussed in the other thread, we could simply
set fx_done back to 0 for other relocs on RELA targets, but REL would
again require more care. E.g. %got_hi would need the high part of the
constant to be installed in-place; simply setting fx_done to 0
and relying on the generic overflow check would produce wrong results
for that kind of reloc. So here too I agree it's best to report
an error across the board.
I ended up adding a separate test for TLS relocs against constants,
since at the moment they trigger a segfault on:
S_SET_THREAD_LOCAL (fixP->fx_addsy);
I also stopped md_assemble from trying to resolve compound relocations
against constants and removed some code from mips_force_relocation that
was superceded by the md_apply_fix fx_tcbit handling.
Tested on the usual targets and installed.
Richard
gas/
* config/tc-mips.h (TC_FORCE_RELOCATION): Remove comment.
* config/tc-mips.c (calculate_reloc): New function.
(append_insn): Use it. Do not resolve compound relocations here.
(mips16_macro_build, mips16_ip): Use calculate_reloc.
(mips16_immed_extend): New function, split out from...
(mips16_immed): ...here.
(mips_frob_file): Handle null symbols.
(mips_force_relocation): Remove NEWABI handling.
(read_reloc_insn, write_reloc_insn): New functions.
(md_apply_fix): Report TLS relocations against constants.
Use read_reloc_insn, calculate_reloc and write_reloc_insn.
Report relocations against constants that can't be resolved
at assembly time.
gas/testsuite/
* gas/mips/elf-rel22.s, gas/mips/elf-rel22.d: Add more tests.
* gas/mips/elf-rel29.s, gas/mips/elf-rel29.d,
gas/mips/micromips@elf-rel29.d, gas/mips/elf-rel30.s,
gas/mips/elf-rel30.l: New tests.
* gas/mips/mips.exp: Run them.
Index: gas/config/tc-mips.h
===================================================================
--- gas/config/tc-mips.h 2012-09-23 11:14:15.139201408 +0100
+++ gas/config/tc-mips.h 2012-09-23 11:14:46.203200507 +0100
@@ -137,8 +137,6 @@ #define MD_APPLY_SYM_VALUE(FIX) 0
#define EXTERN_FORCE_RELOC \
(OUTPUT_FLAVOR == bfd_target_elf_flavour)
-/* When generating NEWABI code, we may need to have to keep combined
- relocations which don't have symbols. */
#define TC_FORCE_RELOCATION(FIX) mips_force_relocation (FIX)
extern int mips_force_relocation (struct fix *);
Index: gas/config/tc-mips.c
===================================================================
--- gas/config/tc-mips.c 2012-09-23 11:14:19.385201287 +0100
+++ gas/config/tc-mips.c 2012-09-23 11:14:46.200200508 +0100
@@ -4022,6 +4022,52 @@ micromips_map_reloc (bfd_reloc_code_real
return reloc;
}
+/* Try to resolve relocation RELOC against constant OPERAND at assembly time.
+ Return true on success, storing the resolved value in RESULT. */
+
+static bfd_boolean
+calculate_reloc (bfd_reloc_code_real_type reloc, offsetT operand,
+ offsetT *result)
+{
+ switch (reloc)
+ {
+ case BFD_RELOC_MIPS_HIGHEST:
+ case BFD_RELOC_MICROMIPS_HIGHEST:
+ *result = ((operand + 0x800080008000ull) >> 48) & 0xffff;
+ return TRUE;
+
+ case BFD_RELOC_MIPS_HIGHER:
+ case BFD_RELOC_MICROMIPS_HIGHER:
+ *result = ((operand + 0x80008000ull) >> 32) & 0xffff;
+ return TRUE;
+
+ case BFD_RELOC_HI16_S:
+ case BFD_RELOC_MICROMIPS_HI16_S:
+ case BFD_RELOC_MIPS16_HI16_S:
+ *result = ((operand + 0x8000) >> 16) & 0xffff;
+ return TRUE;
+
+ case BFD_RELOC_HI16:
+ case BFD_RELOC_MICROMIPS_HI16:
+ case BFD_RELOC_MIPS16_HI16:
+ *result = (operand >> 16) & 0xffff;
+ return TRUE;
+
+ case BFD_RELOC_LO16:
+ case BFD_RELOC_MICROMIPS_LO16:
+ case BFD_RELOC_MIPS16_LO16:
+ *result = operand & 0xffff;
+ return TRUE;
+
+ case BFD_RELOC_UNUSED:
+ *result = operand;
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
/* Output an instruction. IP is the instruction information.
ADDRESS_EXPR is an operand of the instruction to be used with
RELOC_TYPE. EXPANSIONP is true if the instruction is part of
@@ -4057,43 +4103,13 @@ append_insn (struct mips_cl_insn *ip, ex
if (address_expr == NULL)
ip->complete_p = 1;
- else if (*reloc_type <= BFD_RELOC_UNUSED
+ else if (reloc_type[0] <= BFD_RELOC_UNUSED
+ && reloc_type[1] == BFD_RELOC_UNUSED
+ && reloc_type[2] == BFD_RELOC_UNUSED
&& address_expr->X_op == O_constant)
{
- unsigned int tmp;
-
- ip->complete_p = 1;
switch (*reloc_type)
{
- case BFD_RELOC_32:
- ip->insn_opcode |= address_expr->X_add_number;
- break;
-
- case BFD_RELOC_MIPS_HIGHEST:
- tmp = (address_expr->X_add_number + 0x800080008000ull) >> 48;
- ip->insn_opcode |= tmp & 0xffff;
- break;
-
- case BFD_RELOC_MIPS_HIGHER:
- tmp = (address_expr->X_add_number + 0x80008000ull) >> 32;
- ip->insn_opcode |= tmp & 0xffff;
- break;
-
- case BFD_RELOC_HI16_S:
- tmp = (address_expr->X_add_number + 0x8000) >> 16;
- ip->insn_opcode |= tmp & 0xffff;
- break;
-
- case BFD_RELOC_HI16:
- ip->insn_opcode |= (address_expr->X_add_number >> 16) & 0xffff;
- break;
-
- case BFD_RELOC_UNUSED:
- case BFD_RELOC_LO16:
- case BFD_RELOC_MIPS_GOT_DISP:
- ip->insn_opcode |= address_expr->X_add_number & 0xffff;
- break;
-
case BFD_RELOC_MIPS_JMP:
{
int shift;
@@ -4136,13 +4152,22 @@ append_insn (struct mips_cl_insn *ip, ex
ip->insn_opcode |= ((address_expr->X_add_number >> shift)
& 0xffff);
}
- ip->complete_p = 0;
}
break;
default:
- internalError ();
- }
+ {
+ offsetT value;
+
+ if (calculate_reloc (*reloc_type, address_expr->X_add_number,
+ &value))
+ {
+ ip->insn_opcode |= value & 0xffff;
+ ip->complete_p = 1;
+ }
+ }
+ break;
+ }
}
if (mips_relax.sequence != 2 && !mips_opts.noreorder)
@@ -5227,14 +5252,15 @@ mips16_macro_build (expressionS *ep, con
case 'p':
case 'q':
{
+ offsetT value;
+
gas_assert (ep != NULL);
if (ep->X_op != O_constant)
*r = (int) BFD_RELOC_UNUSED + c;
- else
+ else if (calculate_reloc (*r, ep->X_add_number, &value))
{
- mips16_immed (NULL, 0, c, *r, ep->X_add_number,
- 0, &insn.insn_opcode);
+ mips16_immed (NULL, 0, c, *r, value, 0, &insn.insn_opcode);
ep = NULL;
*r = BFD_RELOC_UNUSED;
}
@@ -13376,40 +13402,17 @@ mips16_ip (char *str, struct mips_cl_ins
case '\0':
if (*s == '\0')
{
+ offsetT value;
+
/* Stuff the immediate value in now, if we can. */
if (imm_expr.X_op == O_constant
&& *imm_reloc > BFD_RELOC_UNUSED
- && *imm_reloc != BFD_RELOC_MIPS16_GOT16
- && *imm_reloc != BFD_RELOC_MIPS16_CALL16
- && insn->pinfo != INSN_MACRO)
+ && insn->pinfo != INSN_MACRO
+ && calculate_reloc (*offset_reloc,
+ imm_expr.X_add_number, &value))
{
- valueT tmp;
-
- switch (*offset_reloc)
- {
- case BFD_RELOC_MIPS16_HI16_S:
- tmp = (imm_expr.X_add_number + 0x8000) >> 16;
- break;
-
- case BFD_RELOC_MIPS16_HI16:
- tmp = imm_expr.X_add_number >> 16;
- break;
-
- case BFD_RELOC_MIPS16_LO16:
- tmp = ((imm_expr.X_add_number + 0x8000) & 0xffff)
- - 0x8000;
- break;
-
- case BFD_RELOC_UNUSED:
- tmp = imm_expr.X_add_number;
- break;
-
- default:
- internalError ();
- }
-
mips16_immed (NULL, 0, *imm_reloc - BFD_RELOC_UNUSED,
- *offset_reloc, tmp, forced_insn_length,
+ *offset_reloc, value, forced_insn_length,
&ip->insn_opcode);
imm_expr.X_op = O_absent;
*imm_reloc = BFD_RELOC_UNUSED;
@@ -13995,6 +13998,31 @@ static const struct mips16_immed_operand
#define MIPS16_NUM_IMMED \
(sizeof mips16_immed_operands / sizeof mips16_immed_operands[0])
+/* Marshal immediate value VAL for an extended MIPS16 instruction.
+ NBITS is the number of significant bits in VAL. */
+
+static unsigned long
+mips16_immed_extend (offsetT val, unsigned int nbits)
+{
+ int extval;
+ if (nbits == 16)
+ {
+ extval = ((val >> 11) & 0x1f) | (val & 0x7e0);
+ val &= 0x1f;
+ }
+ else if (nbits == 15)
+ {
+ extval = ((val >> 11) & 0xf) | (val & 0x7f0);
+ val &= 0xf;
+ }
+ else
+ {
+ extval = ((val & 0x1f) << 6) | (val & 0x20);
+ val = 0;
+ }
+ return (extval << 16) | val;
+}
+
/* Install immediate value VAL into MIPS16 instruction *INSN,
extending it if necessary. The instruction in *INSN may
already be extended.
@@ -14078,7 +14106,6 @@ mips16_immed (char *file, unsigned int l
else
{
long minext, maxext;
- int extval;
if (reloc == BFD_RELOC_UNUSED)
{
@@ -14097,23 +14124,7 @@ mips16_immed (char *file, unsigned int l
_("operand value out of range for instruction"));
}
- if (op->extbits == 16)
- {
- extval = ((val >> 11) & 0x1f) | (val & 0x7e0);
- val &= 0x1f;
- }
- else if (op->extbits == 15)
- {
- extval = ((val >> 11) & 0xf) | (val & 0x7f0);
- val &= 0xf;
- }
- else
- {
- extval = ((val & 0x1f) << 6) | (val & 0x20);
- val = 0;
- }
-
- *insn |= (extval << 16) | val;
+ *insn |= mips16_immed_extend (val, op->extbits);
}
}
@@ -15357,9 +15368,11 @@ mips_frob_file (void)
gas_assert (reloc_needs_lo_p (l->fixp->fx_r_type));
/* If a GOT16 relocation turns out to be against a global symbol,
- there isn't supposed to be a matching LO. */
+ there isn't supposed to be a matching LO. Ignore %gots against
+ constants; we'll report an error for those later. */
if (got16_reloc_p (l->fixp->fx_r_type)
- && !pic_need_relax (l->fixp->fx_addsy, l->seg))
+ && !(l->fixp->fx_addsy
+ && pic_need_relax (l->fixp->fx_addsy, l->seg)))
continue;
/* Check quickly whether the next fixup happens to be a matching %lo. */
@@ -15417,9 +15430,6 @@ mips_frob_file (void)
}
}
-/* We may have combined relocations without symbols in the N32/N64 ABI.
- We have to prevent gas from dropping them. */
-
int
mips_force_relocation (fixS *fixp)
{
@@ -15433,23 +15443,40 @@ mips_force_relocation (fixS *fixp)
|| fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1)
return 1;
- if (HAVE_NEWABI
- && S_GET_SEGMENT (fixp->fx_addsy) == bfd_abs_section_ptr
- && (fixp->fx_r_type == BFD_RELOC_MIPS_SUB
- || hi16_reloc_p (fixp->fx_r_type)
- || lo16_reloc_p (fixp->fx_r_type)))
- return 1;
-
return 0;
}
+/* Read the instruction associated with RELOC from BUF. */
+
+static unsigned int
+read_reloc_insn (char *buf, bfd_reloc_code_real_type reloc)
+{
+ if (mips16_reloc_p (reloc) || micromips_reloc_p (reloc))
+ return read_compressed_insn (buf, 4);
+ else
+ return read_insn (buf);
+}
+
+/* Write instruction INSN to BUF, given that it has been relocated
+ by RELOC. */
+
+static void
+write_reloc_insn (char *buf, bfd_reloc_code_real_type reloc,
+ unsigned long insn)
+{
+ if (mips16_reloc_p (reloc) || micromips_reloc_p (reloc))
+ write_compressed_insn (buf, insn, 4);
+ else
+ write_insn (buf, insn);
+}
+
/* Apply a fixup to the object file. */
void
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
{
char *buf;
- long insn;
+ unsigned long insn;
reloc_howto_type *howto;
/* We ignore generic BFD relocations we don't know about. */
@@ -15515,6 +15542,12 @@ md_apply_fix (fixS *fixP, valueT *valP,
case BFD_RELOC_MIPS16_TLS_GOTTPREL:
case BFD_RELOC_MIPS16_TLS_TPREL_HI16:
case BFD_RELOC_MIPS16_TLS_TPREL_LO16:
+ if (!fixP->fx_addsy)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("TLS relocation against a constant"));
+ break;
+ }
S_SET_THREAD_LOCAL (fixP->fx_addsy);
/* fall through */
@@ -15536,6 +15569,7 @@ md_apply_fix (fixS *fixP, valueT *valP,
case BFD_RELOC_MIPS_JALR:
case BFD_RELOC_HI16:
case BFD_RELOC_HI16_S:
+ case BFD_RELOC_LO16:
case BFD_RELOC_GPREL16:
case BFD_RELOC_MIPS_LITERAL:
case BFD_RELOC_MIPS_CALL16:
@@ -15550,6 +15584,7 @@ md_apply_fix (fixS *fixP, valueT *valP,
case BFD_RELOC_MIPS16_CALL16:
case BFD_RELOC_MIPS16_HI16:
case BFD_RELOC_MIPS16_HI16_S:
+ case BFD_RELOC_MIPS16_LO16:
case BFD_RELOC_MIPS16_JMP:
case BFD_RELOC_MICROMIPS_JMP:
case BFD_RELOC_MICROMIPS_GOT_DISP:
@@ -15562,6 +15597,7 @@ md_apply_fix (fixS *fixP, valueT *valP,
case BFD_RELOC_MICROMIPS_JALR:
case BFD_RELOC_MICROMIPS_HI16:
case BFD_RELOC_MICROMIPS_HI16_S:
+ case BFD_RELOC_MICROMIPS_LO16:
case BFD_RELOC_MICROMIPS_GPREL16:
case BFD_RELOC_MICROMIPS_LITERAL:
case BFD_RELOC_MICROMIPS_CALL16:
@@ -15570,7 +15606,23 @@ md_apply_fix (fixS *fixP, valueT *valP,
case BFD_RELOC_MICROMIPS_GOT_LO16:
case BFD_RELOC_MICROMIPS_CALL_HI16:
case BFD_RELOC_MICROMIPS_CALL_LO16:
- /* Nothing needed to do. The value comes from the reloc entry. */
+ if (fixP->fx_done)
+ {
+ offsetT value;
+
+ if (calculate_reloc (fixP->fx_r_type, *valP, &value))
+ {
+ insn = read_reloc_insn (buf, fixP->fx_r_type);
+ if (mips16_reloc_p (fixP->fx_r_type))
+ insn |= mips16_immed_extend (value, 16);
+ else
+ insn |= (value & 0xffff);
+ write_reloc_insn (buf, fixP->fx_r_type, insn);
+ }
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Unsupported constant in relocation"));
+ }
break;
case BFD_RELOC_64:
@@ -15604,27 +15656,6 @@ md_apply_fix (fixS *fixP, valueT *valP,
md_number_to_chars (buf, *valP, fixP->fx_size);
break;
- case BFD_RELOC_LO16:
- case BFD_RELOC_MIPS16_LO16:
- case BFD_RELOC_MICROMIPS_LO16:
- /* FIXME: Now that embedded-PIC is gone, some of this code/comment
- may be safe to remove, but if so it's not obvious. */
- /* When handling an embedded PIC switch statement, we can wind
- up deleting a LO16 reloc. See the 'o' case in mips_ip. */
- if (fixP->fx_done)
- {
- if (*valP + 0x8000 > 0xffff)
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("relocation overflow"));
- /* 32-bit microMIPS instructions are divided into two halfwords.
- Relocations always refer to the second halfword, regardless
- of endianness. */
- if (target_big_endian || fixP->fx_r_type == BFD_RELOC_MICROMIPS_LO16)
- buf += 2;
- md_number_to_chars (buf, *valP, 2);
- }
- break;
-
case BFD_RELOC_16_PCREL_S2:
if ((*valP & 0x3) != 0)
as_bad_where (fixP->fx_file, fixP->fx_line,
Index: gas/testsuite/gas/mips/elf-rel22.s
===================================================================
--- gas/testsuite/gas/mips/elf-rel22.s 2012-09-23 11:06:23.458215124 +0100
+++ gas/testsuite/gas/mips/elf-rel22.s 2012-09-23 11:14:46.201200508 +0100
@@ -1,4 +1,9 @@
+ .eqv early_const,0x123456
lui $4,%lo(%neg(%lo(bar-foo)))
foo:
nop
bar:
+ lui $4,%lo(%neg(%lo(bar-foo)))
+ lui $4,%hi(%gp_rel(early_const))
+ lui $4,%lo(%neg(%gp_rel(late_const)))
+ .eqv late_const,0x234567
Index: gas/testsuite/gas/mips/elf-rel22.d
===================================================================
--- gas/testsuite/gas/mips/elf-rel22.d 2012-09-23 11:06:23.458215124 +0100
+++ gas/testsuite/gas/mips/elf-rel22.d 2012-09-23 11:14:46.201200508 +0100
@@ -7,3 +7,12 @@ Relocation section '\.rela\.text' .*:
.* R_MIPS_LO16 * 4
* Type2: R_MIPS_SUB *
* Type3: R_MIPS_LO16 *
+.* R_MIPS_LO16 * 4
+ * Type2: R_MIPS_SUB *
+ * Type3: R_MIPS_LO16 *
+.* R_MIPS_GPREL16 * 123456
+ * Type2: R_MIPS_HI16 *
+ * Type3: R_MIPS_NONE *
+.* R_MIPS_GPREL16 * 234567
+ * Type2: R_MIPS_SUB *
+ * Type3: R_MIPS_LO16 *
Index: gas/testsuite/gas/mips/elf-rel29.s
===================================================================
--- /dev/null 2012-08-19 20:42:12.842999468 +0100
+++ gas/testsuite/gas/mips/elf-rel29.s 2012-09-23 11:14:46.201200508 +0100
@@ -0,0 +1,12 @@
+ .set nomips16
+ .ent foo
+foo:
+ lui $4,%highest(bar)
+ dsll $4,$4,16
+ daddiu $4,$4,%higher(bar)
+ dsll $4,$4,16
+ daddiu $4,$4,%hi(bar)
+ dsll $4,$4,16
+ lw $4,%lo(bar)($4)
+ .end foo
+ .eqv bar,0x123456789abcdef0
Index: gas/testsuite/gas/mips/elf-rel29.d
===================================================================
--- /dev/null 2012-08-19 20:42:12.842999468 +0100
+++ gas/testsuite/gas/mips/elf-rel29.d 2012-09-23 11:14:46.201200508 +0100
@@ -0,0 +1,18 @@
+#objdump: -dr --show-raw-insn
+#as: -64
+#name: MIPS ELF reloc 29
+#source: elf-rel29.s
+
+.*file format.*
+
+Disassembly .*
+
+0+0 <foo>:
+.*: 3c041234 lui a0,0x1234
+.*: 00042438 dsll a0,a0,0x10
+.*: 64845679 daddiu a0,a0,22137
+.*: 00042438 dsll a0,a0,0x10
+.*: 64849abd daddiu a0,a0,-25923
+.*: 00042438 dsll a0,a0,0x10
+.*: 8c84def0 lw a0,-8464\(a0\)
+#pass
Index: gas/testsuite/gas/mips/micromips@elf-rel29.d
===================================================================
--- /dev/null 2012-08-19 20:42:12.842999468 +0100
+++ gas/testsuite/gas/mips/micromips@elf-rel29.d 2012-09-23 11:14:46.202200508 +0100
@@ -0,0 +1,18 @@
+#objdump: -dr --show-raw-insn
+#as: -64
+#name: MIPS ELF reloc 29
+#source: elf-rel29.s
+
+.*file format.*
+
+Disassembly .*
+
+0+0 <foo>:
+.*: 41a4 1234 lui a0,0x1234
+.*: 5884 8000 dsll a0,a0,0x10
+.*: 5c84 5679 daddiu a0,a0,22137
+.*: 5884 8000 dsll a0,a0,0x10
+.*: 5c84 9abd daddiu a0,a0,-25923
+.*: 5884 8000 dsll a0,a0,0x10
+.*: fc84 def0 lw a0,-8464\(a0\)
+#pass
Index: gas/testsuite/gas/mips/elf-rel30.s
===================================================================
--- /dev/null 2012-08-19 20:42:12.842999468 +0100
+++ gas/testsuite/gas/mips/elf-rel30.s 2012-09-23 11:14:46.202200508 +0100
@@ -0,0 +1,42 @@
+ .set nomips16
+ .eqv c1,0x12345678
+ .ent foo
+foo:
+ lui $4,%call_hi(c1)
+ lui $4,%call_hi(c2)
+ lui $4,%call_lo(c1)
+ lui $4,%call_lo(c2)
+ lui $4,%call16(c1)
+ lui $4,%call16(c2)
+ lui $4,%got_page(c1)
+ lui $4,%got_page(c2)
+ lui $4,%got_disp(c1)
+ lui $4,%got_disp(c2)
+ lui $4,%got_ofst(c1)
+ lui $4,%got_ofst(c2)
+ lui $4,%got_hi(c1)
+ lui $4,%got_hi(c2)
+ lui $4,%got_lo(c1)
+ lui $4,%got_lo(c2)
+ lui $4,%got(c1)
+ lui $4,%got(c2)
+ lui $4,%gp_rel(c1)
+ lui $4,%gp_rel(c2)
+ lui $4,%got(c1)
+ lui $4,%got(c2)
+ lui $4,%tlsgd(c1)
+ lui $4,%tlsgd(c2)
+ lui $4,%tlsldm(c1)
+ lui $4,%tlsldm(c2)
+ lui $4,%dtprel_hi(c1)
+ lui $4,%dtprel_hi(c2)
+ lui $4,%dtprel_lo(c1)
+ lui $4,%dtprel_lo(c2)
+ lui $4,%tprel_hi(c1)
+ lui $4,%tprel_hi(c2)
+ lui $4,%tprel_lo(c1)
+ lui $4,%tprel_lo(c2)
+ lui $4,%gottprel(c1)
+ lui $4,%gottprel(c2)
+ .end foo
+ .eqv c2,0x12345678
Index: gas/testsuite/gas/mips/elf-rel30.l
===================================================================
--- /dev/null 2012-08-19 20:42:12.842999468 +0100
+++ gas/testsuite/gas/mips/elf-rel30.l 2012-09-23 11:14:46.201200508 +0100
@@ -0,0 +1,37 @@
+.*:
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: Unsupported constant in relocation
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
+.*: TLS relocation against a constant
Index: gas/testsuite/gas/mips/mips.exp
===================================================================
--- gas/testsuite/gas/mips/mips.exp 2012-09-23 11:14:15.131201410 +0100
+++ gas/testsuite/gas/mips/mips.exp 2012-09-23 11:14:46.202200508 +0100
@@ -917,7 +917,9 @@ if { [istarget mips*-*-vxworks*] } {
if $has_newabi {
run_dump_test "elf-rel28-n32"
run_dump_test "elf-rel28-n64"
+ run_dump_test_arches "elf-rel29" [mips_arch_list_matching mips3]
}
+ run_list_test_arches "elf-rel30" "-32" [mips_arch_list_all]
if { !$no_mips16 } {
run_dump_test "${tmips}mips${el}16-e"