diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-09-26 11:46:04 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-09-26 11:46:04 +0200 |
| commit | 202a067a6177e4a9d6b31e1089cd81368ae9d4b3 (patch) | |
| tree | c71d2af536678f211cabecc71878bec93d39b6a5 /src | |
| parent | f2d1a8bc709f809f1280a606c01a2e4ed88c82cc (diff) | |
| download | box64-202a067a6177e4a9d6b31e1089cd81368ae9d4b3.tar.gz box64-202a067a6177e4a9d6b31e1089cd81368ae9d4b3.zip | |
Added some untested support for loongarch64 va_list
Diffstat (limited to 'src')
| -rwxr-xr-x | src/include/myalign.h | 22 | ||||
| -rwxr-xr-x | src/libtools/myalign.c | 695 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibc.c | 50 |
3 files changed, 581 insertions, 186 deletions
diff --git a/src/include/myalign.h b/src/include/myalign.h index b711e874..1e238d78 100755 --- a/src/include/myalign.h +++ b/src/include/myalign.h @@ -100,6 +100,21 @@ typedef struct va_list { #define CONVERT_VALIST(A) \ #error TODO! +#elif defined(__loongarch64) +#define CREATE_SYSV_VALIST(A) \ + va_list sysv_vaargs = (va_list)A; +// not creating CONVERT_VALIST(A) on purpose +// this is an approximation, and if the va_list have some float/double, it will fail! +// if the funciton needs more than 100 args, it will also fail +#define CREATE_VALIST_FROM_VAARG(STACK, SCRATCH, N) \ + va_list sysv_varargs; \ + { \ + uintptr_t *p = (uintptr_t*)(SCRATCH); \ + p[0]=R_RDI; p[1]=R_RSI; p[2]=R_RDX; \ + p[3]=R_RCX; p[4]=R_R8; p[5]=R_R9; \ + memcpy(&p[6], STACK, 100*8); \ + sysv_varargs = (void*)&p[N]; \ + } \ #else #error Unknown architecture! #endif @@ -115,9 +130,14 @@ 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 myStackAlignScanf(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, 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); void myStackAlignScanfW(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, int pos); +#ifndef CONVERT_VALIST +void myStackAlignValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va); +void myStackAlignWValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va); +void myStackAlignScanfValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va); +void myStackAlignScanfWValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va); +#endif struct x64_stat64 { /* x86_64 arm64 */ uint64_t st_dev; /* 0 */ /* 0 */ diff --git a/src/libtools/myalign.c b/src/libtools/myalign.c index 81bca493..51fcd503 100755 --- a/src/libtools/myalign.c +++ b/src/libtools/myalign.c @@ -499,190 +499,6 @@ void myStackAlignScanfW(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* } } -#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)); -} - -#endif #undef st_atime #undef st_mtime @@ -807,4 +623,513 @@ uintptr_t getVArgs(x64emu_t* emu, int pos, uintptr_t* b, int N) if((pos+N)>5) return b[pos+N-6]; return emu->regs[regs_abi[pos+N]].q[0]; -} \ No newline at end of file +} + +#ifndef CONVERT_VALIST +void myStackAlignValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va) +{ + if(!fmt) + return; + // loop... + const char* p = fmt; + int state = 0; + #ifndef HAVE_LD80BITS + double d; + long double ld; + #endif + int x = 0; + uintptr_t *area = (uintptr_t*)va->reg_save_area; // the direct registers copy + uintptr_t *st = (uintptr_t*)va->overflow_arg_area; // the stack arguments + uintptr_t gprs = va->gp_offset; + uintptr_t fprs = va->fp_offset; + 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 + case 5: // z + 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 'z': state = 5; ++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 '*': + if(gprs<X64_VA_MAX_REG) { + *mystack = area[gprs/8]; + gprs+=8; + } else { + *mystack = *st; + ++st; + } + ++mystack; + ++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 15: //%zg, meh.. double? + if(fprs<X64_VA_MAX_XMM) { + *mystack = area[fprs/8]; + fprs+=8; + mystack++; + } else { + *mystack = *st; + st++; mystack++; + } + state = 0; + ++p; + break; + case 14: //%LG long double + if((((uintptr_t)st)&0xf)!=0) + st++; + #ifdef HAVE_LD80BITS + if((((uintptr_t)mystack)&0xf)!=0) + mystack++; + memcpy(mystack, st, 16); + st+=2; mystack+=2; + #else + // there is 128bits long double on ARM64, but they need 128bit alignment + if((((uintptr_t)mystack)&0xf)!=0) + mystack++; + LD2D((void*)st, &d); + ld = d ; + memcpy(mystack, &ld, 16); + st+=2; mystack+=2; + #endif + state = 0; + ++p; + break; + case 20: // fallback + case 21: + case 22: + case 23: // 64bits int + case 24: // normal int / pointer + case 25: // size_t int + case 30: + if(gprs<X64_VA_MAX_REG) { + *mystack = area[gprs/8]; + gprs+=8; + } else { + *mystack = *st; + ++st; + } + ++mystack; + state = 0; + ++p; + break; + default: + // whaaaat? + state = 0; + } + } +} + +void myStackAlignWValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va) +{ + // loop... + const wchar_t* p = (const wchar_t*)fmt; + int state = 0; + #ifndef HAVE_LD80BITS + double d; + long double ld; + #endif + int x = 0; + uintptr_t *area = (uintptr_t*)va->reg_save_area; // the direct registers copy + uintptr_t *st = (uintptr_t*)va->overflow_arg_area; // the stack arguments + uintptr_t gprs = va->gp_offset; + uintptr_t fprs = va->fp_offset; + 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 + case 5: // z + 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 'z': state = 5; ++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 '*': + if(gprs<X64_VA_MAX_REG) { + *mystack = area[gprs/8]; + gprs+=8; + } else { + *mystack = *st; + ++st; + } + ++mystack; + ++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 15: //%zg, meh .. double + if(fprs<X64_VA_MAX_XMM) { + *mystack = area[fprs/8]; + fprs+=8; + mystack++; + } else { + *mystack = *st; + st++; mystack++; + } + state = 0; + ++p; + break; + case 14: //%LG long double + if((((uintptr_t)st)&0xf)!=0) + st++; + #ifdef HAVE_LD80BITS + if((((uintptr_t)mystack)&0xf)!=0) + mystack++; + memcpy(mystack, st, 16); + st+=2; mystack+=2; + #else + // there is 128bits long double on ARM64, but they need 128bit alignment + if((((uintptr_t)mystack)&0xf)!=0) + mystack++; + LD2D((void*)st, &d); + ld = d ; + memcpy(mystack, &ld, 16); + st+=2; mystack+=2; + #endif + state = 0; + ++p; + break; + case 20: // fallback + case 21: + case 22: + case 23: // 64bits int + case 24: // normal int / pointer + case 25: // size_t int + case 30: + if(gprs<X64_VA_MAX_REG) { + *mystack = area[gprs/8]; + gprs+=8; + } else { + *mystack = *st; + ++st; + } + ++mystack; + state = 0; + ++p; + break; + default: + // whaaaattt? + state = 0; + } + } +} + +void myStackAlignScanfValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va) +{ + + if(!fmt) + return; + // loop... + const char* p = fmt; + int state = 0; + int ign = 0; + uintptr_t *area = (uintptr_t*)va->reg_save_area; // the direct registers copy + uintptr_t *st = (uintptr_t*)va->overflow_arg_area; // the stack arguments + uintptr_t gprs = va->gp_offset; + uintptr_t fprs = va->fp_offset; + while(*p) + { + switch(state) { + case 0: + ign = 0; + switch(*p) { + case '%': state = 1; ++p; break; + default: + ++p; + } + break; + case 1: // normal + case 2: // l + case 3: // ll + case 4: // L + case 5: // z + 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 'z': state = 5; ++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 '*': ign=1; ++p; break; // ignore arg + 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 14: //%Lg long double + case 15: //%zg + case 20: // fallback + case 21: + case 22: + case 23: // 64bits int + case 24: // normal int / pointer + case 25: // size_t int + case 30: + if(!ign) { + if(gprs<X64_VA_MAX_REG) { + *mystack = area[gprs/8]; + gprs+=8; + } else { + *mystack = *st; + ++st; + } + ++mystack; + } + state = 0; + ++p; + break; + default: + // whaaaat? + state = 0; + } + } +} + +void myStackAlignScanfWValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va) +{ + + if(!fmt) + return; + // loop... + const wchar_t* p = (const wchar_t*)fmt; + int state = 0; + int ign = 0; + uintptr_t *area = (uintptr_t*)va->reg_save_area; // the direct registers copy + uintptr_t *st = (uintptr_t*)va->overflow_arg_area; // the stack arguments + uintptr_t gprs = va->gp_offset; + uintptr_t fprs = va->fp_offset; + while(*p) + { + switch(state) { + case 0: + ign = 0; + switch(*p) { + case '%': state = 1; ++p; break; + default: + ++p; + } + break; + case 1: // normal + case 2: // l + case 3: // ll + case 4: // L + case 5: // z + 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 'z': state = 5; ++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 '*': ign = 1; ++p; break; // ignore arg + 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 14: //%Lg long double + case 15: //%zg + case 20: // fallback + case 21: + case 22: + case 23: // 64bits int + case 24: // normal int / pointer + case 25: // size_t int + case 30: + if(!ign) { + if(gprs<X64_VA_MAX_REG) { + *mystack = area[gprs/8]; + gprs+=8; + } else { + *mystack = *st; + ++st; + } + ++mystack; + } + state = 0; + ++p; + break; + default: + // whaaaat? + state = 0; + } + } +} + +#endif \ No newline at end of file diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 5a6237ff..b4dd0a12 100755 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -558,14 +558,24 @@ EXPORT int my___printf_chk(x64emu_t *emu, int chk, void* fmt, void* b) EXPORT int my_vprintf(x64emu_t *emu, void* fmt, x64_va_list_t b) { (void)emu; + #ifdef CONVERT_VALIST CONVERT_VALIST(b); + #else + myStackAlignValist(emu, (const char*)fmt, emu->scratch, b); + PREPARE_VALIST; + #endif return vprintf(fmt, VARARGS); } EXPORT int my___vprintf_chk(x64emu_t *emu, void* fmt, x64_va_list_t b) __attribute__((alias("my_vprintf"))); EXPORT int my_vfprintf(x64emu_t *emu, void* F, void* fmt, x64_va_list_t b) { (void)emu; + #ifdef CONVERT_VALIST CONVERT_VALIST(b); + #else + myStackAlignValist(emu, (const char*)fmt, emu->scratch, b); + PREPARE_VALIST; + #endif return vfprintf(F, fmt, VARARGS); } EXPORT int my___vfprintf_chk(x64emu_t *emu, void* F, void* fmt, x64_va_list_t b) __attribute__((alias("my_vfprintf"))); @@ -686,13 +696,23 @@ EXPORT int my___asprintf(x64emu_t* emu, void** buff, void * fmt, uint64_t * b) _ EXPORT int my_vasprintf(x64emu_t* emu, char** buff, void* fmt, x64_va_list_t b) { (void)emu; + #ifdef CONVERT_VALIST CONVERT_VALIST(b); + #else + myStackAlignValist(emu, (const char*)fmt, emu->scratch, b); + PREPARE_VALIST; + #endif return vasprintf(buff, fmt, VARARGS); } EXPORT int my_vsprintf(x64emu_t* emu, void* buff, void * fmt, x64_va_list_t b) { (void)emu; + #ifdef CONVERT_VALIST CONVERT_VALIST(b); + #else + myStackAlignValist(emu, (const char*)fmt, emu->scratch, b); + PREPARE_VALIST; + #endif return vsprintf(buff, fmt, VARARGS); } EXPORT int my___vsprintf_chk(x64emu_t* emu, void* buff, void * fmt, x64_va_list_t b) __attribute__((alias("my_vsprintf"))); @@ -700,14 +720,24 @@ EXPORT int my___vsprintf_chk(x64emu_t* emu, void* buff, void * fmt, x64_va_list_ EXPORT int my_vfscanf(x64emu_t* emu, void* stream, void* fmt, x64_va_list_t b) { (void)emu; + #ifdef CONVERT_VALIST CONVERT_VALIST(b); + #else + myStackAlignScanfValist(emu, (const char*)fmt, emu->scratch, b); + PREPARE_VALIST; + #endif return vfscanf(stream, fmt, VARARGS); } EXPORT int my_vsscanf(x64emu_t* emu, void* stream, void* fmt, x64_va_list_t b) { (void)emu; + #ifdef CONVERT_VALIST CONVERT_VALIST(b); + #else + myStackAlignScanfValist(emu, (const char*)fmt, emu->scratch, b); + PREPARE_VALIST; + #endif return vsscanf(stream, fmt, VARARGS); } @@ -742,7 +772,12 @@ EXPORT int my___isoc99_sscanf(x64emu_t* emu, void* stream, void* fmt, uint64_t* EXPORT int my_vsnprintf(x64emu_t* emu, void* buff, size_t s, void * fmt, x64_va_list_t b) { (void)emu; + #ifdef CONVERT_VALIST CONVERT_VALIST(b); + #else + myStackAlignValist(emu, (const char*)fmt, emu->scratch, b); + PREPARE_VALIST; + #endif int r = vsnprintf(buff, s, fmt, VARARGS); return r; } @@ -768,7 +803,12 @@ EXPORT int my_vasprintf(x64emu_t* emu, void* strp, void* fmt, void* b, va_list V EXPORT int my___vasprintf_chk(x64emu_t* emu, void* buff, int flags, void* fmt, x64_va_list_t b) { (void)emu; (void)flags; + #ifdef CONVERT_VALIST CONVERT_VALIST(b); + #else + myStackAlignValist(emu, (const char*)fmt, emu->scratch, b); + PREPARE_VALIST; + #endif int r = vasprintf(buff, fmt, VARARGS); return r; } @@ -780,7 +820,12 @@ EXPORT int my___asprintf_chk(x64emu_t* emu, void* result_ptr, int flags, void* f } EXPORT int my_vswprintf(x64emu_t* emu, void* buff, size_t s, void * fmt, x64_va_list_t b) { (void)emu; + #ifdef CONVERT_VALIST CONVERT_VALIST(b); + #else + myStackAlignWValist(emu, (const char*)fmt, emu->scratch, b); + PREPARE_VALIST; + #endif int r = vswprintf(buff, s, fmt, VARARGS); return r; } @@ -857,7 +902,12 @@ EXPORT void my___syslog_chk(x64emu_t* emu, int priority, int flags, const char* EXPORT void my_vsyslog(x64emu_t* emu, int priority, const char* fmt, x64_va_list_t b) { (void)emu; + #ifdef CONVERT_VALIST CONVERT_VALIST(b); + #else + myStackAlignValist(emu, (const char*)fmt, emu->scratch, b); + PREPARE_VALIST; + #endif return vsyslog(priority, fmt, VARARGS); } |