mirror of
https://github.com/ptitSeb/box64.git
synced 2024-11-24 06:59:53 +00:00
Added printf wrapped function and some VA_ARG work
This commit is contained in:
parent
2e3c25f8e1
commit
7716633bf7
@ -117,6 +117,7 @@ set(ELFLOADER_SRC
|
||||
"${BOX64_ROOT}/src/librarian/librarian.c"
|
||||
"${BOX64_ROOT}/src/librarian/library.c"
|
||||
"${BOX64_ROOT}/src/libtools/auxval.c"
|
||||
"${BOX64_ROOT}/src/libtools/myalign.c"
|
||||
"${BOX64_ROOT}/src/libtools/threads.c"
|
||||
"${BOX64_ROOT}/src/tools/box64stack.c"
|
||||
"${BOX64_ROOT}/src/tools/bridge.c"
|
||||
|
@ -376,16 +376,16 @@ typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
|
||||
reg_arg = ["R_RDI", "R_RSI", "R_RDX", "R_RCX", "R_R8", "R_R9"]
|
||||
# vreg: value is in a general register
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N, M
|
||||
vreg = [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0]
|
||||
vreg = [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 2]
|
||||
# vxmm: value is in a XMM register
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N, M
|
||||
vxmm = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
# vother: value is elsewere
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N, M
|
||||
vother = [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||
vother = [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0]
|
||||
# vstack: value is on the stack (or out of register)
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N, M
|
||||
vstack = [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0]
|
||||
vstack = [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 2]
|
||||
arg_s = [
|
||||
"", # E
|
||||
"", # e
|
||||
@ -405,14 +405,14 @@ typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
|
||||
"*(intptr_t*)(R_RSP + {p}), ", # l
|
||||
"*(uintptr_t*)(R_RSP + {p}), ", # L
|
||||
"*(void**)(R_RSP + {p}), ", # p
|
||||
"(void*)(R_RSP + {p}), ", # V
|
||||
"", # V
|
||||
"of_convert(*(int32_t*)(R_RSP + {p})), ", # O
|
||||
"io_convert(*(void**)(R_RSP + {p})), ", # S
|
||||
"(_2uint_struct_t){{*(uintptr_t*)(R_RSP + {p}),*(uintptr_t*)(R_RSP + {p} + 4)}}, ", # 2
|
||||
"", # P
|
||||
"", # G
|
||||
"*(void**)(R_RSP + {p}), ", # N
|
||||
"*(void**)(R_RSP + {p}),*(void**)(R_RSP + {p} + 4), ", # M
|
||||
"*(void**)(R_RSP + {p}),*(void**)(R_RSP + {p} + 8), ", # M
|
||||
]
|
||||
arg_r = [
|
||||
"", # E
|
||||
@ -439,8 +439,8 @@ typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
|
||||
"", # 2
|
||||
"", # P
|
||||
"", # G
|
||||
"", # N
|
||||
"", # M
|
||||
"(void*){p}, ", # N
|
||||
"(void*){p}, ", # M
|
||||
]
|
||||
arg_x = [
|
||||
"", # E
|
||||
@ -489,14 +489,14 @@ typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
|
||||
"", # l
|
||||
"", # L
|
||||
"", # p
|
||||
"", # V
|
||||
"(void*)(R_RSP + {p}), ", # V
|
||||
"", # O
|
||||
"", # S
|
||||
"", # 2
|
||||
"arg{p}, ", # P
|
||||
"&arg{p}, ", # G
|
||||
"*(void**)(R_RSP + {p}), ", # N
|
||||
"*(void**)(R_RSP + {p}),*(void**)(R_RSP + {p} + 4), ", # M
|
||||
"", # N
|
||||
"", # M
|
||||
]
|
||||
|
||||
vals = [
|
||||
@ -546,9 +546,13 @@ typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
|
||||
return "1, " + function_args(args[1:], d, r, x)
|
||||
|
||||
idx = values.index(args[0])
|
||||
if r<5 and vreg[idx]>0:
|
||||
return arg_r[idx].format(p=reg_arg[r]) + function_args(args[1:], d, r+1, x)
|
||||
if x<7 and vxmm[idx]>0:
|
||||
if r<6 and vreg[idx]>0:
|
||||
if vreg[idx]==2 and r==6:
|
||||
return arg_r[idx-1].format(p=reg_arg[r]) + arg_s[idx-1].format(p=d) + function_args(args[1:], d + vother[idx-1]*8, r+1, x)
|
||||
if vreg[idx]==2 and r<6:
|
||||
return arg_r[idx].format(p=reg_arg[r]) + arg_r[idx].format(p=reg_arg[r+1]) + function_args(args[1:], d, r+2, x)
|
||||
return arg_r[idx].format(p=reg_arg[r]) + function_args(args[1:], d, r+1, x)
|
||||
if x<8 and vxmm[idx]>0:
|
||||
return arg_x[idx].format(p=x) + function_args(args[1:], d, r, x+1)
|
||||
if vstack[idx]>0:
|
||||
return arg_s[idx].format(p=d) + function_args(args[1:], d+8*vstack[idx], r, x)
|
||||
|
43
src/include/myalign.h
Executable file
43
src/include/myalign.h
Executable file
@ -0,0 +1,43 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
// x86_64, 6 64bits general regs and 16 or 8? 128bits float regs
|
||||
#define CREATE_SYSV_VALIST(A) \
|
||||
va_list sysv_varargs; \
|
||||
sysv_varargs->gp_offset=(6*8); \
|
||||
sysv_varargs->fp_offset=(6*8)+(16*16); \
|
||||
sysv_varargs->overflow_arg_area=A;
|
||||
#elif defined(__aarch64__)
|
||||
// aarch64: 8 64bits general regs and 8 128bits float regs
|
||||
#define CREATE_SYSV_VALIST(A) \
|
||||
va_list sysv_varargs; \
|
||||
sysv_varargs->gp_offset=(8*8); \
|
||||
sysv_varargs->fp_offset=(8*8)+(8*16); \
|
||||
sysv_varargs->overflow_arg_area=A;
|
||||
#elif defined(__powerpc64__)
|
||||
// TODO, is this correct?
|
||||
#define CREATE_SYSV_VALIST(A) \
|
||||
va_list sysv_varargs; \
|
||||
sysv_varargs->gpr=8; \
|
||||
sysv_varargs->fpr=8; \
|
||||
sysv_varargs->overflow_arg_area=A;
|
||||
#else
|
||||
#error Unknown architecture!
|
||||
#endif
|
||||
|
||||
|
||||
#define VARARGS sysv_varargs
|
||||
#define PREPARE_VALIST CREATE_SYSV_VALIST(emu->scratch)
|
||||
#define VARARGS_(A) sysv_varargs
|
||||
#define PREPARE_VALIST_(A) CREATE_SYSV_VALIST(A)
|
||||
|
||||
typedef struct x64emu_s x64emu_t;
|
||||
|
||||
// 1st pos is of vaarg is 0, not 1!
|
||||
void myStackAlign(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, int xmm, int pos);
|
||||
void myStackAlignGVariantNew(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, int xmm, int pos);
|
||||
void myStackAlignW(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, int xmm, int pos);
|
||||
|
||||
// defined in wrapperlibc.c
|
||||
int of_convert(int); // x86->arm
|
||||
int of_unconvert(int); // arm->x86
|
427
src/libtools/myalign.c
Executable file
427
src/libtools/myalign.c
Executable file
@ -0,0 +1,427 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <wchar.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <fts.h>
|
||||
|
||||
#include "x64emu.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "myalign.h"
|
||||
|
||||
static int regs_abi[] = {_DI, _SI, _DX, _CX, _R8, _R9};
|
||||
|
||||
void myStackAlign(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, int xmm, int pos)
|
||||
{
|
||||
|
||||
if(!fmt)
|
||||
return;
|
||||
// loop...
|
||||
const char* p = fmt;
|
||||
int state = 0;
|
||||
#ifndef HAVE_LD80BITS
|
||||
double d;
|
||||
#endif
|
||||
int x = 0;
|
||||
while(*p)
|
||||
{
|
||||
switch(state) {
|
||||
case 0:
|
||||
switch(*p) {
|
||||
case '%': state = 1; ++p; break;
|
||||
default:
|
||||
++p;
|
||||
}
|
||||
break;
|
||||
case 1: // normal
|
||||
case 2: // l
|
||||
case 3: // ll
|
||||
case 4: // L
|
||||
switch(*p) {
|
||||
case '%': state = 0; ++p; break; //%% = back to 0
|
||||
case 'l': ++state; if (state>3) state=3; ++p; break;
|
||||
case 'L': state = 4; ++p; break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'g':
|
||||
case 'G':
|
||||
case 'F':
|
||||
case 'f': state += 10; break; // float
|
||||
case 'd':
|
||||
case 'i':
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 'X': state += 20; break; // int
|
||||
case 'h': ++p; break; // ignored...
|
||||
case '\'':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '.':
|
||||
case '+':
|
||||
case '-': ++p; break; // formating, ignored
|
||||
case 'm': state = 0; ++p; break; // no argument
|
||||
case 'n':
|
||||
case 'p':
|
||||
case 'S':
|
||||
case 's': state = 30; break; // pointers
|
||||
case '$': ++p; break; // should issue a warning, it's not handled...
|
||||
case '*': *(mystack++) = *(st++); ++p; break; // fetch an int in the stack....
|
||||
case ' ': state=0; ++p; break;
|
||||
default:
|
||||
state=20; // other stuff, put an int...
|
||||
}
|
||||
break;
|
||||
case 11: //double
|
||||
case 12: //%lg, still double
|
||||
case 13: //%llg, still double
|
||||
if(xmm) {
|
||||
*mystack = emu->xmm[x++].q[0];
|
||||
--xmm;
|
||||
} else {
|
||||
*mystack = *st;
|
||||
st++; mystack++;
|
||||
}
|
||||
state = 0;
|
||||
++p;
|
||||
break;
|
||||
case 14: //%LG long double
|
||||
#ifdef HAVE_LD80BITS
|
||||
memcpy(mystack, st, 16);
|
||||
st+=2; mystack+=2;
|
||||
#else
|
||||
// there is no long double on ARM, so tranform that in a regular double
|
||||
LD2D((void*)st, &d);
|
||||
*mystack = *(uint64_t*)&d;
|
||||
st+=2; mystack+=1;
|
||||
#endif
|
||||
state = 0;
|
||||
++p;
|
||||
break;
|
||||
case 20: // fallback
|
||||
case 21:
|
||||
case 22:
|
||||
case 23: // 64bits int
|
||||
case 24: // normal int / pointer
|
||||
case 30:
|
||||
if(pos<6)
|
||||
*mystack = emu->regs[regs_abi[pos++]].q[0];
|
||||
else {
|
||||
*mystack = *st;
|
||||
++st;
|
||||
}
|
||||
++mystack;
|
||||
state = 0;
|
||||
++p;
|
||||
break;
|
||||
default:
|
||||
// whattt?
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
void myStackAlignGVariantNew(const char* fmt, uint32_t* st, uint32_t* mystack)
|
||||
{
|
||||
if (!fmt)
|
||||
return;
|
||||
|
||||
const char *p = fmt;
|
||||
int state = 0;
|
||||
int inblocks = 0;
|
||||
int tmp;
|
||||
|
||||
do {
|
||||
switch(state) {
|
||||
case 0: // Nothing
|
||||
switch(*p) {
|
||||
case 'b': // gboolean
|
||||
case 'y': // guchar
|
||||
case 'n': // gint16
|
||||
case 'q': // guint16
|
||||
case 'i': // gint32
|
||||
case 'u': // guint32
|
||||
case 'h': // gint32
|
||||
case 's': // const gchar*
|
||||
case 'o':
|
||||
case 'g':
|
||||
case 'v': // GVariant*
|
||||
case '*': // GVariant* of any type
|
||||
case '?': // GVariant* of basic type
|
||||
case 'r': // GVariant* of tuple type
|
||||
*mystack = *st;
|
||||
++mystack;
|
||||
++st;
|
||||
break;
|
||||
case 'x': // gint64
|
||||
case 't': // guint64
|
||||
case 'd': // gdouble
|
||||
if ((((uint32_t)mystack)&0x7)!=0)
|
||||
++mystack;
|
||||
*(uint64_t*)mystack = *(uint64_t*)st;
|
||||
st+=2; mystack+=2;
|
||||
break;
|
||||
case '{':
|
||||
case '(': ++inblocks; break;
|
||||
case '}':
|
||||
case ')': --inblocks; break;
|
||||
case 'a': state = 1; break; // GVariantBuilder* or GVariantIter**
|
||||
case 'm': state = 2; break; // maybe types
|
||||
case '@': state = 3; break; // GVariant* of type [type]
|
||||
case '^': state = 4; break; // pointer value
|
||||
case '&': break; // pointer: do nothing
|
||||
}
|
||||
break;
|
||||
case 1: // Arrays
|
||||
switch(*p) {
|
||||
case '{':
|
||||
case '(': ++tmp; break;
|
||||
case '}':
|
||||
case ')': --tmp; break;
|
||||
}
|
||||
if (*p == 'a') break;
|
||||
if (tmp == 0) {
|
||||
*mystack = *st;
|
||||
++mystack;
|
||||
++st;
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 2: // Maybe-types
|
||||
switch(*p) {
|
||||
case 'b': // gboolean
|
||||
case 'y': // guchar
|
||||
case 'n': // gint16
|
||||
case 'q': // guint16
|
||||
case 'i': // gint32
|
||||
case 'u': // guint32
|
||||
case 'h': // gint32
|
||||
case 'x': // gint64
|
||||
case 't': // guint64
|
||||
case 'd': // gdouble
|
||||
case '{':
|
||||
case '}':
|
||||
case '(':
|
||||
case ')':
|
||||
// Add a gboolean or gboolean*, no char increment
|
||||
*mystack = *st;
|
||||
++mystack;
|
||||
++st;
|
||||
--p;
|
||||
state = 0;
|
||||
break;
|
||||
case 'a': // GVariantBuilder* or GVariantIter**
|
||||
case 's': // const gchar*
|
||||
case 'o':
|
||||
case 'g':
|
||||
case 'v': // GVariant*
|
||||
case '@': // GVariant* of type [type]
|
||||
case '*': // GVariant* of any type
|
||||
case '?': // GVariant* of basic type
|
||||
case 'r': // GVariant* of tuple type
|
||||
case '&': // pointer
|
||||
case '^': // pointer value
|
||||
// Just maybe-NULL
|
||||
--p;
|
||||
state = 0;
|
||||
break;
|
||||
|
||||
default: // Default to add a gboolean & reinit state?
|
||||
*mystack = *st;
|
||||
++mystack;
|
||||
++st;
|
||||
--p;
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 3: // GVariant*
|
||||
switch(*p) {
|
||||
case '{':
|
||||
case '(': ++tmp; break;
|
||||
case '}':
|
||||
case ')': --tmp; break;
|
||||
case 'a': // GVariantBuilder* or GVariantIter**
|
||||
do { ++p; } while(*p == 'a'); // Use next character which is not an array (array definition)
|
||||
switch(*p) {
|
||||
case '{':
|
||||
case '(': ++tmp; break;
|
||||
case '}':
|
||||
case ')': --tmp; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (tmp == 0) {
|
||||
*mystack = *st;
|
||||
++mystack;
|
||||
++st;
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 4: // ^
|
||||
if (*p == 'a') state = 5;
|
||||
else if (*p == '&') state = 8;
|
||||
else state = 0; //???
|
||||
break;
|
||||
case 5: // ^a
|
||||
if ((*p == 's') || (*p == 'o') || (*p == 'y')) {
|
||||
*mystack = *st;
|
||||
++mystack;
|
||||
++st;
|
||||
state = 0;
|
||||
} else if (*p == '&') state = 6;
|
||||
else if (*p == 'a') state = 7;
|
||||
else state = 0; //???
|
||||
break;
|
||||
case 6: // ^a&
|
||||
if ((*p == 's') || (*p == 'o')) {
|
||||
*mystack = *st;
|
||||
++mystack;
|
||||
++st;
|
||||
state = 0;
|
||||
} else if (*p == 'a') state = 7;
|
||||
else state = 0; //???
|
||||
break;
|
||||
case 7: // ^aa / ^a&a
|
||||
if (*p == 'y') {
|
||||
*mystack = *st;
|
||||
++mystack;
|
||||
++st;
|
||||
state = 0;
|
||||
} else state = 0; //???
|
||||
case 8: // ^&
|
||||
if (*p == 'a') state = 9;
|
||||
else state = 0; //???
|
||||
case 9: // ^&a
|
||||
if (*p == 'y') {
|
||||
*mystack = *st;
|
||||
++mystack;
|
||||
++st;
|
||||
state = 0;
|
||||
} else state = 0; //???
|
||||
}
|
||||
++p;
|
||||
} while (*p && (inblocks || state));
|
||||
}
|
||||
|
||||
void myStackAlignW(const char* fmt, uint32_t* st, uint32_t* mystack)
|
||||
{
|
||||
// loop...
|
||||
const wchar_t* p = (const wchar_t*)fmt;
|
||||
int state = 0;
|
||||
double d;
|
||||
while(*p)
|
||||
{
|
||||
switch(state) {
|
||||
case 0:
|
||||
switch(*p) {
|
||||
case '%': state = 1; ++p; break;
|
||||
default:
|
||||
++p;
|
||||
}
|
||||
break;
|
||||
case 1: // normal
|
||||
case 2: // l
|
||||
case 3: // ll
|
||||
case 4: // L
|
||||
switch(*p) {
|
||||
case '%': state = 0; ++p; break; //%% = back to 0
|
||||
case 'l': ++state; if (state>3) state=3; ++p; break;
|
||||
case 'L': state = 4; ++p; break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'g':
|
||||
case 'G':
|
||||
case 'F':
|
||||
case 'f': state += 10; break; // float
|
||||
case 'd':
|
||||
case 'i':
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 'X': state += 20; break; // int
|
||||
case 'h': ++p; break; // ignored...
|
||||
case '\'':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '.':
|
||||
case '+':
|
||||
case '-': ++p; break; // formating, ignored
|
||||
case 'm': state = 0; ++p; break; // no argument
|
||||
case 'n':
|
||||
case 'p':
|
||||
case 'S':
|
||||
case 's': state = 30; break; // pointers
|
||||
case '$': ++p; break; // should issue a warning, it's not handled...
|
||||
case '*': *(mystack++) = *(st++); ++p; break; //fetch an int in the stack
|
||||
case ' ': state=0; ++p; break;
|
||||
default:
|
||||
state=20; // other stuff, put an int...
|
||||
}
|
||||
break;
|
||||
case 11: //double
|
||||
case 12: //%lg, still double
|
||||
case 13: //%llg, still double
|
||||
case 23: // 64bits int
|
||||
if((((uint32_t)mystack)&0x7)!=0)
|
||||
mystack++;
|
||||
*(uint64_t*)mystack = *(uint64_t*)st;
|
||||
st+=2; mystack+=2;
|
||||
state = 0;
|
||||
++p;
|
||||
break;
|
||||
case 14: //%LG long double
|
||||
#ifdef HAVE_LD80BITS
|
||||
if((((uint32_t)mystack)&0x7)!=0)
|
||||
mystack++;
|
||||
memcpy(mystack, st, 10);
|
||||
st+=3; mystack+=3;
|
||||
#else
|
||||
// there is no long double on ARM, so tranform that in a regular double
|
||||
LD2D((void*)st, &d);
|
||||
if((((uint32_t)mystack)&0x7)!=0)
|
||||
mystack++;
|
||||
*(uint64_t*)mystack = *(uint64_t*)&d;
|
||||
st+=3; mystack+=2;
|
||||
#endif
|
||||
state = 0;
|
||||
++p;
|
||||
break;
|
||||
case 20: // fallback
|
||||
case 21:
|
||||
case 22:
|
||||
case 24: // normal int / pointer
|
||||
case 30:
|
||||
*mystack = *st;
|
||||
++mystack;
|
||||
++st;
|
||||
state = 0;
|
||||
++p;
|
||||
break;
|
||||
default:
|
||||
// whattt?
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -14,6 +14,7 @@
|
||||
#() pFEp
|
||||
#() vFEpu
|
||||
#() iFEpp
|
||||
#() iFEpV
|
||||
#() iFpiu
|
||||
#() pFEpi
|
||||
#() pFEpp
|
||||
|
@ -85,6 +85,7 @@ typedef int32_t (*iFup_t)(uint32_t, void*);
|
||||
typedef void* (*pFEp_t)(x64emu_t*, void*);
|
||||
typedef void (*vFEpu_t)(x64emu_t*, void*, uint32_t);
|
||||
typedef int32_t (*iFEpp_t)(x64emu_t*, void*, void*);
|
||||
typedef int32_t (*iFEpV_t)(x64emu_t*, void*, void*);
|
||||
typedef int32_t (*iFpiu_t)(void*, int32_t, uint32_t);
|
||||
typedef void* (*pFEpi_t)(x64emu_t*, void*, int32_t);
|
||||
typedef void* (*pFEpp_t)(x64emu_t*, void*, void*);
|
||||
@ -114,6 +115,7 @@ void iFup(x64emu_t *emu, uintptr_t fcn) { iFup_t fn = (iFup_t)fcn; R_RAX=fn((uin
|
||||
void pFEp(x64emu_t *emu, uintptr_t fcn) { pFEp_t fn = (pFEp_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI); }
|
||||
void vFEpu(x64emu_t *emu, uintptr_t fcn) { vFEpu_t fn = (vFEpu_t)fcn; fn(emu, (void*)R_RDI, (uint32_t)R_RSI); }
|
||||
void iFEpp(x64emu_t *emu, uintptr_t fcn) { iFEpp_t fn = (iFEpp_t)fcn; R_RAX=fn(emu, (void*)R_RDI, (void*)R_RSI); }
|
||||
void iFEpV(x64emu_t *emu, uintptr_t fcn) { iFEpV_t fn = (iFEpV_t)fcn; R_RAX=fn(emu, (void*)R_RDI, (void*)(R_RSP + 16)); }
|
||||
void iFpiu(x64emu_t *emu, uintptr_t fcn) { iFpiu_t fn = (iFpiu_t)fcn; R_RAX=fn((void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX); }
|
||||
void pFEpi(x64emu_t *emu, uintptr_t fcn) { pFEpi_t fn = (pFEpi_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (int32_t)R_RSI); }
|
||||
void pFEpp(x64emu_t *emu, uintptr_t fcn) { pFEpp_t fn = (pFEpp_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI); }
|
||||
@ -125,7 +127,7 @@ void iFuipp(x64emu_t *emu, uintptr_t fcn) { iFuipp_t fn = (iFuipp_t)fcn; R_RAX=f
|
||||
void pFEppi(x64emu_t *emu, uintptr_t fcn) { pFEppi_t fn = (pFEppi_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX); }
|
||||
void pFEppp(x64emu_t *emu, uintptr_t fcn) { pFEppp_t fn = (pFEppp_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX); }
|
||||
void iFipppi(x64emu_t *emu, uintptr_t fcn) { iFipppi_t fn = (iFipppi_t)fcn; R_RAX=fn((int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int32_t)R_R8); }
|
||||
void iFEpippppp(x64emu_t *emu, uintptr_t fcn) { iFEpippppp_t fn = (iFEpippppp_t)fcn; R_RAX=fn(emu, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, *(void**)(R_RSP + 16), *(void**)(R_RSP + 24)); }
|
||||
void iFEpippppp(x64emu_t *emu, uintptr_t fcn) { iFEpippppp_t fn = (iFEpippppp_t)fcn; R_RAX=fn(emu, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 16)); }
|
||||
|
||||
void iFEv(x64emu_t *emu, uintptr_t fcn) { iFE_t fn = (iFE_t)fcn; R_RAX=fn(emu); }
|
||||
void pFEv(x64emu_t *emu, uintptr_t fcn) { pFE_t fn = (pFE_t)fcn; R_RAX=(uintptr_t)fn(emu); }
|
||||
|
@ -46,6 +46,7 @@ void iFup(x64emu_t *emu, uintptr_t fnc);
|
||||
void pFEp(x64emu_t *emu, uintptr_t fnc);
|
||||
void vFEpu(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFEpp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFEpV(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpiu(x64emu_t *emu, uintptr_t fnc);
|
||||
void pFEpi(x64emu_t *emu, uintptr_t fnc);
|
||||
void pFEpp(x64emu_t *emu, uintptr_t fnc);
|
||||
|
@ -42,12 +42,12 @@
|
||||
#include "debug.h"
|
||||
#include "wrapper.h"
|
||||
#include "bridge.h"
|
||||
//#include "callback.h"
|
||||
#include "callback.h"
|
||||
#include "librarian.h"
|
||||
#include "librarian/library_private.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "box64context.h"
|
||||
//#include "myalign.h"
|
||||
#include "myalign.h"
|
||||
//#include "signals.h"
|
||||
#include "fileutils.h"
|
||||
#include "auxval.h"
|
||||
@ -569,25 +569,15 @@ EXPORT void my___longjmp_chk(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/voi
|
||||
EXPORT int32_t my_setjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p);
|
||||
EXPORT int32_t my__setjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p) __attribute__((alias("my_setjmp")));
|
||||
EXPORT int32_t my___sigsetjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p) __attribute__((alias("my_setjmp")));
|
||||
#endif
|
||||
|
||||
void myStackAlign(const char* fmt, uint32_t* st, uint32_t* mystack); // align st into mystack according to fmt (for v(f)printf(...))
|
||||
typedef int (*iFpp_t)(void*, void*);
|
||||
typedef int (*iFppp_t)(void*, void*, void*);
|
||||
typedef int (*iFpupp_t)(void*, uint32_t, void*, void*);
|
||||
EXPORT int my_printf(x64emu_t *emu, void* fmt, void* b, va_list V) {
|
||||
#ifndef NOALIGN
|
||||
// need to align on arm
|
||||
myStackAlign((const char*)fmt, b, emu->scratch);
|
||||
EXPORT int my_printf(x64emu_t *emu, void* fmt, void* b) {
|
||||
myStackAlign(emu, (const char*)fmt, b, emu->scratch, R_EAX, 1);
|
||||
PREPARE_VALIST;
|
||||
void* f = vprintf;
|
||||
return ((iFpp_t)f)(fmt, VARARGS);
|
||||
#else
|
||||
// other platform don't need that
|
||||
return vprintf((const char*)fmt, V);
|
||||
#endif
|
||||
return vprintf((const char*)fmt, VARARGS);
|
||||
}
|
||||
EXPORT int my___printf_chk(x64emu_t *emu, void* fmt, void* b, va_list V) __attribute__((alias("my_printf")));
|
||||
|
||||
EXPORT int my___printf_chk(x64emu_t *emu, void* fmt, void* b) __attribute__((alias("my_printf")));
|
||||
#if 0
|
||||
EXPORT int my_vprintf(x64emu_t *emu, void* fmt, void* b, va_list V) {
|
||||
#ifndef NOALIGN
|
||||
// need to align on arm
|
||||
|
@ -1331,7 +1331,7 @@ GO(name_to_handle_at, iFipppi)
|
||||
//GO(preadv2,
|
||||
//GO(preadv64,
|
||||
//GO(preadv64v2,
|
||||
//GO(printf,
|
||||
GOM(printf, iFEpV)
|
||||
//GO(__printf_chk,
|
||||
//GO(__printf_fp,
|
||||
//GO(printf_size,
|
||||
|
Loading…
Reference in New Issue
Block a user