From 8d0ad8e7f4a544e2d6289a21ea366df952f2d3ff Mon Sep 17 00:00:00 2001
From: jdh8d <jdh8d@git.zephyr-software.com>
Date: Mon, 13 Jul 2015 02:39:17 +0000
Subject: [PATCH] BuildFuncIR draft, untested, but builds.

Former-commit-id: de39c9aba850a9ce19fb7a54c0706b8b155f299b
---
 .gitattributes                             |   2 +
 SConscript                                 |   7 +-
 SConscript.irdb                            |   4 +-
 include/base/SMPFunction.h                 |   2 +
 include/interfaces/irdb/STARSFunction.h    |  47 +++-
 include/interfaces/irdb/STARSInstruction.h |  81 +++++++
 include/interfaces/irdb/STARSInterface.h   |  19 +-
 include/interfaces/irdb/STARSSegment.h     |   2 +-
 src/interfaces/idapro/STARSFunction.cpp    |   2 +-
 src/interfaces/irdb/STARSFunction.cpp      | 258 +++++++++++++++++++++
 10 files changed, 401 insertions(+), 23 deletions(-)
 create mode 100644 include/interfaces/irdb/STARSInstruction.h
 create mode 100644 src/interfaces/irdb/STARSFunction.cpp

diff --git a/.gitattributes b/.gitattributes
index 85aace05..88e0c1a8 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -37,6 +37,7 @@ include/interfaces/idapro/STARSProgram.h -text
 include/interfaces/idapro/STARSSegment.h -text
 include/interfaces/idapro/all.h -text
 include/interfaces/irdb/STARSFunction.h -text
+include/interfaces/irdb/STARSInstruction.h -text
 include/interfaces/irdb/STARSInterface.h -text
 include/interfaces/irdb/STARSProgram.h -text
 include/interfaces/irdb/STARSSegment.h -text
@@ -76,6 +77,7 @@ src/interfaces/idapro/STARSIDAOp.cpp -text
 src/interfaces/idapro/STARSIDAProgram.cpp -text
 src/interfaces/idapro/STARSInterface.cpp -text
 src/interfaces/irdb/Makefile.in -text
+src/interfaces/irdb/STARSFunction.cpp -text
 src/interfaces/irdb/STARSIRDBProgram.cpp -text
 tests/commit/busybox.psexe -text
 tests/commit/bzip2.psexe -text
diff --git a/SConscript b/SConscript
index 673e30fb..739f8f4f 100644
--- a/SConscript
+++ b/SConscript
@@ -31,18 +31,17 @@ if argenv['IDAROOT'] is None:
 
 if int(argenv['debug']) == 1:
 	print "Setting debug mode"
-	STARS_CCFLAGS=" -g"
+	STARS_CCFLAGS=" -g "
 else:
 	print "Setting release mode"
-	STARS_CCFLAGS=" -O3"
+	STARS_CCFLAGS=" -O3 "
 
 if int(argenv['do_64bit_analysis']) == 1:
-	STARS_CCFLAGS+=" -D__EA64__"
+	STARS_CCFLAGS+=" -D__EA64__ "
 
 
 Export('argenv', 'STARS_CCFLAGS')
 
-
 if int(argenv['build_ida']) == 1:
 	lib=SConscript('SConscript.ida', variant_dir='build_ida')
 if int(argenv['build_irdb']) == 1:
diff --git a/SConscript.irdb b/SConscript.irdb
index 30a1a6dd..e850c84a 100644
--- a/SConscript.irdb
+++ b/SConscript.irdb
@@ -29,10 +29,10 @@ cpppath='''
 IRDB_CCFLAGS=''' -std=c++0x  \
         -w \
         -DSTARS_IRDB_INTERFACE  \
-        '''+STARS_CCFLAGS
+        '''+STARS_CCFLAGS+" "
 
 IRDB_LIBPATH="$SECURITY_TRANSFORMS_HOME/lib $SECURITY_TRANSFORMS_HOME/beaengine/lib/Linux.gnu.Debug "
