From 1ec9897c46ab71b4d79fe0033b5a289151d792d2 Mon Sep 17 00:00:00 2001
From: clc5q <clc5q@git.zephyr-software.com>
Date: Thu, 8 Oct 2015 14:09:49 +0000
Subject: [PATCH] Expand chunks to include interleaved orphan code regions.

Former-commit-id: ed95b04147243753433effb793a64cc4b91b75a8
---
 src/base/SMPFunction.cpp                      | 18 +++---
 src/drivers/idapro/SMPStaticAnalyzer.cpp      |  2 +
 src/interfaces/idapro/STARSFunction.cpp       | 64 ++++++++++++++++++-
 tests/commit/save-xedit.psexe.infoannot       |  2 +-
 ...ted-save-ffmpeg.psexe.annot.REMOVED.git-id |  2 +-
 ...-gnome-terminal.psexe.annot.REMOVED.git-id |  2 +-
 ...rted-save-xedit.psexe.annot.REMOVED.git-id |  2 +-
 7 files changed, 78 insertions(+), 14 deletions(-)

diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp
index 425370ef..b141ed17 100644
--- a/src/base/SMPFunction.cpp
+++ b/src/base/SMPFunction.cpp
@@ -5443,7 +5443,7 @@ void SMPFunction::DetectLoopInvariantDEFs(void) {
 						}
 #if STARS_DEBUG_LOOP_INVARIANTS
 						SMP_msg("INFO: Invariant DEF at %llx InvariantForAllLoops: %d LoopHeadAddr: %llx\n", (unsigned long long) DefAddr,
-							InvariantForAllLoops, this->GetBlockByNum(HeadBlockNum)->GetFirstAddr());
+							InvariantForAllLoops, (unsigned long long) this->GetBlockByNum(HeadBlockNum)->GetFirstAddr());
 #endif
 					}
 				}
