#ifndef __MY_ALIGN__H_
#define __MY_ALIGN__H_
#include <stdint.h>
typedef struct x64_va_list_s {
unsigned int gp_offset;
unsigned int fp_offset;
void *overflow_arg_area;
void *reg_save_area;
} x64_va_list_t[1];
#define X64_VA_MAX_REG (6*8)
#define X64_VA_MAX_XMM ((6*8)+(8*16))
#ifdef __x86_64__
For reference, here is the x86_64 va_list structure
typedef struct {
unsigned int gp_offset;
unsigned int fp_offset;
void *overflow_arg_area;
void *reg_save_area;
} va_list[1];
*/
#define CREATE_SYSV_VALIST(A) \
va_list sysv_varargs; \
sysv_varargs->gp_offset=X64_VA_MAX_REG; \
sysv_varargs->fp_offset=X64_VA_MAX_XMM; \
sysv_varargs->reg_save_area=(A); \
sysv_varargs->overflow_arg_area=A
#define CONVERT_VALIST(A) \
va_list sysv_varargs; \
sysv_varargs->gp_offset=(A)->gp_offset; \
sysv_varargs->fp_offset=(A)->fp_offset; \
sysv_varargs->reg_save_area=(A)->reg_save_area; \
sysv_varargs->overflow_arg_area=(A)->overflow_arg_area;
#define CREATE_VALIST_FROM_VAARG(STACK, SCRATCH, N) \
va_list sysv_varargs; \
sysv_varargs->gp_offset=(6-(((N)<6)?(N):6))*8; \
sysv_varargs->fp_offset=(6*8); \
sysv_varargs->reg_save_area=(SCRATCH); \
sysv_varargs->overflow_arg_area=(STACK); \
{ \
uint64_t *p = (uint64_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], emu->xmm, 8*16); \
}
#define PREFER_CONVERT_VAARG
#elif defined(__aarch64__)
va_list declared as
typedef struct va_list {
void * stack; // next stack param
void * gr_top; // end of GP arg reg save area
void * vr_top; // end of FP/SIMD arg reg save area
int gr_offs; // offset from gr_top to next GP register arg
int vr_offs; // offset from vr_top to next FP/SIMD register arg
} va_list;
*/
#define CREATE_SYSV_VALIST(A) \
va_list sysv_varargs; \
sysv_varargs.__gr_offs=(8*8); \
sysv_varargs.__vr_offs=(8*16); \
sysv_varargs.__stack=(A)
#define CONVERT_VALIST(A) \
va_list sysv_varargs; \
sysv_varargs.__gr_offs=-(6*8)+(A)->gp_offset; \
sysv_varargs.__vr_offs=-(8*16)+((A)->fp_offset-X64_VA_MAX_REG); \
sysv_varargs.__stack=(A)->overflow_arg_area; \
sysv_varargs.__gr_top=(A)->reg_save_area + X64_VA_MAX_REG; \
sysv_varargs.__vr_top=(A)->reg_save_area + X64_VA_MAX_XMM;
#define CREATE_VALIST_FROM_VAARG(STACK, SCRATCH, N) \
va_list sysv_varargs; \
sysv_varargs.__gr_offs=-(6*8)+(8*(((N)<6)?(N):6)); \
sysv_varargs.__vr_offs=-(8*16); \
sysv_varargs.__stack=(STACK); \
sysv_varargs.__gr_top=(void*)((uintptr_t)(SCRATCH) + X64_VA_MAX_REG); \
sysv_varargs.__vr_top=(void*)((uintptr_t)(SCRATCH) + X64_VA_MAX_XMM); \
{ \
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], emu->xmm, 8*16); \
}
#define PREFER_CONVERT_VAARG
#elif defined(__sw_64__)
typdef struct {
char* __base;
int __offset;
}va_list;
*/
#define CREATE_SYSV_VALIST(A) \
va_list sysv_varargs; \
sysv_varargs.__offset=0; \
sysv_varargs.__base=(A)
#define CREATE_VALIST_FROM_VALIST(VA, SCRATCH) \
va_list sysv_varargs; \
{ \
uintptr_t *p = (uintptr_t*)(SCRATCH); \
int n = (X64_VA_MAX_REG - (VA)->gp_offset)/8; \
if(n) memcpy(&p[0], (VA)->reg_save_area+X64_VA_MAX_REG-n*8, n*8); \
memcpy(&p[n], (VA)->overflow_arg_area, 20*8); \
sysv_varargs.__offset = (VA)->gp_offset; \
sysv_varargs.__base = (char*)p; \
}
#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[8+N], STACK, 20*8); \
sysv_varargs.__offset = N*8; \
sysv_varargs.__base = (char*)p; \
}
#elif defined(__loongarch64) || defined(__powerpc64__) || defined(__riscv)
#define CREATE_SYSV_VALIST(A) \
va_list sysv_varargs = (va_list)A
#define CREATE_VALIST_FROM_VALIST(VA, SCRATCH) \
va_list sysv_varargs; \
{ \
if((VA)->fp_offset!=X64_VA_MAX_XMM) printf_log(LOG_DEBUG, "Warning: %s: CREATE_VALIST_FROM_VALIST with %d XMM register!\n", __FUNCTION__, (X64_VA_MAX_XMM - (VA)->fp_offset)/16);\
uintptr_t *p = (uintptr_t*)(SCRATCH); \
int n = (X64_VA_MAX_REG - (VA)->gp_offset)/8; \
if(n) memcpy(&p[0], (VA)->reg_save_area+X64_VA_MAX_REG-n*8, n*8); \
memcpy(&p[n], (VA)->overflow_arg_area, 20*8); \
sysv_varargs = (va_list)p; \
}
#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, 20*8); \
sysv_varargs = (va_list)&p[N]; \
}
#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;
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 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 {
uint64_t st_dev;
uint64_t st_ino;
uint64_t st_nlink;
uint32_t st_mode;
uint32_t st_uid;
uint32_t st_gid;
int __pad0;
uint64_t st_rdev;
int64_t st_size;
int64_t st_blksize;
uint64_t st_blocks;
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
uint64_t __glibc_reserved[3];
} __attribute__((packed));
void AlignStat64(const void* source, void* dest);
void UnalignStat64(const void* source, void* dest);
int of_convert(int);
int of_unconvert(int);
void UnalignEpollEvent(void* dest, void* source, int nbr);
void AlignEpollEvent(void* dest, void* source, int nbr);
void UnalignSemidDs(void *dest, const void* source);
void AlignSemidDs(void *dest, const void* source);
void* align_xcb_connection(void* src);
void unalign_xcb_connection(void* src, void* dst);
void* add_xcb_connection(void* src);
void del_xcb_connection(void* src);
uintptr_t getVArgs(x64emu_t* emu, int pos, uintptr_t* b, int N);
typedef struct jump_buff_x64_s {
uint64_t save_rbx;
uint64_t save_rbp;
uint64_t save_r12;
uint64_t save_r13;
uint64_t save_r14;
uint64_t save_r15;
uint64_t save_rsp;
uint64_t save_rip;
} jump_buff_x64_t;
typedef struct __jmp_buf_tag_s {
jump_buff_x64_t __jmpbuf;
int __mask_was_saved;
#ifdef ANDROID
sigset_t __saved_mask;
#else
__sigset_t __saved_mask;
#endif
} __jmp_buf_tag_t;
#endif