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

📄 write_script.cpp

📁 当前支持 16-bit, 32-bit and 64-bit 的二进制文件
💻 CPP
字号:
// read_script.cpp
// Copyright (C) 2008 Willow Schlanger

#include "x86s_script.h"

#include "types.h"
#include "x86s_common.h"

#include <list>
#include <set>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <fstream>

namespace x86s
{

std::string get_prefix(std::string src)
{
	std::string dest;
	for(std::string::iterator i = src.begin(); i != src.end(); ++i)
		if(*i == '_')
			break;
		else
			dest += *i;
	return dest;
}

std::string char_to_string(char c)
{
	char s[2];
	s[0] = c;
	s[1] = '\0';
	return s;
}

void write_encoding_suffixes(std::stringstream &s, tmp_encoding_t &tmp, globals_t &globals)
{
	std::vector<std::string> prefix;
	std::vector<std::string> suffix;
	
	// First initialize the vector.
	for(base_option_list_t::iterator i = globals.elist.begin(); i != globals.elist.end(); ++i)
	{
		if(i->empty())
			throw __LINE__;
		std::string p = get_prefix(*i->begin());
		prefix.push_back(p);
		suffix.push_back(p + "_def");
	}
	
	for(std::set<std::string>::iterator i = tmp.suffix.begin(); i != tmp.suffix.end(); ++i)
	{
		SINT j = globals.elist.do_find(*i);
		if(j != -1)
		{
			// What about conflicting suffixes? We just use the last one given.
			suffix[j] = *i;
		}
		else
		{
			std::cout << "Can\'t find: \'" << *i << "\'!" << std::endl;
			throw __LINE__;
		}
	}
	
	// Now output the values.
	for(std::vector<std::string>::iterator i = suffix.begin(); i != suffix.end(); ++i)
	{
		if(i != suffix.begin())
			s << ", ";
		s << *i;
	}
}

void encoding_to_string(std::string &out, tmp_encoding_t &tmp, globals_t &globals)
{
	std::stringstream s;
	
	//s << std::hex << 0x1234 << std::dec;
	s << "{";
	s << "insn_" << tmp.insn << ", ";
	s << std::hex << "0x" << tmp.basecode << std::dec << ", ";
	if(tmp.nextbyte == 511)
		s << "511, ";
	else
		s << std::hex << "0x" << tmp.nextbyte << std::dec << ", ";
	s << "{";

	write_encoding_suffixes(s, tmp, globals);

	s << "},";

	s << "{";
	for(int i = 0; i < MAX_ARGS; ++i)
	{
		if(i != 0)
			s << ", ";

		s << "ARGTYPE(";
		s << "argtype_" << tmp.argtype[i];
		s << ", ";
		if(tmp.argtype_hi[i] == "0")
			s << "0";
		else
			s << "argtypehi_" << tmp.argtype_hi[i];
		s << ")";
	}

	s << "}, ";
	s << "{";
	for(int i = 0; i < MAX_ARGS; ++i)
	{
		if(i != 0)
			s << ", ";
		s << "ARGSIZE(";
		s << "argsize_" << tmp.argsize[i];
		s << ", argsize_hi_";
		s << tmp.argsize_hi[i];
		s << ")";
	}

	s << "}, ";
	s << "{";
	for(int i = 0; i < MAX_ARGS; ++i)
	{
		if(i != 0)
			s << ", ";
		s << std::hex << "0x" << tmp.argvalue[i] << std::dec;
	}
	s << "}";
	s << "}";
	
	out = s.str();
}

void write_out_encodings_h(globals_t &g)
{
	std::list<insn_t> &data = g.data;
	std::ofstream fo("out_encodings.h");
	bool need_comma = false;
	std::string s;
	fo << "// out_encodings.h  (note: this is an automatically generated file - do not edit!)" << std::endl;
	fo << "// " << COPYRIGHT << std::endl;
	fo << std::endl;
	for(std::list<insn_t>::iterator i = data.begin(); i != data.end(); ++i)
	{
		for(std::vector<tmp_encoding_t>::iterator j = i->encodings.begin(); j != i->encodings.end(); ++j)
		{
			if(need_comma)
				fo << "," << std::endl;
			need_comma = true;
			encoding_to_string(s, *j, g);
			fo << s;
		}
	}
	fo << "," << std::endl;
	fo << "{insn__count}" << std::endl;
	fo << std::endl;
}

void write_out_insn_enums_h(globals_t &g)
{
	std::list<insn_t> &data = g.data;
	std::ofstream fo("out_insn_enums.h");
	bool need_comma = false;
	std::string s;
	fo << "// out_insn_enums.h  (note: this is an automatically generated file - do not edit!)" << std::endl;
	fo << "// " << COPYRIGHT << std::endl;
	fo << std::endl;
	fo << "enum" << std::endl;
	fo << "{" << std::endl;
	int count = 0;
	for(std::list<insn_t>::iterator i = data.begin(); i != data.end(); ++i)
	{
		if(need_comma)
			fo << "," << std::endl;
		need_comma = true;
		fo << "\tinsn_" << i->insn_name;
		if(i->insn_name.empty())
			throw __LINE__;
		if(i->insn_name[0] != '_')
			++count;
	}
	fo << "," << std::endl;
	fo << "\tinsn__count," << std::endl;
	fo << "\tinsn__string_count = " << count << "\t// number of instructions whose name does not begin with a \'_\' character" << std::endl;
	fo << "};" << std::endl;
	fo << std::endl;
	fo << std::endl;
}

void write_out_insn_strings_h(globals_t &g)
{
	std::list<insn_t> &data = g.data;
	std::ofstream fo("out_insn_strings.h");
	bool need_comma = false;
	std::string s;
	fo << "// out_insn_strings.h  (note: this is an automatically generated file - do not edit!)" << std::endl;
	fo << "// " << COPYRIGHT << std::endl;
	fo << std::endl;
	for(std::list<insn_t>::iterator i = data.begin(); i != data.end(); ++i)
	{
		if(need_comma)
			fo << "," << std::endl;
		need_comma = true;
		if(i->insn_name.empty())
			throw __LINE__;
		if(i->insn_name[0] == '_')
			fo << "/* " << i->insn_name << "*/ 0";
		else
			fo << "\"" << i->insn_name << "\"";
	}
	fo << std::endl;
	fo << std::endl;
}

void write_out_insn_search_table_h(globals_t &g)
{
	std::ofstream fo("out_insn_search_table.h");
	bool need_comma = false;
	std::string s;
	fo << "// out_insn_search_table.h  (note: this is an automatically generated file - do not edit!)" << std::endl;
	fo << "// " << COPYRIGHT << std::endl;
	fo << std::endl;
	fo << "// out_insn_enums.h defines the enum \'insn__string_count\' which specifies the number of elements listed here." << std::endl;
	fo << std::endl;
	for(std::set<std::string>::iterator i = g.insns.begin(); i != g.insns.end(); ++i)
	{
		if(i->empty())
			throw __LINE__;
		if((*i)[0] == '_')
			continue;
		if(need_comma)
			fo << "," << std::endl;
		need_comma = true;
		fo << "insn_" << *i;
	}
	fo << std::endl;
	fo << std::endl;
}

void write_out_insns_h(globals_t &g)
{
	std::list<insn_t> &data = g.data;
	std::ofstream fo("out_insns.h");
	bool need_comma = false;
	std::string s;
	fo << "// out_insns.h  (note: this is an automatically generated file - do not edit!)" << std::endl;
	fo << "// " << COPYRIGHT << std::endl;
	fo << std::endl;
	UINT index = 0;
	UINT size;
	for(std::list<insn_t>::iterator i = data.begin(); i != data.end(); ++i)
	{
		size = i->encodings.size();
		if(need_comma)
			fo << "," << std::endl;
		need_comma = true;
		
		insn_t &insn = *i;
		
		fo << "{";
		fo << index << ", " << size << ", {";
		// --- begin write insn suffixes ---
		{
			std::vector<std::string> prefix;
			std::vector<std::string> suffix;
			
			// First initialize the vector.
			globals_t &globals = g;
			for(base_option_list_t::iterator i = globals.ilist.begin(); i != globals.ilist.end(); ++i)
			{
				if(i->empty())
					throw __LINE__;
				std::string p = get_prefix(*i->begin());
				prefix.push_back(p);
				suffix.push_back(p + "_def");
			}
			
			for(std::set<std::string>::iterator i = insn.insn_suffix.begin(); i != insn.insn_suffix.end(); ++i)
			{
				SINT j = globals.ilist.do_find(*i);
				if(j != -1)
				{
					// What about conflicting suffixes? We just use the last one given.
					suffix[j] = *i;
				}
				else
				{
					std::cout << "Can\'t find: \'" << *i << "\'!" << std::endl;
					throw __LINE__;
				}
			}
			
			// Now output the values.
			for(std::vector<std::string>::iterator i = suffix.begin(); i != suffix.end(); ++i)
			{
				if(i != suffix.begin())
					fo << ", ";
				fo << *i;
			}
		}
		// --- end write insn suffixes ---
		fo << "}";
		fo << "}";
				
		index += size;
	}
	fo << std::endl;
	fo << std::endl;
}

void write_out_disassemble_h(globals_t &g)
{
	std::ofstream fo("out_disassemble.h");
	fo << "// out_disassemble.h  (note: this is an automatically generated file - do not edit!)" << std::endl;
	fo << "// " << COPYRIGHT << std::endl;
	fo << std::endl;

	for(std::list<insn_t>::iterator i = g.data.begin(); i != g.data.end(); ++i)
	{
		if(i->disasm_code.empty())
			continue;
		fo << "case insn_" << i->insn_name << ":" << std::endl;
		for(std::list<std::string>::iterator j = i->disasm_code.begin(); j != i->disasm_code.end(); ++j)
		{
			fo << *j << std::endl;
		}
		fo << "\tbreak;" << std::endl;
	}
	
	fo << std::endl;
	fo << std::endl;
}

void write_out_semantics_h(globals_t &g)
{
	std::ofstream fo("out_semantics.h");
	fo << "// out_semantics.h  (note: this is an automatically generated file - do not edit!)" << std::endl;
	fo << "// " << COPYRIGHT << std::endl;
	fo << std::endl;
	
	fo << "tnode x86_tcode_nodes[] = {" << std::endl;
	
	std::string insn;
	Semantics sem(fo);
	try
	{
	
		sem.maxsize = 0;
		sem.max = "";
		sem.lastinsn = "";
		for(std::list<insn_t>::iterator i = g.data.begin(); i != g.data.end(); ++i)
		{
			//sem.insnindex[i->insn_name] = 0xffffffff;
			sem.insntemps[i->insn_name] = 0;	// # of temporary variables used by the insn
			insn = i->insn_name;
			sem.begin_insn(i->insn_name.c_str());
			//fo << "begin_insn(\"" << i->insn_name << "\", insn_" << i->insn_name << ");" << std::endl;
			//if(i->disasm_code.empty())
			//	continue;
			//fo << "case insn_" << i->insn_name << ":" << std::endl;
			for(std::list<std::string>::iterator j = i->semantics.begin(); j != i->semantics.end(); ++j)
				sem.parse(j->c_str());
			sem.end_insn();
			//	fo << "parse(\"" << *j << "\");" << std::endl;
			//fo << "end_insn();" << std::endl;
		}
		
		std::ofstream ff("out_semantics_h.h");
		ff << "// out_semantics_h.h  (note: this is an automatically generated file - do not edit!)" << std::endl;
		ff << "// " << COPYRIGHT << std::endl;
		ff << std::endl;
		ff << "#define X86S_SEMANTICS_MAX_SIZE " << sem.maxsize << " /* " << sem.max << " */" << std::endl;
		ff << std::endl;
		ff << std::endl;
	}
	catch(const char *s)
	{
		std::cout << "Error generating out_semantics.h (" << insn << "): " << s << std::endl;
	}
	fo << std::endl;
	fo << "// end of table" << std::endl;
	fo << "{nt_void}" << std::endl;
	fo << "};" << std::endl;
	
	for(std::list<insn_t>::iterator i = g.data.begin(); i != g.data.end(); ++i)
	{
		if(sem.insnindex.find(i->insn_name) == sem.insnindex.end())
			continue;
		fo << std::endl;
		fo << "U4 sem_insn_" << i->insn_name << "[] = {" << std::endl;
		fo << "\t" << sem.insnsize[i->insn_name] << ",\t// total size" << std::endl;
		fo << "\t" << sem.insnstart[i->insn_name] << ",\t// start index" << std::endl;
		for(std::vector<U4>::iterator j = sem.insnindex[i->insn_name].begin(); j != sem.insnindex[i->insn_name].end(); ++j)
		{
			fo << std::hex << "\t0x" << *j << std::dec << "," << std::endl;
		}
		fo << "\t0xffffffff\t// end" << std::endl;
		fo << "};" << std::endl;
	}

	fo << std::endl;
	fo << "tcode_element x86_tcode_table[] =" << std::endl;
	fo << "{" << std::endl;

	for(std::list<insn_t>::iterator i = g.data.begin(); i != g.data.end(); ++i)
	{
		//fo << "\t{0x" << std::hex << sem.insnindex[i->insn_name] << std::dec;
		if(sem.insnindex.find(i->insn_name) == sem.insnindex.end())
			fo << "\t{ 0";
		else
			fo << "\t{ sem_insn_" << i->insn_name << std::dec;
		fo << ", " << sem.insntemps[i->insn_name];
		int numargs = -1;
		
		for(std::vector<tmp_encoding_t>::iterator j = i->encodings.begin(); j != i->encodings.end(); ++j)
		{
			int n;
			for(n = 0; n < MAX_ARGS; ++n)
				if(j->argtype[n] == "void")
					break;
			if(numargs == -1)
				numargs = n;
			else
			if(numargs != n)
			{
				std::cout << "Error: instruction " << insn << " must have all encodings with same number of arguments." << std::endl;
				return;
			}
		}
		if(numargs == -1)
		{
			std::cout << "Error: instruction " << insn << " must have at least one encoding." << std::endl;
			return;
		}
		
		fo << ", " << numargs;
		fo << "},\t// " << i->insn_name << std::endl;
	}
	
	fo << "\t{0, 0, 0}\t// end of table" << std::endl;	
	fo << "};" << std::endl;
	fo << std::endl;
}

void write_files(globals_t &g)
{
	write_out_encodings_h(g);
	write_out_insn_enums_h(g);
	write_out_insn_strings_h(g);
	write_out_insn_search_table_h(g);
	write_out_insns_h(g);
	write_out_disassemble_h(g);
	write_out_semantics_h(g);
}

}	// namespace x86s

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -