From 02ce9f645fb21904d7433680bc02d0643d62d7d2 Mon Sep 17 00:00:00 2001
From: jdh8d <jdh8d@git.zephyr-software.com>
Date: Sun, 7 Dec 2014 19:55:24 +0000
Subject: [PATCH]

---
 .gitattributes                              |  1 +
 include/base/SMPFunction.h                  |  9 +-
 include/interfaces/abstract/STARSFunction.h |  5 +-
 include/interfaces/idapro/STARSFunction.h   | 21 ++++-
 src/Makefile.in                             |  4 +-
 src/base/Makefile.in                        |  2 +-
 src/base/SMPFunction.cpp                    | 33 ++++---
 src/interfaces/Makefile.in                  |  4 +-
 src/interfaces/idapro/Makefile.in           | 23 +++--
 src/interfaces/idapro/STARSFunction.cpp     | 97 +++++++++++++++++++++
 10 files changed, 169 insertions(+), 30 deletions(-)
 create mode 100644 src/interfaces/idapro/STARSFunction.cpp

diff --git a/.gitattributes b/.gitattributes
index 15171e6d..c5754d8e 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -42,5 +42,6 @@ src/base/SMPProgram.cpp -text
 src/base/SMPStaticAnalyzer.cpp -text
 src/interfaces/Makefile.in -text
 src/interfaces/idapro/Makefile.in -text
+src/interfaces/idapro/STARSFunction.cpp -text
 src/interfaces/idapro64/Makefile.in -text
 src/interfaces/irdb/Makefile.in -text
diff --git a/include/base/SMPFunction.h b/include/base/SMPFunction.h
index 8415b0a7..325d14d9 100644
--- a/include/base/SMPFunction.h
+++ b/include/base/SMPFunction.h
@@ -163,7 +163,7 @@ public:
 	// Get methods
 	inline SMPProgram *GetProg(void) const { return Program; };
 	inline const char *GetFuncName(void) const { SMP_get_func_name(FirstEA, StaticFuncName, MAXSMPSTR-1); return StaticFuncName; };
-	STARS_Function_t *GetFuncInfo(void);
+	STARS_Function_t *GetFuncInfo(void) const;
 	inline ea_t GetFirstFuncAddr(void) const { return FirstEA; };
 	ushort GetJumpToFollowNodeCounter(ea_t InstAddr) const;
 	inline long GetTypedDefs(void) const { return TypedDefs; };
@@ -292,7 +292,10 @@ public:
 	inline bool HasIndirectJumps(void) const { return IndirectJumps; };
 	inline bool HasUnresolvedIndirectJumps(void) const { return UnresolvedIndirectJumps; };
 	inline bool IsDirectlyRecursive(void) const { return DirectlyRecursive; };
-	inline bool HasSharedChunks(void) const { return SharedChunks; };
+	inline bool HasSharedChunks(void) const { return GetFuncInfo()->HasSharedChunks(); };
+//	inline bool HasSharedChunks(void) const { return SharedChunks; };
+	inline void SetSharedChunks(bool v) { GetFuncInfo()->SetSharedChunks(v); };
+//	inline void SetSharedChunks(bool v) { SharedChunks=v; };
 	inline bool HasGoodRTLs(void) const { return BuiltRTLs; };
 	inline bool HasGoodSSAForm(void) const { return HasGoodSSA; };
 	inline bool HasReducibleControlFlow(void) const { return HasReducibleCFG; };
@@ -399,7 +402,7 @@ private:
 	bool IndirectJumps; // Does function make indirect jumps?
 	bool UnresolvedIndirectJumps; // Jumps could not all be linked to targets
 	bool DirectlyRecursive; // Calls itself
-	bool SharedChunks; // Does function share a tail chunk with other functions?
+//	bool SharedChunks; // Does function share a tail chunk with other functions?
 	bool UnsharedChunks; // Does function have noncontiguous fragments that are not shared with other funcs?
 	bool MultipleEntryPoints; // Does function have multiple entry points from other functions?
 	bool CallsAlloca; // Does function allocate stack space after initial allocation? NOTE:SMPInstr::IsAllocaCall() excludes immediate value alloca calls
