about summary refs log tree commit diff stats
path: root/src/include/myalign.h
blob: 0278fdf435f00e5d2033c3ef28d9eaae5cf3847e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#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__
// x86_64, 6 64bits general regs and 16 or 8? 128bits float regs
/*
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;


#elif defined(__aarch64__)
// aarch64: 8 64bits general regs and 8 128bits float regs
/*
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;

#elif defined(__powerpc64__)
// TODO, is this correct?
#define CREATE_SYSV_VALIST(A) \
  va_list sysv_varargs; \
  sysv_varargs->gpr=8; \
  sysv_varargs->fpr=8; \
  sysv_varargs->overflow_arg_area=A;

#define CONVERT_VALIST(A) \
  #error TODO!
#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;

// 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);

struct x64_stat64 {                   /* x86_64       arm64 */
    uint64_t st_dev;                    /* 0   */   /* 0   */
    uint64_t st_ino;                    /* 8   */   /* 8   */
    uint64_t st_nlink;                  /* 16  */   /* 20  */
    uint32_t st_mode;                   /* 24  */   /* 16  */
    uint32_t st_uid;                    /* 28  */   /* 24  */
    uint32_t st_gid;                    /* 32  */   /* 28  */
    int __pad0;                         /* 36  */   /* --- */
    uint64_t st_rdev;                   /* 40  */   /* 32  */
    int64_t st_size;                    /* 48  */   /* 48  */
    int64_t st_blksize;                 /* 56  */   /* 56  */
    uint64_t st_blocks;                 /* 64  */   /* 64  */
    struct timespec st_atim;            /* 72  */   /* 72  */
    struct timespec st_mtim;            /* 88  */   /* 88  */
    struct timespec st_ctim;            /* 104 */   /* 104 */
    uint64_t __glibc_reserved[3];       /* 120 */   /* 120 */
} __attribute__((packed));              /* 144 */   /* 128 */

void UnalignStat64(const void* source, void* dest);

// defined in wrapperlibc.c
int of_convert(int);    // x86->arm
int of_unconvert(int);  // arm->x86