forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Bug awareness - finding the address of arguments is a NoNo

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
SANiK



Joined: 05 Jul 2005
Posts: 29

PostPosted: Tue Aug 14, 2007 5:08 pm    Post subject: Bug awareness - finding the address of arguments is a NoNo Reply with quote

Err, to save you guys a bunch of debug time, be aware that PSPlink causes random bugs when trying to print a float.
The bug results in PSPlink crashing.
Usbhostfs reports an invalid magic error.

The bug is caused by TyRaNid attempting to find the address of a function argument... although, the PSP uses registers to store/pass arguments, hence the bug.

The bug is in the float printing code of PSPlink, hence avoid printing floats in PSPlink.

And never try to get the address of a function argument!
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Tue Aug 14, 2007 11:05 pm    Post subject: Reply with quote

Could you be more specific where that code is that tries to find the adress of an argument/print floats, that is faulty?
Can't seem to find that part.
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
jbit
Site Admin


Joined: 28 May 2005
Posts: 293
Location: København, Danmark

PostPosted: Wed Aug 15, 2007 12:42 am    Post subject: Re: Bug awareness - finding the address of arguments is a No Reply with quote

SANiK wrote:
And never try to get the address of a function argument!


Erm, why exactly... GCC will automatically store the register on the stack and give that address if you try to get the address of a function argument. The following output is from ee-gcc, but should be similar on PSP compiler...

Original C code:
Code:
void somefunc(int blah)
{
    someotherfunc(&blah);
}


Unoptimized assembly code (with some annotations ;)
Code:
00000020 <somefunc>:
  20:   addiu   sp,sp,-48
  24:   sd  ra,32(sp)
  28:   sd  s8,16(sp)
  2c:   move    s8,sp
  30:   sw  a0,0(s8)    ; value of "blah" is stored on the stack
  34:   jal 0 <someotherfunc>
  38:   move    a0,s8    ; arg0 for someotherfunc is set to the address of "blah" on the stack
  3c:   move    sp,s8
  40:   ld  ra,32(sp)
  44:   ld  s8,16(sp)
  48:   jr  ra
  4c:   addiu   sp,sp,48


EDIT:I should point out the above ASM is raw MIPS asm, so "move a0,s8" is in the branch delay slot for JAL, therefore it's execution is completed before the branch is completed.
Back to top
View user's profile Send private message Visit poster's website
chp



Joined: 23 Jun 2004
Posts: 313

PostPosted: Wed Aug 15, 2007 1:32 am    Post subject: Reply with quote

Also, a printf(char* buf, ...)-style function is a varargs-function, which will store the value before '...' on the stack, because it will need to get the address to 'buf' before it starts processing the format-string. I assume it was a function similar to this that you were using?
_________________
GE Dominator
Back to top
View user's profile Send private message
TyRaNiD



Joined: 18 Jan 2004
Posts: 918

PostPosted: Wed Aug 15, 2007 2:31 am    Post subject: Reply with quote

It does seem to be true that the PSP compiler is broken, it tries to store the value onto the stack but doesn't actually do so until after the code which uses the value. However I fail to see why it would actually die completely, and at any rate I don't fucking care.
Back to top
View user's profile Send private message
SANiK



Joined: 05 Jul 2005
Posts: 29

PostPosted: Wed Aug 15, 2007 2:55 am    Post subject: Reply with quote

jbit - The PSPcompiler has its issues =/

chp/Raphael - The bug is in the PSPLink code which handles the conversion of floats to string, and not within the function printf() itself

/*Taken from util.c*/
Code:

static int is_inf(float val)
{
        void *p;
        unsigned int conv;
        int sign;
        int exp;
        int mantissa;

BUG: p = (void *) &val;
        conv = *((unsigned int *) p);
        sign = (conv >> 31) & 1;

        exp = (conv >> 23) & 0xff;
        mantissa = conv & 0x7fffff;

        if((exp == 255) && (mantissa == 0))
        {
                if(sign)
                {
                        return -1;
                }
                else
                {
                        return 1;
                }
        }

        return 0;
}
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Wed Aug 15, 2007 11:34 pm    Post subject: Reply with quote

Code:

static int is_inf(float val)
{
   void *p;
   unsigned int conv;
   int sign;
   int exp;
   int mantissa;

   p = (void *) &val;
   conv = *((unsigned int *) p);
   sign = (conv >> 31) & 1;

   exp = (conv >> 23) & 0xff;
   mantissa = conv & 0x7fffff;

   if((exp == 255) && (mantissa == 0))
   {
      if(sign)
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }

   return 0;
}


