Next Generation Emulation banner
61 - 80 of 86 Posts

· Registered
Joined
·
111 Posts
well I'm gong to take a look at the intel manuals but for now I have a question again, if I just call the Ret function shouldn't that work when I attempt to call the BlockFunction?

I run the program through the debugger and it just crashes as soon as it tries to call the code.
 

· Emu author
Joined
·
1,490 Posts
well I'm gong to take a look at the intel manuals but for now I have a question again, if I just call the Ret function shouldn't that work when I attempt to call the BlockFunction?

I run the program through the debugger and it just crashes as soon as it tries to call the code.
You'll have to be more specific.

The first thing I recommend you do is dump your recompiled code buffer to a file and run it through a disassembler like objdump. This way you'll be able to verify what you have.

If it looks correct then you most likely either have a problem with how you're calling it or the code buffer is execute protected. If it's the latter then you'll have to make an OS call to turn off protection.

Paste more of what you're doing.
 

· Emu author
Joined
·
6 Posts
By the way, if anyone was getting an access violation from the OP's first Dynarec code, then here is the modified code that works. Credit given to Martyn.Rae on dreamincode.net

Code:
#include <windows.h>
#include <stdio.h>

/* In the beginning we'll have to define the function pointer.  */ 
/* I called the function 'dyncode' and gave it an int argument  */ 
/* as well as an int return value just to show what's possible. */ 
 
int (*dyncode)(int);  /* prototype for call of dynamic code */ 
 
/* The following char array is initialized with some binary code */ 
/* which takes the first argument from the stack, increases it,  */ 
/* and returns to the caller.                                    */ 
/* Just very simple code for testing purposes...                 */ 
 
unsigned char code[] = {0x8B,0x44,0x24,0x04,  /* mov eax, [esp+4] */ 
                        0x40,                 /* inc eax          */ 
                        0xC3                  /* ret              */ 
                       }; 
 
 
/* Include the prototypes of the functions we are using... */ 
 
 
int main() 
{ 
        /* To show you that the code can be dynamically generated    */ 
        /* although I defined static data above, the code is copied  */ 
        /* into an allocated memory area and the starting address is */ 
        /* assigned to the function pointer 'dyncode'.               */ 
        /* The strange stuff in front of the malloc is just to cast  */ 
        /* the address to the same format the function pointer is    */ 
        /* definded with, otherwise you'd get a compiler warning.    */ 
 
        dyncode = (int (*)(int)) VirtualAlloc(NULL, sizeof(code),
                                              MEM_COMMIT, PAGE_EXECUTE_READWRITE);

        /* We now have a page of memory that is readable, writeable    */
        /* and executable. so the memcpy will work without any         */
        /* problems!                                                   */

        memcpy(dyncode, code, sizeof(code)); 
 
        /* To show that the code works it is called with the argument 41 */ 
        /* and the retval sould be 42, obviously.                        */ 
 
        /* This code will now execute correctly!                         */

        printf("retval = %d\n", (*dyncode)(41) );  /* call the code and print the return value */   

        /* Freeing the page allocated.                                   */

        VirtualFree(dyncode, NULL, MEM_RELEASE);
        return 0;
}
:thumb:
 

· Registered
Joined
·
111 Posts
By the way, if anyone was getting an access violation from the OP's first Dynarec code (On windows 7), then here is the modified code that works. Credit given to Martyn.Rae on dreamincode.net

Code:
#include <windows.h>
#include <stdio.h>

/* In the beginning we'll have to define the function pointer.  */ 
/* I called the function 'dyncode' and gave it an int argument  */ 
/* as well as an int return value just to show what's possible. */ 
 
int (*dyncode)(int);  /* prototype for call of dynamic code */ 
 
/* The following char array is initialized with some binary code */ 
/* which takes the first argument from the stack, increases it,  */ 
/* and returns to the caller.                                    */ 
/* Just very simple code for testing purposes...                 */ 
 
unsigned char code[] = {0x8B,0x44,0x24,0x04,  /* mov eax, [esp+4] */ 
                        0x40,                 /* inc eax          */ 
                        0xC3                  /* ret              */ 
                       }; 
 
 
/* Include the prototypes of the functions we are using... */ 
 
 
int main() 
{ 
        /* To show you that the code can be dynamically generated    */ 
        /* although I defined static data above, the code is copied  */ 
        /* into an allocated memory area and the starting address is */ 
        /* assigned to the function pointer 'dyncode'.               */ 
        /* The strange stuff in front of the malloc is just to cast  */ 
        /* the address to the same format the function pointer is    */ 
        /* definded with, otherwise you'd get a compiler warning.    */ 
 
        dyncode = (int (*)(int)) VirtualAlloc(NULL, sizeof(code),
                                              MEM_COMMIT, PAGE_EXECUTE_READWRITE);

        /* We now have a page of memory that is readable, writeable    */
        /* and executable. so the memcpy will work without any         */
        /* problems!                                                   */

        memcpy(dyncode, code, sizeof(code)); 
 
        /* To show that the code works it is called with the argument 41 */ 
        /* and the retval sould be 42, obviously.                        */ 
 
        /* This code will now execute correctly!                         */

        printf("retval = %d\n", (*dyncode)(41) );  /* call the code and print the return value */   

        /* Freeing the page allocated.                                   */

        VirtualFree(dyncode, NULL, MEM_RELEASE);
        return 0;
}
:thumb:
THANK YOU!