-LIBS="IRDB-core IRDB-cfg pqxx BeaEngine_s_d MEDSannotation pq"
+LIBS="IRDB-core IRDB-cfg pqxx BeaEngine_s_d MEDSannotation pq IRDB-util"
 IRDB_LDFLAGS=" "
 
 
diff --git a/include/base/SMPFunction.h b/include/base/SMPFunction.h
index f93c28b9..0f1c9d12 100644
--- a/include/base/SMPFunction.h
+++ b/include/base/SMPFunction.h
@@ -52,6 +52,7 @@
 
 class SMPProgram;	// forward declaration so we can declare a pointer to an SMPProgram
 class STARS_IDA_Function_t;
+class STARS_IRDB_Function_t;
 
 #define SMP_DEBUG_STACK_GRANULARITY 0
 
@@ -603,6 +604,7 @@ private:
 	bool IsCallerReturnAddressReadOrWritten(void); // Can the return address of any caller be read or written directly from this function?
 
 	friend class STARS_IDA_Function_t;
+	friend class STARS_IRDB_Function_t;
 }; // end class SMPFunction
 
 #endif
diff --git a/include/interfaces/irdb/STARSFunction.h b/include/interfaces/irdb/STARSFunction.h
index 2a4fe221..02428fe5 100644
--- a/include/interfaces/irdb/STARSFunction.h
+++ b/include/interfaces/irdb/STARSFunction.h
@@ -5,6 +5,7 @@
 #include <libIRDB-core.hpp>
 
 class SMPFunction;
+class SMPInstr;
 
 class STARS_IRDB_Function_t : public STARS_Function_t 
 {
@@ -18,26 +19,32 @@ public:
         virtual char* GetFunctionName(const char* name, const int len) const { assert(0); }
 
 	// get entry point of function
-        virtual STARS_ea_t get_startEA(){ return the_func->GetEntryPoint()->GetBaseID(); }
+        virtual STARS_ea_t get_startEA() { return the_func->GetEntryPoint()->GetBaseID(); }
 
 	// clc needs to review and get back to me.
-        virtual STARS_ea_t get_endEA(){ assert(0); }
+        virtual STARS_ea_t get_endEA() { assert(0); }
 
-	virtual std::size_t GetFuncSize() { assert(false); } // TODO
+	// return # of instructions.
+	virtual std::size_t GetFuncSize() { return the_func->GetInstructions().size(); } 
 
+
+#if 1
+//This chunk of things is going away?
 	// init class-local variable with IRDB value
 	// and these are accessors to that.
 	virtual std::size_t GetFrameSize(){ return the_func -> GetStackFrameSize(); }
+
+
+	// should go away.
 	virtual void SetFrameSize(std::size_t size) { assert(0); }
 
 	// todo for clc: audit these functions and see if they are really getting info from idapro
 	// or if these can be removed from the interface because they are calculated by STARS 
 	// interface-independent routines.
+	// eventually going away.
 	virtual std::size_t GetSavedRegSize() { assert(0); }
 	virtual std::size_t GetIncomingArgumentSize() { assert(0); }
-	virtual std::size_t GetFrameReturnAddressSize() { assert(0); }
-
-
+	virtual std::size_t GetFrameReturnAddressSize() {assert(0); } 
 
         virtual bool FunctionUsesFP(){ return the_func->GetUseFramePointer(); }
         virtual bool IsStaticFunction(){ return false; }
@@ -52,17 +59,37 @@ public:
 	virtual bool HasSharedChunks() const { assert(0); }
 	virtual void SetSharedChunks(bool v) { assert(0); }
         virtual void UpdateXrefs(){ assert(0); }
-	virtual void BuildFuncIR(SMPFunction *func){ assert(0); }
-        virtual bool FindDistantCodeFragment(SMPFunction* func, STARS_ea_t TargetAddr){ assert(0); }
 	virtual void FillInLocalVarTable(SMPFunction *CurrFunc) { assert(0); }
-	virtual bool AnalyzeInstAsCallTarget(SMPFunction *CurrFunc, bool &IsIndirectCallTarget, bool &IsTailCallTarget) { assert(0); }
 	virtual bool IsChunkUnshared(STARS_ea_t ChunkAddr, STARS_ea_t FuncHeadStart, STARS_ea_t FuncHeadEnd) { assert(0); }
-	virtual bool IsInstIDInFunc(STARS_ea_t InstID) {assert(0); }
+#endif
+
+	virtual void BuildFuncIR(SMPFunction *func);
+
+
+        virtual bool FindDistantCodeFragment(SMPFunction* func, STARS_ea_t TargetAddr)
+	{ return false; } 
+
+
+	// see src/ file.
+	virtual bool AnalyzeInstAsCallTarget(SMPFunction *CurrFunc, 
+		     	bool &IsIndirectCallTarget, 
+			bool &IsTailCallTarget) ;
+
+	// see src/ dir.
+	virtual bool IsInstIDInFunc(STARS_ea_t InstID);
 
 
 private:
 	libIRDB::Function_t* the_func;
 
+	// disallow access to class members.
+	static void IRDB_IR_Build_helper
+                (
+                        SMPFunction *func,
+                        SMPInstr *CurrInst
+                );
+
+
 };
 
 #endif