diff --git a/include/interfaces/abstract/STARSFunction.h b/include/interfaces/abstract/STARSFunction.h
index b3f1f77e..e165b104 100644
--- a/include/interfaces/abstract/STARSFunction.h
+++ b/include/interfaces/abstract/STARSFunction.h
@@ -18,7 +18,10 @@ class STARS_Function_t
                 virtual bool IsStackPointerAnalyzed()=0;
 		virtual uint64_t get_spd(STARS_ea_t ea)=0;
 		virtual bool HasReturnPoints()=0;
-		
+		virtual bool IsMultiEntry()=0;
+		virtual void MarkSharedChunks()=0;
+		virtual bool HasSharedChunks() const =0;
+		virtual void SetSharedChunks(bool v) =0;
 };
 
 #endif
diff --git a/include/interfaces/idapro/STARSFunction.h b/include/interfaces/idapro/STARSFunction.h
index e49a774e..31d05c21 100644
--- a/include/interfaces/idapro/STARSFunction.h
+++ b/include/interfaces/idapro/STARSFunction.h
@@ -5,12 +5,18 @@ class STARS_IDA_Function_t : public STARS_Function_t
 {
 	public:
 
-                virtual STARS_ea_t get_startEA() { return the_func->startEA; }
-                virtual STARS_ea_t get_endEA() { return the_func->endEA; }
 
 
-		STARS_IDA_Function_t(func_t* func) : the_func(func), frsize(the_func->frsize) {}
+		STARS_IDA_Function_t(func_t* func) : 
+			the_func(func), 
+			frsize(the_func->frsize),
+			SharedChunks(false), 
+			UnsharedChunks(false)
+		{}
 
+
+                virtual STARS_ea_t get_startEA() { return the_func->startEA; }
+                virtual STARS_ea_t get_endEA() { return the_func->endEA; }
                 virtual char* GetFunctionName(const char* name, const int len) const
 			{ return ::get_func_name(the_func->startEA,(char*)name,len); }
                 virtual size_t GetFrameSize() { return frsize; }
@@ -24,6 +30,13 @@ class STARS_IDA_Function_t : public STARS_Function_t
 		virtual bool IsStackPointerAnalyzed() { return the_func->analyzed_sp(); }
                 virtual uint64_t get_spd(STARS_ea_t ea) { return ::get_spd(the_func,ea); }
 		virtual bool HasReturnPoints() { return the_func->does_return(); }
+		virtual bool IsMultiEntry();
+                virtual void MarkSharedChunks();
+                virtual bool HasSharedChunks() const {return SharedChunks; }
+                virtual void SetSharedChunks(bool v) { SharedChunks=v; }
+
+
+
 
 		/* temporary cast operator for testing */
 		operator func_t* () { return the_func; }
@@ -31,6 +44,8 @@ class STARS_IDA_Function_t : public STARS_Function_t
 	private:
 
 		func_t* the_func;
+		bool SharedChunks;
+		bool UnsharedChunks;
 		size_t frsize;
 };
 
diff --git a/src/Makefile.in b/src/Makefile.in
index 41122040..bf441dec 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,10 +1,10 @@
 .SUFFIXES: 
 
-dirs="base interfaces"
+dirs=base interfaces
 
 
 all: .PHONY 
-	for i in ${dirs};  do cd $$i; make || exit 1; cd ..; done
+	for i in ${dirs};  do echo ${PWD}; cd $$i; make || exit 1; cd ..; done
 
 clean:   .PHONY
 	for i in ${dirs};  do cd $$i; make clean; cd ..; done
diff --git a/src/base/Makefile.in b/src/base/Makefile.in
index 792b6f21..55bcd08b 100644
--- a/src/base/Makefile.in
+++ b/src/base/Makefile.in
@@ -23,7 +23,7 @@ all: $(OBJS)
 	@rm -f $*.d.tmp
 
 clean:  
-	rm -f $(OBJS) 
+	rm -f $(OBJS) *.d
 
 .PHONY:
 	@if [ "${IDAROOT}"X = "X"  ];  then echo Please set IDAROOT; exit 1; fi
diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp
index aed395a0..74881290 100644
--- a/src/base/SMPFunction.cpp
+++ b/src/base/SMPFunction.cpp
@@ -158,7 +158,7 @@ SMPFunction::SMPFunction(STARS_Function_t *Info, SMPProgram* pgm) {
 	this->IndirectJumps = false;
 	this->UnresolvedIndirectJumps = false;
 	this->DirectlyRecursive = false;
-	this->SharedChunks = false;
+	this->SetSharedChunks(false);
 	this->UnsharedChunks = false;
 	this->MultipleEntryPoints = false;
 	this->CallsAlloca = false;
@@ -282,7 +282,7 @@ SMPFunction::~SMPFunction() {
 }
 
 // Get a non-stale pointer to the STARS_Function_t info for the current function.
-STARS_Function_t *SMPFunction::GetFuncInfo(void) {
+STARS_Function_t *SMPFunction::GetFuncInfo(void)  const {
 	STARS_Function_t *myPtr = SMP_get_func(this->FirstEA);
 	assert(NULL != myPtr);
 	return myPtr;
@@ -3852,6 +3852,11 @@ void SMPFunction::EmitStackFrameAnnotations(FILE *AnnotFile, SMPInstr *Instr) {
 //  are probably IDA Pro disassembly problems rather than true multi-entry functions.
 void SMPFunction::DetectMultiEntryFunction(void) {
 
+#if 0
+ 	this->MultipleEntryPoints = GetFuncInfo()->IsMultiEntry();
+#else
+
+
 /* convert to something like:
  *	this->IsMultiEntry = GetFuncInfo()->IsMultiEntry();
  */
@@ -3885,6 +3890,7 @@ void SMPFunction::DetectMultiEntryFunction(void) {
 		this->MultipleEntryPoints = true;
 	}
 	return;
+#endif
 } // end of SMPFunction::DetectMultiEntryFunction()
 
 // Audit and fix the IDA Pro code cross references for jumps and jump targets.
@@ -4034,12 +4040,16 @@ void SMPFunction::AnalyzeFunc(void) {
 		this->GetProg()->SetProgramThrowsExceptions();
 	}
 
-	// Determine if we are dealing with shared chunks.
+
 	size_t ChunkCounter = 0;
+	// Determine if we are dealing with shared chunks.
+#if 1
+	GetFuncInfo()->MarkSharedChunks();
 	func_tail_iterator_t FuncTail((func_t*)*dynamic_cast<STARS_IDA_Function_t*>(this->GetFuncInfo()));
+#else
+	// Determine if we are dealing with shared chunks.
 	ea_t FuncHeadLastAddr = 0;
-
-/* convert to GetFuncInfo()->MarkSharedChunks() */
+	func_tail_iterator_t FuncTail((func_t*)*dynamic_cast<STARS_IDA_Function_t*>(this->GetFuncInfo()));
 	for (bool ChunkOK = FuncTail.main(); ChunkOK; ChunkOK = FuncTail.next()) {
 		const area_t &CurrChunk = FuncTail.chunk();
 		++ChunkCounter;
@@ -4067,6 +4077,7 @@ void SMPFunction::AnalyzeFunc(void) {
 #endif // STARS_FIND_UNSHARED_CHUNKS
 		}
 	}
+#endif
 
 #if STARS_AUDIT_JUMP_XREFS
 	this->MDAuditJumpXrefs();
@@ -4384,15 +4395,15 @@ void SMPFunction::AnalyzeFunc(void) {
 	} // end for (bool ChunkOK = ...)
 
 #if KLUDGE_VFPRINTF_FAMILY
-	if (!this->SharedChunks && (0 != strstr(this->GetFuncName(), "printf"))) {
-		this->SharedChunks = true;
+	if (!this->HasSharedChunks() && (0 != strstr(this->GetFuncName(), "printf"))) {
+		GetFuncInfo()->SetSharedChunks(true);
 		SMP_msg("INFO: Kludging function %s\n", this->GetFuncName());
 	}
 #endif
 
 #if SMP_IDAPRO52_WORKAROUND
-	if (!this->SharedChunks && (0 == strcmp(this->GetFuncName(), "error_for_asm"))) {
-		this->SharedChunks = true;
+	if (!this->HasSharedChunks() && (0 == strcmp(this->GetFuncName(), "error_for_asm"))) {
+		GetFuncInfo()->SetSharedChunks(true);
 		SMP_msg("Kludging function %s\n", this->GetFuncName());
 	}
 #endif
@@ -9230,7 +9241,7 @@ void SMPFunction::MarkFunctionSafe() {
 	// For mmStrata bounds checking of the stack frame, we don't care
 	//  about indirect writes unless they are to the stack.
 	bool SpecUnsafe = (HasStackPointerCopy || HasStackPointerPush 
-		|| HasIndexedStackWrite || this->SharedChunks
+		|| HasIndexedStackWrite || this->HasSharedChunks()
 		|| this->HasUnresolvedIndirectJumps());
 	bool Unsafe = SpecUnsafe || this->UnresolvedIndirectCalls;
 
@@ -9307,7 +9318,7 @@ void SMPFunction::MarkFunctionSafe() {
 			WritesAboveLocalFrame, AccessesReturnAddress, HasIndexedStackWrite, HasIndirectWrite);
 		SMP_msg("AnalyzedSP: %d UnresolvedCalls: %d UnresolvedJumps: %d SharedChunks: %d IsLeaf: %d ",
 			this->AnalyzedSP, this->UnresolvedIndirectCalls, this->HasUnresolvedIndirectJumps(),
-			this->SharedChunks, this->IsLeaf());
+			this->HasSharedChunks(), this->IsLeaf());
 		SMP_msg("IndirCallTarget: %d TailCallTarget: %d HasNoCallers: %d MultiEntry: %d\n", 
 			this->PossibleIndirectCallTarget, this->PossibleTailCallTarget, HasNoCallers, this->MultipleEntryPoints);
 #endif
diff --git a/src/interfaces/Makefile.in b/src/interfaces/Makefile.in
index e1f803cf..7ab75433 100644
--- a/src/interfaces/Makefile.in
+++ b/src/interfaces/Makefile.in
@@ -1,10 +1,10 @@
 .SUFFIXES: 
 
-dirs=base interfaces
+dirs=idapro
 
 
 all: .PHONY 
-        for i in ${dirs};  do cd $$i; make; cd ..; done
+	for i in ${dirs};  do cd $$i; make; cd ..; done
 
 clean:   .PHONY
 	for i in ${dirs};  do cd $$i; make clean; cd ..; done
diff --git a/src/interfaces/idapro/Makefile.in b/src/interfaces/idapro/Makefile.in
index 946ee594..d6aecaa9 100644
--- a/src/interfaces/idapro/Makefile.in
+++ b/src/interfaces/idapro/Makefile.in
@@ -1,19 +1,28 @@
 
-OBJS=SMPStaticAnalyzer.o   SMPDataFlowAnalysis.o   SMPInstr.o   SMPBasicBlock.o   \
-	SMPFunction.o   SMPProgram.o   SMPDBInterface.o ProfilerInformation.o
+OBJS=STARSFunction.o
 CXX=@CXX@
 LD=@LD@
+EXTRA_CXXFLAGS=@EXTRA_CXXFLAGS@
+LIB=${SMPSA_HOME}/lib/libbase.a
 
 all: $(OBJS)
 
-$(OBJS): $(INCLUDE)/base/*.h		# *.cpp depends on *.h
+# pull in dependency info for *existing* .o files
+-include $(OBJS:.o=.d)
 
-.cpp.o:
-	$(CXX) $(EXTRA_CXXFLAGS) -c $< 
-	$(AR) -r $(LIB) $(OBJS)
+%.o: %.cpp
+	$(CXX) -c  $(EXTRA_CXXFLAGS) $*.cpp 
+	$(AR) -r $(LIB) $*.o
+	@#
+	@# build dependencies --  http://scottmcpeak.com/autodepend/autodepend.html
+	@#
+	$(CXX) -MM $(EXTRA_CXXFLAGS) $*.cpp > $*.d
+	@cp -f $*.d $*.d.tmp
+	@sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d
+	@rm -f $*.d.tmp
 
 clean:  
-	rm -f $(OBJS) 
+	rm -f $(OBJS)  *.d
 
 .PHONY:
 	@if [ "${IDAROOT}"X = "X"  ];  then echo Please set IDAROOT; exit 1; fi
diff --git a/src/interfaces/idapro/STARSFunction.cpp b/src/interfaces/idapro/STARSFunction.cpp
new file mode 100644
index 00000000..db9fb52a
--- /dev/null
+++ b/src/interfaces/idapro/STARSFunction.cpp
@@ -0,0 +1,97 @@
+
+#include "interfaces/SMPDBInterface.h"
+#include "interfaces/abstract/all.h"
+#include "interfaces/idapro/all.h"
+
+
+static bool IsChunkUnshared(ea_t ChunkAddr, ea_t FuncHeadStart, ea_t FuncHeadEnd) 
+{
+        bool Unshared = true;
+        SMP_xref_t CurrXrefs;
+
+        // See if any xref reaches this ChunkAddr from outside the FuncHead range.
+        for (bool ok = CurrXrefs.SMP_first_to(ChunkAddr, XREF_ALL);     ok;     ok = CurrXrefs.SMP_next_to()) {
+                ea_t FromAddr = CurrXrefs.GetFrom();
+                if ((FromAddr != 0) && (CurrXrefs.GetIscode())) {
+                        // We found a code xref that comes to the ChunkAddr. Whether it is a fall-through or
+                        //  a jump/call, it is unshared only if it comes from within the FuncHead address range.
+                        if ((FromAddr < FuncHeadStart) || (FromAddr >= FuncHeadEnd)) {
+                                Unshared = false;
+                                break;
+                        }
+                }
+        }
+
+        return Unshared;
+} // end of SMPProgram::IsChunkUnshared()
+
+
+
+void STARS_IDA_Function_t::MarkSharedChunks()
+{
+
+	char name[1000];
+	ea_t FirstEA=this->get_startEA();
+	::get_func_name(FirstEA,name,sizeof(name));
+        // Determine if we are dealing with shared chunks.
+        ea_t FuncHeadLastAddr = 0;
+        size_t ChunkCounter = 0;
+        //func_tail_iterator_t FuncTail((func_t*)*dynamic_cast<STARS_IDA_Function_t*>(this->GetFuncInfo()));
+        func_tail_iterator_t FuncTail(the_func);// (func_t*)*(dynamic_cast<STARS_IDA_Function_t*>(this->GetFuncInfo())));
+        for (bool ChunkOK = FuncTail.main(); ChunkOK; ChunkOK = FuncTail.next()) 
+	{
+                const area_t &CurrChunk = FuncTail.chunk();
+                ++ChunkCounter;
+                if (1 == ChunkCounter) { // head chunk
+                        FuncHeadLastAddr = CurrChunk.endEA;
+                }
+                else { // a tail chunk
+                        if (IsChunkUnshared(CurrChunk.startEA, FirstEA, FuncHeadLastAddr)) 
+			{
+//                                this->UnsharedChunks = true;
+//                                SMP_msg("INFO: Interface Found unshared tail chunk for %s at %lx\n",
+//                                        name, (unsigned long) CurrChunk.startEA);
+                        }
+                        else 
+			{
+                                this->SharedChunks = true;
+//                                SMP_msg("INFO: Interface Found tail chunk for %s at %lx\n",
+//                                        name, (unsigned long) CurrChunk.startEA);
+                        }
+                }
+        }
+
+}
+
+bool STARS_IDA_Function_t::IsMultiEntry()
+{
+	ea_t FirstEA=this->get_startEA();
+        func_tail_iterator_t FuncTail(the_func);// (func_t*)*(dynamic_cast<STARS_IDA_Function_t*>(this->GetFuncInfo())));
+        size_t CallTargetCount = 0; // how many addresses in this function are called?
+
+        if (this->HasSharedChunks() || this->UnsharedChunks) {
+                for (bool ChunkOK = FuncTail.main(); ChunkOK; ChunkOK = FuncTail.next()) {
+                        const area_t &CurrChunk = FuncTail.chunk();
+                        ea_t addr = CurrChunk.startEA; // Start with just the beginning addrs of chunks.
+                        // Determine whether the instruction is a call target by looking
+                        //  at its cross references and seeing if it has "TO" code xrefs.
+                        SMP_xref_t xrefs, Distant_xrefs;
+                        for (bool ok = xrefs.SMP_first_to(addr, XREF_FAR); ok; ok = xrefs.SMP_next_to()) {
+                                ea_t DistantAddr = xrefs.GetFrom();
+                                if ((DistantAddr != 0) && (xrefs.GetIscode())) {
+                                        // Now we see if the distant instruction is in another function.
+                                        STARS_Function_t *SourceFunc = SMP_get_func(DistantAddr);
+                                        if (NULL != SourceFunc) {
+                                                if (SourceFunc->get_startEA() != FirstEA) {
+                                                        ++CallTargetCount;
+                                                        break;
+                                                }
+                                        }
+                                }
+                        } // end for all xrefs
+                } // end for all chunks
+        }
+
+        return  CallTargetCount > 1;
+} 
+
-- 
GitLab