www.pudn.com > ASM86_64.rar > a64-2.c
/*
* a64.h for mik's assembler attribute
*/
#include "a64-2.h"
#include "opcode.h"
/*
* x86-64 full registers
*/
reg_t regs[] = {
/* 1-byte regs */
{ "al", 0x10 }, { "cl", 0x11 }, { "dl", 0x12 }, { "bl", 0x13 },
{ "ah", 0x14 }, { "spl", 0x14 }, { "ch", 0x15 }, { "bpl", 0x15 },
{ "dh", 0x16 }, { "sil", 0x16 }, { "bh", 0x17 }, { "dil", 0x17 },
{ "r8b", 0x18 }, { "r9b",0x19 }, { "r10b", 0x1a }, { "r11b", 0x1b },
{ "r12b", 0x1c }, { "r13b", 0x1d }, { "r14b", 0x1e }, { "r15b", 0x1f },
/* 2-bytes regs */
{ "ax", 0x20 }, { "cx", 0x21 }, { "dx", 0x22 }, { "bx", 0x23 },
{ "sp", 0x24 }, { "bp", 0x25 }, { "si", 0x26 }, { "di", 0x27 },
{ "r8w", 0x28 }, { "r9w", 0x29 }, { "r10w", 0x2a }, { "r11w", 0x2b },
{ "r12w", 0x2c }, { "r13w", 0x2d }, { "r14w", 0x2e }, { "r15w", 0x2f },
/* 4-bytes regs */
{ "eax", 0x40 }, { "ecx", 0x41 }, { "edx", 0x42 }, { "ebx", 0x43 },
{ "esp", 0x44 }, { "ebp", 0x45 }, { "esi", 0x46 }, { "edi", 0x47 },
{ "r8d", 0x48 }, { "r9d", 0x49 }, { "r10d", 0x4a }, { "r11d", 0x4b },
{ "r12d", 0x4c }, { "r13d", 0x4d }, { "r14d", 0x4e}, { "r15d", 0x4f },
/* 8-bytes regs */
{ "rax", 0x80 }, { "rcx", 0x81 }, { "rdx", 0x82 }, { "rbx", 0x83 },
{ "rsp", 0x84 }, { "rbp", 0x85 }, { "rsi", 0x86 }, { "rdi", 0x87 },
{ "r8", 0x88 }, { "r9", 0x89 }, { "r10", 0x8a }, { "r11", 0x8b },
{ "r12", 0x8c }, { "r13", 0x8d }, { "r14", 0x8e }, { "r15", 0x8f },
/* 64-bit mmx regs */
{ "mmx0", 0xe0 }, { "mmx1", 0xe1 }, { "mmx2", 0xe2 }, { "mmx3", 0xe3 },
{ "mmx4", 0xe4 }, { "mmx5", 0xe5 }, { "mmx6", 0xe6 }, { "mmx7", 0xe7 },
/* 128-bit xmm regs */
{ "xmm0", 0xf0 }, { "xmm1", 0xf1 }, { "xmm2", 0xf2 }, { "xmm3", 0xf3 },
{ "xmm4", 0xf4 }, { "xmm5", 0xf5 }, { "xmm6", 0xf6 }, { "xmm7", 0xf7 },
{ "xmm8", 0xf8 }, { "xmm9", 0xf9 }, { "xmm10", 0xfa }, {"xmm11", 0xfb},
{ "xmm12", 0xfc }, { "xmm13", 0xfd }, {"xmm14", 0xfe}, {"xmm15", 0xff},
/* segment regs */
{"es", 0xa0}, {"cs", 0xa1}, {"ss", 0xa2},
{"ds", 0xa3}, {"fs", 0xa4}, {"gs", 0xa5},
/* control regs */
{ "cr0", 0xc0 }, { "cr1", 0xc1 }, { "cr2", 0xc2 }, { "cr3", 0xc3 },
{ "cr4", 0xc4 }, { "cr5", 0xc5 }, { "cr6", 0xc6 }, { "cr7", 0xc7 },
{ "cr8", 0xc8 }, { "cr9", 0xc9 }, { "cr10", 0xca }, { "cr11", 0xcb },
{ "cr12", 0xcc }, { "cr13", 0xcd }, { "cr14", 0xce }, { "cr15", 0xcf },
/* debug regs */
{ "dr0", 0xd0 }, { "dr1", 0xd1 }, { "dr2", 0xd2 }, { "dr3", 0xd3 },
{ "dr4", 0xd4 }, { "dr5", 0xd5 }, { "dr6", 0xd6 }, { "dr7", 0xd7 },
{ "dr8", 0xd8 }, { "dr9", 0xd9 }, { "dr10", 0xda }, { "dr11", 0xdb },
{ "dr12", 0xdc }, { "dr13", 0xdd }, { "dr14", 0xde }, { "dr15", 0xdf },
/* end flag */
{ 0, 0 }
};
/******************************************************/
oseg_t osegs[] = {
{ "cs", 0x2e }, { "ds", 0x3e }, { "es", 0x26 },
{ "fs", 0x64 }, { "gs", 0x65 }, { "ss", 0x36 },
/* end flag */
{ 0, 0 }
};
scale_t scales[] = {
{ "1", 0x10 }, { "2", 0x21 }, { "4", 0x42 }, { "8", 0x83 },
{ 0, 0 } /* end flag */
};
cast_t casts[] = {
{ "byte", 8 }, { "word", 16 }, { "dword", 32 }, { "qword", 64 },
{ "near", NEAR_ID }, { "far", FAR_ID },
{ 0, 0 } /* end flag */
};
i_prefix_t i_prefixs[] = {
{ "lock", 0xf0 }, { "rep", 0xf3 }, { "repe", 0xf3 },
{ "repz", 0xf3 }, { "repne", 0xf2 }, { "repnz", 0xf2 },
{ 0, 0 }
};
/******************************************************************/
keyword_t keyword[] = {
{ "mode", KW_MODE }, { "bits", KW_BITS },
{ "org", KW_ORG },
{ "byte", KW_BYTE }, { "word", KW_WORD },
{ "dword", KW_DWORD }, { "qword", KW_QWORD },
{ "dqword", KW_DQWORD }, { "ptr", KW_PTR },
{ "const", KW_CONST }, { "function", KW_FUNCTION },
{ "var", KW_VAR }, { "macro", KW_MACRO },
{ "text", KW_TEXT }, { "code", KW_CODE },
{ 0, 0 }
};
bitmode_t modes[] = {
{ "long.64", 64 }, { "long.compatibility", 32 },
{ "protected", 32 }, { "v86", 16 }, { "real", 16 },
{ 0, 0 }
};
bits_t bits[] = {
{ "16", 16 }, { "32", 32 }, { "64", 64 },
{ 0, 0 }
};
/************************************************************/
/***** a64 gloabl variable *****/
unsigned int current_mode = LONG_64;
unsigned int current_bits = 64;
unsigned long long current_pc = 0;
unsigned long long org = 0;
unsigned long line = 0;
e_key_t *e_key_link = 0;
/*
* a64.h's function
*/
/* the memcpy of a64 */
#define do_mem_copy(dest, src, size) \
asm("movl %0, %%edi; movl %1, %%esi; \
movl %2, %%ecx; movl %%ecx, %%eax; \
shr $2, %%ecx; rep movsl; \
movl %%eax, %%ecx; andl $3, %%ecx; \
rep movsb" \
: \
: "r" (dest), "r" (src), "r" (size) \
);
#define do_mem_zero(ptr, size) \
asm("movl %0, %%edi; movl %1, %%ecx; \
xorl %%eax, %%eax; rep stosb" \
: \
: "r" (ptr), "r" (size) \
);
__inline__ void mem_copy(void *dest, void *src, unsigned int size)
{
do_mem_copy(dest, src, size);
}
__inline__ void mem_zero(void *ptr, unsigned int size)
{
do_mem_zero(ptr, size);
}
void *a64_malloc(unsigned int size)
{
void *ptr = (void *)malloc(size);
if (!ptr) {
printf("error! no enought memory\n");
release_resource();
exit(1);
}
mem_zero(ptr, size);
return ptr;
}
void a64_free(void *ptr)
{
free(ptr);
}
int str_cmp(char *d, char *s)
{
if (!d || !s)
return 0;
while (*d && *d == *s) {
d++; s++;
}
return ((*d == *s) && (*(d-1) == *(s-1)));
}
int str_len(char *s)
{
char *p = s;
if (!p) return 0;
while (*p) p++;
return p - s;
}
int str_cat(char *d, char *s)
{
char *p = d;
if (!d || !s) return 0;
while (*d) d++;
while (*s) *d++ = *s++;
return d - p;
}
/******************************************************
*******************************************************/
int trim_space(char *d, char *s)
{
if (!d || !s || !s[0])
return 0;
int i = 0, j = 0;
char *p = s;
char *q = s;
while (*s) {
if (*s != ' ')
*d++ = *s++;
else if (s == p) { /* head */
while (*s && (*s == ' ')) s++;
} else {
q = s - 1;
while (*s && (*s == ' ')) s++;
if ((is_c(*q) || is_n(*q)) && (is_c(*s) || is_n(*s)))
*d++ = ' ';
}
}
*d = 0;
return 1;
}
int get_c(char *s, char c)
{
int ret = 0;
while (*s) {
ret += (*s == c);
s++;
}
return ret;
}
int is_c(char c) {
return (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')));
}
int is_n(char c) {
return ((c >= '0') && (c <= '9'));
}
int is_hc(char c) {
return (((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F')));
}
int is_dec(char *s) {
if (!s) return 0;
while (*s) {
if (!(*s >= '0' && *s <= '9'))
return 0;
s++;
}
return 1;
}
int is_hex(char *s) {
if (!s) return 0;
if ((*s == '0') && (*(s+1) == 'x' || *(s+1) == 'X'))
{
s += 2;
while (*s) {
if (!(is_n(*s) || is_hc(*s)))
return 0;
s++;
}
} else if ((*s == '0') && is_hc(*(s+1))) {
s += 2;
while (*s) {
if (!(is_n(*s) || is_hc(*s)))
break;
s++;
}
if (*s == 0)
return 0;
if ((*s == 'h' || *s == 'H') && (*(s+1) == 0))
return 1;
} else
return 0;
return 1;
}
int is_binary(char *s) {
if (!s) return 0;
while (*s && (*s == '0' || *s == '1'))
s++;
if (*s == 0)
return 0;
else if ((*s == 'b' || *s == 'B') && (*(s+1) == 0))
return 1;
else
return 0;
return 1;
}
int is_numeric(char *s) {
int ret = 0;
if (!s) return 0;
if (is_c(*s))
return 0;
if (!(ret = is_hex(s)))
if (!(ret = is_dec(s)))
ret = is_binary(s);
return ret;
}
int get_sizeof(long long n)
{
int ret = 0;
if (n < 0)
n = -n;
union {
long long ll;
long l[2];
char c[4];
} u;
u.ll = n;
/*
if (n) {
if (u.l[1])
ret = 8;
else if (n <= 0xff)
ret = 1;
else if (n <= 0xffff)
ret = 2;
else if (n <= 0xffffffff)
ret = 4;
}
*/
if (n) {
if (u.l[1])
ret = 8;
else if (u.c[3] || u.c[2])
ret = 4;
else if (u.c[1])
ret = 2;
else if (u.c[0])
ret = 1;
} else
ret = 1;
return ret;
}
/* ----------------------------------------------- */
unsigned char get_regid(char *s)
{
reg_t *p = regs;
if (!s || !s[0])
return 0;
while (p->reg && !str_cmp(s, p->reg))
p++;
return p->reg_id;
}
unsigned char get_osegid(char *s)
{
oseg_t *p = osegs;
if (!s || !s[0])
return 0;
while (p->oseg && !str_cmp(s, p->oseg))
p++;
return p->oseg_id;
}
unsigned char get_scaleid(char *s)
{
scale_t *p = scales;
if (!s || !s[0])
return 0;
while (p->scale && !str_cmp(s, p->scale))
p++;
return p->scale_id;
}
unsigned char get_castid(char *s)
{
cast_t *p = casts;
if (!s || !s[0])
return 0;
while (p->cast && !str_cmp(s, p->cast))
p++;
return p->cast_id;
}
unsigned char get_prefixid(char *s)
{
i_prefix_t *p = i_prefixs;
if (!s || !s[0])
return 0;
while (p->prefix && !str_cmp(s, p->prefix))
p++;
return p->prefix_id;
}
unsigned char get_modeid(char *s)
{
bitmode_t *p = modes;
if (!s || !s[0])
return 0;
while (p->mode && !str_cmp(s, p->mode))
p++;
return p->mode_id;
}
unsigned char get_bitsid(char *s)
{
bits_t *p = bits;
if (!s || !s[0])
return 0;
while (p->bits && !str_cmp(s, p->bits))
p++;
return p->bits_id;
}
/*************************************************************/
int check_cast(unsigned char cast)
{
if (cast == NEAR_ID || cast == FAR_ID) {
/* it's transfer cast */
} else if (cast && (current_bits == 64)) {
} else if (!cast || cast == 64)
return 0;
return 1;
}
int check_oseg(unsigned char oseg)
{
if (oseg && (current_bits != 64)) {
/* 32-bit */
} else if (!oseg || (oseg == 0x2e) || (oseg == 0x3e) ||
(oseg == 0x26) || (oseg == 0x36))
/* in 64-bit mode: the CS,DS,ES and SS is invalid */
return 0;
return 1;
}
/*****************************************
check register is GPR
*****************************************/
/*
int is_GPR(unsigned char regid)
{
return regid && ((regid & 0xf0) < 0xa0);
}
*/
// #define is_GPR(regid) ((regid) && ((regid & 0xf0) < 0xa0))
/*
int is_eGPR(unsigned char regid)
{
return regid && ((regid & 0xf0) == 0x80);
}
*/
// #define is_eGPR(regid) ((regid) && ((regid & 0xf0) == 0x80))
int get_reg_size(unsigned char regid)
{
int reg_size = 0;
if (is_GPR(regid))
reg_size = (regid & 0xf0) >> 1;
else if ((regid & 0xf0) == 0xa0) /* segment register */
reg_size = 16;
else if ((regid & 0xf0) == 0xc0) /* control register */
reg_size = 16;
else if ((regid & 0xf0) == 0xd0) /* debug register */
reg_size = 16;
else if ((regid & 0xf0) == 0xe0) /* mmx register */
reg_size = 64;
else if ((regid & 0xf0) == 0xf0) /* xmm register */
reg_size = 128;
return reg_size;
}
/**************************************************
the funtion check base or index register
***************************************************/
int check_mreg(unsigned char regid)
{
if (!regid || ((regid & 0xF0) == 0x10)) /* 1-byte register */
return 0;
else if ((regid & 0xF0) >= 0xa0) /* not GPR */
return 0;
else if ((regid & 0xF0) == 0x20) { /* 2-byte register */
/* it's 16-bit address mode */
/* in 64-bit mode: not support 16-bit address */
if (current_bits == 64)
return 0;
/* in 32-bit mode: 16-bit address base register
only support bx, bp, si and di register */
else if (regid == BX || regid == BP || regid == SI
|| regid == DI) {
/* at 32-bit or 16-bit... OK */
} else
return 0;
} else if ((regid == ESP) || (regid == RSP)) {
/* 32-bit address or 64-bit address is OK */
}
return 1;
}
/*********************************************************
check the string is var ????
**********************************************************/
int check_var(char *s)
{
return 1;
}
/************************************************************/
kw_id_t get_keyword(char *s) {
keyword_t *p = keyword;
if (!s) return 0;
while (p->keyword && !str_cmp(p->keyword, s))
p++;
return p->keyword_id;
}
long long strd_to_n(char *s) {
long long retval = 0;
while (*s)
retval = retval * 10 + (*s++ - '0');
return retval;
}
long long strh_to_n(char *s) {
long long retval = 0;
int i = 0;
s++;
if (*s == 'x' || *s == 'X') {
s++;
while (*s) {
if (is_n(*s))
i = *s - '0';
else if (is_hc(*s))
i = *s - 'a' + 10;
else
return 0;
retval = retval * 16 + i;
s++;
}
} else {
while (*s) {
if (*s == 'h' || *s == 'H')
break;
if (is_n(*s))
i = *s - '0';
else if (is_hc(*s))
i = *s - 'a' + 10;
else
return 0;
retval = retval * 16 + i;
s++;
}
}
return retval;
}
long long strb_to_n(char *s) {
long long retval = 0;
while (*s) {
if (*s == 'b' || *s == 'B')
break;
retval = retval * 2 + (*s - '0');
s++;
}
return retval;
}
long long str_to_n(char *s)
{
long long retval = 0;
if (!s || !s[0]) return 0;
if (is_hex(s))
retval = strh_to_n(s);
else if (is_dec(s))
retval = strd_to_n(s);
else if (is_binary(s))
retval = strb_to_n(s);
else
return 0;
return retval;
}
/***********************************************************
* i_key_t *get_i_key(char *s)
* return value: i_key if found
* 0 if no found
************************************************************/
i_key_t *get_ins(char *s)
{
if (!s || !s[0])
return 0;
i_set_t *p = i_set;
while (p->mnemonic && !str_cmp(s, p->mnemonic))
p++;
return p->i_key;
}
i_key_t *get_transfer_ins(char *s)
{
if (!s || !s[0])
return 0;
i_set_t *p = i_transfer;
while (p->mnemonic && !str_cmp(s, p->mnemonic))
p++;
return p->i_key;
}
int is_string_ins(i_key_t *ins_key)
{
if (ins_key == CMPSB) {
} else if (ins_key == CMPSW) {
} else if (ins_key == CMPSD) {
} else if (ins_key == CMPSQ) {
} else if (ins_key == SCASB) {
} else if (ins_key == SCASW) {
} else if (ins_key == SCASD) {
} else if (ins_key == SCASQ) {
} else if (ins_key == MOVSB) {
} else if (ins_key == MOVSW) {
} else if (ins_key == MOVSD) {
} else if (ins_key == MOVSQ) {
} else if (ins_key == LODSB) {
} else if (ins_key == LODSW) {
} else if (ins_key == LODSD) {
} else if (ins_key == LODSQ) {
} else if (ins_key == STOSB) {
} else if (ins_key == STOSW) {
} else if (ins_key == STOSD) {
} else if (ins_key == STOSQ) {
} else
return 0;
return 1;
}
int is_transfer_ins(i_key_t *ins_key)
{
if (ins_key == JMP) {
} else if (ins_key == CALL) {
} else if (ins_key == JO) {
} else if (ins_key == JNO) {
} else if (ins_key == JB) {
} else if (ins_key == JNB) {
} else if (ins_key == JZ) {
} else if (ins_key == JNZ) {
} else if (ins_key == JBE) {
} else if (ins_key == JNBE) {
} else if (ins_key == JS) {
} else if (ins_key == JNS) {
} else if (ins_key == JP) {
} else if (ins_key == JNP) {
} else if (ins_key == JL) {
} else if (ins_key == JNL) {
} else if (ins_key == JLE) {
} else if (ins_key == JNLE) {
} else if (ins_key == LOOP) {
} else if (ins_key == LOOPZ) {
} else
return 0;
return 1;
}
int is_imul_ins(i_key_t *i_key)
{
int ret = 0;
if ((i_key >= IMUL) && (i_key < (IMUL + sizeof(IMUL))))
ret = 1;
return ret;
}
/****************************************************************/
i_key_t *get_i_key(i_key_t *i_key, ops_attr_t *ops_attr)
{
if (!i_key || !ops_attr)
return 0;
unsigned int i_attr = 0;
unsigned int i_so_attr = 0;
unsigned int i_do_attr = 0;
unsigned int i_to_attr = 0;
unsigned int so_attr = ops_attr->so_attr;
unsigned int do_attr = ops_attr->do_attr;
unsigned int to_attr = ops_attr->to_attr;
while (i_key->opcode || i_key->i_attr) {
i_attr = i_key->i_attr;
i_so_attr = i_key->so_attr;
i_do_attr = i_key->do_attr;
i_to_attr = i_key->to_attr;
if (((i_so_attr == 0) && (so_attr != 0))
|| ((i_so_attr != 0) && (so_attr == 0))
|| ((i_do_attr == 0) && (do_attr != 0))
|| ((i_do_attr != 0) && (do_attr == 0))
|| ((i_to_attr == 0) && (to_attr != 0))
|| ((i_to_attr != 0) && (to_attr == 0)))
{
i_key++;
continue;
}
/*
if (((OPTYPE(i_so_attr) == 0) && (OPTYPE(so_attr) != 0))
|| ((SIZE(i_so_attr) == 0) && (SIZE(so_attr) != 0))
|| ((OPTYPE(i_so_attr) != 0) && (OPTYPE(so_attr) == 0))
|| ((SIZE(i_so_attr) != 0) && (SIZE(so_attr) == 0))
|| ((OPTYPE(i_do_attr) == 0) && (OPTYPE(do_attr) != 0))
|| ((SIZE(i_do_attr) == 0) && (SIZE(do_attr) != 0))
|| ((OPTYPE(i_do_attr) != 0) && (OPTYPE(do_attr) == 0))
|| ((SIZE(i_do_attr) != 0) && (SIZE(do_attr) == 0))
|| ((OPTYPE(i_to_attr) == 0) && (OPTYPE(to_attr) != 0))
|| ((SIZE(i_to_attr) == 0) && (SIZE(to_attr) != 0))
|| ((OPTYPE(i_to_attr) != 0) && (OPTYPE(to_attr) == 0))
|| ((SIZE(i_to_attr) != 0) && (SIZE(to_attr) == 0)))
{
i_key++;
continue;
}
*/
if (((so_attr & i_so_attr) == so_attr)
&& ((do_attr & i_do_attr) == do_attr)
&& ((to_attr & i_to_attr) == to_attr))
{
if (current_bits == 64) {
if (is_INVLD_IN_64(i_attr)) {
i_key++;
continue;
}
}
if (is_FS_64(i_attr) && (current_bits != 64)) {
i_key++;
continue;
}
return i_key;
}
i_key++;
}
return 0;
}
/*********************************************************/
static void release_o_key(o_key_t *o_key)
{
if (o_key->mem)
a64_free(o_key->mem);
if (o_key->imme)
a64_free(o_key->imme);
a64_free(o_key);
}
static void release_ops_key(ops_key_t *ops_key)
{
if (ops_key->so_key)
release_o_key(ops_key->so_key);
if (ops_key->do_key)
release_o_key(ops_key->do_key);
if (ops_key->to_key)
release_o_key(ops_key->to_key);
a64_free(ops_key);
}
static void release_e_key(e_key_t *e_key)
{
if (e_key) {
if (e_key->ops_key)
release_ops_key(e_key->ops_key);
/*
e_key->i_key it's not need malloc()!!!
*/
if (e_key->i_prefix)
a64_free(e_key->i_prefix);
}
a64_free(e_key);
}
static void release_e_key_link()
{
e_key_t *e_key_next;
while (e_key_link) {
e_key_next = e_key_link->next;
release_e_key(e_key_link);
e_key_link = e_key_next;
}
}
void release_resource()
{
release_e_key_link();
release_label_table();
release_hole_link();
release_err_link();
}
void reset_environment()
{
current_mode = LONG_64;
current_bits = 64;
current_pc = 0;
line = 0;
org = 0;
}