diff --git a/.gitattributes b/.gitattributes
index 26df0c319c674f7aba13b73356ce1032b2303edf..98931638e4cd0e8892919f21a4779429fb0f44ee 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1207,6 +1207,7 @@ tools/transforms/AnnotationBoundaryGenerator.cpp -text
 tools/transforms/AnnotationBoundaryGenerator.hpp -text
 tools/transforms/DirectOffsetInference.cpp -text
 tools/transforms/DirectOffsetInference.hpp -text
+tools/transforms/EhUpdater.hpp -text
 tools/transforms/General_Utility.cpp -text
 tools/transforms/General_Utility.hpp -text
 tools/transforms/Makefile.in -text
diff --git a/libIRDB/include/core/baseobj.hpp b/libIRDB/include/core/baseobj.hpp
index 4575331a0595c2aa8669a7a8d5bd94f36e632d2f..20b41051039dfb63eb4d71cce46dd8589b257c4b 100644
--- a/libIRDB/include/core/baseobj.hpp
+++ b/libIRDB/include/core/baseobj.hpp
@@ -52,6 +52,7 @@ class BaseObj_t
 	static const db_id_t NOT_IN_DATABASE;
 
 	virtual RelocationSet_t& GetRelocations() { return relocs; }
+	virtual const RelocationSet_t& GetRelocations() const { return relocs; }
 
 
     protected:
diff --git a/libIRDB/include/core/eh.hpp b/libIRDB/include/core/eh.hpp
index f720847133c2bcbfe67de817f2e9b4fbdfd96cbe..58b9999df359ffe8c0bf479e68a53e32aaa67b07 100644
--- a/libIRDB/include/core/eh.hpp
+++ b/libIRDB/include/core/eh.hpp
@@ -26,6 +26,20 @@ class EhProgram_t : public BaseObj_t
 {
 	public:
 
+	EhProgram_t(const EhProgram_t& orig)
+		: 
+		BaseObj_t(NULL)
+	{
+		cie_program=orig.cie_program;
+		fde_program=orig.fde_program;
+		code_alignment_factor=orig.code_alignment_factor;
+		data_alignment_factor=orig.data_alignment_factor;
+		return_register=orig.return_register;
+		ptrsize=orig.ptrsize;
+		SetBaseID(BaseObj_t::NOT_IN_DATABASE);
+		GetRelocations()=orig.GetRelocations();
+		
+	}
 	EhProgram_t(db_id_t id, const uint64_t caf, const int64_t daf, const uint8_t rr, const uint8_t p_ptrsize)
 		: 
 		BaseObj_t(NULL), 
diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp
index d19b493fdff6237de6a586fd8cd1ed8124e6a652..23f15847c4454d3f6ce80c3ea352ce86cadfc221 100644
--- a/libIRDB/src/core/fileir.cpp
+++ b/libIRDB/src/core/fileir.cpp
@@ -1626,6 +1626,35 @@ void FileIR_t::SplitScoop(
 		}
 	
 	}
+
+	/* look at each relocation in the IR */
+	for(auto & r : GetRelocations())
+	{
+		if(r->GetWRT()==tosplit)
+		{
+			const auto &addend=r->GetAddend();
+			const auto containing_start_offset=(containing -> GetStart()->GetVirtualOffset() - 
+				tosplit->GetStart()->GetVirtualOffset());
+			const auto containing_end_offset=containing_start_offset+containing->GetSize();
+			if(needs_before && addend<before->GetSize())
+			{
+				r->SetWRT(before);
+			}
+			else if( addend < containing_end_offset)
+			{
+				r->SetWRT(containing);
+				r->SetAddend(addend-containing_start_offset);
+			}
+			else 		
+			{
+				assert(needs_after);
+				const auto after_start_offset=(after -> GetStart()->GetVirtualOffset() - 
+					tosplit->GetStart()->GetVirtualOffset());
+				r->SetWRT(after);
+				r->SetAddend(addend-after_start_offset);
+			}
+		}
+	}
 	
 
 	GetAddresses().erase(tosplit->GetStart());
diff --git a/libIRDB/test/split_eh_frame.cpp b/libIRDB/test/split_eh_frame.cpp
index 2e6e132b88ec64f96c0ed82bce94736209a1310b..a60b44c0c8abf19f1c4356e27e8de2243f8f36a6 100644
--- a/libIRDB/test/split_eh_frame.cpp
+++ b/libIRDB/test/split_eh_frame.cpp
@@ -299,7 +299,7 @@ class eh_program_insn_t
 			}
 			case 3:
 			{
-				// case DW_CFA_offset:
+				// case DW_CFA_restore (register #):
 				cout<<"				cfa_restore"<<endl;
 				break;
 			}
