diff --git a/.gitattributes b/.gitattributes
index 5d6462a718b423ea428c5ac2f52d0233795a4512..ce4a0f652de27bd618199d4973d3f18291e7ec6e 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -204,6 +204,7 @@ libIRDB/SConstruct -text
 libIRDB/include/cfg/BasicBlock.hpp -text
 libIRDB/include/cfg/CFG.hpp -text
 libIRDB/include/cfg/callgraph.hpp -text
+libIRDB/include/cfg/domgraph.hpp -text
 libIRDB/include/core/address.hpp -text
 libIRDB/include/core/archdesc.hpp -text
 libIRDB/include/core/baseobj.hpp -text
diff --git a/libIRDB/include/cfg/BasicBlock.hpp b/libIRDB/include/cfg/BasicBlock.hpp
index bd61587db7bc449803d1ec121ec5b6152cb2ef4d..340c9d697dc1e8ce801c5e5641ae2bcedb9b9cb8 100644
--- a/libIRDB/include/cfg/BasicBlock.hpp
+++ b/libIRDB/include/cfg/BasicBlock.hpp
@@ -36,9 +36,15 @@ class BasicBlock_t
 		BasicBlockSet_t&     GetPredecessors() { return predecessors; }
 		BasicBlockSet_t&     GetSuccessors()   { return successors; }
 		BasicBlockSet_t&     GetIndirectTargets() { return indirect_targets; }
-
 		BasicBlock_t* GetFallthrough();
 		BasicBlock_t* GetTarget();
+
+		// for const correctness if you aren't modifying.
+		const InstructionVector_t& GetInstructions() const { return instructions; }
+		const BasicBlockSet_t&     GetPredecessors() const { return predecessors; }
+		const BasicBlockSet_t&     GetSuccessors()   const { return successors; }
+		const BasicBlockSet_t&     GetIndirectTargets() const { return indirect_targets; }
+
 		bool EndsInBranch();
 		bool EndsInIndirectBranch();
 		bool EndsInConditionalBranch();
diff --git a/libIRDB/include/cfg/CFG.hpp b/libIRDB/include/cfg/CFG.hpp
index afb0e63bb57b1a98487e3ac2c41bf0c89d23596d..532570be5ed3343adc29f77c7ea56f431f163736 100644
--- a/libIRDB/include/cfg/CFG.hpp
+++ b/libIRDB/include/cfg/CFG.hpp
@@ -42,6 +42,7 @@ class ControlFlowGraph_t
 	public:
 		friend std::ostream& operator<<(std::ostream& os, const ControlFlowGraph_t& cfg);
 		BasicBlockSet_t& GetBlocks()   { return blocks; }
+		const BasicBlockSet_t& GetBlocks()   const { return blocks; }
 };
 
 
diff --git a/libIRDB/include/cfg/domgraph.hpp b/libIRDB/include/cfg/domgraph.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d5de10e5ebdc389b40eaebe1520fa0a0dfdd8c59
--- /dev/null
+++ b/libIRDB/include/cfg/domgraph.hpp
@@ -0,0 +1,50 @@
+
+
+
+typedef std::map<const BasicBlock_t*, BasicBlockSet_t> DominatorMap_t;
+typedef std::map<const BasicBlock_t*, BasicBlock_t*> BlockToBlockMap_t;
+
+class DominatorGraph_t
+{
+	public:
+		DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms=false, bool needs_idoms=false);
+
+
+		// get the (post) dominators for a node 
+		BasicBlockSet_t& GetDominators(const BasicBlock_t* node) { return dom_graph[node]; }
+		BasicBlockSet_t& GetPostDominators(const BasicBlock_t* node) { return post_dom_graph[node]; }
+
+		const BasicBlockSet_t& GetDominators(const BasicBlock_t* node) const { return dom_graph.at(node); }
+		const BasicBlockSet_t& GetPostDominators(const BasicBlock_t* node) const { return post_dom_graph.at(node); }
+
+
+		// get the immeidate (post) dominators for a node 
+		const BasicBlock_t* GetImmediateDominator(const BasicBlock_t* node)  const
+		{ auto it=idom_graph.find(node); return (it!=idom_graph.end()) ? it->second : NULL; }
+		const BasicBlock_t* GetImmediatePostDominators(const BasicBlock_t* node)  const
+		{ auto it=post_idom_graph.find(node); return (it!=post_idom_graph.end()) ? it->second : NULL; }
+
+
+	private:
+
+        	typedef const BasicBlockSet_t& (*pred_func_ptr_t) (const BasicBlock_t* node);
+
+		DominatorMap_t Dom_Comp(const BasicBlockSet_t& N, pred_func_ptr_t pred_func, BasicBlock_t* r);
+		BlockToBlockMap_t Idom_Comp(const BasicBlockSet_t& N, const DominatorMap_t &Domin, BasicBlock_t* r);
+
+
+		DominatorMap_t dom_graph;
+		BlockToBlockMap_t idom_graph;
+
+		DominatorMap_t post_dom_graph;
+		BlockToBlockMap_t post_idom_graph;
+
+		const ControlFlowGraph_t& cfg;	// a reference to our cfg.
+
+                friend std::ostream& operator<<(std::ostream& os, const DominatorGraph_t& cfg);
+	
+};
+
+std::ostream& operator<<(std::ostream& os, const DominatorGraph_t& cfg);
+
+
diff --git a/libIRDB/include/libIRDB-cfg.hpp b/libIRDB/include/libIRDB-cfg.hpp
index 6cfc423dfc66eba3e394fd671d6441cde7eca32e..1a720ec614c5b281ceaef0efe3230d37c8fda04e 100644
--- a/libIRDB/include/libIRDB-cfg.hpp
+++ b/libIRDB/include/libIRDB-cfg.hpp
@@ -36,6 +36,7 @@ namespace libIRDB
 #include <cfg/BasicBlock.hpp>
 #include <cfg/CFG.hpp>
 #include <cfg/callgraph.hpp>
