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

📄 semantics.h

📁 当前支持 16-bit, 32-bit and 64-bit 的二进制文件
💻 H
📖 第 1 页 / 共 2 页
字号:
					default:
						break;
				}
				
				s += "(";
				for(U4 x = 0; x < 3; ++x)
				{
					if(tnodes[operand].data[x] == (0x80000000 + no_void))
						break;
					if(x != 0)
						s += ", ";
					s += get_operand_text(tnodes[operand].data[x], icode);
				}
				s += ")";
			}
		}
		
		return s;
	}
	
	void specialize(U4 index, U4 base, U4 encoding, icode_t &icode, int dsz)
	{
		tnode &node = tnodes[index];
		node = x86_tcode_nodes[base + index];

		// now specialize 'node'. it may make references to higher nodes--fix them if so.
//std::cout << std::endl;

		if(node.type != nt_literal)
		for(int i = 0; i < 3; ++i)
		{
			if(node.data[i] < 0x80000000)
				node.data[i] -= base;
			else
			if(node.data[i] == 0x80000000 + no_x86_acc)
			{
				if(icode.osz == argsize_16)
					node.data[i] = no_x86_ax + 0x80000000;
				else
				if(icode.osz == argsize_32)
					node.data[i] = no_x86_eax + 0x80000000;
				else
					node.data[i] = no_x86_rax + 0x80000000;
			}
			else
			if(node.data[i] == 0x80000000 + no_x86_acc_lo)
			{
				if(icode.osz == argsize_16)
					node.data[i] = no_x86_al + 0x80000000;
				else
				if(icode.osz == argsize_32)
					node.data[i] = no_x86_ax + 0x80000000;
				else
					node.data[i] = no_x86_eax + 0x80000000;
			}
			else
			if(node.data[i] == 0x80000000 + no_x86_dat)
			{
				if(icode.osz == argsize_16)
					node.data[i] = no_x86_dx + 0x80000000;
				else
				if(icode.osz == argsize_32)
					node.data[i] = no_x86_edx + 0x80000000;
				else
					node.data[i] = no_x86_rdx + 0x80000000;
			}
			else
			if(node.data[i] == 0x80000000 + no_x86_dax)
			{
				if(icode.osz == argsize_16)
					node.data[i] = no_x86_dx_ax + 0x80000000;
				else
				if(icode.osz == argsize_32)
					node.data[i] = no_x86_edx_eax + 0x80000000;
				else
					node.data[i] = no_x86_rdx_rax + 0x80000000;
			}
//std::cout << std::hex << node.data[i] << std::dec << " ";;
		}
//std::cout << std::endl;
		
		// refences now fixed up.
		// take care of ns_argize[0|1|2].
		if(node.size == ns_argsize_0)
			node.size = get_icode_size(icode.argsize[0]);
		else
		if(node.size == ns_argsize_1)
			node.size = get_icode_size(icode.argsize[1]);
		else
		if(node.size == ns_argsize_2)
			node.size = get_icode_size(icode.argsize[2]);
		
		if(node.size == ns_osz)
		{
			if(icode.osz == argsize_16)
				node.size = ns_word;
			else
			if(icode.osz == argsize_32)
				node.size = ns_dword;
			else
				node.size = ns_qword;
		}
		else		
		if(node.size == ns_asz)
		{
			if(icode.asz == argsize_16)
				node.size = ns_word;
			else
			if(icode.asz == argsize_32)
				node.size = ns_dword;
			else
				node.size = ns_qword;
		}
		else
		if(node.size == ns_osz_times_2)
		{
			if(icode.osz == argsize_16)
				node.size = ns_dword;
			else
			if(icode.osz == argsize_32)
				node.size = ns_qword;
			else
				node.size = ns_oword;
		}
		
		if(node.type == nt_arg)
		{
			if(node.size == ns_void)
			{
				U4 which_arg = tnodes[node.data[0]].data[0];
//std::cout << "(+" << which_arg << ")";
				node.size = get_icode_size(icode.argsize[which_arg]);
			}
		}
		else
		if(node.type > nt__x86__begin_sflags && node.type < nt__x86__end_sflags)
		{
			if(node.size == ns_void)
				node.size = ns_bit;
		}
		else
		if(node.type > nt__begin_bitops && node.type < nt__end_bitops)
		{
			if(node.size == ns_void)
				node.size = ns_bit;
		}
		else
		if(node.type == nt_tmp)
		{
			//if(node.size == ns_void)
			// always do this.
			{
				tnodes[node.data[0]].data[0] += tempcount;
				U4 which_tmp = tnodes[node.data[0]].data[0];
				// if we're reading from a tmp that we've asgn'd to before,
				// get its size.
				if((which_tmp - tempcount) < tmpsizes_count)
					node.size = tmpsizes[which_tmp - tempcount];
			}
		}
		else
		if(node.type == nt_asgn)
		{
			// if we're assigning to a new temp, update its size.
			U4 dest = node.data[0];
			U4 src = node.data[1];
			if(dest < 0x80000000)
			{
				// could be a tmp.
				if(tnodes[dest].type == nt_tmp)
				{
					// we're assigning to a temp.
					U4 which_tmp = tnodes[tnodes[dest].data[0]].data[0];	// fixme--check this (!)
					if((which_tmp - tempcount) == tmpsizes_count)
					{
						// is this right (?)
						tnodes[dest].size = get_operand_size(src);
						
						if(tmpsizes_count >= X86S_TMP_MAX)
							throw std::runtime_error("too many temporaries - increase X86S_TMP_MAX");
						tmpsizes[tmpsizes_count] = tnodes[dest].size;
						++tmpsizes_count;
					}
				}
			}
		}
		else
		if(node.type == nt_void || node.type == nt_literal)
		{
		}
		else
		if(node.type > nt__x86__begin_shift && node.type < nt__x86__end_shift)
		{
			node.size = get_operand_size(node.data[0]);
		}
		else
		if(node.type == nt_quest)
		{
			node.size = get_operand_size(node.data[1]);
		}
		else
		if(node.size == ns_void)
		{
			U2 sz;
			for(U4 x = 0; x < 3; ++x)
			{
				if(node.data[x] == (no_void|0x80000000))
					break;
				sz = get_operand_size(node.data[x]);
				if(sz == ns_void)
					;
				else
				if(node.size == ns_void)
					node.size = sz;
				else
				if(node.size != sz)
				{
std::cout << strings_nt[node.type] << " " << node.data[x];
					throw std::runtime_error("can\'t determine size of a tnode - conflicting sizes of arguments");
				}
			}
			if(node.size == ns_void)
				throw std::runtime_error("can\'t determine size of a tnode");
		}
	}
	
	public:
	U2 get_operand_size(U4 operand)
	{
		if(operand < 0x80000000)
			return tnodes[operand].size;
		operand -= 0x80000000;
		if(operand == no_undefined)
			return ns_bit;
		if(operand > no__begin_x86_flags && operand < no__end_x86_flags)
			return ns_bit;
		if(operand == no_x86_ah || operand == no_x86_al || operand == no_x86_dl)
			return ns_byte;
		if(operand == no_x86_ax || operand == no_x86_dx)
			return ns_word;
		if(operand == no_x86_eax || operand == no_x86_edx)
			return ns_dword;
		if(operand == no_x86_rax || operand == no_x86_rdx)
			return ns_qword;
		if(operand == no_x86_dx_ax)
			return ns_dword;
		if(operand == no_x86_edx_eax)
			return ns_qword;
		if(operand == no_x86_rdx_rax)
			return ns_oword;
		
		throw std::runtime_error("unsupported tcode operand - size unknown!");
		return 0;	// keep compiler happy
	}
	private:
	
	U2 get_icode_size(U1 isize)
	{
//std::cout << "<<" << (int)isize << " " << (int)get_argsize_hi(isize) << ">>";
		if(get_argsize_hi(isize) != argsize__end)
			throw std::runtime_error("unsupported argument size (1)");
		switch(get_argsize_lo(isize))
		{
			case argsize_16:
				return ns_word;
			case argsize_32:
				return ns_dword;
			case argsize_64:
				return ns_qword;
			case argsize_128:
				return ns_oword;
			case argsize_8:
				return ns_byte;
			default:
				break;
		}
		throw std::runtime_error("unsupported argument size (1)");
		return 0;	// keep compiler happy
	}
	public:
	
	// out: tnodes[], tnodes_count.
	void accept(U4 encoding, icode_t &icode, int dsz)
	{
		tnodes_count = 0;
		tcode_element &te = x86_tcode_table[encodings[encoding].insn];
		if(te.index == 0)
			return;
		// te.index != 0.
		const U4 size = te.index[0];
		const U4 base = te.index[1];
		tnodes_count = size;
		tmpsizes_count = 0;
		for(U4 x = 0; x < size; ++x)
		{
			specialize(x, base, encoding, icode, dsz);
		}
		tempcount += tmpsizes_count;
	}
};

}	// namespace x86s

#endif	// l_crudcom__semantics_h__included

⌨️ 快捷键说明

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