Skip to content
Snippets Groups Projects
STARS_IRDB_Instruction.cpp 76.8 KiB
Newer Older
			p = (std::make_shared<STARS_IRDB_op_t>());
			p->MakeFloatingPointRegOpnd(STARS_x86_R_st1);
			features=GetInitialInstFeatures(false,my_disasm) | (STARS_CF_USE1 | STARS_CF_USE2);
			break;
		}



		case STARS_NN_fpatan:	// implicit st1!! write.  implicit st0 read.
		case STARS_NN_fyl2x:	
		case STARS_NN_fyl2xp1:
		{
			do_default=false;
			shared_ptr<STARS_IRDB_op_t> p;

			p = (std::make_shared<STARS_IRDB_op_t>());
			p->MakeFloatingPointRegOpnd(STARS_x86_R_st0);
			Operands[0]=p;

			p = (std::make_shared<STARS_IRDB_op_t>());
			p->MakeFloatingPointRegOpnd(STARS_x86_R_st1);
			features=GetInitialInstFeatures(false,my_disasm) | (STARS_CF_CHG2 | STARS_CF_USE1 | STARS_CF_USE2);
		default:
			do_default=true;
	}

	if(do_default)
	{
		for(auto i=0;i<4;i++)
		{
			if(my_disasm.hasOperand(i))
				Operands[i]=(std::make_shared<STARS_IRDB_op_t>(my_disasm,0,my_disasm.getOperand(i),length));
				Operands[i] = this->MakeVoidOpnd();
		features=GetInitialInstFeatures(false,my_disasm);
	// Simplify the operand encoding so that identical operands don't appear to be different.
	for (std::size_t i = 0; i < STARS_UA_MAXOP; ++i) {
		this->GetOpnd(i)->CleanOpndEncoding();
	}

	return length > 0;
bool STARS_IRDB_Instruction_t::IsUseOpnd(std::size_t OpndNum) const {
   return (this->GetInstFeatures() & UseMacros[OpndNum]);
}

bool STARS_IRDB_Instruction_t::IsDefOpnd(std::size_t OpndNum) const {
   return (this->GetInstFeatures() & DefMacros[OpndNum]);
}

// Based on RegNum, determine byte width to set for new operand.
std::size_t STARS_IRDB_Instruction_t::DetermineRegByteWidth(STARS_regnum_t RegNum) {
	std::size_t ByteWidth = RegSizes[RegNum];
	if ((global_STARS_program->GetSTARS_ISA_Bytewidth() == 8) && this->Has64BitOperands() && (RegNum <= STARS_x86_R_ip)) {
		ByteWidth = 8;
	}
	return ByteWidth;
}

STARSOpndTypePtr STARS_IRDB_Instruction_t::MakeVoidOpnd(void) const 
{
	return this->VoidOpndsPtr; // shared for memory reduction
}


STARSOpndTypePtr STARS_IRDB_Instruction_t::MakeImmediateOpnd(STARS_uval_t value) const 
{

// bad syntax:
//	shared_ptr<STARS_IRDB_op_t> p = dynamic_cast<shared_ptr<STARS_IRDB_op_t> >(MakeVoidOpnd());
// p not of right type.
//	STARSOpndTypePtr p=MakeVoidOpnd();
// not using shared poitners.
//	STARS_IRDB_op_t* p = (STARS_IRDB_op_t*)MakeVoidOpnd();

// shared_ptr use_count goes to 0 and is erased before p can be deref. 
//	auto p=MakeVoidOpnd().get();
//	STARSIRDBOpndTypePtr p=std::dynamic_cast<STARSIRDBOpndTypePtr>(p);

	STARSIRDBOpndTypePtr p=std::make_shared<STARS_IRDB_op_t>();
	assert(p);
	p->MakeImmediateOpnd(value);
	return p;
}
STARSOpndTypePtr STARS_IRDB_Instruction_t::MakeRegOpnd(STARS_regnum_t RegNum, bool DefaultToMachineWidth)  
	STARSIRDBOpndTypePtr p=std::make_shared<STARS_IRDB_op_t>();
	assert(p);
	uint16_t ByteWidth = this->DetermineRegByteWidth(RegNum);
	p->MakeRegOpnd(RegNum);
	return p;
}
STARSOpndTypePtr STARS_IRDB_Instruction_t::MakeFloatingPointRegOpnd(STARS_regnum_t RegNum)  
	STARSIRDBOpndTypePtr p=std::make_shared<STARS_IRDB_op_t>();
	assert(p);
	p->MakeFloatingPointRegOpnd(RegNum);
	p->SetByteWidth(this->DetermineRegByteWidth(RegNum));
	return p;
}
STARSOpndTypePtr STARS_IRDB_Instruction_t::MakeMMXRegOpnd(STARS_regnum_t RegNum)  
	STARSIRDBOpndTypePtr p=std::make_shared<STARS_IRDB_op_t>();
	assert(p);
	p->MakeMMXRegOpnd(RegNum);
	p->SetByteWidth(this->DetermineRegByteWidth(RegNum));
	return p;
}
STARSOpndTypePtr STARS_IRDB_Instruction_t::MakeXMMRegOpnd(STARS_regnum_t RegNum)  
	STARSIRDBOpndTypePtr p=std::make_shared<STARS_IRDB_op_t>();
	assert(p);
	p->MakeXMMRegOpnd(RegNum);
	p->SetByteWidth(this->DetermineRegByteWidth(RegNum));
	return p;
}
STARSOpndTypePtr STARS_IRDB_Instruction_t::MakeYMMRegOpnd(STARS_regnum_t RegNum)  
	STARSIRDBOpndTypePtr p=std::make_shared<STARS_IRDB_op_t>();
	assert(p);
	p->MakeYMMRegOpnd(RegNum);
	p->SetByteWidth(this->DetermineRegByteWidth(RegNum));
	return p;
}
jdh8d's avatar
jdh8d committed

