diff options
Diffstat (limited to 'tests/tests2')
| -rw-r--r-- | tests/tests2/98_al_ax_extend.c | 82 | ||||
| -rw-r--r-- | tests/tests2/99_fastcall.c | 552 |
2 files changed, 317 insertions, 317 deletions
diff --git a/tests/tests2/98_al_ax_extend.c b/tests/tests2/98_al_ax_extend.c index bcbaa6c..9b4e02f 100644 --- a/tests/tests2/98_al_ax_extend.c +++ b/tests/tests2/98_al_ax_extend.c @@ -1,41 +1,41 @@ -#include <stdio.h>
-#include <stdlib.h>
-asm (
- ".text;"
- ".globl _us;.globl _ss;.globl _uc;.globl _sc;"
- "_us:;_ss:;_uc:;_sc:;"
- "movl $0x1234ABCD, %eax;"
- "ret;"
-);
-
-#if 1
-#define us _us
-#define ss _ss
-#define uc _uc
-#define sc _sc
-#endif
-
-int main()
-{
- unsigned short us(void);
- short ss(void);
- unsigned char uc(void);
- signed char sc(void);
-
- unsigned short (*fpus)(void) = us;
- short (*fpss)(void) = ss;
- unsigned char (*fpuc)(void) = uc;
- signed char (*fpsc)(void) = sc;
-
- printf("%08X %08X\n", us() + 1, fpus() + 1);
- printf("%08X %08X\n", ss() + 1, fpss() + 1);
- printf("%08X %08X\n", uc() + 1, fpuc() + 1);
- printf("%08X %08X\n", sc() + 1, fpsc() + 1);
- printf("\n");
- printf("%08X %08X\n", fpus() + 1, us() + 1);
- printf("%08X %08X\n", fpss() + 1, ss() + 1);
- printf("%08X %08X\n", fpuc() + 1, uc() + 1);
- printf("%08X %08X\n", fpsc() + 1, sc() + 1);
-
- return 0;
-}
+#include <stdio.h> +#include <stdlib.h> +asm ( + ".text;" + ".globl _us;.globl _ss;.globl _uc;.globl _sc;" + "_us:;_ss:;_uc:;_sc:;" + "movl $0x1234ABCD, %eax;" + "ret;" +); + +#if 1 +#define us _us +#define ss _ss +#define uc _uc +#define sc _sc +#endif + +int main() +{ + unsigned short us(void); + short ss(void); + unsigned char uc(void); + signed char sc(void); + + unsigned short (*fpus)(void) = us; + short (*fpss)(void) = ss; + unsigned char (*fpuc)(void) = uc; + signed char (*fpsc)(void) = sc; + + printf("%08X %08X\n", us() + 1, fpus() + 1); + printf("%08X %08X\n", ss() + 1, fpss() + 1); + printf("%08X %08X\n", uc() + 1, fpuc() + 1); + printf("%08X %08X\n", sc() + 1, fpsc() + 1); + printf("\n"); + printf("%08X %08X\n", fpus() + 1, us() + 1); + printf("%08X %08X\n", fpss() + 1, ss() + 1); + printf("%08X %08X\n", fpuc() + 1, uc() + 1); + printf("%08X %08X\n", fpsc() + 1, sc() + 1); + + return 0; +} diff --git a/tests/tests2/99_fastcall.c b/tests/tests2/99_fastcall.c index cd15541..1ac8a5f 100644 --- a/tests/tests2/99_fastcall.c +++ b/tests/tests2/99_fastcall.c @@ -1,276 +1,276 @@ -#include <stdio.h>
-#include <assert.h>
-
-#ifndef _WIN32
-#define __fastcall __attribute((fastcall))
-#endif
-
-#if 1
-#define SYMBOL(x) _##x
-#else
-#define SYMBOL(x) x
-#endif
-
-/////////////////////////////////////////////////////////////////////////
-////////// TRAP FRAMEWORK
-/////////////////////////////////////////////////////////////////////////
-// if you cast 'TRAP' to a function pointer and call it,
-// it will save all 8 registers,
-// and jump into C-code (previously set using 'SET_TRAP_HANDLER(x)'),
-// in C-code you can pop DWORDs from stack and modify registers
-//
-
-void *SYMBOL(trap_handler);
-
-extern unsigned char SYMBOL(trap)[];
-asm (
- ".text;"
- "_trap:;"
- "pushl %esp;"
- "pusha;"
- "addl $0x4, 0xc(%esp);"
- "pushl %esp;"
- "call *_trap_handler;"
- "addl $0x4, %esp;"
- "movl 0xc(%esp), %eax;"
- "movl %eax, 0x20(%esp);"
- "popa;"
- "popl %esp;"
- "ret;"
-);
-
-struct trapframe {
- unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax;
-};
-
-
-#define M_FLOAT(addr) (*(float *)(addr))
-#define M_DWORD(addr) (*(unsigned *)(addr))
-#define M_WORD(addr) (*(unsigned short *)(addr))
-#define M_BYTE(addr) (*(unsigned char *)(addr))
-#define R_EAX ((tf)->eax)
-#define R_ECX ((tf)->ecx)
-#define R_EDX ((tf)->edx)
-#define R_EBX ((tf)->ebx)
-#define R_ESP ((tf)->esp)
-#define R_EBP ((tf)->ebp)
-#define R_ESI ((tf)->esi)
-#define R_EDI ((tf)->edi)
-
-#define ARG(x) (M_DWORD(R_ESP + (x) * 4))
-
-#define RETN(x) do { \
- M_DWORD(R_ESP + (x)) = M_DWORD(R_ESP); \
- R_ESP += (x); \
-} while (0)
-
-#define DUMP() do { \
- unsigned i; \
- printf("EAX: %08X\n", R_EAX); \
- printf("ECX: %08X\n", R_ECX); \
- printf("EDX: %08X\n", R_EDX); \
- printf("EBX: %08X\n", R_EBX); \
- printf("ESP: %08X\n", R_ESP); \
- printf("EBP: %08X\n", R_EBP); \
- printf("ESI: %08X\n", R_ESI); \
- printf("EDI: %08X\n", R_EDI); \
- printf("\n"); \
- printf("[RETADDR]: %08X\n", M_DWORD(R_ESP)); \
- for (i = 1; i <= 8; i++) { \
- printf("[ARG%4d]: %08X\n", i, ARG(i)); \
- } \
-} while (0)
-
-#define SET_TRAP_HANDLER(x) ((SYMBOL(trap_handler)) = (x))
-#define TRAP ((void *) &SYMBOL(trap))
-
-
-
-/////////////////////////////////////////////////////////////////////////
-////////// SAFECALL FRAMEWORK
-/////////////////////////////////////////////////////////////////////////
-// this framwork will convert any calling convention to cdecl
-// usage: first set call target with 'SET_SAFECALL_TARGET(x)'
-// then cast 'SAFECALL' to target funtion pointer type and invoke it
-// after calling, 'ESPDIFF' is the differance of old and new esp
-
-void *SYMBOL(sc_call_target);
-unsigned SYMBOL(sc_retn_addr);
-unsigned SYMBOL(sc_old_esp);
-unsigned SYMBOL(sc_new_esp);
-
-extern unsigned char SYMBOL(safecall)[];
-asm (
- ".text;"
- "_safecall:;"
- "popl _sc_retn_addr;"
- "movl %esp, _sc_old_esp;"
- "call *_sc_call_target;"
- "movl %esp, _sc_new_esp;"
- "movl _sc_old_esp, %esp;"
- "jmp *_sc_retn_addr;"
-);
-
-#define SET_SAFECALL_TARGET(x) ((SYMBOL(sc_call_target)) = (x))
-#define SAFECALL ((void *) &SYMBOL(safecall))
-#define ESPDIFF (SYMBOL(sc_new_esp) - SYMBOL(sc_old_esp))
-
-
-/////////////////////////////////////////////////////////////////////////
-////////// TEST FASTCALL INVOKE
-/////////////////////////////////////////////////////////////////////////
-
-void check_fastcall_invoke_0(struct trapframe *tf)
-{
- //DUMP();
- RETN(0);
-}
-
-void check_fastcall_invoke_1(struct trapframe *tf)
-{
- //DUMP();
- assert(R_ECX == 0x11111111);
- RETN(0);
-}
-void check_fastcall_invoke_2(struct trapframe *tf)
-{
- //DUMP();
- assert(R_ECX == 0x11111111);
- assert(R_EDX == 0x22222222);
- RETN(0);
-}
-void check_fastcall_invoke_3(struct trapframe *tf)
-{
- //DUMP();
- assert(R_ECX == 0x11111111);
- assert(R_EDX == 0x22222222);
- assert(ARG(1) == 0x33333333);
- RETN(1*4);
-}
-void check_fastcall_invoke_4(struct trapframe *tf)
-{
- //DUMP();
- assert(R_ECX == 0x11111111);
- assert(R_EDX == 0x22222222);
- assert(ARG(1) == 0x33333333);
- assert(ARG(2) == 0x44444444);
- RETN(2*4);
-}
-
-void check_fastcall_invoke_5(struct trapframe *tf)
-{
- //DUMP();
- assert(R_ECX == 0x11111111);
- assert(R_EDX == 0x22222222);
- assert(ARG(1) == 0x33333333);
- assert(ARG(2) == 0x44444444);
- assert(ARG(3) == 0x55555555);
- RETN(3*4);
-}
-
-void test_fastcall_invoke()
-{
- SET_TRAP_HANDLER(check_fastcall_invoke_0);
- ((void __fastcall (*)(void)) TRAP)();
-
- SET_TRAP_HANDLER(check_fastcall_invoke_1);
- ((void __fastcall (*)(unsigned)) TRAP)(0x11111111);
-
- SET_TRAP_HANDLER(check_fastcall_invoke_2);
- ((void __fastcall (*)(unsigned, unsigned)) TRAP)(0x11111111, 0x22222222);
-
- SET_TRAP_HANDLER(check_fastcall_invoke_3);
- ((void __fastcall (*)(unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333);
-
- SET_TRAP_HANDLER(check_fastcall_invoke_4);
- ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444);
-
- SET_TRAP_HANDLER(check_fastcall_invoke_5);
- ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555);
-}
-
-
-/////////////////////////////////////////////////////////////////////////
-////////// TEST FUNCTION CODE GENERATION
-/////////////////////////////////////////////////////////////////////////
-
-int __fastcall check_fastcall_espdiff_0(void)
-{
- return 0;
-}
-
-int __fastcall check_fastcall_espdiff_1(int a)
-{
- return a;
-}
-
-int __fastcall check_fastcall_espdiff_2(int a, int b)
-{
- return a + b;
-}
-
-int __fastcall check_fastcall_espdiff_3(int a, int b, int c)
-{
- return a + b + c;
-}
-
-int __fastcall check_fastcall_espdiff_4(int a, int b, int c, int d)
-{
- return a + b + c + d;
-}
-
-int __fastcall check_fastcall_espdiff_5(int a, int b, int c, int d, int e)
-{
- return a + b + c + d + e;
-}
-
-void test_fastcall_espdiff()
-{
- int x;
- SET_SAFECALL_TARGET(check_fastcall_espdiff_0);
- x = ((typeof(&check_fastcall_espdiff_0))SAFECALL)();
- assert(x == 0);
- assert(ESPDIFF == 0);
-
- SET_SAFECALL_TARGET(check_fastcall_espdiff_1);
- x = ((typeof(&check_fastcall_espdiff_1))SAFECALL)(1);
- assert(x == 1);
- assert(ESPDIFF == 0);
-
- SET_SAFECALL_TARGET(check_fastcall_espdiff_2);
- x = ((typeof(&check_fastcall_espdiff_2))SAFECALL)(1, 2);
- assert(x == 1 + 2);
- assert(ESPDIFF == 0);
-
- SET_SAFECALL_TARGET(check_fastcall_espdiff_3);
- x = ((typeof(&check_fastcall_espdiff_3))SAFECALL)(1, 2, 3);
- assert(x == 1 + 2 + 3);
- assert(ESPDIFF == 1*4);
-
- SET_SAFECALL_TARGET(check_fastcall_espdiff_4);
- x = ((typeof(&check_fastcall_espdiff_4))SAFECALL)(1, 2, 3, 4);
- assert(x == 1 + 2 + 3 + 4);
- assert(ESPDIFF == 2*4);
-
- SET_SAFECALL_TARGET(check_fastcall_espdiff_5);
- x = ((typeof(&check_fastcall_espdiff_5))SAFECALL)(1, 2, 3, 4, 5);
- assert(x == 1 + 2 + 3 + 4 + 5);
- assert(ESPDIFF == 3*4);
-}
-
-int main()
-{
-#define N 10000
- int i;
-
- for (i = 1; i <= N; i++) {
- test_fastcall_espdiff();
- }
-
- for (i = 1; i <= N; i++) {
- test_fastcall_invoke();
- }
-
- puts("TEST OK");
- return 0;
-}
+#include <stdio.h> +#include <assert.h> + +#ifndef _WIN32 +#define __fastcall __attribute((fastcall)) +#endif + +#if 1 +#define SYMBOL(x) _##x +#else +#define SYMBOL(x) x +#endif + +///////////////////////////////////////////////////////////////////////// +////////// TRAP FRAMEWORK +///////////////////////////////////////////////////////////////////////// +// if you cast 'TRAP' to a function pointer and call it, +// it will save all 8 registers, +// and jump into C-code (previously set using 'SET_TRAP_HANDLER(x)'), +// in C-code you can pop DWORDs from stack and modify registers +// + +void *SYMBOL(trap_handler); + +extern unsigned char SYMBOL(trap)[]; +asm ( + ".text;" + "_trap:;" + "pushl %esp;" + "pusha;" + "addl $0x4, 0xc(%esp);" + "pushl %esp;" + "call *_trap_handler;" + "addl $0x4, %esp;" + "movl 0xc(%esp), %eax;" + "movl %eax, 0x20(%esp);" + "popa;" + "popl %esp;" + "ret;" +); + +struct trapframe { + unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax; +}; + + +#define M_FLOAT(addr) (*(float *)(addr)) +#define M_DWORD(addr) (*(unsigned *)(addr)) +#define M_WORD(addr) (*(unsigned short *)(addr)) +#define M_BYTE(addr) (*(unsigned char *)(addr)) +#define R_EAX ((tf)->eax) +#define R_ECX ((tf)->ecx) +#define R_EDX ((tf)->edx) +#define R_EBX ((tf)->ebx) +#define R_ESP ((tf)->esp) +#define R_EBP ((tf)->ebp) +#define R_ESI ((tf)->esi) +#define R_EDI ((tf)->edi) + +#define ARG(x) (M_DWORD(R_ESP + (x) * 4)) + +#define RETN(x) do { \ + M_DWORD(R_ESP + (x)) = M_DWORD(R_ESP); \ + R_ESP += (x); \ +} while (0) + +#define DUMP() do { \ + unsigned i; \ + printf("EAX: %08X\n", R_EAX); \ + printf("ECX: %08X\n", R_ECX); \ + printf("EDX: %08X\n", R_EDX); \ + printf("EBX: %08X\n", R_EBX); \ + printf("ESP: %08X\n", R_ESP); \ + printf("EBP: %08X\n", R_EBP); \ + printf("ESI: %08X\n", R_ESI); \ + printf("EDI: %08X\n", R_EDI); \ + printf("\n"); \ + printf("[RETADDR]: %08X\n", M_DWORD(R_ESP)); \ + for (i = 1; i <= 8; i++) { \ + printf("[ARG%4d]: %08X\n", i, ARG(i)); \ + } \ +} while (0) + +#define SET_TRAP_HANDLER(x) ((SYMBOL(trap_handler)) = (x)) +#define TRAP ((void *) &SYMBOL(trap)) + + + +///////////////////////////////////////////////////////////////////////// +////////// SAFECALL FRAMEWORK +///////////////////////////////////////////////////////////////////////// +// this framwork will convert any calling convention to cdecl +// usage: first set call target with 'SET_SAFECALL_TARGET(x)' +// then cast 'SAFECALL' to target funtion pointer type and invoke it +// after calling, 'ESPDIFF' is the differance of old and new esp + +void *SYMBOL(sc_call_target); +unsigned SYMBOL(sc_retn_addr); +unsigned SYMBOL(sc_old_esp); +unsigned SYMBOL(sc_new_esp); + +extern unsigned char SYMBOL(safecall)[]; +asm ( + ".text;" + "_safecall:;" + "popl _sc_retn_addr;" + "movl %esp, _sc_old_esp;" + "call *_sc_call_target;" + "movl %esp, _sc_new_esp;" + "movl _sc_old_esp, %esp;" + "jmp *_sc_retn_addr;" +); + +#define SET_SAFECALL_TARGET(x) ((SYMBOL(sc_call_target)) = (x)) +#define SAFECALL ((void *) &SYMBOL(safecall)) +#define ESPDIFF (SYMBOL(sc_new_esp) - SYMBOL(sc_old_esp)) + + +///////////////////////////////////////////////////////////////////////// +////////// TEST FASTCALL INVOKE +///////////////////////////////////////////////////////////////////////// + +void check_fastcall_invoke_0(struct trapframe *tf) +{ + //DUMP(); + RETN(0); +} + +void check_fastcall_invoke_1(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + RETN(0); +} +void check_fastcall_invoke_2(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + RETN(0); +} +void check_fastcall_invoke_3(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + RETN(1*4); +} +void check_fastcall_invoke_4(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + assert(ARG(2) == 0x44444444); + RETN(2*4); +} + +void check_fastcall_invoke_5(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + assert(ARG(2) == 0x44444444); + assert(ARG(3) == 0x55555555); + RETN(3*4); +} + +void test_fastcall_invoke() +{ + SET_TRAP_HANDLER(check_fastcall_invoke_0); + ((void __fastcall (*)(void)) TRAP)(); + + SET_TRAP_HANDLER(check_fastcall_invoke_1); + ((void __fastcall (*)(unsigned)) TRAP)(0x11111111); + + SET_TRAP_HANDLER(check_fastcall_invoke_2); + ((void __fastcall (*)(unsigned, unsigned)) TRAP)(0x11111111, 0x22222222); + + SET_TRAP_HANDLER(check_fastcall_invoke_3); + ((void __fastcall (*)(unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333); + + SET_TRAP_HANDLER(check_fastcall_invoke_4); + ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444); + + SET_TRAP_HANDLER(check_fastcall_invoke_5); + ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555); +} + + +///////////////////////////////////////////////////////////////////////// +////////// TEST FUNCTION CODE GENERATION +///////////////////////////////////////////////////////////////////////// + +int __fastcall check_fastcall_espdiff_0(void) +{ + return 0; +} + +int __fastcall check_fastcall_espdiff_1(int a) +{ + return a; +} + +int __fastcall check_fastcall_espdiff_2(int a, int b) +{ + return a + b; +} + +int __fastcall check_fastcall_espdiff_3(int a, int b, int c) +{ + return a + b + c; +} + +int __fastcall check_fastcall_espdiff_4(int a, int b, int c, int d) +{ + return a + b + c + d; +} + +int __fastcall check_fastcall_espdiff_5(int a, int b, int c, int d, int e) +{ + return a + b + c + d + e; +} + +void test_fastcall_espdiff() +{ + int x; + SET_SAFECALL_TARGET(check_fastcall_espdiff_0); + x = ((typeof(&check_fastcall_espdiff_0))SAFECALL)(); + assert(x == 0); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_1); + x = ((typeof(&check_fastcall_espdiff_1))SAFECALL)(1); + assert(x == 1); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_2); + x = ((typeof(&check_fastcall_espdiff_2))SAFECALL)(1, 2); + assert(x == 1 + 2); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_3); + x = ((typeof(&check_fastcall_espdiff_3))SAFECALL)(1, 2, 3); + assert(x == 1 + 2 + 3); + assert(ESPDIFF == 1*4); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_4); + x = ((typeof(&check_fastcall_espdiff_4))SAFECALL)(1, 2, 3, 4); + assert(x == 1 + 2 + 3 + 4); + assert(ESPDIFF == 2*4); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_5); + x = ((typeof(&check_fastcall_espdiff_5))SAFECALL)(1, 2, 3, 4, 5); + assert(x == 1 + 2 + 3 + 4 + 5); + assert(ESPDIFF == 3*4); +} + +int main() +{ +#define N 10000 + int i; + + for (i = 1; i <= N; i++) { + test_fastcall_espdiff(); + } + + for (i = 1; i <= N; i++) { + test_fastcall_invoke(); + } + + puts("TEST OK"); + return 0; +} |