diff --git a/tools/transforms/EhUpdater.hpp b/tools/transforms/EhUpdater.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6f9569fdb976fa991405ed6109775e6868c58c04
--- /dev/null
+++ b/tools/transforms/EhUpdater.hpp
@@ -0,0 +1,33 @@
+#ifndef EhUpdater
+#define EhUpdater
+
+#include <libIRDB-core.hpp>
+#include "PNStackLayout.hpp"
+
+class EhUpdater_t 
+{
+	public:
+
+	EhUpdater_t(libIRDB::FileIR_t* p_firp, libIRDB::Function_t* p_func, PNStackLayout* p_layout)
+		:
+		m_firp(p_firp),
+		m_func(p_func),
+		m_layout(p_layout)
+	{
+	}
+
+	bool execute();
+
+	private:
+
+	bool update_instructions();
+	bool update_instructions(libIRDB::Instruction_t* insn);
+	bool update_program(libIRDB::EhProgram_t* ehpgm);
+
+
+	libIRDB::FileIR_t* m_firp;
+	libIRDB::Function_t* m_func; 
+	PNStackLayout* m_layout;
+};
+
+#endif
diff --git a/tools/transforms/PNStackLayout.hpp b/tools/transforms/PNStackLayout.hpp
index f0d5c41701071a56df3985f60b31e9c5d9cd373a..d6e28e826bfc3cf1f745eb0d2a2281c7c0fc61a3 100644
--- a/tools/transforms/PNStackLayout.hpp
+++ b/tools/transforms/PNStackLayout.hpp
@@ -108,7 +108,7 @@ public:
 	virtual int GetNewOffsetESP(int ebp_offset) const;
 	virtual int GetNewOffsetEBP(int ebp_offset) const;
 	virtual PNStackLayout GetCanaryLayout() const;
-	virtual std::vector<PNRange*> GetRanges() {return mem_objects;}
+	virtual std::vector<PNRange*> GetRanges() const  {return mem_objects;}
 	virtual bool IsCanarySafe() const 
 	{
 		assert(pn_options);
diff --git a/tools/transforms/PNTransformDriver.cpp b/tools/transforms/PNTransformDriver.cpp
index 6b10ce4744d8f45d02448255c275fd78822acbf3..59e249cd95500816eab36f6c352ba47c169397eb 100644
--- a/tools/transforms/PNTransformDriver.cpp
+++ b/tools/transforms/PNTransformDriver.cpp
@@ -29,6 +29,7 @@
 #include <cmath>
 #include "globals.h"
 #include <libIRDB-cfg.hpp>
+#include "EhUpdater.hpp"
 
 #include <fcntl.h>
 #include <sys/types.h>
@@ -37,6 +38,7 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
+
 #ifndef PATH_MAX
 #define PATH_MAX 4096
 #endif
@@ -236,182 +238,6 @@ void PNTransformDriver::SetProtectSharedObjects(bool do_protection)
 }
 
 
