Skip to content
Snippets Groups Projects
STARSInstruction.h 6.31 KiB
Newer Older
jdh8d's avatar
jdh8d committed
#ifndef STARS_IDA_Instruction_h
#define STARS_IDA_Instruction_h
#include <memory>
#include <vector>
#include <cstddef>
#include <cstdint>

#include <pro.h>
#include <ua.hpp>
#include "interfaces/STARSTypes.h"
#include "interfaces/SMPDBInterface.h"
#include "interfaces/abstract/STARSInstruction.h"
#include "interfaces/abstract/STARSInstructionID.h"
// struct to hold items that mimic the IDA Pro type insn_t.
struct STARS_IDA_insn_t
{

#if 0  // duplicate info

// Current segment base paragraph. Initialized by the kernel.

  STARS_ea_t cs;                      // segment base (in paragraphs)


// Virtual address of the instruction (address within the segment)
// Initialized by the kernel.

  STARS_ea_t ip;                      // offset in the segment


// Linear address of the instruction.
// Initialized by the kernel.

  STARS_ea_t ea;                      // instruction start addresses
#endif

// Internal code of instruction. IDP should define its own instruction
// codes. These codes are usually defined in ins.hpp. The array of instruction
// names and features (ins.cpp) is accessed using this code.

  uint16_t itype;                 // instruction code (see ins.hpp)
								// only for canonical insns (not user defined!):

// Size of instruction in bytes.
// The analyzer should put here the actual size of the instruction.

  uint16_t size;                  // instruction size in bytes


// Additional information about the instruction.
// Definitions are processor-dependent.

  union
  {
	uint16_t auxpref;             // processor dependent field
	struct
	{
	  uchar low;
	  uchar high;
	} auxpref_chars;
  };
  char segpref;                 // processor dependent field
  char insnpref;                // processor dependent field

// Information about instruction operands.
  std::vector<STARSOpndTypePtr> Operands;

  char flags;                   // instruction flags

}; // end of struct STARS_IDA_insn_t

class STARS_IDA_Instruction_t : public STARS_Instruction_t
{
	public:
		
		// Constructors and destructors
		STARS_IDA_Instruction_t(const STARS_InstructionID_t& p_id) : STARSCmd({}), STARS_Instruction_t(p_id), ImplicitDEFs(false) {
			if (STARS_IsSSAMarkerPseudoID(p_id.GetIDWithinFile())) { // SSA marker pseudo-inst
				STARScmd.itype = NN_fnop;
				STARScmd.size = 1;
			}
		};

		// Data initialization methods
		// Get (accessor) methods
		inline uint16_t GetSize(void) const { return STARScmd.size; }; // Size of instruction in bytes
		inline uint16_t GetIDAOpcode(void) { return STARScmd.itype; };
		STARS_InstructionID_t GetNextInstructionID(void) const;
		STARS_InstructionID_t GetTargetInstructionID(void) const;
		uint32_t GetInstFeatures(void) const { return STARSfeatures; };
		STARSOpndTypePtr GetOpnd(std::size_t OpndNum) const { 
			assert(OpndNum < STARScmd.Operands.size());
			return STARScmd.Operands.at(OpndNum); 
		};

		// Set (mutator) methods
		void SetOpUsed(std::size_t OpndNum); // set the USE bit
		void SetOpNotUsed(std::size_t OpndNum); // reset the USE bit
		void SetOpDefed(std::size_t OpndNum); // set the DEF bit
		void SetOpNotDefed(std::size_t OpndNum); // reset the DEF bit
		void RemoveIDAOp1ForIMUL(void); // Fix up IDA Pro IMUL instruction by removing operand 1

		// Query methods
		inline bool HasRepeatIfEqualPrefix(void) const { return (0 != (STARScmd.auxpref & aux_rep)); };
		inline bool HasRepeatIfNotEqualPrefix(void) const { return (0 != (STARScmd.auxpref & aux_repne)); };
		inline bool HasAnyRepeatPrefix(void) const { return (0 != (STARScmd.auxpref & (aux_rep | aux_repne))); };
		bool Has64BitOperands(void);
		inline bool Uses64BitAddressing(void) const { 
#ifdef __EA64__
			return ((STARScmd.auxpref & (aux_use32 | aux_use64 | aux_natad)) == (aux_natad | aux_use64));
#else
			return false;
#endif
		};
		bool Uses32BitAddressing(void) const;
		inline bool IsRegOpnd(std::size_t OpndNum) const { return (STARScmd.Operands.at(OpndNum)->IsRegOp()); };
		inline bool IsImmedOpnd(std::size_t OpndNum) const { return (STARScmd.Operands.at(OpndNum)->IsImmedOp()); };
		inline bool RegOpndMatches(std::size_t OpndNum, STARS_regnum_t RegNum) const { return STARScmd.Operands.at(OpndNum)->MatchesReg(RegNum); };
		inline bool HasImplicitlyModifiedRegs(void) const { return ImplicitDEFs; }; 
		bool IsUseOpnd(std::size_t OpndNum) const;
		bool IsDefOpnd(std::size_t OpndNum) const;
		bool IsBranchToFarChunk(SMPInstr *CurrInst, STARS_ea_t &TargetAddr);
		STARSOpndTypePtr MakeVoidOpnd(void) const ;
		STARSOpndTypePtr MakeImmediateOpnd(STARS_uval_t value) const;
		STARSOpndTypePtr MakeRegOpnd(STARS_regnum_t RegNum, bool DefaultToMachineWidth = true);
		STARSOpndTypePtr MakeFloatingPointRegOpnd(STARS_regnum_t RegNum);
		STARSOpndTypePtr MakeMMXRegOpnd(STARS_regnum_t RegNum);
		STARSOpndTypePtr MakeXMMRegOpnd(STARS_regnum_t RegNum);
		STARSOpndTypePtr MakeYMMRegOpnd(STARS_regnum_t RegNum);
clc5q's avatar
clc5q committed
		STARSOpndTypePtr MakeNearPointerOpnd(STARS_ea_t TargetAddr) const;
		STARSOpndTypePtr MakeMemDisplacementOpnd(STARS_regnum_t BaseRegNum, STARS_regnum_t IndexRegNum, uint16_t ScaleFactor, STARS_ea_t offset);
		STARSOpndTypePtr MakeMemPhraseOpnd(STARS_regnum_t BaseRegNum, STARS_regnum_t IndexRegNum, uint16_t ScaleFactor);
		virtual bool IsPushFromFixedCall(void) const; // Is push from a call that became a push/jump pair?
		virtual STARS_InstructionID_Set_t GetReferencedInstructionIDs(bool &success);
		// Get inst IDs of jump targets, call targets, etc., including for analyzeable indirect calls and jumps; success = false otherwise
		virtual STARS_InstructionID_Set_t GetTargetedInstructionIDs(bool &success);

		// return inst ID addr for fall-through from this inst
		virtual STARS_ea_t GetFallThroughInstID(void);

		// Analyze the indirect jump at IndirJumpInst, put switch table info in TableInfo if available, return false otherwise.
		// Note: The TableInfo.FollowNodeNum field must be determined by later analysis.
		virtual bool AnalyzeSwitchStatement(SMPInstr *IndirJumpInst, struct SwitchTableInfo &TableInfo);
		struct STARS_IDA_insn_t STARScmd;
		STARSOpndTypePtr VoidOpndsPtr;  // common pointer to a void operand for all operands not used, to save memory
		bool ImplicitDEFs; // Modifies regs that do not appear as operands, e.g. many mul/div
		void InitOperand(op_t &InitOp) const;