diff --git a/SMPStaticAnalyzer b/SMPStaticAnalyzer
index 26497da37ca82c270e44546d729d66ca0b83a4fa..37851eabacb015faecf0ef92f334b7176165c8b3 160000
--- a/SMPStaticAnalyzer
+++ b/SMPStaticAnalyzer
@@ -1 +1 @@
-Subproject commit 26497da37ca82c270e44546d729d66ca0b83a4fa
+Subproject commit 37851eabacb015faecf0ef92f334b7176165c8b3
diff --git a/irdb-libs/ir_builders/fill_in_cfg.cpp b/irdb-libs/ir_builders/fill_in_cfg.cpp
index e1f694fd28c7b84093a4cb5f31aa897de958cf8d..8e131c6b5b1dc0e84669bb9755ba2cdd9518fa83 100644
--- a/irdb-libs/ir_builders/fill_in_cfg.cpp
+++ b/irdb-libs/ir_builders/fill_in_cfg.cpp
@@ -664,15 +664,16 @@ void PopulateCFG::ctor_detection(FileIR_t *firp)
 	auto find_ctor_start=[&](const exeio_section_t* sec, const VirtualOffset_t end_of_ctor) -> VirtualOffset_t
 		{
 			// values needed later for various things
-			const auto ptrsize   = 8;
+			const auto ptrsize   = firp->getArchitectureBitWidth() / 8 ;
 			const auto sec_data  = sec->get_data();
 			const auto sec_start = sec->get_address();
 
 			// check for a null terminator at the stated end of table
 			const auto null_term_addr=end_of_ctor-ptrsize;
-			const auto null_term_value=
+			const auto null_term_value =
 				ptrsize == 8 ?  *(uint64_t*)(sec_data+null_term_addr-sec_start) :
-				                throw invalid_argument("Unknown ptrsize");
+				ptrsize == 4 ?  *(uint32_t*)(sec_data+null_term_addr-sec_start) :
+		                throw invalid_argument("Unknown ptrsize");
 
 			// not found, return this isn't sane.
 			if(null_term_value!=0) return 0;
@@ -685,12 +686,14 @@ void PopulateCFG::ctor_detection(FileIR_t *firp)
 				if(next_addr<sec_start) return 0;
 
 				// get the table entry
-				const auto ctor_entry_value=
+				const auto ctor_entry_value =
 					ptrsize == 8 ?  *(uint64_t*)(sec_data+next_addr-sec_start) :
-							throw invalid_argument("Unknown ptrsize");
+					ptrsize == 4 ?  *(uint32_t*)(sec_data+next_addr-sec_start) :
+					throw invalid_argument("Unknown ptrsize");
 
 				// check for the -1 terminator
-				if((int64_t)ctor_entry_value==int64_t(-1)) return next_addr;
+				if(ptrsize == 8 && (int64_t)ctor_entry_value==int64_t(-1)) return next_addr;
+				if(ptrsize == 4 && (int32_t)ctor_entry_value==int32_t(-1)) return next_addr;
 
 				// check if the table entry isn't a valid address
 				const auto is_before_start = ctor_entry_value <  sec->get_address() ;
@@ -718,6 +721,7 @@ void PopulateCFG::ctor_detection(FileIR_t *firp)
 
 			// finally, create the new scoop
 			firp->addNewDataScoop( name, startaddr, endaddr, NULL, permissions, is_relro, the_contents);
+			cout << "Added ctor/dtor scoop called " << name << " at " << hex << start_vo << "-" << end_vo << endl;
 		};	
 
 	const auto text_sec = exeiop->sections[".text"];