+#include <cfg/domgraph.hpp>
 
 };
 
diff --git a/libIRDB/src/cfg/BasicBlock.cpp b/libIRDB/src/cfg/BasicBlock.cpp
index 8cf8350612ee882b15b0095fd915152c3005d582..f45440423294f95c37431c2ba4d05d88934e980f 100644
--- a/libIRDB/src/cfg/BasicBlock.cpp
+++ b/libIRDB/src/cfg/BasicBlock.cpp
@@ -69,6 +69,35 @@ void BasicBlock_t::BuildBlock
 			successors.insert(target_block);
 		}
 
+		/* This is also the end of the block if this is a function exit instruction */
+		if(insn->IsFunctionExit()) 
+		{
+			is_exit_block=true;
+		}
+
+		// handle fixed-call fallthroughs.
+		for_each(insn->GetRelocations().begin(), insn->GetRelocations().end(), [this,&insn2block_map](Relocation_t* reloc)
+		{
+			/* and has a reloc that's a pcrel with a WRT object */ 
+			if( reloc->GetType()==string("fix_call_fallthrough")) 
+			{
+				assert(reloc->GetWRT()!=NULL);
+				Instruction_t* fix_call_fallthrough_insn=dynamic_cast<Instruction_t*>(reloc->GetWRT());
+				assert(fix_call_fallthrough_insn);
+
+				// this block has a fallthrough to the return block.
+				if(is_in_container(insn2block_map,fix_call_fallthrough_insn))
+				{
+					BasicBlock_t* fix_call_fallthrough_blk=find_map_object(insn2block_map,fix_call_fallthrough_insn);
+					successors.insert(fix_call_fallthrough_blk);
+					fix_call_fallthrough_blk->GetPredecessors().insert(this);
+				}
+
+				is_exit_block=false;
+			}
+		});
+
+
 		/* if there's a fallthrough block, insert it into the appropriate sets */
 		if(ft_block)
 		{
@@ -81,16 +110,34 @@ void BasicBlock_t::BuildBlock
 			break;
 
 		/* or if there is a fallthrough block already built */
-		if(target_insn || ft_block)
+		if(ft_block)
 			break;
 
-		/* This is also the end of the block if this is a function exit instruction */
-		if(insn->IsFunctionExit()) 
+		/* check for a fallthrough out of the function */
+		if(ft_insn && !is_in_container(func->GetInstructions(),ft_insn))
 			break;
 
+
 		/* otherwise, move to the fallthrough */
 		insn=ft_insn;
 	}
