This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: 2.10.91: A problem with R_MIPS_CALL relocations within gas
- To: Ian Lance Taylor <ian at zembu dot com>
- Subject: Re: 2.10.91: A problem with R_MIPS_CALL relocations within gas
- From: "Maciej W. Rozycki" <macro at ds2 dot pg dot gda dot pl>
- Date: Fri, 17 Nov 2000 18:56:06 +0100 (MET)
- cc: binutils at sourceware dot cygnus dot com, ralf at uni-koblenz dot de, ulfc at engr dot sgi dot com
- Organization: Technical University of Gdansk
- Reply-To: "Maciej W. Rozycki" <macro at ds2 dot pg dot gda dot pl>
On 17 Nov 2000, Ian Lance Taylor wrote:
> Your patch looks OK to me. The only thing I would change would be the
> comments, to put ``if tempreg is PIC_CALL_REG'' before the new sample
> code, as in ``or, if tempreg is PIC_CALL_REG,''.
Thanks for the clarification of gcc's code generation. Here is a
modified version.
gas/ChangeLog:
2000-11-05 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
* config/tc-mips.c (macro): For M_LA_AB emit a
BFD_RELOC_MIPS_CALL16 relocation or a
BFD_RELOC_MIPS_CALL_HI16/BFD_RELOC_MIPS_CALL_LO16 pair instead of
BFD_RELOC_MIPS_GOT16 and
BFD_RELOC_MIPS_GOT_HI16/BFD_RELOC_MIPS_GOT_LO16, respectively for
loading the jump register when generating SVR4_PIC code.
Maciej
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
diff -up --recursive --new-file binutils.macro/gas/config/tc-mips.c binutils/gas/config/tc-mips.c
--- binutils.macro/gas/config/tc-mips.c Thu Sep 21 03:25:40 2000
+++ binutils/gas/config/tc-mips.c Sun Nov 5 21:36:57 2000
@@ -4276,9 +4276,13 @@ macro (ip)
}
else if (mips_pic == SVR4_PIC && ! mips_big_got)
{
+ int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT16;
+
/* If this is a reference to an external symbol, and there
is no constant, we want
lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ or if tempreg is PIC_CALL_REG
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_CALL16)
For a local symbol, we want
lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
nop
@@ -4305,9 +4309,11 @@ macro (ip)
expr1.X_add_number = offset_expr.X_add_number;
offset_expr.X_add_number = 0;
frag_grow (32);
+ if (expr1.X_add_number == 0 && tempreg == PIC_CALL_REG)
+ lw_reloc_type = (int) BFD_RELOC_MIPS_CALL16;
macro_build ((char *) NULL, &icnt, &offset_expr,
dbl ? "ld" : "lw",
- "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
+ "t,o(b)", tempreg, lw_reloc_type, GP);
if (expr1.X_add_number == 0)
{
int off;
@@ -4413,12 +4419,18 @@ macro (ip)
else if (mips_pic == SVR4_PIC)
{
int gpdel;
+ int lui_reloc_type = (int) BFD_RELOC_MIPS_GOT_HI16;
+ int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT_LO16;
/* This is the large GOT case. If this is a reference to an
external symbol, and there is no constant, we want
lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
addu $tempreg,$tempreg,$gp
lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ or if tempreg is PIC_CALL_REG
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_CALL_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_CALL_LO16)
For a local symbol, we want
lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
nop
@@ -4457,8 +4469,13 @@ macro (ip)
gpdel = 4;
else
gpdel = 0;
+ if (expr1.X_add_number == 0 && tempreg == PIC_CALL_REG)
+ {
+ lui_reloc_type = (int) BFD_RELOC_MIPS_CALL_HI16;
+ lw_reloc_type = (int) BFD_RELOC_MIPS_CALL_LO16;
+ }
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
- tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);
+ tempreg, lui_reloc_type);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
|| ! ISA_HAS_64BIT_REGS (mips_opts.isa))
@@ -4466,8 +4483,7 @@ macro (ip)
"d,v,t", tempreg, tempreg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
dbl ? "ld" : "lw",
- "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT_LO16,
- tempreg);
+ "t,o(b)", tempreg, lw_reloc_type, tempreg);
if (expr1.X_add_number == 0)
{
int off;