diff --git a/irdb-libs/ir_builders/fill_in_indtargs.cpp b/irdb-libs/ir_builders/fill_in_indtargs.cpp
index b13d9c2228e26c98a62176226b15c1fd3d6a996f..e8a27bd8085cbef7a199dd02df69aa487796bfed 100644
--- a/irdb-libs/ir_builders/fill_in_indtargs.cpp
+++ b/irdb-libs/ir_builders/fill_in_indtargs.cpp
@@ -479,6 +479,21 @@ void handle_scoop_scanning(FileIR_t* firp)
 	// check for addresses in scoops in the text section. 
 	for(auto scoop : firp->getDataScoops())
 	{
+		if(scoop->getName() == ".ctor" || scoop->getName() == ".dtor" )
+		{
+			const auto  ptrsize        = firp->getArchitectureBitWidth() / 8 ;
+			const auto &scoop_contents = scoop->getContents();
+			for(auto i = 0u; i + ptrsize < scoop_contents.size(); i += ptrsize)
+			{
+				const auto ptr =
+				       	ptrsize == 8 ? *reinterpret_cast<const uint64_t*>(scoop_contents.c_str() + i) : 
+				       	ptrsize == 4 ? *reinterpret_cast<const uint32_t*>(scoop_contents.c_str() + i) : 
+					throw invalid_argument("Cannot map ptrsize to deref type");
+				possible_target(ptr, scoop->getStart()->getVirtualOffset() + i, ibt_provenance_t::ibtp_data);
+			}
+
+		}
+
 		// test if scoop was added by fill_in_cfg -- make this test better.
 		if(scoop->getName().find("data_in_text_")==string::npos) continue;
 
@@ -547,113 +562,6 @@ set<Instruction_t*> find_in_function(string needle, Function_t *haystack)
 }
 
 