-/*
-  void PNTransformDriver::GenerateTransforms2(FileIR_t *virp,vector<Function_t*> funcs,string BED_script, int progid)
-  {
-  for(int i=0;i<funcs.size();++i)
-  {
-  //transform all with
-	
-  vector<PNStackLayout*> layouts = GenerateInferences(funcs[i], 0);
-	
-  if(layouts.size() == 0)
-  continue;
-	
-  sort(layouts.begin(),layouts.end(),CompareBoundaryNumbers);
-	
-  if(layouts[0]->CanShuffle())
-  {
-  layouts[0]->Shuffle();
-  }
-	
-  //just for now padd too
-  layouts[0]->AddPadding();
-	
-  if(!Rewrite(layouts[0],funcs[i]))
-  {
-  //I need to undo instead but right now undo will undo everything
-  assert(false);
-  }  
-  }
-	
-  //TODO: right now I am passing the first func just to test this out, change validate to accept a string
-  if(!Validate(virp,funcs[0],BED_script,progid))
-  {
-  undo(undo_list,funcs[0]);
-	
-  if(funcs.size()>1)
-  {
-  vector<Function_t*> left;
-  vector<Function_t*> right;
-		
-  left.insert(left.begin(),funcs.begin(),funcs.begin()+(funcs.size()/2));
-  right.insert(right.begin(),funcs.begin()+(funcs.size()/2),funcs.end());
-		
-  GenerateTransforms2(virp,left,BED_script,progid);
-  GenerateTransforms2(virp,right,BED_script,progid);
-  }
-  else
-  {
-  vector<PNStackLayout*> layouts = GenerateInferences(funcs[0],0);
-		
-  if(layouts.size() == 0)
-  return;
-		
-  sort(layouts.begin(),layouts.end(),CompareBoundaryNumbers);
-		
-  //TODO: I should not have to use the first inference at this point
-  for(int i=0;i<layouts.size();++i)
-  {
-  if(layouts[i]->CanShuffle())
-  {
-  layouts[i]->Shuffle();
-  }
-		
-  //just for now padd too
-  layouts[i]->AddPadding();
-		
-  if(!Rewrite(layouts[i],funcs[0]))
-  {
-  //I need to undo instead but right now undo will undo everything
-  assert(false);
-  }  
-  else if(!Validate(virp,funcs[0],BED_script,progid))
-  {
-  undo(undo_list,funcs[0]);
-  continue;
-  }
-  }
-  }
-  }
-  else
-  {
-  cerr<<"Validated "<<funcs.size()<<" functions"<<endl;
-  virp->WriteToDB();
-  undo_list.clear();
-  }
-
-  //Call a recursive function that takes in the number of total funcs, and attempts a 
-  //transform and validation
-  //Divide into N regions, initial N is total_funcs
-  //for each division, transform all functions, then validate.
-  //if validation succeeds, commit
-  //if validation fails, divide N by 2 (if N is odd add one first)
-  //Attemp transform for those divisions, when completley validated, continue on
-
-  //recursive_validate(virp,total_funcs,BED_script, progid)
-  //The problem is undoing only part of the undo list
-  //when all validate, attempt transform again, only shuffling
-  //when that validates add padding, 
-  //You must remember the most aggressive transform that did not fail in some previous
-  //run for each function, never use a more aggressive transform.
-
-  //use a map to hold a pnstack layout for every function
-  //after validation, loop through all functions again, and use these pnstack layouts
-  //if the layout fails, how do I know which transform to pick next?
-  //Perhaps another map listing the perferences of transforms?
-  }
-*/
-
-bool PNTransformDriver::CanaryTransformHandler(PNStackLayout *layout, Function_t *func, bool validate)
-{
-
-	bool success = false;
-
-	if(!validate) 
-		cerr<<"PNTransformDriver: Function "<<func->GetName()<<" is flagged to be transformed without validation"<<endl;
-
-	cerr<<"PNTransformDriver: Function "<<func->GetName()<<" is canary safe, attempting canary rewrite"<<endl;
-
-	layout->Shuffle();
-	layout->AddRandomPadding(do_align);
-
-	if(!Canary_Rewrite(layout,func))
-	{
-		//Experimental code
-		undo(func);
-
-		//TODO: error message
-		cerr<<"PNTransformDriver: canary_rewrite failure"<<endl;
-	}
-	else
-	{
-		//if(!Validate(new_virp,targ_func))
-		if(validate && !Validate(orig_virp,func->GetName()))
-		{
-			//Experimental code
-			undo(func);
-
-			//TODO: error message
-			cerr<<"PNTransformDriver: canary validation failure, rolling back"<<endl;
-		}
-		else
-		{
-			cerr<<"PNTransformDriver: Final Transformation Success: "<<layout->ToString()<<endl;
-			cerr<<"PNTransformDriver: Canary rewrite and validation successful."<<endl;
-
-			//TODO: I would like to set something in the data structures to indicate
-			//the canary is possible, but turned off. 
-
-// fixme jdh canaries per function?
-
-			if(!pn_options->shouldCanaryFunction(func->GetName()))
-			{
-				cerr<<"PNTransformDriver: canary transformations turned off, removing canary from transformation."<<endl;
-				undo(func);
-				Sans_Canary_Rewrite(layout,func);
-			}
-
-//			transformed_history[layout->GetLayoutName()].push_back(layout);
-
-			// finalize_record fr;
-			// fr.layout = layout;
-			// fr.func = func;
-			// fr.firp = orig_virp;
-			// finalization_registry.push_back(fr);
-			// undo(func);
-
-			success = true;
-			//TODO: message
-
-		}
-	}
-
-	//reset_undo(func->GetName());
-
-	return success;
-}
-
 bool PNTransformDriver::PaddingTransformHandler(PNStackLayout *layout, Function_t *func, bool validate)
 {
 	bool success = false;
@@ -546,6 +372,7 @@ void PNTransformDriver::GenerateTransformsInit()
 	jump_table_sanitized = 0;
 	bad_variadic_func_sanitized = 0;
 	pic_jump_table_sanitized = 0;
+	eh_sanitized = 0;
 	dynamic_frames = 0;
 	high_coverage_count = low_coverage_count = no_coverage_count = validation_count = 0;
 	not_transformable.clear();
@@ -761,7 +588,7 @@ Instruction_t* find_exit_insn(Instruction_t *insn, Function_t *func)
 	{
 		DISASM d;
 		prev->Disassemble(d);
-		if(strstr(d.CompleteInstr,"ret")!=NULL) // return ret.
+		if(strstr(d.CompleteInstr,"ret ")!=NULL) // return ret.
 			return prev;
 		return NULL; // indirect branch 
 	}
@@ -1270,6 +1097,18 @@ void PNTransformDriver::SanitizeFunctions()
 			      continue;
 			    }    
 			}