int main(int argc, char *argv[])
{
   float x = rand()/32768.f;
   if (is_inf(x))
   {
      printf("IsINF\n");
   }

   sceKernelExitGame();
   return(0);
}


Compiled with same flags as psplink results in the following compiler output:
Code:

$LC1:
   .ascii   "IsINF\012\000"
 #NO_APP
   .section   .rodata.cst4,"aM",@progbits,4
   .align   2
$LC0:
   .word   939524096
   .text
   .align   2
   .globl   main
   .ent   main
main:
   .frame   $sp,16,$31      # vars= 8, regs= 1/0, args= 0, gp= 0
   .mask   0x80000000,-8
   .fmask   0x00000000,0
   .set   noreorder
   .set   nomacro
   
   addiu   $sp,$sp,-16
   sw   $31,8($sp)
   jal   rand
   nop

   mtc1   $2,$f0
   lui   $2,%hi($LC0)
   cvt.s.w   $f1,$f0
   lwc1   $f0,%lo($LC0)($2)
   lw   $3,0($sp)          # !WRONG
   li   $2,8323072         # 0x7f0000
   mul.s   $f1,$f1,$f0
   ori   $2,$2,0xffff
   and   $5,$3,$2
   ext   $3,$3,23,8
   li   $2,255         # 0xff
   bne   $3,$2,$L2
   swc1   $f1,0($sp)          # !WRONG

   lui   $4,%hi($LC1)
   bne   $5,$0,$L2
   addiu   $4,$4,%lo($LC1)

   jal   printf
   nop

$L2:
   jal   sceKernelExitGame
   nop

   lw   $31,8($sp)
   move   $2,$0
   j   $31
   addiu   $sp,$sp,16


As Tyranid said, gcc tries to put the float on stack and pop as integer register to do the conversion. However, it puts it in wrong order, hence this code produces wrong results.
Funnily enough, with -O1 it puts them in correct order, but not with any optimization value.

Correct result is given with this code in any case though:
Code:

static int is_inf(float val)
{
   unsigned int conv;
   int sign;
   int exp;
   int mantissa;

   asm("mfc1 %0, %1\n":"=r"(conv):"f"(val));
   sign = (conv >> 31) & 1;

   exp = (conv >> 23) & 0xff;
   mantissa = conv & 0x7fffff;

   if((exp == 255) && (mantissa == 0))
   {
      if(sign)
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }

   return 0;
}


Here's a patch for PSPLINKUSB (plus a small fix for VFPU disasm with prefixes) - I could probably commit it myself, but I don't feel like I should be messing on Tyranids repository:
Code:

Index: psplink/util.c
===================================================================
--- psplink/util.c   (revision 2280)
+++ psplink/util.c   (working copy)
@@ -860,14 +860,16 @@
 
 static int is_nan(float val)
 {
-   void *p;
+   //void *p;
    unsigned int conv;
    int sign;
    int exp;
    int mantissa;
 
-   p = (void *) &val;
-   conv = *((unsigned int *) p);
+   /*p = (void *) &val;
+   conv = *((unsigned int *) p);*/
+   // Help stupid GCC compiler
+   asm("mfc1 %0, %1\n":"=r"(conv):"f"(val));
    sign = (conv >> 31) & 1;
 
    exp = (conv >> 23) & 0xff;
@@ -883,14 +885,16 @@
 
 static int is_inf(float val)
 {
-   void *p;
+   //void *p;
    unsigned int conv;
    int sign;
    int exp;
    int mantissa;
 
-   p = (void *) &val;
-   conv = *((unsigned int *) p);
+   /*p = (void *) &val;
+   conv = *((unsigned int *) p);*/
+   // Help stupid GCC compiler
+   asm("mfc1 %0, %1\n":"=r"(conv):"f"(val));
    sign = (conv >> 31) & 1;
 
    exp = (conv >> 23) & 0xff;
Index: pspsh/disasm.C
===================================================================
--- pspsh/disasm.C   (revision 2280)
+++ pspsh/disasm.C   (working copy)
@@ -1149,7 +1149,7 @@
 // [hlide] added pfx_sat_names
 static const char * const pfx_sat_names[4] =
 {
-  "",  "[0:1]",  "",  "[-1:1]"
+  "",  "0:1",  "",  "-1:1"
 };
 
 /* VFPU prefix instruction operands.  The *_SH_* values really specify where

_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group