guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Libffi (git master) and guile (git master) on MIPS n32


From: rixed
Subject: Re: Libffi (git master) and guile (git master) on MIPS n32
Date: Tue, 8 Feb 2011 08:48:06 +0100
User-agent: Mutt/1.5.20 (2009-06-14)

-[ Mon, Feb 07, 2011 at 01:58:07PM -0800, Andrew Pinski ]----
> > The problem is : of these 64 bits, only the 32 lowest bits were set by
> > guile, and the upper 32 are desperately random.
> 
> How were those lower 32bits set?  If set by the 32bit instructions
> then it is automatically sign extended.  If not then there is a bug in
> how guile is doing the returns

These lowest 32bits were set by guile's foreign.c/unpack function, using
this:

// called with type = ffi_cif->rtype of course, and loc = return value address
unpack (const ffi_type *type, void *loc, SCM x)
{
  switch (type->type)
    {
        (...)
    case FFI_TYPE_SINT32:
      *(scm_t_int32 *) loc = scm_to_int32 (x);
      break;
        (...)
    }
}

(note: this cast of an lvalue is not legal C but that's another story)

AFAICT, Guile is not tell how much data it should write, so it must resort
on rtype->type.

> Unless you have a bug somewhere in which you are using a non sign
> extended value with the 32bit instructions which then it becomes
> undefined at what the value of those instructions do (could be either
> treating it as a 64bit value, or do a sign extend or even put
> 0xDEADBEEFDEADBEEF in the register which is what the Octeon simulators
> do).

Sorry I do not understand this. Let's take a concrete exemple : guile
comparison function returns -1 to qsort. So it writes -1 on the return
value location (as a 32 bits value) with the code given above. This
location, which 32 upper bits were random (but positive) now looks like
this quad-word (this is a little endian mips) :

0x7fff09c0: 0xFF 0xFF 0xFF 0xFF 0x78 0x56 0x34 0x12

Now libffi loads this value into v0 :

ffi_closure_N32:
   (...)
   # Return flags are in v0
   bne     v0, FFI_TYPE_SINT32, cls_retint  # v0 = FFI_TYPE_INT here, from the 
flags
   lw  v0, V0_OFF2($sp)
   (...)
cls_retint:
   bne     v0, FFI_TYPE_INT, cls_retfloat
   ld      v0, V0_OFF2($sp)                 # now v0 = 0x12345678FFFFFFFF
   b   cls_epilogue

And now we are back to the libc qsort, which will certainly compare v0
with 0 and see it's positive.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]