diff --git a/include/ehwrite.h b/include/ehwrite.h
index 4c909149388d24850e2a8a8a9ec28ab27926b93c..63e4b0ef2fcb00e2908360071b6ed04114b74a8c 100644
--- a/include/ehwrite.h
+++ b/include/ehwrite.h
@@ -1,5 +1,5 @@
-#ifndef ElfWriter_h
-#define ElfWriter_h
+#ifndef EhWriter_h
+#define EhWriter_h
 
 #include <iostream>
 
diff --git a/include/elfwrite.h b/include/elfwrite.h
index b3d176d89f5221f68f3c6a72065e2105f94b7ebd..4025208c018c38733725b3dfa85af9c38023baa4 100644
--- a/include/elfwrite.h
+++ b/include/elfwrite.h
@@ -1,15 +1,15 @@
 
-#ifndef EhWriter_h
-#define EhWriter_h
+#ifndef ElfWriter_h
+#define ElfWriter_h
 
 #include <vector>
 #include <map>
 
-
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
 #endif
 
+
 class ElfWriter
 {
 	protected: 
diff --git a/include/pewrite.h b/include/pewrite.h
new file mode 100644
index 0000000000000000000000000000000000000000..92b551d3d44806289ec951fa703974a7afdb801f
--- /dev/null
+++ b/include/pewrite.h
@@ -0,0 +1,50 @@
+
+#ifndef PeWriter_h
+#define PeWriter_h
+
+#include <vector>
+#include <map>
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+
+
+class PeWriter
+{
+	public: 
+		PeWriter(IRDB_SDK::FileIR_t* firp, bool write_sections, bool bss_opts) : m_firp(firp), m_write_sections(write_sections), m_bss_opts(bss_opts) { }
+		virtual ~PeWriter() {}
+		void Write(const EXEIO::exeio *exeiop, const std::string &out_file, const std::string &infile);
+
+	protected:
+
+		FileIR_t* m_firp=nullptr;
+		bool m_write_sections=false;
+		bool m_bss_opts=false;
+
+
+
+		
+};
+
+
+// 
+
+
+template <int bitwidth>
+class PeWriterImpl : public PeWriter
+{
+	public:
+		PeWriterImpl(IRDB_SDK::FileIR_t* firp, bool write_sections, bool bss_opts) 
+			: PeWriter(firp,write_sections,bss_opts)
+		{
+		}
+};
+
+using PeWriter64 = PeWriterImpl<64>;
+
+
+
+#endif
+
diff --git a/include/zipr_all.h b/include/zipr_all.h
index eacb5068e636acc0245af3040941d7207138a276..63831e4fb0cbe71bc56405596993f66eee3f1594 100644
--- a/include/zipr_all.h
+++ b/include/zipr_all.h
@@ -41,6 +41,7 @@
 #include <algorithm>
 #include <memory>
 
+#include "exeio.h"
 
 #pragma GCC diagnostic ignored "-Wsign-compare"
 #include "elfio/elfio.hpp"
@@ -79,6 +80,7 @@ namespace zipr
 #include <zipr_optimizations.h>
 #include <zipr_stats.h>
 #include <elfwrite.h>
+#include <pewrite.h>
 #include <ehwrite.h>
 
 };
diff --git a/include/zipr_impl.h b/include/zipr_impl.h
index 163b720ba4518a651b0bedfb0bb078df9a24d06e..f8193cde3d17f91ed9ba9a2c91b70ecb576a9a3b 100644
--- a/include/zipr_impl.h
+++ b/include/zipr_impl.h
@@ -84,7 +84,7 @@ class ZiprImpl_t : public Zipr_t
 			lo(nullptr),
 			m_error(false),
 			m_dollop_mgr(this),
-			elfiop(new ELFIO::elfio), 
+			exeiop(new EXEIO::exeio), 
 			start_of_new_space(0),
 			memory_space(),
 			m_zipr_options(argc-1, argv+1)
@@ -181,7 +181,7 @@ class ZiprImpl_t : public Zipr_t
                 virtual Zipr_SDK::MemorySpace_t *getMemorySpace() { return &memory_space; }
                 virtual Zipr_SDK::MemorySpace_t *GetMemorySpace() { return &memory_space; }
 		virtual Zipr_SDK::DollopManager_t *getDollopManager() { return &m_dollop_mgr; }
