diff options
Diffstat (limited to 'Src/ns-eel2/glue_x86_64.h')
-rw-r--r-- | Src/ns-eel2/glue_x86_64.h | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/Src/ns-eel2/glue_x86_64.h b/Src/ns-eel2/glue_x86_64.h new file mode 100644 index 00000000..addaa882 --- /dev/null +++ b/Src/ns-eel2/glue_x86_64.h @@ -0,0 +1,261 @@ +#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 |