@@ -6089,7 +6089,9 @@ void SMPFunction::RPONumberBlocks(void) {
 	while (!WorkList.empty()) {
 		change = false;
 		while (CurrListItem != WorkList.end()) {
-			if ((*CurrListItem)->IsProcessed()) {
+			CurrBlock = (*CurrListItem);
+			STARS_ea_t CurrAddr = CurrBlock->GetFirstAddr();
+			if (CurrBlock->IsProcessed()) {
 				// Duplicates get pushed onto the WorkList because a block
 				//  can be the successor of multiple other blocks. If it is
 				//  already numbered, it is a duplicate and can be removed
@@ -6098,21 +6100,21 @@ void SMPFunction::RPONumberBlocks(void) {
 				change = true;
 				continue;
 			}
-			if ((*CurrListItem)->AllPredecessorsProcessed()) {
+			if (CurrBlock->AllPredecessorsProcessed()) {
 				// Ready to be numbered.
-				(*CurrListItem)->SetNumber(CurrNum);
-				(*CurrListItem)->SetProcessed(true);
+				CurrBlock->SetNumber(CurrNum);
+				CurrBlock->SetProcessed(true);
 #if 0
 				SMP_msg("Set RPO number %d\n", CurrNum);
 				if (DebugFlag && (7 == CurrNum))
 					this->Dump();
 #endif
-				this->RPOBlocks.push_back(*CurrListItem);
+				this->RPOBlocks.push_back(CurrBlock);
 				++CurrNum;
 				change = true;
 				// Push its unnumbered successors onto the work list.
-				CurrSucc = (*CurrListItem)->GetFirstSucc();
-				while (CurrSucc != (*CurrListItem)->GetLastSucc()) {
+				CurrSucc = CurrBlock->GetFirstSucc();
+				while (CurrSucc != CurrBlock->GetLastSucc()) {
 					if (!(*CurrSucc)->IsProcessed())
 						WorkList.push_back(*CurrSucc);
 					++CurrSucc;
diff --git a/src/drivers/idapro/SMPStaticAnalyzer.cpp b/src/drivers/idapro/SMPStaticAnalyzer.cpp
index a8c55b1c..62e8b3df 100644
--- a/src/drivers/idapro/SMPStaticAnalyzer.cpp
+++ b/src/drivers/idapro/SMPStaticAnalyzer.cpp
@@ -384,6 +384,7 @@ void IDAP_run(int arg) {
 #endif
 
 	STARS_ea_t RecentAddr;
+#if 0
 #if SMP_DEBUG_CODE_ORPHANS
 	CodeOrphans.clear();
 	RecentAddr = STARS_BADADDR;
@@ -392,6 +393,7 @@ void IDAP_run(int arg) {
 		if (seg->IsCodeSegment())
 			Debug_FindOrphanedCode(seg, true);
 	}
+#endif
 #endif
 
 	// Read the Zephyr Security Toolkit system call security policies, if available.
diff --git a/src/interfaces/idapro/STARSFunction.cpp b/src/interfaces/idapro/STARSFunction.cpp
index da2e34ec..b088725e 100644
--- a/src/interfaces/idapro/STARSFunction.cpp
+++ b/src/interfaces/idapro/STARSFunction.cpp
@@ -3,6 +3,7 @@
 
 #include <pro.h>
 #include <area.hpp>
+#include <funcs.hpp>
 #include <xref.hpp>
 
 // #include "interfaces/STARSTypes.h"
@@ -18,7 +19,11 @@
 
 using namespace std;
 
-#define SMP_DEBUG_BUILD_RTL 1   // leave this on; serious errors reported
+// leave this on; serious errors reported
+#define SMP_DEBUG_BUILD_RTL 1   
+
+// Expand chunks to include interleaved regions of insts not in any other function
+#define STARS_INTEGRATE_ORPHANED_REGIONS 1  
 
 // Used for binary search by function number in SMPStaticAnalyzer.cpp
 //  to trigger debugging output and find which instruction in which
@@ -58,7 +63,7 @@ void STARS_IDA_Function_t::MarkSharedChunks(void) {
 	::get_func_name(FirstEA,name,sizeof(name));
 	// Determine if we are dealing with shared chunks.
 	STARS_ea_t FuncHeadLastAddr = 0;
-	size_t ChunkCounter = 0;
+	std::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()) {
@@ -80,6 +85,61 @@ void STARS_IDA_Function_t::MarkSharedChunks(void) {
 			}
 		}
 	}
+
+#if STARS_INTEGRATE_ORPHANED_REGIONS
+	if (1 < ChunkCounter) { // search for interleaved orphaned instructions and integrate them
+		STARS_ea_t ExpectedStartAddr = STARS_BADADDR;
+		STARS_ea_t PreviousStartAddr = STARS_BADADDR;
+		for (bool ChunkOK = FuncTail.main(); ChunkOK; ChunkOK = FuncTail.next()) {
+			const area_t &CurrChunk = FuncTail.chunk();
+			if (STARS_BADADDR != ExpectedStartAddr) {
+				if ((CurrChunk.startEA) > ExpectedStartAddr) { // gap between chunks
+					// Go through addresses between the chunks and find the extent of instructions
+					//  that are orphans (not part of any function) and expand the earlier chunk to
+					//  include the orphans.
+					STARS_ea_t UpperLimit = 0;
+					for (STARS_ea_t addr = ExpectedStartAddr; addr < CurrChunk.startEA; addr = SMP_get_item_end(addr)) {
+						flags_t InstrFlags = SMP_getFlags(addr);
+						if (!SMP_isHead(InstrFlags)) {
+							continue;
+						}
+						if (SMP_isCode(InstrFlags)) {
+							func_t *NextFunc = ::get_func(addr);
+							if (NULL == NextFunc) { // inst is not in any func
+								UpperLimit = SMP_get_item_end(addr);
+							}
+							else {
+								if (NextFunc->startEA == FirstEA) {
+									SMP_msg("ERROR: Found code for current func in supposed orphan region at %llx func FirstEA: %llx\n",
+										(unsigned long long) addr, (unsigned long long) FirstEA);
+								}
+								else {
+									SMP_msg("SERIOUS WARNING: Found code for different func interleaved with current func at %llx currfunc FirstEA: %llx newfunc FirstEA: %llx\n",
+										(unsigned long long) addr, (unsigned long long) FirstEA, (unsigned long long) NextFunc->startEA);
+								}
+								break;
+							}
+						}
+					} // for all addrs between CurrChunk and NextChunk
+					if (UpperLimit > 0) { // need to expand earlier chunk
+						bool success = ::func_setend(PreviousStartAddr, (STARS_ea_t) UpperLimit);
+						if (success) {
+							SMP_msg("INFO: Expanded chunk limit at %llx to new limit at %llx to include orphan code.\n",
+								(unsigned long long) PreviousStartAddr, (unsigned long long) UpperLimit);
+						}
+						else {
+							SMP_msg("ERROR: Failed to expand chunk limit at %llx to new limit at %llx to include orphan code.\n",
+								(unsigned long long) PreviousStartAddr, (unsigned long long) UpperLimit);
+						}
+					}
+				} // end if gap between chunks
+			} // end if (STARS_BADADDR != ExpectedStartAddr)
+			PreviousStartAddr = CurrChunk.startEA;
+			ExpectedStartAddr = CurrChunk.endEA;
+		} // end for all chunks
+	} // end if (1 < ChunkCounter)
+#endif  // STARS_INTEGRATE_ORPHANED_REGIONS
+
 	return;
 } // end of STARS_IDA_Function_t::MarkSharedChunks()
 
diff --git a/tests/commit/save-xedit.psexe.infoannot b/tests/commit/save-xedit.psexe.infoannot
index a3103e4a..999ff121 100644
--- a/tests/commit/save-xedit.psexe.infoannot
+++ b/tests/commit/save-xedit.psexe.infoannot
@@ -1785,7 +1785,7 @@
             44ba90     51 FUNC INARGS    6  ARG0 0 ARG1 0 ARG2 0 ARG3 0 ARG4 0 ARG5 0 
             44bac8     46 FUNC RETURNTYPE RAX 0
             44bac8     46 FUNC PROBLEM sub_44BAC8 JUMPUNRESOLVED 
-            44bb00     55 FUNC RETURNTYPE RAX 1
+            44bb00     55 FUNC RETURNTYPE RAX 96
             44bb00     55 FUNC INARGS    6  ARG0 0 ARG1 0 ARG2 0 ARG3 0 ARG4 0 ARG5 0 
             44bb00     55 FUNC PROBLEM sub_44BB00 CHUNKS 
             44bb40    166 FUNC RETURNTYPE RAX 1
diff --git a/tests/commit/trimmed-sorted-save-ffmpeg.psexe.annot.REMOVED.git-id b/tests/commit/trimmed-sorted-save-ffmpeg.psexe.annot.REMOVED.git-id
index 5b9f18d8..2bf6a71f 100644
--- a/tests/commit/trimmed-sorted-save-ffmpeg.psexe.annot.REMOVED.git-id
+++ b/tests/commit/trimmed-sorted-save-ffmpeg.psexe.annot.REMOVED.git-id
@@ -1 +1 @@
-adbb7c5587f18c7df6c886dc5cbb6f3b0a3c8fc1
\ No newline at end of file
+d2994c0ae7f5ef4576b70f31c7aaaa4ff575b891
\ No newline at end of file
diff --git a/tests/commit/trimmed-sorted-save-gnome-terminal.psexe.annot.REMOVED.git-id b/tests/commit/trimmed-sorted-save-gnome-terminal.psexe.annot.REMOVED.git-id
index 2d55fc22..5065cb34 100644
--- a/tests/commit/trimmed-sorted-save-gnome-terminal.psexe.annot.REMOVED.git-id
+++ b/tests/commit/trimmed-sorted-save-gnome-terminal.psexe.annot.REMOVED.git-id
@@ -1 +1 @@
-ad96d40eb1eada26c273ae363e8d13db76d34c34
\ No newline at end of file
+0e140267db7b08cf4894930df1ff05aa8de1510b
\ No newline at end of file
diff --git a/tests/commit/trimmed-sorted-save-xedit.psexe.annot.REMOVED.git-id b/tests/commit/trimmed-sorted-save-xedit.psexe.annot.REMOVED.git-id
index 3d39841c..0ac9a4f1 100644
--- a/tests/commit/trimmed-sorted-save-xedit.psexe.annot.REMOVED.git-id
+++ b/tests/commit/trimmed-sorted-save-xedit.psexe.annot.REMOVED.git-id
@@ -1 +1 @@
-0eb9db4077cbc94208edd6a90ea64b087964ce7a
\ No newline at end of file
+7474808352d5e69ba741eff3b6e623a1c107f586
\ No newline at end of file
-- 
GitLab