diff --git a/include/interfaces/irdb/STARSInstruction.h b/include/interfaces/irdb/STARSInstruction.h
new file mode 100644
index 00000000..7807ad34
--- /dev/null
+++ b/include/interfaces/irdb/STARSInstruction.h
@@ -0,0 +1,81 @@
+#ifndef STARS_IRDB_Instruction_h
+#define STARS_IRDB_Instruction_h
+
+#include <assert.h>
+
+#include "interfaces/abstract/STARSInstruction.h"
+#include "interfaces/abstract/STARSInstructionID.h"
+#include <libIRDB-core.hpp>
+
+class SMPInstr;
+
+class STARS_IRDB_Instruction_t : public STARS_Instruction_t
+{
+	public:
+
+		// Constructors and destructors
+		STARS_IRDB_Instruction_t(const libIRDB::Instruction_t *insn) 
+			: STARS_Instruction_t(insn->GetBaseID()), irdb_insn(insn)
+		{ }
+
+		STARS_InstructionID_t GetID() { return irdb_insn->GetBaseID(); }
+
+		// Data initialization methods
+		virtual bool STARS_GetCmd(void) { assert(0); }
+
+		// Get (accessor) methods
+		virtual inline uint16_t GetSize(void) const { assert(0); }
+		virtual inline uint16_t GetIDAOpcode(void) const { assert(0); }
+		virtual STARS_InstructionID_t GetNextInstructionID(void) { assert(0); }
+		virtual STARS_InstructionID_t GetTargetInstructionID(void) { assert(0); }
+		virtual inline uint32_t GetInstFeatures(void) const { assert(0); }
+		virtual STARSOpndTypePtr GetOpnd(std::size_t OpndNum) const { assert(0); }
+
+		// Set (mutator) methods
+		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 inline bool HasRepeatIfEqualPrefix(void) const {assert(0); }
+		virtual inline bool HasRepeatIfNotEqualPrefix(void) const {assert(0); }
+		virtual inline bool HasAnyRepeatPrefix(void) const {assert(0); }
+		virtual bool OpcodeDefaultsTo64BitOperands(void) const {assert(0); }
+		virtual bool Has64BitOperands(void) const {assert(0); }
+		virtual inline bool Uses64BitAddressing(void) const {assert(0); }
+		virtual bool Uses32BitAddressing(void) const {assert(0); }
+		virtual inline bool IsRegOpnd(std::size_t OpndNum) const {assert(0); }
+		virtual inline bool IsImmedOpnd(std::size_t OpndNum) const {assert(0); }
+		virtual inline bool RegOpndMatches(std::size_t OpndNum, uint16_t RegNum) const {assert(0); }
+		virtual bool IsUseOpnd(std::size_t OpndNum) const {assert(0); }
+		virtual bool IsDefOpnd(std::size_t OpndNum) const {assert(0); }
+		virtual bool IsBranchToFarChunk(SMPInstr *CurrInst, STARS_ea_t &TargetAddr) {assert(0); }
+
+		// Operand creation methods
+		virtual STARSOpndTypePtr MakeVoidOpnd(void) const {assert(0); }
+		virtual STARSOpndTypePtr MakeImmediateOpnd(STARS_uval_t value) const {assert(0); }
+		virtual STARSOpndTypePtr MakeRegOpnd(uint16_t RegNum) const {assert(0); }
+		virtual STARSOpndTypePtr MakeFloatingPointRegOpnd(uint16_t RegNum) const {assert(0); }
+		virtual STARSOpndTypePtr MakeMMXRegOpnd(uint16_t RegNum) const {assert(0); }
+		virtual STARSOpndTypePtr MakeXMMRegOpnd(uint16_t RegNum) const {assert(0); }
+		virtual STARSOpndTypePtr MakeYMMRegOpnd(uint16_t RegNum) const {assert(0); }
+		virtual STARSOpndTypePtr MakeMemDisplacementOpnd(uint16_t BaseRegNum, uint16_t IndexRegNum, uint16_t ScaleFactor, STARS_ea_t offset) const {assert(0); }
+		virtual STARSOpndTypePtr MakeMemPhraseOpnd(uint16_t BaseRegNum, uint16_t IndexRegNum, uint16_t ScaleFactor) const {assert(0); }
+
+		// Analysis methods
+
+		
+		virtual const libIRDB::Instruction_t* GetIRDBInstruction() const { return irdb_insn;}
+
+	private:
+
+		const libIRDB::Instruction_t* irdb_insn;
+
+};
+
+#endif
+
+
+
diff --git a/include/interfaces/irdb/STARSInterface.h b/include/interfaces/irdb/STARSInterface.h
index 4e8bf028..4323e94a 100644
--- a/include/interfaces/irdb/STARSInterface.h
+++ b/include/interfaces/irdb/STARSInterface.h
@@ -9,21 +9,26 @@
 #include <elfio/elfio_dump.hpp>
 
 #include <libIRDB-core.hpp>
