[WRAPPER] Fixed myStackAlignGVariantNew and refined the test too (#2038)

This commit is contained in:
Yang Liu 2024-11-16 04:37:36 +08:00 committed by GitHub
parent 385a31ec11
commit 5ab8a6f6f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 71 additions and 101 deletions

View File

@ -1141,59 +1141,41 @@ void myStackAlignScanfWValist(x64emu_t* emu, const char* fmt, uint64_t* mystack,
void myStackAlignGVariantNew(x64emu_t* emu, const char* fmt, uint64_t* scratch, x64_va_list_t* b)
{
uintptr_t* p = (uintptr_t*)(emu->scratch);
uintptr_t* p2 = (uintptr_t*)scratch;
int n = (X64_VA_MAX_REG - (*b)->gp_offset)/8;
int m = (X64_VA_MAX_XMM - (*b)->fp_offset)/8;
if(n) memcpy(&p[0], (*b)->reg_save_area+X64_VA_MAX_REG-n*8, n*8+m*16);
memcpy(&p[n+m], (*b)->overflow_arg_area, 20*8);
if (box64_log == LOG_DEBUG) {
printf_log(LOG_DEBUG, "%s\n", __FUNCTION__);
for (int i = 0; i < n+m+20; i++) {
printf_log(LOG_DEBUG, "p%d: 0x%lx\n", i, p[i]);
}
}
uint64_t* grp = (uint64_t*)((*b)->reg_save_area);
uint64_t* frp = (uint64_t*)((*b)->reg_save_area + X64_VA_MAX_REG);
int idx = 0;
int gr_offs = 0; // offset in the reg_save_area
int fr_offs = 0;
int oa_gr_offs = 0; // offset in the overflow_arg_area
int oa_fr_offs = 0;
int gr_offs = ((*b)->gp_offset) / 8;
int fr_offs = ((*b)->fp_offset - X64_VA_MAX_REG) / 8;
int oa_offs = 0;
const char* pfmt = fmt;
while (*pfmt) {
switch (*pfmt) {
case 'd':
// double
if (fr_offs > m-2) {
p2[idx] = p[n+m+oa_fr_offs];
oa_gr_offs++;
oa_fr_offs++;
} else {
p2[idx] = p[n+fr_offs];
fr_offs+=2;
}
idx++;
break;
case 'b':
case 'y':
case 'n':
case 'q':
case 'i':
case 'h':
case 'u':
case 'x':
case 't':
if (gr_offs > n-1) {
p2[idx] = p[n+m+oa_gr_offs];
oa_gr_offs++;
oa_fr_offs++;
} else {
p2[idx] = p[gr_offs];
gr_offs++;
}
idx++;
break;
default:
break;
case 'd': // double
if (fr_offs >= ((X64_VA_MAX_XMM - X64_VA_MAX_REG) / 8)) {
scratch[idx++] = ((uint64_t*)((*b)->overflow_arg_area))[oa_offs++];
} else {
scratch[idx++] = frp[fr_offs];
fr_offs += 2;
}
break;
case 'b':
case 'y':
case 'n':
case 'q':
case 'i':
case 'h':
case 'u':
case 'x':
case 't':
if (gr_offs >= (X64_VA_MAX_REG / 8))
scratch[idx++] = ((uint64_t*)((*b)->overflow_arg_area))[oa_offs++];
else
scratch[idx++] = grp[gr_offs++];
break;
default:
break;
}
pfmt++;
}

View File

@ -1080,44 +1080,13 @@ EXPORT void* my_g_variant_new_va(x64emu_t* emu, char* fmt, void* endptr, x64_va_
#else
#if defined(__loongarch64) || defined(__riscv)
va_list sysv_varargs;
uint64_t scratch[N_SCRATCH];
myStackAlignGVariantNew(emu, fmt, scratch, b);
sysv_varargs = (va_list)scratch;
myStackAlignGVariantNew(emu, fmt, emu->scratch, b);
sysv_varargs = (va_list)emu->scratch;
#else
CREATE_VALIST_FROM_VALIST(*b, emu->scratch);
#endif
#endif
if (box64_log == LOG_DEBUG) {
printf_log(LOG_DEBUG, "fmt: %s\n", fmt);
const char* pfmt = fmt;
int i = 0;
while (*pfmt) {
switch (*pfmt) {
case 'b':
case 'y':
case 'n':
case 'q':
case 'i':
case 'h':
case 'u':
printf_log(LOG_DEBUG, "%2d: %d\n", i, va_arg(sysv_varargs, int));
break;
case 'x':
case 't':
printf_log(LOG_DEBUG, "%2d: %ld\n", i, va_arg(sysv_varargs, long));
break;
case 'd':
printf_log(LOG_DEBUG, "%2d: %f\n", i, va_arg(sysv_varargs, double));
break;
default:
break;
}
pfmt++;
i++;
}
}
va_list* aligned = &sysv_varargs;
return my->g_variant_new_va(fmt, endptr, &aligned);
return my->g_variant_new_va(fmt, endptr, &sysv_varargs);
}
EXPORT void* my_g_variant_new(x64emu_t* emu, char* fmt, uint64_t* V)

BIN
tests/misc/gvariant Executable file

Binary file not shown.

31
tests/misc/gvariant.c Normal file
View File

@ -0,0 +1,31 @@
// gcc `pkg-config --cflags glib-2.0` `pkg-config --libs glib-2.0` -O1 gvariant.c -o gvariant
#include <glib.h>
static void func(const gchar* format, ...)
{
GVariant* variant = NULL;
va_list ap;
va_start(ap, format);
variant = g_variant_new_va(format, NULL, &ap);
va_end(ap);
if (variant != NULL) {
gchar* str = g_variant_print(variant, TRUE);
g_print("%s\n", str);
g_free(str);
g_variant_unref(variant);
} else {
g_print("Failed to create GVariant\n");
}
}
int main(int argc, char* argv[])
{
func("(bynqiuxthiiiiiiiiiiiiii)", FALSE, 'A', 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23);
func("(bynqiuxthdiiiiiiiiidiii)", TRUE, 'A', 3, 4, 5, 6, 7, 8, 9, 10.1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20.2, 21, 22, 23);
func("(bdididxdidididididididi)", TRUE, 2.2, 3, 4.4, 5, 6.6, 7, 8.8, 9, 10.1, 11, 12.12, 13, 14.14, 15, 16.16, 17, 18.18, 19, 20.2, 21, 22.22, 23);
func("(bdididxdididididiiiiiii)", TRUE, 2.2, 3, 4.4, 5, 6.6, 7, 8.8, 9, 10.1, 11, 12.12, 13, 14.14, 15, 16.16, 17, 18, 19, 20, 21, 22, 23);
func("(biidiixdiiidiiidiiidiii)", TRUE, 2, 3, 4.4, 5, 6, 7, 8.8, 9, 10, 11, 12.12, 13, 14, 15, 16.16, 17, 18, 19, 20.2, 21, 22, 23);
func("(ddddddddddddddddddddddd)", 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.1, 11.11, 12.12, 13.13, 14.14, 15.15, 16.16, 17.17, 18.18, 19.19, 20.2, 21.21, 22.22, 23.23);
return 0;
}

6
tests/misc/gvariant.txt Normal file
View File

@ -0,0 +1,6 @@
(false, byte 0x41, int16 3, uint16 4, 5, uint32 6, int64 7, uint64 8, handle 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23)
(true, byte 0x41, int16 3, uint16 4, 5, uint32 6, int64 7, uint64 8, handle 9, 10.1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20.199999999999999, 21, 22, 23)
(true, 2.2000000000000002, 3, 4.4000000000000004, 5, 6.5999999999999996, int64 7, 8.8000000000000007, 9, 10.1, 11, 12.119999999999999, 13, 14.140000000000001, 15, 16.16, 17, 18.18, 19, 20.199999999999999, 21, 22.219999999999999, 23)
(true, 2.2000000000000002, 3, 4.4000000000000004, 5, 6.5999999999999996, int64 7, 8.8000000000000007, 9, 10.1, 11, 12.119999999999999, 13, 14.140000000000001, 15, 16.16, 17, 18, 19, 20, 21, 22, 23)
(true, 2, 3, 4.4000000000000004, 5, 6, int64 7, 8.8000000000000007, 9, 10, 11, 12.119999999999999, 13, 14, 15, 16.16, 17, 18, 19, 20.199999999999999, 21, 22, 23)
(1.1000000000000001, 2.2000000000000002, 3.2999999999999998, 4.4000000000000004, 5.5, 6.5999999999999996, 7.7000000000000002, 8.8000000000000007, 9.9000000000000004, 10.1, 11.109999999999999, 12.119999999999999, 13.130000000000001, 14.140000000000001, 15.15, 16.16, 17.170000000000002, 18.18, 19.190000000000001, 20.199999999999999, 21.210000000000001, 22.219999999999999, 23.23)

Binary file not shown.

View File

@ -1,18 +0,0 @@
#include <glib.h>
static void func(const gchar* format, ...) {
va_list ap;
va_start(ap, format);
g_variant_new_va(format, NULL, &ap);
va_end(ap);
}
int main(int argc, char* argv[]) {
func("(bynqiuxthiiiiiiiiiiiiii)", TRUE, 'A', 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23);
func("(bynqiuxthdiiiiiiiiidiii)", TRUE, 'A', 3, 4, 5, 6, 7, 8, 9, 10.1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20.2, 21, 22, 23);
func("(bdididxdidididididididi)", TRUE, 2.2, 3, 4.4, 5, 6.6, 7, 8.8, 9, 10.1, 11, 12.12, 13, 14.14, 15, 16.16, 17, 18.18, 19, 20.2, 21, 22.22, 23);
func("(bdididxdididididiiiiiii)", TRUE, 2.2, 3, 4.4, 5, 6.6, 7, 8.8, 9, 10.1, 11, 12.12, 13, 14.14, 15, 16.16, 17, 18, 19, 20, 21, 22, 23);
func("(biidiixdiiidiiidiiidiii)", TRUE, 2, 3, 4.4, 5, 6, 7, 8.8, 9, 10, 11, 12.12, 13, 14, 15, 16.16, 17, 18, 19, 20.2, 21, 22, 23);
func("(ddddddddddddddddddddddd)", 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.1, 11.11, 12.12, 13.13, 14.14, 15.15, 16.16, 17.17, 18.18, 19.19, 20.2, 21.21, 22.22, 23.23);
return 0;
}