Newer
Older
#ifndef STARS_IRDB_Instruction_h
#define STARS_IRDB_Instruction_h
#include <assert.h>
#include "interfaces/abstract/STARSInstruction.h"
#include "interfaces/abstract/STARSInstructionID.h"
#include "interfaces/irdb/STARSOp.h"
extern STARS_Interface_t* global_stars_interface;
class STARS_IRDB_Instruction_t : public STARS_Instruction_t
{
public:
// create SSA marker
STARS_IRDB_Instruction_t(STARS_InstructionID_t id)
{
irdb_insn=NULL;
memset(&disasm, 0, sizeof(disasm));
disasm.Argument1.ArgType=NO_ARGUMENT;
disasm.Argument2.ArgType=NO_ARGUMENT;
disasm.Argument3.ArgType=NO_ARGUMENT;
disasm.Argument4.ArgType=NO_ARGUMENT;
strcpy(disasm.Instruction.Mnemonic, "fnop "); // set to fnop
IDAOpcode = STARS_NN_fnop;
IDAOpcodeCached = true;
// Constructors and destructors
STARS_IRDB_Instruction_t(const libIRDB::Instruction_t *insn)
: STARS_Instruction_t(insn->GetBaseID()), irdb_insn(insn), features(0)
{
assert(irdb_insn);
irdb_insn->Disassemble(disasm);
bool res=STARS_GetCmd();
assert(res);
STARS_InstructionID_t GetID() { return irdb_insn->GetBaseID(); }
// Data initialization methods
// return true/false if instruction is valid.
// all irdb insns are valid?
virtual bool STARS_GetCmd(void);
virtual uint16_t GetSize(void) const
{ return irdb_insn->GetDataBits().length(); }
// see .cpp
virtual uint16_t GetIDAOpcode(void);
{ return STARS_InstructionID_t(irdb_insn->GetFallthrough()->GetBaseID()); }
{ return STARS_InstructionID_t(irdb_insn->GetTarget()->GetBaseID()); }
// example:
// add rax, rdx (intel) means rax=rax+rdx;
// features = STARS_CF_USE1 | STARS_CF_USE2 | STARS_CF_CHG1
virtual uint32_t GetInstFeatures(void) const { return features; }
virtual uint32_t GetInitialInstFeatures(void) const;
virtual STARSOpndTypePtr GetOpnd(std::size_t OpndNum) const
{
// if(Operands.at(OpndNum)->IsVoidOp())
// return nullptr;
// assert(OpndNum < Operands.size());
clc5q
committed
return Operands.at(OpndNum);
// ANSWER: Imitating IDA Pro structure. Operands appear in many containers where it would not make
// sense to carry around DEF or USE bits, but the features bitmap in the instruction holds them
// within the context of the instruction they are part of. These mutators set bits in STARSfeatures.
// REPLY: I'm a bit confused. let's discuss in person.
// final: these are part of the IDA fix-up of missing operands, etc.
virtual void SetOpUsed(std::size_t OpndNum) {assert(0); } // set the USE bit
virtual void SetOpNotUsed(std::size_t OpndNum) {assert(0); } // reset the USE bit
virtual void SetOpDefed(std::size_t OpndNum) {assert(0); } // set the DEF bit
virtual void SetOpNotDefed(std::size_t OpndNum) {assert(0); } // reset the DEF bit
virtual void RemoveIDAOp1ForIMUL(void) {assert(0); } // Fix up IDA Pro IMUL instruction by removing operand 1
// Query methods
virtual bool HasRepeatIfEqualPrefix(void) const
{ return disasm.Prefix.RepnePrefix!=NotUsedPrefix; }
virtual bool HasRepeatIfNotEqualPrefix(void) const
{ return disasm.Prefix.RepPrefix!=NotUsedPrefix; }
virtual bool HasAnyRepeatPrefix(void) const
{ return HasRepeatIfEqualPrefix() || HasRepeatIfNotEqualPrefix(); }
virtual bool HasOperandSizePrefix(void) const
{ return disasm.Prefix.OperandSize!=NotUsedPrefix; }
virtual bool HasREXWPrefix(void) const
virtual bool mode64(void) const
{
STARS_IRDB_Interface_t *my_global_stars_interface=NULL;
my_global_stars_interface=
dynamic_cast<STARS_IRDB_Interface_t*>(global_stars_interface);
assert(my_global_stars_interface);
return my_global_stars_interface->GetArchitectureBitWidth()==64;
}
// ANSWER: Yes. See implementations in STARSIDAInstruction.cpp.
virtual bool Has64BitOperands(void)
{
// not a 64-bit machine, can't be a 64-bit op.
if ( !this->mode64() )
return false;
// has the REXW indicates it's a 64-bit op.
if ( this->HasREXWPrefix() )
return true;
// no size prefix and opcode defaults to 64-bit
if (!this->HasOperandSizePrefix() && this->OpcodeDefaultsTo64BitOperands() )
return true;
// size prefix or non-64 bit operand
return false;
}
virtual bool Uses64BitAddressing(void) const
{ return mode64() && !HasOperandSizePrefix(); }
virtual bool Uses32BitAddressing(void) const
virtual bool IsRegOpnd(std::size_t OpndNum) const
{ return (Operands.at(OpndNum)->IsRegOp()); }
virtual bool IsImmedOpnd(std::size_t OpndNum) const
{ return (Operands.at(OpndNum)->IsImmedOp()); }
virtual bool RegOpndMatches(std::size_t OpndNum, uint16_t RegNum) const
{ return Operands.at(OpndNum)->MatchesReg(RegNum); }
// see .cpp
virtual bool IsUseOpnd(std::size_t OpndNum) const ;
// see .cpp
virtual bool IsDefOpnd(std::size_t OpndNum) const ;
virtual bool IsBranchToFarChunk(SMPInstr *CurrInst, STARS_ea_t &TargetAddr)
{ return false; /* no far chunks in irdb. */ }
virtual STARS_InstructionID_Set_t GetReferencedInstructionIDs(bool &success);
// jdh: do these "make operand" methods create an operand that's somehow linked/related to this instruction,
// or are these generic operand for any instruction. If generic, we should make them static factory-type methods
// of the operand class.
// ANSWER: Could be static factory methods of operand class. Current idapro/STARSIDAInstruction.cpp implementations
// make use of IDA Pro headers.
// ANSWER: Placeholder, e.g. in an RTL tree, when there is no operand. Also, IDA Pro has an array of six operands
// for each instruction, and many of them have IDA Pro type o_void, which is now simulated in our brave new world
// of shared_ptrs to operands by having a VoidOpnd.
virtual STARSOpndTypePtr MakeVoidOpnd(void) const;
virtual STARSOpndTypePtr MakeImmediateOpnd(STARS_uval_t value) const;
virtual STARSOpndTypePtr MakeRegOpnd(uint16_t RegNum);
virtual STARSOpndTypePtr MakeFloatingPointRegOpnd(uint16_t RegNum);
virtual STARSOpndTypePtr MakeMMXRegOpnd(uint16_t RegNum);
virtual STARSOpndTypePtr MakeXMMRegOpnd(uint16_t RegNum);
virtual STARSOpndTypePtr MakeYMMRegOpnd(uint16_t RegNum);
virtual STARSOpndTypePtr MakeNearPointerOpnd(STARS_ea_t TargetAddr) const ;
virtual STARSOpndTypePtr MakeMemDisplacementOpnd(uint16_t BaseRegNum,
uint16_t IndexRegNum, uint16_t ScaleFactor, STARS_ea_t offset);
virtual STARSOpndTypePtr MakeMemPhraseOpnd(uint16_t BaseRegNum,
uint16_t IndexRegNum, uint16_t ScaleFactor);
// Is push from a call that became a push/jump pair?
virtual bool IsPushFromFixedCall(void) const;
virtual const libIRDB::Instruction_t* GetIRDBInstruction() const { return irdb_insn;}
private:
const libIRDB::Instruction_t* irdb_insn;
DISASM disasm;
std::vector<STARSOpndTypePtr> Operands;
uint16_t IDAOpcode; // cached result from GetIDAOpcode()
bool IDAOpcodeCached; // does IDAOpcode contain a result, or does GetIDAOpcode() need to compute for first time?
std::size_t DetermineRegByteWidth(uint16_t RegNum); // Based on RegNum, determine byte width to set for new operand.