+#include <libIRDB-util.hpp>
 #include <assert.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <pqxx/pqxx>
 
+class STARS_IRDB_Function_t;
+
 class STARS_IRDB_Interface_t: public STARS_Interface_t
 {
 public:
 
 // Constructors
-	STARS_IRDB_Interface_t(FileIR_t* p_firp, libIRDB::pqxxDB_t &p_pqxx_interface) : 
+	STARS_IRDB_Interface_t(libIRDB::FileIR_t* p_firp, libIRDB::pqxxDB_t &p_pqxx_interface) : 
 		firp(p_firp), pqxx_interface(p_pqxx_interface) 
 	{ 
 		InitSegments();
 		InitFunctions();
+		// init instruction predecessors.
+		instruction_preds.AddFile(p_firp);
 	}
 
 	~STARS_IRDB_Interface_t()
@@ -197,8 +202,8 @@ private:
 		elfiop=new ELFIO::elfio;
 		elfiop->load("readeh_tmp_file.exe");
 
-		ELFIO::dump::header(cout,*elfiop);
-		ELFIO::dump::section_headers(cout,*elfiop);
+		ELFIO::dump::header(std::cout,*elfiop);
+		ELFIO::dump::section_headers(std::cout,*elfiop);
 
 		segments.resize(elfiop->sections.size());
 		int j=0;
@@ -206,8 +211,8 @@ private:
 		{
 			if((elfiop->sections[i]->get_flags() & SHF_ALLOC) == SHF_ALLOC)
 			{
-				cout<<"Found 'segment'["<<dec<<i<<"] named "<<elfiop->sections[i]->get_name();
-				cout<<" start: "<<hex<<elfiop->sections[i]->get_address()<<endl;
+				std::cout<<"Found 'segment'["<<std::dec<<i<<"] named "<<elfiop->sections[i]->get_name();
+				std::cout<<" start: "<<std::hex<<elfiop->sections[i]->get_address()<<std::endl;
 				segments[j]=new STARS_IRDB_Segment_t(elfiop->sections[i],j);
 				j++;
 			}
@@ -244,6 +249,10 @@ private:
 
 	libIRDB::FileIR_t *firp;
 	libIRDB::pqxxDB_t &pqxx_interface;
+
+	libIRDB::InstructionPredecessors_t instruction_preds;
+
+	friend class STARS_IRDB_Function_t;
 };
 
 
diff --git a/include/interfaces/irdb/STARSSegment.h b/include/interfaces/irdb/STARSSegment.h
index 8750d677..238ecfbd 100644
--- a/include/interfaces/irdb/STARSSegment.h
+++ b/include/interfaces/irdb/STARSSegment.h
@@ -24,7 +24,7 @@ class STARS_IRDB_Segment_t : public STARS_Segment_t
 		virtual STARS_ea_t get_endEA() { return the_seg->get_address()+the_seg->get_size(); }
 
 		// Get the segment size in bytes.
-		virtual std::size_t get_seg_size() { the_seg->get_size(); }
+		virtual std::size_t get_seg_size() { return (std::size_t) the_seg->get_size(); }
 
 		// return if the EXE bit is set.
 		virtual bool IsCodeSegment()  
diff --git a/src/interfaces/idapro/STARSFunction.cpp b/src/interfaces/idapro/STARSFunction.cpp
index f0448e46..586c6af3 100644
--- a/src/interfaces/idapro/STARSFunction.cpp
+++ b/src/interfaces/idapro/STARSFunction.cpp
@@ -321,7 +321,7 @@ void STARS_IDA_Function_t::BuildFuncIR(SMPFunction *func)
 					CurrInst->AnalyzeCallInst(func->GetFirstFuncAddr());
 #endif
 					STARS_ea_t TargetAddr = CurrInst->GetCallTarget();
-					bool LinkedToTarget = (BADADDR != TargetAddr);
+					bool LinkedToTarget = (STARS_BADADDR != TargetAddr);
 					if (LinkedToTarget) {
 						if (0 == TargetAddr) {
 							SMP_msg("WARNING: Ignoring NULL call target (unreachable) at %lx\n", 
diff --git a/src/interfaces/irdb/STARSFunction.cpp b/src/interfaces/irdb/STARSFunction.cpp
new file mode 100644
index 00000000..17d3e9dc
--- /dev/null
+++ b/src/interfaces/irdb/STARSFunction.cpp
@@ -0,0 +1,258 @@
+
+#include <SMPFunction.h>
+#include <SMPInstr.h>
+#include <interfaces/abstract/STARSFunction.h>
+#include <interfaces/irdb/STARSFunction.h>
+#include <interfaces/irdb/STARSInstruction.h>
+#include <interfaces/irdb/STARSInterface.h>
+#include <libIRDB-core.hpp>
+#include <libIRDB-cfg.hpp>
+
+#include <list>
+
+using namespace std;
+using namespace libIRDB;
+
+void STARS_IRDB_Function_t::IRDB_IR_Build_helper
+		(
+			SMPFunction *func,
+			SMPInstr *CurrInst 
+		)
+{
+#if 1
+                                SMPitype DataFlowType = CurrInst->GetDataFlowType();
+                                if ((DataFlowType == INDIR_CALL) || (DataFlowType == CALL)) {
+                                        // See if IDA has determined the target of the call.
+#if 0                           // Phase ordering: Do this later.
+                                        CurrInst->AnalyzeCallInst(func->GetFirstFuncAddr());
+#endif
+                                        STARS_ea_t TargetAddr = CurrInst->GetCallTarget();
+                                        bool LinkedToTarget = (STARS_BADADDR != TargetAddr);
+                                        if (LinkedToTarget) {
+                                                if (0 == TargetAddr) {
+                                                        SMP_msg("WARNING: Ignoring NULL call target (unreachable) at %lx\n",
+                                                                (unsigned long) CurrInst->GetAddr());
+                                                }
+                                                else {
+                                                        if (INDIR_CALL == DataFlowType) {
+                                                                pair<set<STARS_ea_t>::iterator, bool> InsertResult = func->IndirectCallTargets.insert(TargetAddr);
+                                                                if (InsertResult.second) {
+                                                                        func->AllCallTargets.push_back(TargetAddr);
+                                                                }
+                                                        }
+                                                        else {
+                                                                (void) func->AddDirectCallTarget(TargetAddr);
+                                                        }
+                                                }
+                                        }
+                                        if (DataFlowType == INDIR_CALL) {
+                                                func->IndirectCalls = true;
+                                                func->UnresolvedIndirectCalls = (!LinkedToTarget);
+                                        }
+                                } // end if INDIR_CALL or CALL
+                                else if (DataFlowType == INDIR_JUMP) {
+                                        func->IndirectJumps = true;
+// was if STARS_AUDIT_INDIR_JUMP_XREFS
+#if 0
+                                        PreviousIndirJumpAddr = addr;
+#endif
+                                }
+                                else if (DataFlowType == RETURN) {
+                                        func->HasReturnInst = true;
+                                }
+/*
+                                else if (CurrInst->IsBranchToFarChunk()) {
+					probably doesn't apply to IRDB.
+				}	
+*/
+
+
+
+#endif
+}
+
+void STARS_IRDB_Function_t::BuildFuncIR(SMPFunction *func)
+{
+
+typedef list<SMPInstr*> SMPInstrList_t;
+
+	SMPInstrList_t::iterator FirstInBlock = func->Instrs.end();
+        SMPInstrList_t::iterator LastInBlock = func->Instrs.end();
+	bool GoodRTL=false;
+
+	// build cfg 
+	ControlFlowGraph_t cfg(the_func);
+
+	// sort the blocks into any order where the entry block is first.
+	vector<BasicBlock_t*> sorted_blocks;
+
+	sorted_blocks.push_back(cfg.GetEntry());
+	for(BasicBlockSet_t::iterator it=cfg.GetBlocks().begin();
+		it!=cfg.GetBlocks().end(); ++it)
+	{
+		BasicBlock_t* block=*it;
+		if(cfg.GetEntry() ==  block)	// we did the entry block first.
+			continue;
+		sorted_blocks.push_back(block);
+	}
+
+
+
+
+	bool first_in_func=true;
+	for(vector<BasicBlock_t*>::iterator block_it=sorted_blocks.begin();
+			block_it!=sorted_blocks.end(); ++block_it)
+	{
+		list<SMPInstr*> block_id_map;
+		block_id_map.clear();
+		BasicBlock_t* block=*block_it;
+		for(InstructionVector_t::iterator insn_it=block->GetInstructions().begin();
+			insn_it!=block->GetInstructions().end(); ++insn_it)
+		{
+			Instruction_t* irdb_insn=*insn_it;
+			STARS_IRDB_Instruction_t* interface_insn=new STARS_IRDB_Instruction_t(irdb_insn);
+			STARS_InstructionID_t instruction_id=interface_insn->GetID();
+			// create instruction
+			SMPInstr *CurrInst = new SMPInstr(interface_insn->GetID().GetIDWithinFile());
+			CurrInst->Analyze();
+
+			block_id_map.push_back(CurrInst);
+
+			if(first_in_func)
+			{
+				first_in_func=false;
+
+				// create SSA marker instruction
+				SMPInstr *MarkerInst = new SMPInstr(STARS_SSA_MARKER_PSEUDO_ID);
+
+				MarkerInst->AnalyzeMarker();
+				assert(STARS_NN_fnop == MarkerInst->GetIDAOpcode());
+				GoodRTL = MarkerInst->BuildRTL();
+				func->BuiltRTLs = (func->BuiltRTLs && GoodRTL);
+				if (GoodRTL) {
+					MarkerInst->SetGoodRTL();
+				}
+				assert(FirstInBlock == func->Instrs.end());
+				func->Instrs.push_back(MarkerInst);
+
+
+				// find all callers.
+				//for each instruction id, FromAddr, that might jump 
+				//	 (but not fallthrough):
+				STARS_IRDB_Interface_t *sGi=dynamic_cast<STARS_IRDB_Interface_t*>
+					(global_stars_interface);
+				assert(sGi);
+				Instruction_t* entry=the_func->GetEntryPoint();
+				for(InstructionSet_t::iterator tmp_it=sGi->instruction_preds[entry].begin();
+					tmp_it!=sGi->instruction_preds[entry].end(); ++tmp_it)
+				{
+					Instruction_t* tmp=*tmp_it;
+					if(tmp->GetFunction()!=the_func && tmp->GetFallthrough()!=entry)
+						// tell stars about the jump
+						func->AddCallSource(tmp->GetBaseID());
+				}
+
+				if(the_func->GetEntryPoint()->GetIndirectBranchTargetAddress())
+					func->PossibleIndirectCallTarget = true;
+
+
+			}
+	
+			// do a bunch of stuff that is based on the currently built IR.  why 
+			// this needs to be specific to IRDB I don't know.  Ask clc.
+			IRDB_IR_Build_helper(func,CurrInst);
+
+			// Build tree RTLs for the instruction.
+			GoodRTL = CurrInst->BuildRTL();
+			func->BuiltRTLs = (func->BuiltRTLs && GoodRTL);
+			if (GoodRTL) {
+				CurrInst->SetGoodRTL();
+			}
+
+			// Insert instruction at end of list.
+			func->Instrs.push_back(CurrInst);
+			
+		}
+
+		// find start/end of block
+
+		// get first and last insn in the block.
+		FirstInBlock=find( func->Instrs.begin(), func->Instrs.end(), *(block_id_map.begin()));
+		LastInBlock =find( func->Instrs.begin(), func->Instrs.end(), *(--block_id_map.end()));
+  		SMPBasicBlock *NewBlock = new SMPBasicBlock(func, FirstInBlock, LastInBlock);
+
+	}
+
+}
+
+
+
+
+bool STARS_IRDB_Function_t::IsInstIDInFunc(STARS_ea_t InstID)
+{
+	STARS_InstructionID_t id(InstID);
+	const STARS_Instruction_t *stars_insn=id.GetInstruction();
+	const STARS_IRDB_Instruction_t* interface_insn=dynamic_cast<const STARS_IRDB_Instruction_t*>(stars_insn);
+	assert(interface_insn);
+	libIRDB::Instruction_t* irdb_insn=(libIRDB::Instruction_t*)interface_insn->GetIRDBInstruction();
+	InstructionSet_t::iterator it=the_func->GetInstructions().find(irdb_insn);
+	if(it==the_func->GetInstructions().end())
+		return false;
+	return true;
+}
+
+
+// assert this represents the same function as CurrFunc
+// IsIndirectCallTarget if some instruction (might) indirectly
+//      branch to this function's entry.
+// IsTailCallTarget if some function has a jump to this function's entry
+// use IRDB-util::preds class to check that all predecessors are
+// call instructions.  How to deal with push/jmp pairs?  ignore for now?
+bool STARS_IRDB_Function_t::AnalyzeInstAsCallTarget(SMPFunction *CurrFunc,
+		bool &IsIndirectCallTarget,
+		bool &IsTailCallTarget)
+{
+	// Init.
+	IsIndirectCallTarget=false;
+	IsTailCallTarget=false;
+
+	// Sanity
+	assert(the_func);
+
+	// Get Entry.
+	Instruction_t* entry=the_func->GetEntryPoint();
+	assert(entry);
+
+	// Check if entry is an IBT 
+	if(entry->GetIndirectBranchTargetAddress())
+		// report appropriately.
+		IsIndirectCallTarget=true;
+
+	extern STARS_Interface_t* global_stars_interface;
+	// safe convert.
+	STARS_IRDB_Interface_t *sGi=dynamic_cast<STARS_IRDB_Interface_t*>( global_stars_interface);
+	assert(sGi);
+
+
+	for(InstructionSet_t::iterator it=sGi->instruction_preds[entry].begin();
+		it!=sGi->instruction_preds[entry].end(); ++it)
+	{
+		Instruction_t* pred=*it;
+
+		// skip any fallthroughs to the entry (weird, but could happen)
+		if(pred->GetFallthrough()==entry)
+			continue;
+
+		// skip any call instructions that target the branch
+		DISASM d;
+		pred->Disassemble(d);
+		if(d.Instruction.BranchType==CallType)
+			continue;
+
+		IsTailCallTarget=true;
+	}
+
+	return true;
+
+}
+
-- 
GitLab