-#if 0
-bool backup_until(const string &insn_type_regex_str, 
-		  Instruction_t *& prev, 
-		  Instruction_t* orig, 
-		  const string & stop_if_set="", 
-		  bool recursive=false, 
-		  uint32_t max_insns=10000u, 
-		  uint32_t max_recursions=5u)
-{
-
-	const auto find_or_build_regex=[&] (const string& s) -> regex_t&
-		{
-			// declare a freer for regexs so they go away when the program ends.
-			const auto regex_freer=[](regex_t* to_free)  -> void
-			{
-				regfree(to_free);
-				delete to_free;
-			};
-			// keep the map safe from anyone but me using it.
-			using regex_unique_ptr_t=unique_ptr<regex_t, decltype(regex_freer)>;
-			static map<string, regex_unique_ptr_t > regexs_used;
-
-			if(s=="")
-			{
-				static regex_t empty;
-				return empty;
-			}
-			const auto it=regexs_used.find(s);
-			if(it==regexs_used.end())
-			{
-				// allocate a new regex ptr
-				regexs_used.insert(pair<string,regex_unique_ptr_t>(s,move(regex_unique_ptr_t(new regex_t, regex_freer))));
-				// and compile it.
-				auto &regex_ptr=regexs_used.at(s);
-				const auto ret=regcomp(regex_ptr.get(), s.c_str(), REG_EXTENDED);
-				// error check
-				assert(ret==0);
-			}
-			return *regexs_used.at(s).get();
-		};
-
-
-	// build regexs.
-	const auto &preg            = find_or_build_regex(insn_type_regex_str);
-	const auto &stop_expression = find_or_build_regex(stop_if_set);
-
-
-	prev=orig;
-	while(preds[prev].size()==1 && max_insns > 0)
-	{
-		// dec max for next loop 
-		max_insns--;
-
-		// get the only item in the list.
-		prev=*(preds[prev].begin());
-	
-
-       		// get I7's disassembly
-		const auto disasm=DecodedInstruction_t::factory(prev);
-
-       		// check it's the requested type
-       		if(regexec(&preg, disasm->getDisassembly().c_str(), 0, nullptr, 0) == 0)
-			return true;
-
-		if(stop_if_set!="")
-		{
-			for(const auto operand : disasm->getOperands())
-			{
-				if(operand->isWritten() && regexec(&stop_expression, operand->getString().c_str(), 0, nullptr, 0) == 0)
-					return false;
-			}
-		}
-
-		// otherwise, try backing up again.
-	}
-	if(recursive && max_insns > 0 && max_recursions > 0 )
-	{
-		const auto myprev=prev;
-		// can't just use prev because recursive call will update it.
-		const auto &mypreds=preds[myprev];
-		for(const auto pred : mypreds)
-		{
-			prev=pred;// mark that we are here, in case we return true here.
-			const auto disasm=DecodedInstruction_t::factory(pred);
-       			// check it's the requested type
-       			if(regexec(&preg, disasm->getDisassembly().c_str(), 0, nullptr, 0) == 0)
-				return true;
-			if(stop_if_set!="")
-			{
-				for(const auto operand : disasm->getOperands())
-				{
-					if(operand->isWritten() && regexec(&stop_expression, operand->getString().c_str(), 0, nullptr, 0) == 0)
-						return false;
-				}
-			}
-			if(backup_until(insn_type_regex_str, prev, pred, stop_if_set, recursive, max_insns, max_recursions/mypreds.size()))
-				return true;
-
-			// reset for next call
-			prev=myprev;
-		}
-	}
-	return false;
-}
-#endif
-
-
 void check_for_arm32_switch_type1(
 		FileIR_t *firp, 
 		Instruction_t* insn, 
@@ -4058,16 +3966,6 @@ set<VirtualOffset_t> forced_pins;
 
 int parseArgs(const vector<string> step_args)
 {
-
-#if 0
-	if(step_args.size()<1)
-	{
-		cerr<<"Usage: <id> [--[no-]split-eh-frame] [--[no-]unpin] [addr,...]"<<endl;
-		exit(-1);
-	}
-#endif
-
-	// variant_id=stoi(step_args[0]);
 	cout<<"Parsing parameters with argc= " << step_args.size()<<endl;
 
 	// parse dash-style options.
diff --git a/irdb-libs/libIRDB-cfg/include/domgraph.hpp b/irdb-libs/libIRDB-cfg/include/domgraph.hpp
index db37459ae80730a03cc2a15e599ba5b8003d5a72..b7fb70b29ba986ead40f2a5502b02a36d8682f4f 100644
--- a/irdb-libs/libIRDB-cfg/include/domgraph.hpp
+++ b/irdb-libs/libIRDB-cfg/include/domgraph.hpp
@@ -51,8 +51,8 @@ namespace libIRDB
 
 			using pred_func_ptr_t =  const IRDB_SDK::BasicBlockSet_t& (*) (const IRDB_SDK::BasicBlock_t* node);
 
-			DominatorMap_t Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pred_func_ptr_t pred_func, IRDB_SDK::BasicBlock_t* r);
-			BlockToBlockMap_t Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r);
+			DominatorMap_t Dom_Comp(const IRDB_SDK::BasicBlockVector_t& N, pred_func_ptr_t pred_func, IRDB_SDK::BasicBlock_t* r);
+			BlockToBlockMap_t Idom_Comp(const IRDB_SDK::BasicBlockVector_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r);
 
 
 			DominatorMap_t dom_graph;