STARSOpndTypePtr STARS_IRDB_Instruction_t::MakeNearPointerOpnd(STARS_uval_t value) const 
{
	STARSIRDBOpndTypePtr p=std::make_shared<STARS_IRDB_op_t>();
	p->MakeNearPointerOpnd(disasm.getAddress() /*Instruction.AddrValue*/);
STARSOpndTypePtr STARS_IRDB_Instruction_t::MakeMemDisplacementOpnd
	(STARS_regnum_t BaseRegNum, STARS_regnum_t IndexRegNum, uint16_t ScaleFactor, STARS_ea_t offset)  
	STARSIRDBOpndTypePtr p=std::make_shared<STARS_IRDB_op_t>();
	assert(p);
	p->MakeMemDisplacementOpnd(BaseRegNum, IndexRegNum, ScaleFactor, offset);
	return p;
}
STARSOpndTypePtr STARS_IRDB_Instruction_t::MakeMemPhraseOpnd
	(STARS_regnum_t BaseRegNum, STARS_regnum_t IndexRegNum, uint16_t ScaleFactor) 
	STARSIRDBOpndTypePtr p=std::make_shared<STARS_IRDB_op_t>();
	assert(p);
	p->MakeMemPhraseOpnd(BaseRegNum, IndexRegNum, ScaleFactor);
	return p;
}
bool STARS_IRDB_Instruction_t::IsPushFromFixedCall(void) const
{
	const auto insn = const_cast<Instruction_t*>(GetIRDBInstruction());
	if (insn == nullptr)
		return false;
	const auto &all_relocs = insn->GetRelocations();
	const auto reloc_it = find_if(ALLOF(all_relocs), [](const Relocation_t* reloc)
	{ 
		return (reloc->GetType() == string("32-bit")) || (reloc->GetType() == string("push64"));
	});
	return (reloc_it != all_relocs.end());
}