+			// if it's not already sanitized
+			if(sanitized.find(func)==sanitized.end())
+			{
+				if(instr->GetEhCallSite() && 
+				   instr->GetEhCallSite()->GetLandingPad() && 
+				   instr->GetEhCallSite()->GetLandingPad()->GetFunction()!=func) 
+				{
+			      		eh_sanitized++;
+					sanitized.insert(func);
+					continue;
+				}
+			}
 		}
 
 		// if it's not already sanitized
@@ -1294,7 +1133,6 @@ void PNTransformDriver::SanitizeFunctions()
 				continue;
 			}
 		}
-
 	}
 	//TODO: print sanitized list. 
 
@@ -2024,6 +1862,7 @@ void PNTransformDriver::Print_Report()
 	cerr<<"Blacklisted Functions \t\t"<<blacklist_funcs<<endl;
 	cerr<<"Sanitized Functions \t\t"<<sanitized_funcs<<endl;
 	cerr<<"Push/Pop Sanitized Functions \t\t"<<push_pop_sanitized_funcs<<endl;
+	cerr<<"EH-land-pad-not-in-func Sanitized Functions \t\t"<<eh_sanitized<<endl;
 	cerr<<"Bad Variadic Sanitized Functions \t\t"<<push_pop_sanitized_funcs<<endl;
 	cerr<<"Jump table Sanitized Functions \t\t"<<jump_table_sanitized<<endl;
 	cerr<<"PIC Jump table Sanitized Functions \t\t"<<jump_table_sanitized<<endl;
@@ -2435,6 +2274,10 @@ bool PNTransformDriver::Canary_Rewrite(PNStackLayout *orig_layout, Function_t *f
 	orig_layout->SetBaseID(func->GetBaseID());
 	orig_layout->SetEntryID(func->GetEntryPoint()->GetBaseID());
 
+	EhUpdater_t eh_update(orig_virp, func, layout);
+	if(!eh_update.execute())
+		return false;
+
 	return true;
 }
 
@@ -2464,6 +2307,9 @@ bool PNTransformDriver::Sans_Canary_Rewrite(PNStackLayout *layout, Function_t *f
 		if(!Instruction_Rewrite(layout,instr,&cfg))
 			return false;
 	}
+	EhUpdater_t eh_update(orig_virp, func, layout);
+	if(!eh_update.execute())
+		return false;
 
 	return true;
 }
@@ -3110,6 +2956,7 @@ void PNTransformDriver::undo(Function_t *func)
 	{
 		orig_virp->UnregisterAssembly(*it);
 		orig_virp->GetInstructions().erase(*it);
+		func->GetInstructions().erase(*it);
 		delete *it;
 	}
 
diff --git a/tools/transforms/PNTransformDriver.hpp b/tools/transforms/PNTransformDriver.hpp
index d57d5b098c7e3ecb68b0934966528f8bafadb204..acc41b3648008661a7c3d9cdfc8b20ffaf418db6 100644
--- a/tools/transforms/PNTransformDriver.hpp
+++ b/tools/transforms/PNTransformDriver.hpp
@@ -89,6 +89,7 @@ class PNTransformDriver
 	int bad_variadic_func_sanitized;
 	int jump_table_sanitized;
   	int pic_jump_table_sanitized;
+  	int eh_sanitized;
     	int total_funcs;
 	int dynamic_frames;
     	std::vector<std::string> not_transformable;