-                virtual ELFIO::elfio *getELFIO() { return elfiop; }
+                virtual EXEIO::exeio *getEXEIO() { return exeiop; }
                 virtual IRDB_SDK::FileIR_t *getFileIR() { return m_firp; }
                 virtual Zipr_SDK::InstructionLocationMap_t *getLocationMap() { return &final_insn_locations; }
                 virtual Zipr_SDK::InstructionLocationMap_t *GetLocationMap() { return &final_insn_locations; }
@@ -207,7 +207,7 @@ class ZiprImpl_t : public Zipr_t
 		 *
 		 * Input: Nothing
 		 * Output: Nothing
-		 * Uses: elfio
+		 * Uses: exeio
 		 * Effects: memory_space
 		 *
 		 * Adds available memory ranges to memory space.
@@ -218,7 +218,7 @@ class ZiprImpl_t : public Zipr_t
 		/* 
 		 * Input: A map of section addresses to integers in order of address
 		 * Output:  A new scoop with RX perms for each allocatable/executable series-of-segments.
-		 * Uses: elfio
+		 * Uses: exeio
 		 * Effects: IRDB_SDK IR.
  	         *
 		 * Creates a scoop for the executable instructions in the IR.
@@ -355,10 +355,10 @@ class ZiprImpl_t : public Zipr_t
 		void CallToNop(RangeAddress_t at_addr);
 
 		// outputing new .exe
-		void FillSection(ELFIO::section* sec, FILE* fexe);
+		void FillSection(EXEIO::section* sec, FILE* fexe);
 		void OutputBinaryFile(const std::string &name);
 		IRDB_SDK::DataScoop_t* FindScoop(const RangeAddress_t &addr);
-		void WriteScoop(ELFIO::section* sec, std::FILE* fexe);
+		void WriteScoop(EXEIO::section* sec, std::FILE* fexe);
 
 
 		// helpers.
@@ -368,7 +368,7 @@ class ZiprImpl_t : public Zipr_t
 		RangeAddress_t FindCallbackAddress(RangeAddress_t end_of_new_space,RangeAddress_t start_addr, const std::string &callback);
 
 		// support
-		RangeAddress_t extend_section(ELFIO::section *sec,ELFIO::section *next_sec);
+		RangeAddress_t extend_section(EXEIO::section *sec,EXEIO::section *next_sec);
 
 		void dump_scoop_map();
 		void dump_instruction_map();
@@ -407,7 +407,7 @@ class ZiprImpl_t : public Zipr_t
 		std::map<std::string,RangeAddress_t> callback_addrs;
 
 		// way to read elf headers, etc.
-		ELFIO::elfio*    elfiop;
+		EXEIO::exeio*    exeiop;
 
 		// records where we will insert extra bytes into the program.
 		RangeAddress_t start_of_new_space;
diff --git a/src/SConscript b/src/SConscript
index c0979f7c0ee5d1b8dd4568454f5a22ad90a41ff1..515ca2d5125f9eecb6b9a93f0e309939f1fb2118 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -23,6 +23,7 @@ files=  '''
 	dollop.cpp
 	zipr_dollop_man.cpp
 	elfwrite.cpp
+	pewrite.cpp
 	ehwrite.cpp
 	arch_base.cpp
 	pinner_arm64.cpp  
@@ -41,6 +42,7 @@ files=  '''
 cpppath=''' 
 	.
 	$SECURITY_TRANSFORMS_HOME/third_party/elfio-code
+	$SECURITY_TRANSFORMS_HOME/libEXEIO/include
 	$IRDB_SDK//include/
 	$ZIPR_HOME/include/
 	$ZIPR_SDK/include/
diff --git a/src/ehwrite.cpp b/src/ehwrite.cpp
index 1c730db5906e907491e25364cfd6bf4c2b3291b3..65b82543ccb9bdefce386776aa710a21d22bf6cb 100644
--- a/src/ehwrite.cpp
+++ b/src/ehwrite.cpp
@@ -16,13 +16,12 @@
 
 #include <zipr_dwarf2.hpp>
 
-#include "elfio/elfio.hpp"
-#include "elfio/elfio_dump.hpp"
+#include "exeio.h"
 
 using namespace IRDB_SDK;
 using namespace std;
 using namespace zipr;
-using namespace ELFIO;
+using namespace EXEIO;
 
 template < typename T > std::string to_hex_string( const T& n )
 {
@@ -1354,12 +1353,12 @@ void EhWriterImpl_t<ptrsize>::CompileEhOutput()
 template<int ptrsize>
 void EhWriterImpl_t<ptrsize>::ScoopifyEhOutput()
 {
-        ELFIO::elfio ehframe_exe_elfio;
-	ehframe_exe_elfio.load(ehframe_exe_filename);
+        EXEIO::exeio ehframe_exe_rep;
+	ehframe_exe_rep.load(ehframe_exe_filename);
 
 	auto to_scoop=[&](const string &secname)->void
 	{
-		const auto &sec=ehframe_exe_elfio.sections[secname];
+		const auto &sec=ehframe_exe_rep.sections[secname];
 
 		// if sec is missing, don't scoopify.
 
diff --git a/src/patcher_arm64.cpp b/src/patcher_arm64.cpp
index fd3b24dab1b2c82409fe8b3e3b1981b58ebaf83b..7b07fe4e7c23c19bfdb246e17472da18d64c04e9 100644
--- a/src/patcher_arm64.cpp
+++ b/src/patcher_arm64.cpp
@@ -45,15 +45,11 @@ namespace zipr
 #include <string>     // std::string, std::to_string
 #include <fstream>
 
-#include "elfio/elfio.hpp"
-#include "elfio/elfio_dump.hpp"
-
 #define ALLOF(a) begin(a),end(a)
 
 using namespace IRDB_SDK;
 using namespace std;
 using namespace zipr;
-using namespace ELFIO;
 
 ZiprPatcherARM64_t::ZiprPatcherARM64_t(Zipr_SDK::Zipr_t* p_parent) :
 	m_parent(dynamic_cast<zipr::ZiprImpl_t*>(p_parent)),     // upcast to ZiprImpl
diff --git a/src/patcher_base.cpp b/src/patcher_base.cpp
index c4fded78237d5e57661339985b0db579568f52cf..769a01f9e7a98f2f73ec538d0c37110a7849e9e2 100644
--- a/src/patcher_base.cpp
+++ b/src/patcher_base.cpp
@@ -48,15 +48,11 @@ namespace zipr
 #include <string>     // std::string, std::to_string
 #include <fstream>
 
-#include "elfio/elfio.hpp"
-#include "elfio/elfio_dump.hpp"
-
 #define ALLOF(a) begin(a),end(a)
 
 using namespace IRDB_SDK;
 using namespace std;
 using namespace zipr;
-using namespace ELFIO;
 
 unique_ptr<ZiprPatcherBase_t> ZiprPatcherBase_t::factory(Zipr_SDK::Zipr_t* p_parent)
 {
diff --git a/src/patcher_x86.cpp b/src/patcher_x86.cpp
index 9eac960c46e9da91404745521ea76169edbd9c48..550b83f0b067b483acf3dde2c767259d0f7fd977 100644
--- a/src/patcher_x86.cpp
+++ b/src/patcher_x86.cpp
@@ -45,15 +45,11 @@ namespace zipr
 #include <string>     // std::string, std::to_string
 #include <fstream>
 
-#include "elfio/elfio.hpp"
-#include "elfio/elfio_dump.hpp"
-
 #define ALLOF(a) begin(a),end(a)
 
 using namespace IRDB_SDK;
 using namespace std;
 using namespace zipr;
-using namespace ELFIO;
 
 ZiprPatcherX86_t::ZiprPatcherX86_t(Zipr_SDK::Zipr_t* p_parent) :
 	m_parent(dynamic_cast<zipr::ZiprImpl_t*>(p_parent)),     // upcast to ZiprImpl
diff --git a/src/pewrite.cpp b/src/pewrite.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5d9395e5ec8786eea6a1128d4fddeaf864d6c424
--- /dev/null
+++ b/src/pewrite.cpp
@@ -0,0 +1,41 @@
+
+#include <zipr_all.h>
+#include <irdb-core>
+#include <iostream>
+#include <stdlib.h>
+#include <string.h>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <sys/mman.h>
+#include <ctype.h>
+#include <iostream>   
+#include <string>     
+#include <fstream>
+#include <elf.h>
+
+
+using namespace IRDB_SDK;
+using namespace std;
+using namespace zipr;
+using namespace EXEIO;
+
+
+static inline uintptr_t page_round_down(uintptr_t x)
+{
+        return x & (~(PAGE_SIZE-1));
+}
+static inline uintptr_t page_round_up(uintptr_t x)
+{
+        return  ( (((uintptr_t)(x)) + PAGE_SIZE-1)  & (~(PAGE_SIZE-1)) );
+}
+
+
+
+void PeWriter::Write(const EXEIO::exeio *exeiop, const string &out_file, const string &infile)
+{
+
+	assert(0); // to do 
+
+}
+
diff --git a/src/pinner_x86.cpp b/src/pinner_x86.cpp
index b7b8c07d840b69292fbf8b8ada6e4c78928d0157..f88e9dd3fa49e1bdefd1e288ce7c0618d832ab9b 100644
--- a/src/pinner_x86.cpp
+++ b/src/pinner_x86.cpp
@@ -327,7 +327,7 @@ void ZiprPinnerX86_t::PreReserve2ByteJumpTargets()
 							(void*)(uintptr_t)upinsn->getIndirectBranchTargetAddress()->getVirtualOffset() : 0x0);
 
 						up.SetRange(Range_t(addr+i, addr+i+size));
-						for (unsigned int j = up.GetRange().getStart(); j<up.GetRange().getEnd(); j++)
+						for (auto j = up.GetRange().getStart(); j<up.GetRange().getEnd(); j++)
 						{
 							memory_space.splitFreeRange(j);
 						}
@@ -469,7 +469,7 @@ void ZiprPinnerX86_t::InsertJumpPoints68SledArea(Sled_t &sled)
 Instruction_t* ZiprPinnerX86_t::Emit68Sled(RangeAddress_t addr, Sled_t sled, Instruction_t* next_sled)
 {
 	Instruction_t *sled_start_insn = nullptr;
-	unsigned int sled_number = addr - sled.SledRange().getStart();
+	auto sled_number = addr - sled.SledRange().getStart();
 	size_t sled_size = sled.SledRange().getEnd() - sled.SledRange().getStart();
 
 	sled_start_insn = FindPinnedInsnAtAddr(addr);
@@ -935,17 +935,12 @@ void ZiprPinnerX86_t::ReservePinnedInstructions()
 	/* first, for each pinned instruction, try to 
 	 * put down a jump for the pinned instruction
  	 */