#if 0
bool STARS_IRDB_Instruction_t::IsPushFromFixedCall(void) const
{
	Instruction_t* insn=const_cast<Instruction_t*>(GetIRDBInstruction());
	if(!insn)
		return false;
	RelocationSet_t::iterator rit;
	for( rit=insn->GetRelocations().begin();
	     rit!=insn->GetRelocations().end();
	     ++rit
	   )
	{
		Relocation_t* reloc=*rit;
		if(reloc->GetType()==string("32-bit") || reloc->GetType()==string("push64"))
		{
			return true;
		}
	}
	return false;
bool STARS_IRDB_Instruction_t::IsJumpFromFixedCall(void) const
{
	Instruction_t* insn=const_cast<Instruction_t*>(GetIRDBInstruction());
	if(!insn)
		return false;
	RelocationSet_t::iterator rit;
	for( rit=insn->GetRelocations().begin();
	     rit!=insn->GetRelocations().end();
	     ++rit
	   )
	{
		Relocation_t* reloc=*rit;
		if(reloc->GetType()==string("fix_call_fallthrough"))
		{
			return true;
		}
	}
	return false;
}

STARS_InstructionID_Set_t STARS_IRDB_Instruction_t::GetReferencedInstructionIDs(bool &success) 
{

	extern STARS_Interface_t* global_stars_interface; 
	STARS_IRDB_Interface_t* gsi=dynamic_cast<STARS_IRDB_Interface_t*>(global_stars_interface); 

	success=false;
	STARS_InstructionID_Set_t ret;

	assert(irdb_insn);
	if(irdb_insn->GetTarget())
		ret.insert(irdb_insn->GetTarget()->GetBaseID());

	if (this->GetIDAOpcode() == STARS_NN_push)

		RelocationSet_t::iterator rit;
		for (rit = irdb_insn->GetRelocations().begin();
			rit != irdb_insn->GetRelocations().end();
			++rit
			)
		{
			Relocation_t* reloc = *rit;
			if (reloc->GetType() == string("fix_call_fallthrough"))
			{
				assert(nullptr != reloc->GetWRT());
				ret.insert(reloc->GetWRT()->GetBaseID());
			}
		}
#if 0
		libIRDB::virtual_offset_t ibta = GetOpnd(0)->GetAddr();
		AddressID_t aid(libIRDB::BaseObj_t::NOT_IN_DATABASE, irdb_insn->GetAddress()->GetFileID(), ibta);
		bool found_insn=false;
		Instruction_t* targ_insn=gsi->GetIBT(aid,found_insn);
		if(found_insn)
		{
			assert(targ_insn);
			ret.insert(targ_insn->GetBaseID());
		}
	else if(IsJumpFromFixedCall())
	{
		Instruction_t* insn=const_cast<Instruction_t*>(GetIRDBInstruction());
		RelocationSet_t::iterator rit;
		for( rit=insn->GetRelocations().begin();
		     rit!=insn->GetRelocations().end();
		     ++rit
		   )
		{
			Relocation_t* reloc=*rit;
			if(reloc->GetType()==string("fix_call_fallthrough"))
			{
				Instruction_t* insn=dynamic_cast<Instruction_t*>(reloc->GetWRT());
				if(insn)
					ret.insert(insn->GetBaseID());

			}
		}
	}
// return inst ID addr for fall-through from this inst
STARS_ea_t STARS_IRDB_Instruction_t::GetFallThroughInstID(void) {
	STARS_ea_t FallThroughID = STARS_BADADDR;
	const libIRDB::Instruction_t* irdb_inst = this->GetIRDBInstruction();
	assert(nullptr != irdb_inst);
	libIRDB::Instruction_t* FallThroughInst = irdb_inst->GetFallthrough();
	if (nullptr != FallThroughInst) {
		FallThroughID = (STARS_ea_t) FallThroughInst->GetAddress()->GetBaseID();