This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: [patch] MIPS/gas: load/store address overflow on binutils 2.14
Maciej W. Rozycki wrote:
> On Tue, 16 Sep 2003, Thiemo Seufer wrote:
>
> > > > The appended version does so. It gets also rid of the bogus
> > > > HAVE_64_BIT_ADDRESS_CONSTANTS define, which was effectively an alias for
> > > > HAVE_64_BIT_GPRS, and fixes the generation of constant 64-bit addresses
> > > > which are not 32-bit sign extended values. I guess the latter went
> > > > unnoticed for so long because kernels are usually built in the 32-bit
> > > > compatibility space and userland is PIC code.
> > >
> > > I do build kernels as n64, but I haven't noticed any difference. I don't
> > > think the difference would actually appear under any conditions
> >
> > Your n64 kernels are still loaded in (C)KSEG0. A kernel in XKPHYS would die.
[snip]
> I asked, because I fail to see how bad behavior might actually get
> triggered for any constants. Can you please provide examples of source
> code triggering bad binary code generation by gas as of before your patch?
I got it wrong, the Linux kernel hack catches this case, so the code
generation is ok. I nevertheless leave this change in CVS, as it
seperates the kernel hack condition from the one for optimized n64
constant loading.
> > I'll add the as_bad() and add a testcase tomorrow.
The first part is appended.
Thiemo
2003-09-18 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
/gas/ChangeLog
* config/tc-mips.c (macro_build_ldst_constoffset): Don't silently
truncate values which won't fit im 32 bits.
(load_register): Likewise.
(macro): Likewise.
--- source-orig/gas/config/tc-mips.c Mon Sep 15 18:08:20 2003
+++ source/gas/config/tc-mips.c Wed Sep 17 04:28:44 2003
@@ -3229,8 +3229,14 @@ macro_build_ldst_constoffset (char *plac
/* Sign-extending 32-bit constants makes their handling easier. */
if (! dbl)
+ {
+ if (ep->X_add_number & ~((bfd_vma) 0xffffffff)
+ && ~(ep->X_add_number | 0xffffffff))
+ as_bad (_("too large constant specified"));
+
ep->X_add_number = (((ep->X_add_number & 0xffffffff) ^ 0x80000000)
- 0x80000000);
+ }
/* Right now, this routine can only handle signed 32-bit contants. */
if (! IS_SEXT_32BIT_NUM(ep->X_add_number))
@@ -3387,8 +3396,14 @@ load_register (int *counter, int reg, ex
/* Sign-extending 32-bit constants makes their handling easier. */
if (! dbl)
+ {
+ if (ep->X_add_number & ~((bfd_vma) 0xffffffff)
+ && ~(ep->X_add_number | 0xffffffff))
+ as_bad (_("too large constant specified"));
+
ep->X_add_number = (((ep->X_add_number & 0xffffffff) ^ 0x80000000)
- 0x80000000);
+ }
if (IS_SEXT_16BIT_NUM (ep->X_add_number))
{
@@ -5793,8 +5808,14 @@ macro (struct mips_cl_insn *ip)
if ((! HAVE_64BIT_ADDRESSES
&& (! HAVE_64BIT_GPRS && offset_expr.X_op == O_constant))
&& (offset_expr.X_op == O_constant))
+ {
+ if (offset_expr.X_add_number & ~((bfd_vma) 0xffffffff)
+ && ~(offset_expr.X_add_number | 0xffffffff))
+ as_bad (_("too large constant specified"));
+
offset_expr.X_add_number = (((offset_expr.X_add_number & 0xffffffff)
^ 0x80000000) - 0x80000000);
+ }
/* For embedded PIC, we allow loads where the offset is calculated
by subtracting a symbol in the current segment from an unknown