123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- #ifndef _NSEEL_GLUE_X86_64_H_
- #define _NSEEL_GLUE_X86_64_H_
- #define GLUE_MAX_FPSTACK_SIZE 8
- #define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (offset))
- #define GLUE_PREFER_NONFP_DV_ASSIGNS
- static const unsigned char GLUE_JMP_NC[] = { 0xE9, 0,0,0,0, }; // jmp<offset>
- static const unsigned char GLUE_JMP_IF_P1_Z[] = {0x85, 0xC0, 0x0F, 0x84, 0,0,0,0 }; // test eax, eax, jz
- static const unsigned char GLUE_JMP_IF_P1_NZ[] = {0x85, 0xC0, 0x0F, 0x85, 0,0,0,0 }; // test eax, eax, jnz
- #define GLUE_FUNC_ENTER_SIZE 0
- #define GLUE_FUNC_LEAVE_SIZE 0
- const static unsigned int GLUE_FUNC_ENTER[1];
- const static unsigned int GLUE_FUNC_LEAVE[1];
- // on x86-64:
- // stack is always 16 byte aligned
- // pushing values to the stack (for eel functions) has alignment pushed first, then value (value is at the lower address)
- // pushing pointers to the stack has the pointer pushed first, then the alignment (pointer is at the higher address)
- #define GLUE_MOV_PX_DIRECTVALUE_SIZE 10
- static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wr) {
- const static unsigned short tab[3] =
- {
- 0xB848 /* mov rax, dv*/,
- 0xBF48 /* mov rdi, dv */ ,
- 0xB948 /* mov rcx, dv */
- };
- unsigned short *bb = (unsigned short *)b;
- *bb++ = tab[wr]; // mov rax, directvalue
- *(INT_PTR *)bb = v;
- }
- const static unsigned char GLUE_PUSH_P1[2]={ 0x50,0x50}; // push rax (pointer); push rax (alignment)
- #define GLUE_POP_PX_SIZE 2
- static void GLUE_POP_PX(void *b, int wv)
- {
- static const unsigned char tab[3][GLUE_POP_PX_SIZE]=
- {
- {0x58,/*pop eax*/ 0x58}, // pop alignment, then pop pointer
- {0x5F,/*pop edi*/ 0x5F},
- {0x59,/*pop ecx*/ 0x59},
- };
- memcpy(b,tab[wv],GLUE_POP_PX_SIZE);
- }
- static const unsigned char GLUE_PUSH_P1PTR_AS_VALUE[] =
- {
- 0x50, /*push rax - for alignment */
- 0xff, 0x30, /* push qword [rax] */
- };
- static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) // trashes P2 (rdi) and P3 (rcx)
- {
- if (buf)
- {
- *buf++ = 0x48; *buf++ = 0xB9; *(void **) buf = destptr; buf+=8; // mov rcx, directvalue
- *buf++ = 0x8f; *buf++ = 0x01; // pop qword [rcx]
- *buf++ = 0x5F ; // pop rdi (alignment, safe to trash rdi though)
- }
- return 1+10+2;
- }
- static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) // trashes P2/P3
- {
- if (buf)
- {
- *buf++ = 0x48; *buf++ = 0xB9; *(void **) buf = destptr; buf+=8; // mov rcx, directvalue
- *buf++ = 0x48; *buf++ = 0x8B; *buf++ = 0x38; // mov rdi, [rax]
- *buf++ = 0x48; *buf++ = 0x89; *buf++ = 0x39; // mov [rcx], rdi
- }
- return 3 + 10 + 3;
- }
- static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
- {
- if (buf)
- {
- *buf++ = 0x48;
- *buf++ = 0xB8;
- *(void **) buf = destptr; buf+=8; // mov rax, directvalue
- *buf++ = 0xDD; *buf++ = 0x18; // fstp qword [rax]
- }
- return 2+8+2;
- }
- #define GLUE_SET_PX_FROM_P1_SIZE 3
- static void GLUE_SET_PX_FROM_P1(void *b, int wv)
- {
- static const unsigned char tab[3][GLUE_SET_PX_FROM_P1_SIZE]={
- {0x90,0x90,0x90}, // should never be used! (nopnop)
- {0x48,0x89,0xC7}, // mov rdi, rax
- {0x48,0x89,0xC1}, // mov rcx, rax
- };
- memcpy(b,tab[wv],GLUE_SET_PX_FROM_P1_SIZE);
- }
- #define GLUE_POP_FPSTACK_SIZE 2
- static const unsigned char GLUE_POP_FPSTACK[2] = { 0xDD, 0xD8 }; // fstp st0
- static const unsigned char GLUE_POP_FPSTACK_TOSTACK[] = {
- 0x48, 0x81, 0xEC, 16, 0,0,0, // sub rsp, 16
- 0xDD, 0x1C, 0x24 // fstp qword (%rsp)
- };
- static const unsigned char GLUE_POP_FPSTACK_TO_WTP[] = {
- 0xDD, 0x1E, /* fstp qword [rsi] */
- 0x48, 0x81, 0xC6, 8, 0,0,0,/* add rsi, 8 */
- };
- #define GLUE_SET_PX_FROM_WTP_SIZE 3
- static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
- {
- static const unsigned char tab[3][GLUE_SET_PX_FROM_WTP_SIZE]={
- {0x48, 0x89,0xF0}, // mov rax, rsi
- {0x48, 0x89,0xF7}, // mov rdi, rsi
- {0x48, 0x89,0xF1}, // mov rcx, rsi
- };
- memcpy(b,tab[wv],GLUE_SET_PX_FROM_WTP_SIZE);
- }
- #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 2
- static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
- {
- static const unsigned char tab[3][GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE]={
- {0xDD,0x00}, // fld qword [rax]
- {0xDD,0x07}, // fld qword [rdi]
- {0xDD,0x01}, // fld qword [rcx]
- };
- memcpy(b,tab[wv],GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE);
- }
- static unsigned char GLUE_POP_STACK_TO_FPSTACK[] = {
- 0xDD, 0x04, 0x24, // fld qword (%rsp)
- 0x48, 0x81, 0xC4, 16, 0,0,0, // add rsp, 16
- };
- #define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (GLUE_SET_PX_FROM_WTP_SIZE + sizeof(GLUE_POP_FPSTACK_TO_WTP))
- static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
- {
- GLUE_SET_PX_FROM_WTP(buf,wv);
- memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP));
- };
- const static unsigned char GLUE_RET=0xC3;
- static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
- {
- if (out)
- {
- *out++ = 0x48;
- *out++ = 0xBE; // mov rsi, constant64
- *(void **)out = ptr;
- out+=sizeof(void *);
- }
- return 2+sizeof(void *);
- }
- extern void win64_callcode(INT_PTR code, INT_PTR ram_tab);
- #define GLUE_CALL_CODE(bp, cp, rt) win64_callcode(cp, rt)
- static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
- {
- char *p=(char*)_p;
- INT_PTR scan = 0xFEFEFEFEFEFEFEFE;
- while (*(INT_PTR *)p != scan) p++;
- *(INT_PTR *)p = newv;
- return (unsigned char *) (((INT_PTR*)p)+1);
- }
- #define INT_TO_LECHARS(x) ((x)&0xff),(((x)>>8)&0xff), (((x)>>16)&0xff), (((x)>>24)&0xff)
- #define GLUE_INLINE_LOOPS
- static const unsigned char GLUE_LOOP_LOADCNT[]={
- 0xDD, 0x0E, //fistTp qword [rsi]
- 0x48, 0x8B, 0x0E, // mov rcx, [rsi]
- 0x48, 0x81, 0xf9, 1,0,0,0, // cmp rcx, 1
- 0x0F, 0x8C, 0,0,0,0, // JL <skipptr>
- };
- static const unsigned char GLUE_LOOP_CLAMPCNT[]={
- 0x48, 0x81, 0xf9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // cmp rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
- 0x0F, 0x8C, 10,0,0,0, // JL over-the-mov
- 0x48, 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), 0,0,0,0, // mov rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
- };
- static const unsigned char GLUE_LOOP_BEGIN[]={
- 0x56, //push rsi
- 0x51, // push rcx
- };
- static const unsigned char GLUE_LOOP_END[]={
- 0x59, //pop rcx
- 0x5E, // pop rsi
- 0xff, 0xc9, // dec rcx
- 0x0f, 0x85, 0,0,0,0, // jnz ...
- };
- static const unsigned char GLUE_WHILE_SETUP[]={
- 0x48, 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), 0,0,0,0, // mov rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
- };
- static const unsigned char GLUE_WHILE_BEGIN[]={
- 0x56, //push rsi
- 0x51, // push rcx
- };
- static const unsigned char GLUE_WHILE_END[]={
- 0x59, //pop rcx
- 0x5E, // pop rsi
- 0xff, 0xc9, // dec rcx
- 0x0f, 0x84, 0,0,0,0, // jz endpt
- };
- static const unsigned char GLUE_WHILE_CHECK_RV[] = {
- 0x85, 0xC0, // test eax, eax
- 0x0F, 0x85, 0,0,0,0 // jnz looppt
- };
- static const unsigned char GLUE_SET_P1_Z[] = { 0x48, 0x29, 0xC0 }; // sub rax, rax
- static const unsigned char GLUE_SET_P1_NZ[] = { 0xb0, 0x01 }; // mov al, 1
- #define GLUE_HAS_FXCH
- static const unsigned char GLUE_FXCH[] = {0xd9, 0xc9};
- #define GLUE_HAS_FLDZ
- static const unsigned char GLUE_FLDZ[] = {0xd9, 0xee};
- #define GLUE_HAS_FLD1
- static const unsigned char GLUE_FLD1[] = {0xd9, 0xe8};
- static EEL_F negativezeropointfive=-0.5f;
- static EEL_F onepointfive=1.5f;
- #define GLUE_INVSQRT_NEEDREPL &negativezeropointfive, &onepointfive,
- #define GLUE_HAS_NATIVE_TRIGSQRTLOG
- static void *GLUE_realAddress(void *fn, void *fn_e, int *size)
- {
- static const unsigned char sig[12] = { 0x89, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
- unsigned char *p = (unsigned char *)fn;
- while (memcmp(p,sig,sizeof(sig))) p++;
- p+=sizeof(sig);
- fn = p;
- while (memcmp(p,sig,sizeof(sig))) p++;
- *size = p - (unsigned char *)fn;
- return fn;
- }
- // end of x86-64
- #endif
|