-	for(
-		set<UnresolvedPinned_t,pin_sorter_t>::const_iterator it=unresolved_pinned_addrs.begin();
-		it!=unresolved_pinned_addrs.end();
-		++it
-		)
+	for( auto it=unresolved_pinned_addrs.begin(); it!=unresolved_pinned_addrs.end(); ++it)
 	{
 		char bytes[]={(char)0xeb,(char)0}; // jmp rel8
 		UnresolvedPinned_t up=*it;
-		Instruction_t* upinsn=up.getInstrution();
-		RangeAddress_t addr=(unsigned)upinsn->getIndirectBranchTargetAddress()
-		                                    ->getVirtualOffset();
+		const auto upinsn=up.getInstrution();
+		auto addr=upinsn->getIndirectBranchTargetAddress()->getVirtualOffset();
 
 		if(upinsn->getIndirectBranchTargetAddress()->getFileID() ==
 		   BaseObj_t::NOT_IN_DATABASE)
@@ -962,7 +957,7 @@ void ZiprPinnerX86_t::ReservePinnedInstructions()
 			if (m_verbose)
 				printf("Final pinning %p-%p.  fid=%d\n", (void*)addr, (void*)(addr+upinsn->getDataBits().size()-1),
 				upinsn->getAddress()->getFileID());
-			for(unsigned int i=0;i<upinsn->getDataBits().size();i++)
+			for(auto i=0u;i<upinsn->getDataBits().size();i++)
 			{
 				memory_space[addr+i]=upinsn->getDataBits()[i];
 				memory_space.splitFreeRange(addr+i);
@@ -995,7 +990,7 @@ void ZiprPinnerX86_t::ReservePinnedInstructions()
 			 * Assert that the space is free.  We already checked that it should be 
 			 * with the FindPinnedInsnAtAddr, but just to be safe.
 			 */
-			for(unsigned int i=0;i<sizeof(bytes);i++)
+			for(auto i=0u;i<sizeof(bytes);i++)
 			{
 				assert(memory_space.find(addr+i) == memory_space.end() );
 				memory_space[addr+i]=bytes[i];
@@ -1064,7 +1059,7 @@ void ZiprPinnerX86_t::ReservePinnedInstructions()
 			addr += sizeof(push_bytes);
 
 			// reserve the bytes for the jump at the end of the push.
-			for(unsigned int i=0;i<sizeof(bytes);i++)
+			for(auto i=0u;i<sizeof(bytes);i++)
 			{
 				assert(memory_space.find(addr+i) == memory_space.end() );
 				memory_space[addr+i]=bytes[i];
@@ -1113,16 +1108,15 @@ void ZiprPinnerX86_t::ReservePinnedInstructions()
 		// After we resync, we have to inspect the TOS elements to see which instruction we jumped to.
 		else if (FindPinnedInsnAtAddr(addr+1))
 		{
-			RangeAddress_t end_of_sled=Do68Sled(addr);
+			const auto end_of_sled=Do68Sled(addr);
 
 			// skip over some entries until we get passed the sled.
 			while (true)
 			{
 				// get this entry
-				UnresolvedPinned_t up=*it;
-				Instruction_t* upinsn=up.getInstrution();
-				RangeAddress_t addr=(unsigned)upinsn->getIndirectBranchTargetAddress()
-		                                    ->getVirtualOffset();
+				const auto up=*it;
+				const auto upinsn=up.getInstrution();
+				auto addr=upinsn->getIndirectBranchTargetAddress() ->getVirtualOffset();
 
 				// is the entry within the sled?
 				if(addr>=end_of_sled)
@@ -1211,7 +1205,7 @@ void ZiprPinnerX86_t::ExpandPinnedInstructions()
 			/*
 			 * Unreserve those bytes that we reserved before!
 			 */
-			for (unsigned int j = up.GetRange().getStart(); j<up.GetRange().getEnd(); j++)
+			for (auto j = up.GetRange().getStart(); j<up.GetRange().getEnd(); j++)
 			{
 				if (!m_AddrInSled[j])
 					memory_space.mergeFreeRange(j);
@@ -1286,7 +1280,7 @@ void ZiprPinnerX86_t::Fix2BytePinnedInstructions()
 			 */
 			if (up.HasRange())
 			{
-				for (unsigned int j = up.GetRange().getStart(); j<up.GetRange().getEnd(); j++)
+				for (auto j = up.GetRange().getStart(); j<up.GetRange().getEnd(); j++)
 				{
 					if (!m_AddrInSled[j])
 						memory_space.mergeFreeRange(j);
@@ -1303,7 +1297,7 @@ void ZiprPinnerX86_t::Fix2BytePinnedInstructions()
 			 * Do this here because some/most of the algorithms
 			 * that we use below assume that it is unreserved.
 			 */
-			for (unsigned int j = up.GetRange().getStart(); j<up.GetRange().getEnd(); j++)
+			for (auto j = up.GetRange().getStart(); j<up.GetRange().getEnd(); j++)
 			{
 				if (!m_AddrInSled[j])
 					memory_space.mergeFreeRange(j);
diff --git a/src/zipr.cpp b/src/zipr.cpp
index 623f1f9e12ff5afb5e5142dbe69a23c6a615835b..3f658f1334f3923fe636823363425c919eec76cf 100644
--- a/src/zipr.cpp
+++ b/src/zipr.cpp
@@ -41,15 +41,12 @@
 #include <string>     // std::string, std::to_string
 #include <fstream>
 
-#include "elfio/elfio.hpp"
-#include "elfio/elfio_dump.hpp"
-
 #define ALLOF(a) begin(a),end(a)
 
 using namespace IRDB_SDK;
 using namespace std;
 using namespace zipr;
-using namespace ELFIO;
+using namespace EXEIO;
 using namespace Zipr_SDK;
 
 
@@ -184,8 +181,7 @@ void ZiprImpl_t::registerOptions()
 
 void ZiprImpl_t::CreateBinaryFile()
 {
-	elfiop->load("a.ncexe");
-	ELFIO::dump::section_headers(cout,*elfiop);
+	exeiop->load("a.ncexe");
 
 	if (*m_architecture == 0)
 	{
@@ -260,13 +256,14 @@ void ZiprImpl_t::CreateBinaryFile()
 	PrintStats();
 }
 
-static bool in_same_segment(ELFIO::section* sec1, ELFIO::section* sec2, ELFIO::elfio* elfiop)
+#if 0
+static bool in_same_segment(EXEIO::section* sec1, EXEIO::section* sec2, EXEIO::exeio* exeiop)
 {
-	ELFIO::Elf_Half n = elfiop->segments.size();
-	for ( ELFIO::Elf_Half i = 0; i < n; ++i ) 
+	auto n = exeiop->segments.size();
+	for ( auto i = 0; i < n; ++i ) 
 	{
-		uintptr_t segstart=elfiop->segments[i]->get_virtual_address();
-		uintptr_t segsize=elfiop->segments[i]->get_file_size();
+		uintptr_t segstart=exeiop->segments[i]->get_virtual_address();
+		uintptr_t segsize=exeiop->segments[i]->get_file_size();
 
 		/* sec1 in segment i? */
 		if(segstart <= sec1->get_address() && sec1->get_address() < (segstart+segsize))
@@ -279,13 +276,16 @@ static bool in_same_segment(ELFIO::section* sec1, ELFIO::section* sec2, ELFIO::e
 
 	return false;
 }
+#endif
 
 
 //
 // check if there's padding we can use between this section and the next section.
 //
-RangeAddress_t ZiprImpl_t::extend_section(ELFIO::section *sec, ELFIO::section *next_sec)
+RangeAddress_t ZiprImpl_t::extend_section(EXEIO::section *sec, EXEIO::section *next_sec)
 {
+	assert(0);
+#if 0
 	RangeAddress_t start=sec->get_address();
 	RangeAddress_t end=sec->get_size()+start;
 	if( (next_sec->get_flags() & SHF_ALLOC) != 0 && in_same_segment(sec,next_sec,elfiop))
@@ -295,6 +295,7 @@ RangeAddress_t ZiprImpl_t::extend_section(ELFIO::section *sec, ELFIO::section *n
 		sec->set_size(next_sec->get_address() - sec->get_address() - 1);
 	}
 	return end;
+#endif
 }
 
 void ZiprImpl_t::CreateExecutableScoops(const std::map<RangeAddress_t, int> &ordered_sections)
@@ -305,22 +306,18 @@ void ZiprImpl_t::CreateExecutableScoops(const std::map<RangeAddress_t, int> &ord
 	 */
 	for(auto it = ordered_sections.begin(); it!=ordered_sections.end();  /* empty */ ) 
 	{
-		section* sec = elfiop->sections[it->second];
+		auto sec = exeiop->sections[it->second];
 		assert(sec);
 
 		// skip non-exec and non-alloc sections.
-		if( (sec->get_flags() & SHF_ALLOC) ==0 || (sec->get_flags() & SHF_EXECINSTR) ==0 )
+		// if( (sec->get_flags() & SHF_ALLOC) ==0 || (sec->get_flags() & SHF_EXECINSTR) ==0 )
+		if(!sec->isLoadable() || !sec->isExecutable())
 		{
 			++it;
 			continue;
 		}
 
 		// setup start of scoop.
-		/*
-		AddressID_t *text_start=new AddressID_t();
-		text_start->setVirtualOffset(sec->get_address());
-		m_firp->getAddresses().insert(text_start);
-		*/
 		auto text_start=m_firp->addNewAddress(m_firp->getFile()->getBaseID(), sec->get_address());
 
 		/*
@@ -329,16 +326,18 @@ void ZiprImpl_t::CreateExecutableScoops(const std::map<RangeAddress_t, int> &ord
 		 */
 		while(1)
 		{
-			sec = elfiop->sections[it->second];
+			sec = exeiop->sections[it->second];
 
 			// skip non-alloc sections.
-			if( (sec->get_flags() & SHF_ALLOC) ==0)
+			// if( (sec->get_flags() & SHF_ALLOC) ==0)
+			if(!sec->isLoadable())
 			{
 				++it;
 				continue;
 			}
 			// stop if not executable.
-			if( (sec->get_flags() & SHF_EXECINSTR) ==0 )
+			// if( (sec->get_flags() & SHF_EXECINSTR) ==0 )
+			if(!sec->isExecutable())
 				break;
 
 			// try next 
@@ -447,10 +446,10 @@ void ZiprImpl_t::FindFreeRanges(const std::string &name)
 	 * Make an ordered list of the sections
 	 * by their starting address.
 	 */
-	ELFIO::Elf_Half n = elfiop->sections.size();
-	for ( ELFIO::Elf_Half i = 0; i < n; ++i ) 
+	auto n = exeiop->sections.size();
+	for ( auto i = 0; i < n; ++i ) 
 	{ 
-		section* sec = elfiop->sections[i];
+		auto sec = exeiop->sections[i];
 		assert(sec);
 		ordered_sections.insert(std::pair<RangeAddress_t,int>(sec->get_address(), i));
 	}
@@ -460,7 +459,7 @@ void ZiprImpl_t::FindFreeRanges(const std::string &name)
 	// scan sections for a max-addr.
 	for (auto p : ordered_sections )
 	{ 
-		section* sec = elfiop->sections[p.second];
+		section* sec = exeiop->sections[p.second];
 		assert(sec);
 
 		RangeAddress_t start=sec->get_address();
@@ -476,7 +475,8 @@ void ZiprImpl_t::FindFreeRanges(const std::string &name)
 			max_addr=end;
 		}
 
-		if( (sec->get_flags() & SHF_ALLOC) ==0 )
+		// if( (sec->get_flags() & SHF_ALLOC) ==0 )
+		if(!sec->isLoadable())	
 			continue;
 	}
 
@@ -1905,29 +1905,45 @@ void ZiprImpl_t::OutputBinaryFile(const string &name)
 	// re-generate the eh information.
 	RelayoutEhInfo(); 
 
+	const auto file_type = m_firp->getArchitecture()->getFileType();
+	const auto is_elf    = file_type == IRDB_SDK::adftELFEXE || file_type ==  IRDB_SDK::adftELFSO;
+	const auto is_pe     = file_type == IRDB_SDK::adftPE;
+	const auto bit_width = m_firp->getArchitectureBitWidth();
+	const auto output_filename="c.out";
 
-	// create the output file in a totally different way using elfwriter. later we may 
-	// use this instead of the old way.
-
-
-	string elfwriter_filename="c.out";
-	ElfWriter *ew=nullptr;
-	if(m_firp->getArchitectureBitWidth()==64)
+	if(is_elf)
 	{
-		ew=new ElfWriter64(m_firp, *m_add_sections, *m_bss_opts);
+		// create the output file in a totally different way using elfwriter. later we may 
+		// use this instead of the old way.
+
+		auto elfiop=reinterpret_cast<ELFIO::elfio*>(exeiop->get_elfio());
+		auto ew=unique_ptr<ElfWriter>();
+		ew.reset(
+			bit_width == 64 ? (ElfWriter*)new ElfWriter64(m_firp, *m_add_sections, *m_bss_opts) :
+			bit_width == 32 ? (ElfWriter*)new ElfWriter32(m_firp, *m_add_sections, *m_bss_opts) :
+			throw invalid_argument("Unknown machine width")
+			);
+		ew->Write(elfiop,m_firp, output_filename, "a.ncexe");
+		ew.reset(nullptr); // explicitly free ew as we're done with it
 	}
-	else if(m_firp->getArchitectureBitWidth()==32)
+	else if (is_pe)
 	{
-		ew=new ElfWriter32(m_firp, *m_add_sections, *m_bss_opts);
+		assert(m_firp->getArchitectureBitWidth()==64);
+		auto pe_write=new PeWriter64(m_firp, *m_add_sections, *m_bss_opts);
+		pe_write->Write(exeiop,output_filename, "a.ncexe");
+	}
+	else
+	{
+		cout << "Cannot create output file of correct type " << endl;
+		assert(0); 
+		abort(); 
 	}
-	else assert(0);
 
-	ew->Write(elfiop,m_firp,elfwriter_filename, "a.ncexe");
-	delete ew;
-	string chmod_cmd=string("chmod +x "); 
-	chmod_cmd=chmod_cmd+elfwriter_filename;
+	// change permissions on output file
+	auto chmod_cmd=string("chmod +x ")+output_filename;
 	auto res=system(chmod_cmd.c_str());
 	assert(res!=-1);
+
 }
 
 
diff --git a/test/SConscript b/test/SConscript
index cf39dd3fa42bc2ce562a58c12fb2dc78bf35bdb4..0770eca4f87e28175d3dfce686ddc6df4ca6db0c 100644
--- a/test/SConscript
+++ b/test/SConscript
@@ -42,6 +42,7 @@ DollopFiles= '''
 cpppath=''' 
 	.
 	$SECURITY_TRANSFORMS_HOME/third_party/elfio-code/
+	$SECURITY_TRANSFORMS_HOME/libEXEIO/include
 	$IRDB_SDK/include/
 	$ZIPR_HOME/include/
 	$ZIPR_SDK/include/