Broken jump patching on x86_64

View: New views
10 Messages — Rating Filter:   Alert me  

Broken jump patching on x86_64

by Pippijn van Steenhoven :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello Lightning List,

I am experiencing very strange experience with GNU Lightning on x86_64.
Consider the following simple code:

  #include <lightning.h>

  #define CRASH 1

  struct foo
  {
    jit_state current;
  };
 
  int
  main()
  {
    typedef int (*pifii)(int, int);
 
    jit_insn codeBuffer[1024];
    struct jit_state _jit;
    struct foo as;
 
  #if CRASH
  #define _jit as.current
  #endif
 
    pifii myFunction = (pifii) (jit_set_ip (codeBuffer).iptr);
    int   ofs;
 
    // start off like in add.c
    jit_leaf (2);
    ofs = jit_arg_i ();
    jit_getarg_i (JIT_R0, ofs);
    ofs = jit_arg_i ();
    jit_getarg_i (JIT_R1, ofs);
 
    // if R0 == R1, goto patch
    jit_insn *ref = jit_beqr_i (jit_forward (), JIT_R0, JIT_R1);
    jit_addr_i (JIT_RET, JIT_R0, JIT_R1); // if R0 != R1, RET = R0 + R1
    jit_ret ();
 
    jit_patch (ref); // if R0 == R1, RET = R0 * 2
    jit_muli_i (JIT_RET, JIT_R0, 2);
    jit_ret ();
 
    jit_flush_code (codeBuffer, jit_get_ip ().ptr);
 
    printf ("%d + %d = %d\n", 5, 5, myFunction (5, 5));
 
    return 0;
  }

This code generates broken machine code on x86_64. It's pretty much
random what it produces. The resulting code might contain illegal
instructions or just jump wildly, causing segfaults or cause floating
point exceptions.. anyways completely undefined. What's funny is that if
CRASH is defined to 0, it does not crash. It also does not crash if
"struct foo as" is static. Can anyone confirm these issues? I don't
really know what information I can provide that might be helpful. I could
provide a disassembly of the generated code, but it is so
non-deterministic that I suspect it to be rather useless.

Regards,
 
--
Pippijn van Steenhoven


_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning

signature.asc (196 bytes) Download Attachment

Re: Broken jump patching on x86_64

by Pippijn van Steenhoven :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I forgot to mention that it also does not break when "jit_state _jit"
inside main() is either static or not there at all. It also works when
"struct foo as" is outside main with external linkage.

--
Pippijn van Steenhoven


_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning

signature.asc (196 bytes) Download Attachment

Re: Broken jump patching on x86_64

by Paolo Bonzini-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


>     jit_insn codeBuffer[1024];
>     struct jit_state _jit;
>     struct foo as;
>
> This code generates broken machine code on x86_64. It's pretty much
> random what it produces. The resulting code might contain illegal
> instructions or just jump wildly, causing segfaults or cause floating
> point exceptions.. anyways completely undefined. What's funny is that if
> CRASH is defined to 0, it does not crash. It also does not crash if
> "struct foo as" is static. Can anyone confirm these issues? I don't
> really know what information I can provide that might be helpful.

What happens if you:

1) add a "memset (&as, 0, sizeof (as));"

2) change _jit's definition to "(as.current)" with parentheses?

Thanks,

Paolo


_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning

Re: Broken jump patching on x86_64

by Pippijn van Steenhoven :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Jun 08, 2008 at 04:11:02PM -0700, Paolo Bonzini wrote:
> What happens if you:
>
> 1) add a "memset (&as, 0, sizeof (as));"

That fixes it.. stupid of me not to think of that one.

> 2) change _jit's definition to "(as.current)" with parentheses?

That doesn't matter. The parentheses are optional since the member access
operator has highest precedence.

Thanks,

--
Pippijn van Steenhoven


_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning

signature.asc (196 bytes) Download Attachment

Re: Broken jump patching on x86_64

by Laurent Michel-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Paolo,

It's been a while, but I'm still using Lightning on MacOS for one of my projects. At this point I've ported the app to 64-bit on 10.5.3 and I'd love to get lightning up and going there too. So I grabbed the git version of lightning and tried to compile. 

I had to "mess" with the setup a little bit to get going. I couldn't figure out what to pass to configure to get a clean x86_64 target done -- the symlinks in lightning were staying on the 32b version, so I changed them manually, also MacOS expects the option -arch x86_64 to compile the files, had to manually add it to get it to compile. Finally, the test were not working at all. Turns out that on MacOS the VM areas for static vars and malloc do not have the execution bit set. So I was forced to update the test to call mmap and grab a range of addresses with suitable protection bit. This is how I modified the first lines of fib.c 

  jit_insn* codeBuffer = (jit_insn*)   mmap(0,4096*10,PROT_EXEC|PROT_READ|PROT_WRITE,MAP_ANON|MAP_PRIVATE,-1,0);
   printf("Mapping @ %p\n",codeBuffer);
  pifi      nfibs = (pifi) (jit_set_ip(codeBuffer).iptr);


For my own project, I managed the memory manually with mmap anyway, so that is not a big problem. 


After all this, I did get fib.c to compile and run on MacOS 10.5.3 in 64bit! 

Now, I have a question or two....

1) How can I _cleanly_ configure for that target ?