+
+	// deal with IB targets for the end of the block
+
+	insn=instructions[instructions.size()-1]; // get last instruction.
+	assert(insn);
+	if(insn->GetIBTargets())
+	{
+		for_each(insn->GetIBTargets()->begin(), insn->GetIBTargets()->end(), [this,&insn2block_map,func](Instruction_t* target)
+		{
+			if(is_in_container(insn2block_map,target) && target!=func->GetEntryPoint())	// don't link calls to the entry block.
+			{
+				BasicBlock_t* target_block=find_map_object(insn2block_map,target);
+				target_block->GetPredecessors().insert(this);
+				successors.insert(target_block);
+			}
+		});
+	}
 	
 }
 
diff --git a/libIRDB/src/cfg/CFG.cpp b/libIRDB/src/cfg/CFG.cpp
index 3203c947c3a6a4c95acf9411e3afd0b95d1c7895..2e1b80c83572229c76146f501659c5a5c3bd7163 100644
--- a/libIRDB/src/cfg/CFG.cpp
+++ b/libIRDB/src/cfg/CFG.cpp
@@ -139,7 +139,18 @@ void ControlFlowGraph_t::Build(Function_t* func)
 ostream& libIRDB::operator<<(ostream& os, const ControlFlowGraph_t& cfg)
 {
 	int i=0;
+
+	map<BasicBlock_t*,int> blk_numbers;
+	for(
+		set<BasicBlock_t*>::const_iterator it=cfg.blocks.begin();
+		it!=cfg.blocks.end();
+		++it
+	   )
+	{
+			blk_numbers[*it]=i++;
+	}
 	
+
 	for(
 		set<BasicBlock_t*>::const_iterator it=cfg.blocks.begin();
 		it!=cfg.blocks.end();
@@ -152,11 +163,21 @@ ostream& libIRDB::operator<<(ostream& os, const ControlFlowGraph_t& cfg)
 			os<<"**** Entry    ";
 		else
 			os<<"---- NotEntry ";
-		os<<"block "<<std::dec<<i<<endl;
-		i++;
-
+		os<<"block "<<std::dec<<blk_numbers[block]<<endl;
+		os<<"Successors: ";
+		for_each(block->GetSuccessors().begin(), block->GetSuccessors().end(), [&](BasicBlock_t* succ)
+		{
+			os<<blk_numbers[succ]<<", ";
+			
+		});
+		os<<endl;
+		os<<"Predecessors: ";
+		for_each(block->GetPredecessors().begin(), block->GetPredecessors().end(), [&](BasicBlock_t* pred)
+		{
+			os<<blk_numbers[pred]<<", ";
+		});
+		os<<endl;
 		os << *block;
-		
 	}
 
 	return os;
diff --git a/libIRDB/src/cfg/SConscript b/libIRDB/src/cfg/SConscript
index ad91f9943222a6955c43e3b83ad6d2d5dfb27d95..572af82762c62dee62e59bec833cdfc485107fbd 100644
--- a/libIRDB/src/cfg/SConscript
+++ b/libIRDB/src/cfg/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
+	BasicBlock.cpp  callgraph.cpp  CFG.cpp domgraph.cpp
 	'''
 cpppath=''' 
 	$SECURITY_TRANSFORMS_HOME/include/
@@ -18,6 +18,7 @@ cpppath='''
 	'''
 
 #myenv.Append(CCFLAGS=" -Wall -W -Wextra -Wconversion ")
+myenv.Append(CCFLAGS=" -Wall -W -Wextra -Wconversion -std=c++11")
 
 myenv=myenv.Clone(CPPPATH=Split(cpppath))
 lib=myenv.Library(libname, Split(files))
diff --git a/libIRDB/test/fix_calls.cpp b/libIRDB/test/fix_calls.cpp
index 533dc88891d33aca4d4502d33696a3dd81c78a89..b96895c2e5a54a9722ec1c3a858a17cd5dd765ea 100644
--- a/libIRDB/test/fix_calls.cpp
+++ b/libIRDB/test/fix_calls.cpp
@@ -677,6 +677,15 @@ void fix_call(Instruction_t* insn, FileIR_t *firp, bool can_unpin)
 		}
 	}
 
+
+	// mark in the IR what the fallthrough of this insn is.
+	Relocation_t* fix_call_reloc=new Relocation_t(); 
+	fix_call_reloc->SetOffset(0);
+	fix_call_reloc->SetType("fix_call_fallthrough");
+	fix_call_reloc->SetWRT(newindirtarg);
+	callinsn->GetRelocations().insert(fix_call_reloc);
+	firp->GetRelocations().insert(fix_call_reloc);
+
 }