diff --git a/src/libtools/myalign.c b/src/libtools/myalign.c index 796795c07..d34e0b8ef 100644 --- a/src/libtools/myalign.c +++ b/src/libtools/myalign.c @@ -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++; } diff --git a/src/wrapped/wrappedglib2.c b/src/wrapped/wrappedglib2.c index 3a481eff7..0c8bd95b1 100644 --- a/src/wrapped/wrappedglib2.c +++ b/src/wrapped/wrappedglib2.c @@ -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) diff --git a/tests/misc/gvariant b/tests/misc/gvariant new file mode 100755 index 000000000..17c33f3d0 Binary files /dev/null and b/tests/misc/gvariant differ diff --git a/tests/misc/gvariant.c b/tests/misc/gvariant.c new file mode 100644 index 000000000..5e7df6846 --- /dev/null +++ b/tests/misc/gvariant.c @@ -0,0 +1,31 @@ +// gcc `pkg-config --cflags glib-2.0` `pkg-config --libs glib-2.0` -O1 gvariant.c -o gvariant +#include + +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; +} diff --git a/tests/misc/gvariant.txt b/tests/misc/gvariant.txt new file mode 100644 index 000000000..6d26e8c56 --- /dev/null +++ b/tests/misc/gvariant.txt @@ -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) diff --git a/tests/test2025 b/tests/test2025 deleted file mode 100755 index 0cc74b18c..000000000 Binary files a/tests/test2025 and /dev/null differ diff --git a/tests/test2025.c b/tests/test2025.c deleted file mode 100644 index fdfca2e5d..000000000 --- a/tests/test2025.c +++ /dev/null @@ -1,18 +0,0 @@ -#include - -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; -}