2) How could we change the test so that it works out-of-the-box on MacOS (in 64b, in 32b it does work fine).

3) What is the general state of the x86_64 port? What can I expect to work / not work ?  What are the big changes I should be aware of ?

Thanks a bunch!

---
  Laurent



On Jun 8, 2008, at 7:11 PM, Paolo Bonzini wrote:


   jit_insn codeBuffer[1024];
   struct jit_state _jit;
   struct foo as;

This code generates broken machine code on x86_64. It's pretty much
random what it produces. The resulting code might contain illegal
instructions or just jump wildly, causing segfaults or cause floating
point exceptions.. anyways completely undefined. What's funny is that if
CRASH is defined to 0, it does not crash. It also does not crash if
"struct foo as" is static. Can anyone confirm these issues? I don't
really know what information I can provide that might be helpful.

What happens if you:

1) add a "memset (&as, 0, sizeof (as));"

2) change _jit's definition to "(as.current)" with parentheses?

Thanks,

Paolo


_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning

--
  Laurent






_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning

smime.p7s (5K) Download Attachment

Re: Broken jump patching on x86_64

by Paolo Bonzini-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> Turns out that on MacOS the VM areas
> for static vars and malloc do not have the execution bit set.

Does using mprotect work?

> 1) How can I _cleanly_ configure for that target ?

Probably, something like

   CC="gcc -arch x86_64" ./configure && make

> 3) What is the general state of the x86_64 port? What can I expect to
> work / not work ?  What are the big changes I should be aware of ?

Large (>32-bit) immediates do not work for most instructions.  The rest
should be ok.

Thanks,

Paolo


_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning

Re: Re: Broken jump patching on x86_64

by Laurent Michel-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Jun 11, 2008, at 3:44 PM, Paolo Bonzini wrote:

Turns out that on MacOS the VM areas for static vars and malloc do not have the execution bit set.

Does using mprotect work?

It should. But I did not try that. 



1) How can I _cleanly_ configure for that target ?

Probably, something like

 CC="gcc -arch x86_64" ./configure && make

I'll try that. The main issue seemed to be the incorrect symbolic links though (linking to the xxx-32.h rather than xxx-64.h)




3) What is the general state of the x86_64 port? What can I expect to work / not work ?  What are the big changes I should be aware of ?

Large (>32-bit) immediates do not work for most instructions.  The rest should be ok.

Excellent! Thanks for the update.




Thanks,

Paolo


_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning

--
  Laurent






_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning

smime.p7s (5K) Download Attachment

Re: Re: Broken jump patching on x86_64

by Paolo Bonzini-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

>>> 1) How can I _cleanly_ configure for that target ?
>>
>> Probably, something like
>>
>>  CC="gcc -arch x86_64" ./configure && make
>
> I'll try that. The main issue seemed to be the incorrect symbolic links
> though (linking to the xxx-32.h rather than xxx-64.h)

Yeah, it depends on how config.guess works
If it is not enough, do something like this

  CC="gcc -arch x86_64" ./configure --build=x86_64-apple-darwin`uname -r`

Darwin is a mess in that they use the same triplet for both 32-bit and
64-bit.  It's probably possible to add a AC_CHECK_SIZEOF(long) in
configure.ac, and use that to detect whether we're on 32- or 64-bit.
Or, install both versions and dispatch based on some #define that the
preprocessor defines by default... many possibilities.

Paolo


_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning

Re: Re: Broken jump patching on x86_64

by Laurent Michel-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Jun 11, 2008, at 4:13 PM, Paolo Bonzini wrote:

1) How can I _cleanly_ configure for that target ?

Probably, something like

CC="gcc -arch x86_64" ./configure && make
I'll try that. The main issue seemed to be the incorrect symbolic links though (linking to the xxx-32.h rather than xxx-64.h)

Yeah, it depends on how config.guess works
If it is not enough, do something like this

CC="gcc -arch x86_64" ./configure --build=x86_64-apple-darwin`uname -r`

Darwin is a mess in that they use the same triplet for both 32-bit and 64-bit.  It's probably possible to add a AC_CHECK_SIZEOF(long) in configure.ac, and use that to detect whether we're on 32- or 64-bit.

The OS supports both 32 and 64 bit executables. it all dependes on the -arch option passed down to create the universal binary. 


Or, install both versions and dispatch based on some #define that the preprocessor defines by default... many possibilities.

That is how I deal with it in my code. I check

defined(__x86_64__)





Paolo

--
  Laurent






_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning

smime.p7s (5K) Download Attachment

Re: Re: Broken jump patching on x86_64

by Paolo Bonzini-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> That is how I deal with it in my code. I check
>
> defined(__x86_64__)

I settled on this.  In particular, I did something like this:

#if LIGHTNING_CROSS \
        ? LIGHTNING_TARGET == LIGHTNING_X86_64 \
        : defined (__x86_64__)
#include "asm-64.h"
#else
#include "asm-32.h"
#endif

BTW, Brown's mail server complained about messages I send you for the
"git push" problem.  It is a problem with ssh in Leopard, they say you
have to use an explicit -i option (or the equivalent option in
~/.ssh/config) to work around it.

I tested on i386-linux and x86_64-linux.

I guess you'll have to do "git pull --rebase" again.

Paolo


_______________________________________________
Lightning mailing list
Lightning@...
http://lists.gnu.org/mailman/listinfo/lightning