@@ -131,7 +132,7 @@ class PNTransformDriver
 
     	virtual void Print_Report();
     	virtual void Print_Map();
-    	virtual bool CanaryTransformHandler(PNStackLayout *layout, libIRDB::Function_t *func,bool validate);
+//    	virtual bool CanaryTransformHandler(PNStackLayout *layout, libIRDB::Function_t *func,bool validate);
     	virtual bool PaddingTransformHandler(PNStackLayout *layout, libIRDB::Function_t *func,bool validate);
     	virtual bool LayoutRandTransformHandler(PNStackLayout *layout, libIRDB::Function_t *func, bool validate);
     	virtual void GenerateTransformsInit();
diff --git a/tools/transforms/Rewrite_Utility.cpp b/tools/transforms/Rewrite_Utility.cpp
index 957333fb091d42cdeb3ee72e5704c4f5101f7645..69315e901c91c1b23eacaca79a1c8fa367875f3c 100644
--- a/tools/transforms/Rewrite_Utility.cpp
+++ b/tools/transforms/Rewrite_Utility.cpp
@@ -137,6 +137,8 @@ void copyInstruction(Instruction_t* src, Instruction_t* dest)
 	dest->SetTarget(src->GetTarget());
 	dest->SetIBTargets(src->GetIBTargets()); 
 	dest->GetRelocations()=src->GetRelocations();
+	dest->SetEhProgram(src->GetEhProgram());
+	dest->SetEhCallSite(src->GetEhCallSite());
 }
 
 Instruction_t* allocateNewInstruction(FileIR_t* virp, db_id_t p_fileID,Function_t* func)
@@ -356,6 +358,7 @@ Instruction_t* getHandlerCode(FileIR_t* virp, Instruction_t* fallthrough, mitiga
 
 Instruction_t* insertCanaryCheckBefore(FileIR_t* virp,Instruction_t *first, unsigned int canary_val, int esp_offset, Instruction_t *fail_code)
 {
+	auto do_zero=(first->getDisassembly().find("ret")!=string::npos);
 	stringstream ss;
 	const char *sp_reg="esp";
 	if(virp->GetArchitectureBitWidth()==64)
@@ -387,7 +390,9 @@ Instruction_t* insertCanaryCheckBefore(FileIR_t* virp,Instruction_t *first, unsi
 	//TODO: move canary zero to option 
 	if(esp_neg)
 		esp_offset *= -1;
-	insertCanaryZeroAfter(virp,first,esp_offset,fail_code); 
+
+	if(do_zero)
+		insertCanaryZeroAfter(virp,first,esp_offset,fail_code); 
 
 	return next;
 
diff --git a/tools/transforms/SConscript b/tools/transforms/SConscript
index bd3b7da4bfc02515670cc4ead7d587541996258b..9b49aec67392439a25ad44af02faf3b9b1be963e 100644
--- a/tools/transforms/SConscript
+++ b/tools/transforms/SConscript
@@ -6,9 +6,6 @@ myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME'])
 
 
 libname="IRDB-util"
-files=  '''
-	insn_preds.cpp
-	'''
 cpppath=''' 
 	$SECURITY_TRANSFORMS_HOME/include/
 	$SECURITY_TRANSFORMS_HOME/libIRDB/include/
@@ -28,7 +25,9 @@ integer_files="transformutils.cpp integertransformdriver.cpp"
 #myenv.Append(CFLAGS="-Wall")
 #myenv.Append(CCFLAGS="-Wall")
 
-all_files="PNTransformDriver.cpp PNStackLayout.cpp PNRange.cpp Range.cpp OffsetInference.cpp DirectOffsetInference.cpp ScaledOffsetInference.cpp P1Inference.cpp PNRegularExpressions.cpp PNMain.cpp StackLayout.cpp General_Utility.cpp AnnotationBoundaryGenerator.cpp PrecedenceBoundaryInference.cpp PNIrdbManager.cpp"
+myenv.Append(CXXFLAGS = " -std=c++11 ")
+
+all_files="PNTransformDriver.cpp PNStackLayout.cpp PNRange.cpp Range.cpp OffsetInference.cpp DirectOffsetInference.cpp ScaledOffsetInference.cpp P1Inference.cpp PNRegularExpressions.cpp PNMain.cpp StackLayout.cpp General_Utility.cpp AnnotationBoundaryGenerator.cpp PrecedenceBoundaryInference.cpp PNIrdbManager.cpp EhUpdater.cpp"
 
 
 myenv=myenv.Clone(CPPPATH=Split(cpppath))