I had given up on getting this working. This works!
 

· You're already dead...
Joined
·
10,293 Posts

· You're already dead...
Joined
·
10,293 Posts
I wrote a blog post here about how dynarecs work:
[blog] Introduction to Dynamic Recompilation

It also explains how a basic interpreter emulator works as well; and points out why dynarecs are advantageous.

Also there was way too much I had to leave out due to complexity and to keep it short. But hopefully some people find it useful...
 

· Emu Author
Joined
·
616 Posts
I know by the time i am done with this little test program i may hate myself and possibly my pc but i will be trying to convert the working code shown earlier for executing byte code in c++ into a C# program. sadly c# can not directly execute the code BUT i already found a way around the issue so once i am finished i will be posting up the code and everything so for all those who are interested, keep an eye out :D.
 

· You're already dead...
Joined
·
10,293 Posts
interesting, i'd love to see the C# code when you're done.
 

· Emu Author
Joined
·
616 Posts
well i "would" be posting a nice example of my current theory program but i just found out i accidentally removed the c++ platform sdk that i thought i did not need and found out it took out my windows.h file so i am having to repair visual studio so i can compile my code :/.
 

· Emu Author
Joined
·
616 Posts
Sorry it has taken so long, with having to repair my visual studio and other things that took priority i do have a working example of my code but i am going to be fixing it up in the coming days so it does more than spit out static information lol.
 

· Premium Member
Joined
·
8,437 Posts
Just in case anyone would like to know, VMachine is a pretty good open source PC emulator that is very straight forward and very easy to learn from if you'd like to see dynarec in action.

It would be nice to see updates of this emulator, including CD-ROM support, improved SoundBlaster emulation (isn't working for me), RAM size greater than 16MB, improved VGA emulation and maybe some 3D accelerators. I can't remember if the PCI bus is emulated or not, but if it isn't, that would also be a nice touch. Aside from the features it lacks, most of it is pretty good. Emulates Windows 95 rather well. With some more updates and new features, this would be a rather awesome PC emulator.

VMachine: x86 PC Emulator for Windows - Paul's Projects
 

· Registered
Joined
·
111 Posts
I'm trying to make the code work in linux now and I'm having issues.

I used mprotect to let me call the function without a segmentation fault but now I just keep getting zero back from the function.

Not really sure how I can debug this effectively

Code:
/* In the beginning we'll have to define the function pointer.  */
/* I called the function 'dyncode' and gave it an int argument  */
/* as well as an int return value just to show what's possible. */

int (*dyncode)(int);  /* prototype for call of dynamic code */

/* The following char array is initialized with some binary code */
/* which takes the first argument from the stack, increases it,  */
/* and returns to the caller.                                    */
/* Just very simple code for testing purposes...                 */

unsigned char code[] = {0x8B,0x44,0x24,0x04,  /* mov eax, [esp+4] */
                        0x40,                 /* inc eax          */
                        0xC3                  /* ret              */
                       };


/* Include the prototypes of the functions we are using... */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>

int foo(int);
int main(void)
{
  /* To show you that the code can be dynamically generated    */
  /* although I defined static data above, the code is copied  */
  /* into an allocated memory area and the starting address is */
  /* assigned to the function pointer 'dyncode'.               */
  /* The strange stuff in front of the malloc is just to cast  */
  /* the address to the same format the function pointer is    */
  /* definded with, otherwise you'd get a compiler warning.    */

  dyncode = (int (*)(int)) malloc(sizeof(code) + 4095);
  dyncode = (int (*)(int))(((long long)dyncode + 4095 & ~(4095)));

  int t = mprotect(dyncode, sizeof(code), PROT_READ | PROT_WRITE | PROT_EXEC);
  if(t == -1)
    perror("test");
  memcpy(dyncode, code, sizeof(code));

  unsigned char *t2 = (unsigned char *)dyncode;
  int i = 0;
  for(i = 0; i < 10; i++)
  {
    printf("%x\n", *(t2+i));
  }
  /* To show that the code works it is called with the argument 41 */
  /* and the retval sould be 42, obviously.                        */
  int test = dyncode(41);
  //always returns 0
  printf("retval = %d %d %d\n", test, dyncode(42), (*dyncode)(43));/* call the code and print the return value */  

  return 0;
}
 
61 - 80 of 86 Posts
This is an older thread, you may not receive a response, and could be reviving an old thread. Please consider creating a new thread.
Top