Skip to content

Commit

Permalink
[LA64] Implement convert x64_va_list_t to sysv_varargs for float (#2025
Browse files Browse the repository at this point in the history
…) (#2031)

* [LA64] Implement convert x64_va_list_t to sysv_varargs for float (#2025)

* [LA64] Implement myStackAlignGVariantNew (#2025)

* [LA64] Limit the log to LOG_DEBUG (#2055)

* [LA64] Add missing file (#2025)
  • Loading branch information
xiangzhai authored Nov 14, 2024
1 parent cd2638d commit 12f4afc
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/include/myalign.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ typdef struct {
#define CREATE_SYSV_VALIST(A) \
va_list sysv_varargs = (va_list)A
// not creating CONVERT_VALIST(A) on purpose
// this one will create a VA_LIST from x64_va_list using only GPRS and 100 stack element
// this one will create a VA_LIST from x64_va_list using only GPRS (NOFLOAT) and 100 stack element
#define CREATE_VALIST_FROM_VALIST(VA, SCRATCH) \
va_list sysv_varargs; \
{ \
Expand Down Expand Up @@ -179,6 +179,7 @@ void myStackAlignValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_v
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);
void myStackAlignGVariantNew(x64emu_t* emu, const char* fmt, uint64_t* scratch, x64_va_list_t* b);
#endif

struct x64_stat64 { /* x86_64 arm64 */
Expand Down
60 changes: 60 additions & 0 deletions src/libtools/myalign.c
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,66 @@ 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]);
}
}
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;
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;
}
pfmt++;
}
}

#endif

#define MUTEX_SIZE_X64 40
Expand Down
41 changes: 39 additions & 2 deletions src/wrapped/wrappedglib2.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <stdarg.h>

#include "wrappedlibs.h"

Expand Down Expand Up @@ -1077,9 +1078,45 @@ EXPORT void* my_g_variant_new_va(x64emu_t* emu, char* fmt, void* endptr, x64_va_
#ifdef CONVERT_VALIST
CONVERT_VALIST(*b);
#else
CREATE_VALIST_FROM_VALIST(*b, emu->scratch);
#if defined(__loongarch64) || defined(__riscv)
va_list sysv_varargs;
uint64_t scratch[N_SCRATCH];
myStackAlignGVariantNew(emu, fmt, scratch, b);
sysv_varargs = (va_list)scratch;
#else
CREATE_VALIST_FROM_VALIST(*b, emu->scratch);
#endif
#endif
va_list* aligned = &VARARGS;
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);
}

Expand Down
Binary file added tests/test2025
Binary file not shown.
18 changes: 18 additions & 0 deletions tests/test2025.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#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;
}

0 comments on commit 12f4afc

Please sign in to comment.