diff --git a/irdb-libs/libIRDB-cfg/src/SConscript b/irdb-libs/libIRDB-cfg/src/SConscript
index cb08c53f8c8a1a5c37f4e1c1247a591fdda427e5..17ecf7b5232a4fb6214c975845070e75f0983216 100644
--- a/irdb-libs/libIRDB-cfg/src/SConscript
+++ b/irdb-libs/libIRDB-cfg/src/SConscript
@@ -8,7 +8,7 @@ myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME'])
 
 libname="irdb-cfg"
 files=  '''
-	BasicBlock.cpp  callgraph.cpp  CFG.cpp domgraph.cpp criticaledge.cpp
+	BasicBlock.cpp  callgraph.cpp  CFG.cpp domgraph.cpp criticaledge.cpp dfs.cpp
 	'''
 cpppath=''' 
 	$IRDB_SDK/include/
diff --git a/irdb-libs/libIRDB-cfg/src/dfs.cpp b/irdb-libs/libIRDB-cfg/src/dfs.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b8d28a26022eb84521bbe83a18645efa15f0de9c
--- /dev/null
+++ b/irdb-libs/libIRDB-cfg/src/dfs.cpp
@@ -0,0 +1,49 @@
+
+
+#include <irdb-core>
+#include <irdb-cfg>
+#include <vector>
+
+using namespace IRDB_SDK;
+
+using VisitedMap_t = map<BasicBlock_t*,bool> ;
+
+static void doDFS(BasicBlockVector_t &order, VisitedMap_t &visited, BasicBlock_t* node)
+{
+	// visit this node
+	visited[node]=true;
+	order.push_back(node);
+
+	// visit each successor
+	for(auto successor : node->getSuccessors())
+	{
+		if(!visited[successor])
+			doDFS(order,visited,successor);
+	}
+
+}
+
+BasicBlockVector_t IRDB_SDK::getDFSOrder(ControlFlowGraph_t* cfg)
+{
+	assert(cfg!=nullptr);
+
+	auto ret     = BasicBlockVector_t();
+	ret.reserve(cfg->getBlocks().size());
+	auto visited = VisitedMap_t();
+
+	// explicitly fill the map with falses.
+	for(auto& node : cfg->getBlocks())
+		visited[node]=false;
+
+	doDFS(ret,visited,cfg->getEntry());
+
+	// for each node in the map
+	for(auto &p : visited)
+		// if it's not visited
+		if(p.second == false)
+			// that means it appeared unreachable from the entry block
+			// add it to the dfs end.
+			ret.push_back(p.first);
+
+	return move(ret);
+}
diff --git a/irdb-libs/libIRDB-cfg/src/domgraph.cpp b/irdb-libs/libIRDB-cfg/src/domgraph.cpp
index 9c90080ba77618dcb5866ba43fdd940c1b1d9a93..714c78de800488c163613bd1067d06365c5971c4 100644
--- a/irdb-libs/libIRDB-cfg/src/domgraph.cpp
+++ b/irdb-libs/libIRDB-cfg/src/domgraph.cpp
@@ -44,20 +44,18 @@ inline S const& find_map_object( const std::map< T , S > &a_map, const T& key)
 DominatorGraph_t::DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms, bool needs_idoms)
 	: cfg(*p_cfg), warn(false)
 {
-	auto &blocks=p_cfg->getBlocks();
-
-
 	assert(needs_postdoms==false);
 	assert(needs_idoms==false);
 
+	const auto dfs_order = getDFSOrder(const_cast<ControlFlowGraph_t*>(p_cfg));
 
 	pred_func_ptr_t func_get_predecessors=[](const IRDB_SDK::BasicBlock_t* node) -> const IRDB_SDK::BasicBlockSet_t&
 	{
 		return node->getPredecessors();
 	};
 
-	dom_graph=Dom_Comp(blocks, func_get_predecessors, p_cfg->getEntry());
-	idom_graph=Idom_Comp(blocks, dom_graph, p_cfg->getEntry());
+	dom_graph  =  Dom_Comp(dfs_order, func_get_predecessors, p_cfg->getEntry());
+	idom_graph = Idom_Comp(dfs_order, dom_graph,             p_cfg->getEntry());
 
 	Dominated_Compute();
 
@@ -111,7 +109,7 @@ end || Dom_Comp
 
 */
 
-DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pred_func_ptr_t get_preds,  IRDB_SDK::BasicBlock_t* r)
+DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockVector_t& N, pred_func_ptr_t get_preds,  IRDB_SDK::BasicBlock_t* r)
 {
 /*
 	D, T: set of Node
@@ -125,17 +123,15 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pr
 	DominatorMap_t Domin;
 	Domin[r].insert(r);
 
-	IRDB_SDK::BasicBlockSet_t NminusR=N;
-	NminusR.erase(r);
-
 /*
 	for each n \in N - {r} do
 		Domin(n)={N}
 	od
 */
-	for( auto n : NminusR)
+	for( const auto &n : N)
 	{
-		Domin[n]=N;
+		if(n==r) continue;
+		Domin[n]=IRDB_SDK::BasicBlockSet_t(ALLOF(N));
 	};
 
 /* 
@@ -147,17 +143,18 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pr
 		/*
 		for each n \in N - {r} do		
 		*/
-		for( auto n : NminusR)
+		for( const auto &n : N)
 		{
+			if(n == r) continue;
 			/* T := N */
-			T=N;
+			T = IRDB_SDK::BasicBlockSet_t(ALLOF(N));
 /*
 
 			for each p \in Pred(n) do
 				T = T intersect Domin(p)
 			done
 */
-			for(auto p : get_preds(n) )
+			for(const auto &p : get_preds(n) )
 			{
 				IRDB_SDK::BasicBlockSet_t tmp;
 				set_intersection(T.begin(), T.end(), Domin[p].begin(), Domin[p].end(), inserter(tmp,tmp.begin()));
@@ -248,21 +245,20 @@ end || IDom_Comp
 	
 
 
-BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r) 
+BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockVector_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r) 
 {
 	// n, s, t: Node
-	//BasicBlock_t* n=NULL, *s=NULL, *t=NULL;
+	const auto verbose=false;
 
 	// Tmp: Node -> set of Node
-	DominatorMap_t Tmp;
+	auto Tmp = DominatorMap_t();
 	
 	// IDom: Node->Node
-	BlockToBlockMap_t IDom;
-
+	auto IDom = BlockToBlockMap_t() ;
 
-	// calculate this set as we use it several times
-	IRDB_SDK::BasicBlockSet_t NminusR = N;
-	NminusR.erase(r);
+	auto tmp_n_total_size = 0u;
+	auto inner_total      = 0u;
+	auto inner_checks     = 0u;
 
 
 	// for each n \in N do
@@ -271,15 +267,22 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N
 		//Tmp(n) := Domin(n) - {n} 
 		Tmp[n] = Domin.at(n);
 		Tmp[n].erase(n);
+		tmp_n_total_size += Tmp[n].size();
 	// od
-	};
+	}
+
+	if(verbose)
+		cout << "Average size of Tmp[n] = " << tmp_n_total_size / Tmp.size() << endl;
 
 
 	//for each n \in N - {r} do
-	for(auto n : NminusR)
+	for(auto n : N)
 	{
+		if( n == r) continue;
+
 		// for each s \in Tmp(n) do
 		auto Tmp_n=Tmp[n];
+
 		// for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* s)
 		for (auto s : Tmp_n)
 		{
@@ -292,20 +295,29 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N
 				if(t != s)   
 				{
 					//if t \in Tmp(s) then
+					inner_checks ++;
 					if( is_in_container(Tmp[s],t))
 					{
 						//Tmp(n) -= {t}
-						Tmp[n].erase(t);
+						Tmp[n].erase(t); 
+						inner_total ++;
 					}
 				}
 			};
 		};
 	};
 
+	if(verbose)
+	{
+		cout << "Inner checks = " << inner_checks << endl;
+		cout << "Inner total = "  << inner_total  << endl;
+	}
 
 	//for each n \in N-{r} do
-	for (auto n : NminusR)
+	for (auto n : N)
 	{
+		if(n == r) continue;
+
 		//IDom(n) = <only element in>Tmp(n)
 		IDom[n]= *(Tmp[n].begin());
 		if(Tmp[n].size()!=1)	// should only be one idominator.
diff --git a/irdb-libs/libehp b/irdb-libs/libehp
index 173beca81faecfed391fa4c6c881ccf8f49c002c..2991595bd58c79ea894e3cce25b3e67ad02bb99b 160000
--- a/irdb-libs/libehp
+++ b/irdb-libs/libehp
@@ -1 +1 @@
-Subproject commit 173beca81faecfed391fa4c6c881ccf8f49c002c
+Subproject commit 2991595bd58c79ea894e3cce25b3e67ad02bb99b
diff --git a/irdb-sdk b/irdb-sdk
index 3267ac26338c701dffa3267da6c6ca15475b4999..f2ad120cbf9fa7d965288472b67cecb197bb5a12 160000
--- a/irdb-sdk
+++ b/irdb-sdk
@@ -1 +1 @@
-Subproject commit 3267ac26338c701dffa3267da6c6ca15475b4999
+Subproject commit f2ad120cbf9fa7d965288472b67cecb197bb5a12