📄 semantics.h
字号:
// semantics.h
// Copyright (C) 2008 Willow Schlanger
#ifndef l_crudcom__semantics_h__included
#define l_crudcom__semantics_h__included
#include "../x86s/x86s_semantics.h"
#include "../x86s/out_semantics_h.h"
#include "../x86s/x86s_common.h"
#include "parser.h"
#include <stdexcept>
#include <cstddef>
#define X86S_TMP_MAX 32 /* for a given insn. should get this from the script file */
#include <cstdio>
# include <iostream>
namespace x86s
{
const char *get_ll_cc_text(U1 x);
//#include "out_enum.h"
extern const char *strings_no[];
extern const char *strings_nt[];
extern tnode x86_tcode_nodes[];
extern tcode_element x86_tcode_table[];
std::string get_node_size_text(U2 size);
class specialized_tcode_t
{
U4 tempcount;
std::set<int> *flags;
public:
tnode tnodes[X86S_SEMANTICS_MAX_SIZE];
U2 tmpsizes[X86S_TMP_MAX];
U4 tmpsizes_count;
U4 tnodes_count;
specialized_tcode_t()
{
clear();
flags = NULL;
}
void clear()
{
tempcount = 0;
flags = NULL;
}
// in_flags and/or out_flags may be NULL.
void get_text(U4 index, std::string &output, std::set<int> *in_flags, std::set<int> *out_flags, icode_t &icode)
{
output.clear();
if(tnodes[index].type == nt_asgn)
{
if(tnodes[index].data[0] == (no_void|0x80000000))
output = ";";
else
{
output.clear();
if(tnodes[tnodes[index].data[0]].type == nt_tmp)
output = get_node_size_text(tnodes[tnodes[index].data[0]].size) + " ";
flags = out_flags;
output += get_operand_text(tnodes[index].data[0], icode);
output += " = ";
flags = in_flags;
output += get_operand_text(tnodes[index].data[1], icode);
flags = NULL;
output += ";";
// do flags here.
}
}
if(output.empty())
throw std::runtime_error("internal error: can\'t convert tcode into text");
}
private:
std::string get_reg(U1 lo_size, U1 index)
{
const char *reg8[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
const char *reg16[] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"};
const char *reg32[] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
const char *reg64[] = {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"};
if(index < 8)
switch(lo_size)
{
// fixme--add real 64bit support here.
case argsize_16: return std::string("x86_") + reg16[index];
case argsize_32: return std::string("x86_") + reg32[index];
case argsize_64: return std::string("x86_") + reg64[index];
case argsize_8: return std::string("x86_") + reg8[index];
default:
break;
}
throw std::runtime_error("unsupported register");
}
std::string get_operand_arg(U4 arg, icode_t &icode)
{
char buf[1024];
std::string result;
switch(get_argtype_lo(icode.argtype[arg]))
{
case argtype_reg:
return get_reg(get_argsize_lo(icode.argsize[arg]), icode.argvalue[arg]);
break;
case argtype_mem:
result.clear();
if(get_argsize_hi(icode.argsize[arg]) != argsize__end)
throw std::runtime_error("unsupported memory access size! (2)");
/*
result.clear();
result = "[";
if(icode.ea.sreg < 6)
{
if(icode.ea.sreg == 0) result += "es: "; else
if(icode.ea.sreg == 1) result += "cs: "; else
if(icode.ea.sreg == 2) result += "ss: "; else
if(icode.ea.sreg == 3) result += "ds: "; else
if(icode.ea.sreg == 4) result += "fs: "; else
if(icode.ea.sreg == 5) result += "gs: ";
}
{
// fixme--implement 64-bit asz here.
if(icode.asz == argsize_16)
sprintf(buf, "0x%04x", (U4)(U2)icode.disp);
else
sprintf(buf, "0x%08x", icode.disp);
if(icode.ea.index != 31 || icode.ea.base != 31)
result += " + ";
result += buf;
}
// add displacemnet here.
result += "]";
*/
if(get_argtype_hi(icode.argtype[arg]) == argtypehi_mem_disp)
{
return "!!!";
}
if(get_argtype_hi(icode.argtype[arg]) != argtypehi_mem_mem)
{
throw std::runtime_error("Unimplemented memory access type.");
}
switch(get_argsize_lo(icode.argsize[arg]))
{
// fixme--add real 64bit support here.
case argsize_16: result = "w"; break;
case argsize_32: result = "d"; break;
case argsize_64: result = "q"; break;
case argsize_128: result = "o"; break;
case argsize_8: result = "b"; break;
default:
throw std::runtime_error("unsupported memory access size! (1)");
break;
}
result += "[";
// add seg reg here.
if(icode.ea.sreg < 6)
{
if(icode.ea.sreg == 0) result += "es: "; else
if(icode.ea.sreg == 1) result += "cs: "; else
if(icode.ea.sreg == 2) result += "ss: "; else
if(icode.ea.sreg == 3) result += "ds: "; else
if(icode.ea.sreg == 4) result += "fs: "; else
if(icode.ea.sreg == 5) result += "gs: ";
}
if(icode.ea.base != 31)
result += get_reg(icode.asz, icode.ea.base);
if(icode.ea.index != 31)
{
if(icode.ea.base != 31)
result += " + ";
result += get_reg(icode.asz, icode.ea.index);
if(icode.ea.index_scale != 0)
{
result += " * ";
sprintf(buf, "%d", 1 << icode.ea.index_scale);
result += buf;
}
}
if(icode.ea.disp8)
{
// fixme--implement 64-bit asz here.
U1 disp8 = (U1)icode.disp;
if(disp8 < 0x80)
{
sprintf(buf, "0x%02x", disp8);
if(icode.ea.index != 31 || icode.ea.base != 31)
result += " + ";
result += buf;
}
else
{
sprintf(buf, "- 0x%02x", (U4)0x100 - (U4)disp8);
if(icode.ea.index != 31 || icode.ea.base != 31)
result += " ";
result += buf;
}
}
else
if(icode.disp != 0 || (icode.ea.index == 31 && icode.ea.base == 31))
{
// fixme--implement 64-bit asz here.
if(icode.asz == argsize_16)
sprintf(buf, "0x%04x", (U4)(U2)icode.disp);
else
sprintf(buf, "0x%08x", icode.disp);
if(icode.ea.index != 31 || icode.ea.base != 31)
result += " + ";
result += buf;
}
// add displacemnet here.
result += "]";
return result;
case argtype_imm:
switch(get_argtype_hi(icode.argtype[arg]))
{
case argtypehi_imm_imm:
for(U4 x = 0; x < arg; ++x)
{
if(get_argtype_lo(icode.argtype[x]) == argtype_imm)
{
std::sprintf(buf, "0x%x", icode.disp);
return buf;
}
}
std::sprintf(buf, "0x%x", icode.imm);
return buf;
case argtypehi_imm_implict8:
std::sprintf(buf, "0x%x", icode.argvalue[arg]);
return buf;
case argtypehi_imm_cc:
return get_ll_cc_text(icode.argvalue[arg]);
break;
default:
break;
}
break;
default:
break;
}
//throw std::runtime_error("unsupported argument");
return "???";
}
std::string get_operand_text(U4 operand, icode_t &icode)
{
std::string s;
if(operand >= 0x80000000)
{
operand -= 0x80000000;
s = strings_no[operand];
if(flags != NULL)
{
if(operand > no__begin_x86_flags && operand < no__end_x86_flags)
flags->insert(operand);
}
}
else
{
// see if it's a literal.
if(tnodes[operand].type == nt_literal)
{
char buf[1024];
// FIXME--add 64-bit support here.
//std::sprintf(buf, "0x%x", tnodes[tnodes[operand].data[0]].data[0]);
std::sprintf(buf, "0x%x", tnodes[operand].data[0]);
s = buf;
}
else
if(tnodes[operand].type == nt_tmp)
{
char buf[1024];
std::sprintf(buf, "tmp%d", tnodes[tnodes[operand].data[0]].data[0]);
s = buf;
}
else
if(tnodes[operand].type == nt_arg)
{
s = get_operand_arg(tnodes[tnodes[operand].data[0]].data[0], icode);
}
else
{
s = strings_nt[tnodes[operand].type];
switch(tnodes[operand].type)
{
case nt_zx:
case nt_sx:
case nt_trunc:
case nt_deref:
s += "<";
s += get_node_size_text(tnodes[operand].size);
s += ">";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -