This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: MIPS patch to correct the size of %neg() fixups
Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:
> True, replacing it with a remark like "RSS_* handling can be done here
> if it ever becones necessary" is more appropriate.
OK, here's a revised patch which does that. OK to install?
Richard
gas/
* config/tc-mips.c (append_insn): In a compound relocation, take the
field width from the final (outermost) operator.
gas/testsuite/
* gas/mips/elf-rel15.[sd]: New test.
* gas/mips/mips.exp: Run it.
Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.212
diff -c -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.212 tc-mips.c
*** gas/config/tc-mips.c 4 Jun 2003 06:38:38 -0000 1.212
--- gas/config/tc-mips.c 11 Jun 2003 19:35:12 -0000
*************** #define emit_nop() \
*** 2154,2166 ****
}
else
{
- reloc_howto_type *howto;
-
need_reloc:
/* Don't generate a reloc if we are writing into a variant frag. */
if (place == NULL)
{
! howto = bfd_reloc_type_lookup (stdoutput, reloc_type[0]);
fixp[0] = fix_new_exp (frag_now, f - frag_now->fr_literal,
bfd_get_reloc_size(howto),
address_expr,
--- 2154,2173 ----
}
else
{
need_reloc:
/* Don't generate a reloc if we are writing into a variant frag. */
if (place == NULL)
{
! reloc_howto_type *howto;
! int i;
!
! /* In a compound relocation, it is the final (outermost)
! operator that determines the relocated field. */
! for (i = 1; i < 3; i++)
! if (reloc_type[i] == BFD_RELOC_UNUSED)
! break;
!
! howto = bfd_reloc_type_lookup (stdoutput, reloc_type[i - 1]);
fixp[0] = fix_new_exp (frag_now, f - frag_now->fr_literal,
bfd_get_reloc_size(howto),
address_expr,
*************** #define emit_nop() \
*** 2207,2283 ****
hi_fixup->seg = now_seg;
}
! if (reloc_type[1] != BFD_RELOC_UNUSED)
! {
! /* FIXME: This symbol can be one of
! RSS_UNDEF, RSS_GP, RSS_GP0, RSS_LOC. */
! address_expr->X_op = O_absent;
! address_expr->X_add_symbol = 0;
! address_expr->X_add_number = 0;
!
! howto = bfd_reloc_type_lookup (stdoutput, reloc_type[1]);
! fixp[1] = fix_new_exp (frag_now, f - frag_now->fr_literal,
! bfd_get_reloc_size(howto),
! address_expr, FALSE, reloc_type[1]);
!
! /* These relocations can have an addend that won't fit in
! 4 octets for 64bit assembly. */
! if (HAVE_64BIT_GPRS
! && ! howto->partial_inplace
! && (reloc_type[1] == BFD_RELOC_16
! || reloc_type[1] == BFD_RELOC_32
! || reloc_type[1] == BFD_RELOC_MIPS_JMP
! || reloc_type[1] == BFD_RELOC_HI16_S
! || reloc_type[1] == BFD_RELOC_LO16
! || reloc_type[1] == BFD_RELOC_GPREL16
! || reloc_type[1] == BFD_RELOC_MIPS_LITERAL
! || reloc_type[1] == BFD_RELOC_GPREL32
! || reloc_type[1] == BFD_RELOC_64
! || reloc_type[1] == BFD_RELOC_CTOR
! || reloc_type[1] == BFD_RELOC_MIPS_SUB
! || reloc_type[1] == BFD_RELOC_MIPS_HIGHEST
! || reloc_type[1] == BFD_RELOC_MIPS_HIGHER
! || reloc_type[1] == BFD_RELOC_MIPS_SCN_DISP
! || reloc_type[1] == BFD_RELOC_MIPS_REL16
! || reloc_type[1] == BFD_RELOC_MIPS_RELGOT))
! fixp[1]->fx_no_overflow = 1;
!
! if (reloc_type[2] != BFD_RELOC_UNUSED)
! {
! address_expr->X_op = O_absent;
! address_expr->X_add_symbol = 0;
! address_expr->X_add_number = 0;
!
! howto = bfd_reloc_type_lookup (stdoutput, reloc_type[2]);
! fixp[2] = fix_new_exp (frag_now,
! f - frag_now->fr_literal,
! bfd_get_reloc_size(howto),
! address_expr, FALSE,
! reloc_type[2]);
! /* These relocations can have an addend that won't fit in
! 4 octets for 64bit assembly. */
! if (HAVE_64BIT_GPRS
! && ! howto->partial_inplace
! && (reloc_type[2] == BFD_RELOC_16
! || reloc_type[2] == BFD_RELOC_32
! || reloc_type[2] == BFD_RELOC_MIPS_JMP
! || reloc_type[2] == BFD_RELOC_HI16_S
! || reloc_type[2] == BFD_RELOC_LO16
! || reloc_type[2] == BFD_RELOC_GPREL16
! || reloc_type[2] == BFD_RELOC_MIPS_LITERAL
! || reloc_type[2] == BFD_RELOC_GPREL32
! || reloc_type[2] == BFD_RELOC_64
! || reloc_type[2] == BFD_RELOC_CTOR
! || reloc_type[2] == BFD_RELOC_MIPS_SUB
! || reloc_type[2] == BFD_RELOC_MIPS_HIGHEST
! || reloc_type[2] == BFD_RELOC_MIPS_HIGHER
! || reloc_type[2] == BFD_RELOC_MIPS_SCN_DISP
! || reloc_type[2] == BFD_RELOC_MIPS_REL16
! || reloc_type[2] == BFD_RELOC_MIPS_RELGOT))
! fixp[2]->fx_no_overflow = 1;
! }
! }
}
}
}
--- 2214,2235 ----
hi_fixup->seg = now_seg;
}
! /* Add fixups for the second and third relocations, if given.
! Note that the ABI allows the second relocation to be
! against RSS_UNDEF, RSS_GP, RSS_GP0 or RSS_LOC. At the
! moment we only use RSS_UNDEF, but we could add support
! for the others if it ever becomes necessary. */
! for (i = 1; i < 3; i++)
! if (reloc_type[i] != BFD_RELOC_UNUSED)
! {
! address_expr->X_op = O_absent;
! address_expr->X_add_symbol = 0;
! address_expr->X_add_number = 0;
! fixp[i] = fix_new_exp (frag_now, fixp[0]->fx_where,
! fixp[0]->fx_size, address_expr,
! FALSE, reloc_type[i]);
! }
}
}
}
Index: gas/testsuite/gas/mips/mips.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v
retrieving revision 1.72
diff -c -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.72 mips.exp
*** gas/testsuite/gas/mips/mips.exp 22 May 2003 12:13:43 -0000 1.72
--- gas/testsuite/gas/mips/mips.exp 11 Jun 2003 19:35:12 -0000
*************** if { [istarget mips*-*-*] } then {
*** 645,650 ****
--- 645,652 ----
run_dump_test "elf-rel14"
if $has_newabi {
+ run_dump_test "elf-rel15"
+
run_dump_test "elf-rel-got-n32"
run_dump_test "elf-rel-xgot-n32"
run_dump_test "elf-rel-got-n64"
*** /dev/null Thu Apr 11 15:25:15 2002
--- gas/testsuite/gas/mips/elf-rel15.d Wed Jun 11 20:10:05 2003
***************
*** 0 ****
--- 1,14 ----
+ #objdump: -dr
+ #as: -mabi=n32 -mips3
+
+ .*: file format .*
+
+ Disassembly of section \.text:
+
+ 00000000 <foo>:
+ 0: 3c020000 lui v0,0x0
+ 0: R_MIPS_GPREL16 \.text
+ 0: R_MIPS_SUB \*ABS\*
+ 0: R_MIPS_HI16 \*ABS\*
+ 4: 23bdffe4 addi sp,sp,-28
+ ...
*** /dev/null Thu Apr 11 15:25:15 2002
--- gas/testsuite/gas/mips/elf-rel15.s Wed Jun 11 20:10:05 2003
***************
*** 0 ****
--- 1,4 ----
+ foo:
+ lui $2,%hi(%neg(%gp_rel(foo)))
+ sub $sp,$sp,28
+ .space 16