⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 semantics.h

📁 当前支持 16-bit, 32-bit and 64-bit 的二进制文件
💻 H
📖 第 1 页 / 共 2 页
字号:
// 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 + -