From e2196996f9e6866f78677f5261bc28aae29aa561 Mon Sep 17 00:00:00 2001
From: jdh8d <jdh8d@git.zephyr-software.com>
Date: Mon, 25 Nov 2013 22:04:02 +0000
Subject: [PATCH] Former-commit-id: 8627527a2844dfd9337db603e8d38fc9dcb88e79

---
 .gitattributes                    |   1 +
 Makefile                          |   1 +
 appfw/src/Makefile                |   4 +-
 appfw/src/appfw.cpp               |  28 ++++-
 appfw/src/osc_hook.c              |   5 +-
 libIRDB/test/Makefile             |  14 ++-
 libIRDB/test/fill_in_cfg.cpp      |  64 +++++------
 libIRDB/test/fill_in_indtargs.cpp |  96 ++++++++--------
 libIRDB/test/find_strings.cpp     | 175 +++++++++++++++++-------------
 libIRDB/test/read_ehframe.cpp     |  68 ++++--------
 third_party/elfio.patch           | 131 ++++++++++++++++++++++
 11 files changed, 365 insertions(+), 222 deletions(-)
 create mode 100644 third_party/elfio.patch

diff --git a/.gitattributes b/.gitattributes
index 875be3c2a..8969d62ce 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -301,6 +301,7 @@ third_party/beaengine166.tar.gz -text
 third_party/beaengine175.tar.gz -text
 third_party/do_bea_update.sh -text
 third_party/elfio-2.2.tar.gz -text
+third_party/elfio.patch -text
 third_party/sqlite-autoconf-3071300.tar.gz -text
 tools/Makefile -text
 tools/cover/Makefile -text
diff --git a/Makefile b/Makefile
index 5789a389e..d53c1ebeb 100644
--- a/Makefile
+++ b/Makefile
@@ -30,6 +30,7 @@ elfio: 	third_party/elfio-2.2.tar.gz
 	cd $(ELFIO_DIR); if [ ! -f Makefile ]; then ./configure --prefix=${SECURITY_TRANSFORMS_HOME};  fi; 
 	cd $(ELFIO_DIR); make all 
 	cd $(ELFIO_DIR); make install 
+	#cd include/;  patch -p0 < ../third_party/elfio.patch
 
 elfio_clean:
 	rm -Rf third_party/ELFIO
diff --git a/appfw/src/Makefile b/appfw/src/Makefile
index 38706eb9e..09f12f705 100644
--- a/appfw/src/Makefile
+++ b/appfw/src/Makefile
@@ -1,8 +1,8 @@
 LIBAPPFW_DIR=../lib
 
-#CFLAGS=-g -DSHOW_TAINT_MARKINGS 
+CFLAGS=-g -DSHOW_TAINT_MARKINGS 
 #CFLAGS=-DSHOW_TAINT_MARKINGS -O
-CFLAGS=-O -fPIC
+#CFLAGS=-O -fPIC
 
 all: libappfw.so
 
diff --git a/appfw/src/appfw.cpp b/appfw/src/appfw.cpp
index f821713d0..2fd60babb 100644
--- a/appfw/src/appfw.cpp
+++ b/appfw/src/appfw.cpp
@@ -6,6 +6,7 @@
 #include <assert.h>
 #include <ctype.h>
 #include <list>
+#include <sys/time.h>
 
 
 extern "C" 
@@ -480,9 +481,17 @@ extern "C" int appfw_establish_taint_fast(const char *command, char *taint, int
 
 	list<char*>::iterator next;
 
+	int list_depth=0;
+
+	struct timeval blah;
+	gettimeofday(&blah,NULL);
+	fprintf(stdout, "start: %d:%d ", blah.tv_sec, blah.tv_usec);
+	
 	/* iterate the list */
 	for(list<char*>::iterator it=sorted_sigs->begin(); it!=sorted_sigs->end();  it=next)
 	{
+		list_depth++;
+		
 		char* sig=*it;
 		if(verbose)
 			fprintf(stderr,"Considering sig %s\n", sig);
@@ -504,15 +513,28 @@ extern "C" int appfw_establish_taint_fast(const char *command, char *taint, int
 				if(fixed_violations)
 				{
 					if(verbose)
+					{
 						fprintf(stderr,"fixed %d violations at %d\n", fixed_violations,pos);
+						fflush(stderr);
+					}
 					/* move to front */
-					sorted_sigs->erase(it);
-					sorted_sigs->push_front(sig);
+					if(it!=sorted_sigs->begin())
+					{
+						fprintf(stderr,"moving to front\n");
+						sorted_sigs->erase(it);
+						sorted_sigs->push_front(sig);
+					}
+
 					violations-=fixed_violations;
 					if(violations<=0)
 					{
 						if(verbose)
-							fprintf(stderr,"fixed ALL violations at %d\n", fixed_violations,pos);
+						{
+							fprintf(stderr,"fixed ALL violations, list size=%d, iterated to %d\n", sorted_sigs->size(), list_depth);
+							fflush(stderr);
+						}
+						gettimeofday(&blah,NULL);
+						fprintf(stdout, "end: %d:%d ", blah.tv_sec, blah.tv_usec);
 						return TRUE;
 					}
 				}
diff --git a/appfw/src/osc_hook.c b/appfw/src/osc_hook.c
index cde1a8075..2530c358c 100644
--- a/appfw/src/osc_hook.c
+++ b/appfw/src/osc_hook.c
@@ -20,14 +20,15 @@ int (*my_system)(const char *) = NULL;
 #include "oscfw.h"
 int system(const char *p_command)
 {
+  if(getenv("APPFW_VERBOSE"))
+	fprintf(stderr, "In system\n");
+
   char taint[MAX_COMMAND_LENGTH];
   if (!my_system)
     my_system = dlsym(RTLD_NEXT, "system");
 
   oscfw_init(); // will do this automagically later 
 
-  if(getenv("APPFW_VERBOSE"))
-	fprintf(stderr, "In system\n");
 
   if (within_osc_monitor || oscfw_verify(p_command, taint))
   {
diff --git a/libIRDB/test/Makefile b/libIRDB/test/Makefile
index 3ce0b8d12..3fe4cf2ae 100644
--- a/libIRDB/test/Makefile
+++ b/libIRDB/test/Makefile
@@ -1,4 +1,8 @@
 
+
+INCLUDES= -I ../../include -I../include/ -I../../beaengine/include 
+LIBS=-L ../lib/ -lIRDB-core -lIRDB-cfg -lpqxx -L ../../beaengine/lib/Linux.gnu.Debug -lBeaEngine_s_d 
+OPT=-g
 .SUFFIXES: .exe .cpp 
 
 PROGS=print_variant.exe list_programs.exe create_variant.exe create_variantir.exe read_variantir.exe clone.exe ilr.exe \
@@ -9,21 +13,19 @@ all: $(PROGS)
 
 $(PROGS): ../../lib/*
 
-#read_ehframe.exe: unwind-pe.h 
-#	g++ -w -fpermissive -g read_ehframe.cpp -DTEST -I../include/ -I../../beaengine/include -L ../lib/ -lIRDB-core -lIRDB-cfg -lpqxx -L ../../beaengine/lib/Linux.gnu.Debug -lBeaEngine_s_d -o $@
 
 fill_in_indtargs.exe: read_ehframe.o fill_in_indtargs.o check_thunks.o
-	g++ -g fill_in_indtargs.o read_ehframe.o check_thunks.o -I../include/ -I../../beaengine/include -L ../lib/ -lIRDB-core -lIRDB-cfg -lpqxx -L ../../beaengine/lib/Linux.gnu.Debug -lBeaEngine_s_d -o $@
+	g++ fill_in_indtargs.o read_ehframe.o check_thunks.o  $(INCLUDES) $(LIBS) $(OPT) -o $@
 
 
 .o.exe:  $< ../lib/libIRDB-core.a ../lib/libIRDB-cfg.a
-	g++ -g $< -I../include/ -I../../beaengine/include -L ../lib/ -lIRDB-core -lIRDB-cfg -lpqxx -L ../../beaengine/lib/Linux.gnu.Debug -lBeaEngine_s_d -o $@
+	g++ $< $(INCLUDES) $(LIBS) $(OPT)  -o $@
 
 .cpp.o:  $< 
-	g++ -g $< -I../include/ -I../../beaengine/include -I../../include -L../lib/ -lIRDB-core -lIRDB-cfg -lpqxx -L ../../beaengine/lib/Linux.gnu.Debug -lBeaEngine_s_d -o $@ -c
+	g++ $< $(INCLUDES) $(LIBS) $(OPT) -o $@ -c
 
 read_ehframe.o: read_ehframe.cpp
-	g++ -w -fpermissive -g $^ -I../../include -I../include/ -I../../beaengine/include -L ../lib/ -lIRDB-core -lIRDB-cfg -lpqxx -L ../../beaengine/lib/Linux.gnu.Debug -lBeaEngine_s_d -o $@ -c
+	g++ -w -fpermissive $(INCLUDES) $(LIBS)  $(OPT) $^ -o $@ -c
 
 clean:
 	rm -f $(PROGS) *.o
diff --git a/libIRDB/test/fill_in_cfg.cpp b/libIRDB/test/fill_in_cfg.cpp
index 8321c580a..f082b75b5 100644
--- a/libIRDB/test/fill_in_cfg.cpp
+++ b/libIRDB/test/fill_in_cfg.cpp
@@ -6,10 +6,13 @@
 #include <string.h>
 #include <map>
 #include <assert.h>
-#include <elf.h>
 #include <sys/mman.h>
 #include <ctype.h>
-#include <targ-config.h>
+
+#include "elfio/elfio.hpp"
+#include "elfio/elfio_dump.hpp"
+
+#include "targ-config.h"
 
 
 #include "beaengine/BeaEngine.h"
@@ -20,6 +23,7 @@ int bad_fallthrough_count=0;
 
 using namespace libIRDB;
 using namespace std;
+using namespace ELFIO;
 
 set< pair<db_id_t,int> > missed_instructions;
 int failed_target_count=0;
@@ -218,36 +222,33 @@ void add_new_instructions(FileIR_t *firp)
 		/* get the OID of the file */
 		int elfoid=filep->GetELFOID();
 
+		pqxx::largeobject lo(elfoid);
+                lo.to_file(pqxx_interface.GetTransaction(),"readeh_tmp_file.exe");
 
-        	IRDB_Elf_Off sec_hdr_off, sec_off;
-        	IRDB_Elf_Half secnum, strndx, secndx;
-        	IRDB_Elf_Word secsize;
-	
-		pqxx::largeobjectaccess loa(pqxx_interface.GetTransaction(), elfoid, PGSTD::ios::in);
-		
+                ELFIO::elfio    elfiop;
+		elfiop.load("readeh_tmp_file.exe");
+
+		ELFIO::dump::header(cout,elfiop);
+		ELFIO::dump::section_headers(cout,elfiop);
 
-        	/* allcoate memory  */
-        	IRDB_Elf_Ehdr elfhdr;
 
-        	/* Read ELF header */
-        	loa.cread((char*)&elfhdr, sizeof(IRDB_Elf_Ehdr)* 1);
 
-        	sec_hdr_off = elfhdr.e_shoff;
-        	secnum = elfhdr.e_shnum;
-        	strndx = elfhdr.e_shstrndx;
+        	Elf64_Off sec_hdr_off, sec_off;
+        	Elf_Half secnum, strndx, secndx;
+        	Elf_Word secsize;
+	
+		
 
-        	/* Read Section headers */
-        	IRDB_Elf_Shdr *sechdrs=(IRDB_Elf_Shdr*)malloc(sizeof(IRDB_Elf_Shdr)*secnum);
-		assert(sechdrs);
-        	loa.seek(sec_hdr_off, std::ios_base::beg);
-        	loa.cread((char*)sechdrs, sizeof(IRDB_Elf_Shdr)* secnum);
+        	sec_hdr_off = elfiop.get_sections_offset();
+        	secnum = elfiop.sections.size(); 
+        	strndx = elfiop.get_section_name_str_index();
 
 		bool found=false;
 	
         	/* look through each section and find the missing target*/
         	for (secndx=1; secndx<secnum; secndx++)
 		{
-        		int flags = sechdrs[secndx].sh_flags;
+        		int flags = elfiop.sections[secndx]->get_flags();
 
         		/* not a loaded section */
         		if( (flags & SHF_ALLOC) != SHF_ALLOC)
@@ -257,21 +258,15 @@ void add_new_instructions(FileIR_t *firp)
         		if( (flags & SHF_EXECINSTR) != SHF_EXECINSTR)
                 		continue;
 		
-        		int first=sechdrs[secndx].sh_addr;
-        		int second=sechdrs[secndx].sh_addr+sechdrs[secndx].sh_size;
+        		Elf64_Addr first=elfiop.sections[secndx]->get_address();
+        		Elf64_Addr second=elfiop.sections[secndx]->get_address()+elfiop.sections[secndx]->get_size();
 
 			/* is the missed instruction in this section */
 			if(first<=missed_address && missed_address<=second)
 			{
-			        char* data=(char*)malloc(sechdrs[secndx].sh_size+16);	 /* +16 to account for a bogus-y instruction that wraps past the end of the section */
-				assert(data);
-				memset(data,0, sechdrs[secndx].sh_size+16);		 /* bogus bits are always 0 */
-
-				/* grab the data from the ELF file for this section */
-        			loa.seek(sechdrs[secndx].sh_offset, std::ios_base::beg);
-        			loa.read(data, sechdrs[secndx].sh_size * 1);
-
-				int offset_into_section=missed_address-sechdrs[secndx].sh_addr;
+				const char* data=elfiop.sections[secndx]->get_data();
+				// second=data?
+				int offset_into_section=missed_address-elfiop.sections[secndx]->get_address();
 	
 				/* disassemble the instruction */
 				DISASM disasm;
@@ -291,7 +286,6 @@ void add_new_instructions(FileIR_t *firp)
 				/* if we found the instruction, but can't disassemble it, then we skip out for now */
 				if(instr_len==OUT_OF_RANGE || instr_len==UNKNOWN_OPCODE)
 				{
-					free(data);
 					break;
 				}
 
@@ -330,7 +324,6 @@ void add_new_instructions(FileIR_t *firp)
 
 				cout<<"Found new instruction, "<<newinsn->GetComment()<<", at "<<std::hex<<newinsn->GetAddress()->GetVirtualOffset()<<" in file "<<"<no name yet>"<<"."<<endl; 
 				found_instructions++;
-				free(data);
 			}
 		
 		}
@@ -340,8 +333,7 @@ void add_new_instructions(FileIR_t *firp)
 	
 			cout<<"Cannot find address "<<std::hex<<missed_address<<" in file "<<"<no name yet>"<<"."<<endl; 
 		} 
-		free(sechdrs);
-	}
+	}	
 	cout<<"Found a total of "<<std::dec<<found_instructions<<" new instructions."<<endl;
 
 }
diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp
index 83370ce0d..3be5f2ff7 100644
--- a/libIRDB/test/fill_in_indtargs.cpp
+++ b/libIRDB/test/fill_in_indtargs.cpp
@@ -6,20 +6,28 @@
 #include <string.h>
 #include <map>
 #include <assert.h>
-#include <elf.h>
 #include <sys/mman.h>
+// #include <elf.h>
 #include <ctype.h>
-#include "targ-config.h"
 
 
+#include "elfio/elfio.hpp"
+#include "elfio/elfio_dump.hpp"
+
+#include "targ-config.h"
+
 #include "beaengine/BeaEngine.h"
 
+
+#define arch_ptr_bytes() (firp->GetArchitectureBitWidth()/8)
+
 int odd_target_count=0;
 int bad_target_count=0;
 int bad_fallthrough_count=0;
 
 using namespace libIRDB;
 using namespace std;
+using namespace ELFIO;
 
 void possible_target(int p);
 
@@ -173,9 +181,9 @@ void get_instruction_targets(FileIR_t *firp)
 
 }
 
-void get_executable_bounds(IRDB_Elf_Shdr *shdr, pqxx::largeobjectaccess &loa, FileIR_t *firp)
+void get_executable_bounds(FileIR_t *firp, const section* shdr)
 {
-	int flags = shdr->sh_flags;
+	int flags = shdr->get_flags();
 
 	/* not a loaded section */
 	if( (flags & SHF_ALLOC) != SHF_ALLOC)
@@ -185,17 +193,17 @@ void get_executable_bounds(IRDB_Elf_Shdr *shdr, pqxx::largeobjectaccess &loa, Fi
 	if( (flags & SHF_EXECINSTR) != SHF_EXECINSTR)
 		return;
 
-	int first=shdr->sh_addr;
-	int second=shdr->sh_addr+shdr->sh_size;
+	int first=shdr->get_address();
+	int second=shdr->get_address()+shdr->get_size();
 
 	bounds.insert(pair<int,int>(first,second));
 
 
 }
 
-void infer_targets(IRDB_Elf_Shdr *shdr, pqxx::largeobjectaccess &loa, FileIR_t *firp)
+void infer_targets(FileIR_t *firp, section* shdr)
 {
-	int flags = shdr->sh_flags;
+	int flags = shdr->get_flags();
 
 	if( (flags & SHF_ALLOC) != SHF_ALLOC)
 		/* not a loaded section */
@@ -206,26 +214,16 @@ void infer_targets(IRDB_Elf_Shdr *shdr, pqxx::largeobjectaccess &loa, FileIR_t *
 		return;
 
 	/* if the type is NOBITS, then there's no actual data to look through */
-	if(shdr->sh_type==SHT_NOBITS)
+	if(shdr->get_type()==SHT_NOBITS)
 		return;
 
-	char* data=(char*)malloc(shdr->sh_size);
-
-	//fseek(fp,shdr->sh_offset, SEEK_SET);
-        loa.seek(shdr->sh_offset, std::ios_base::beg);
-
-
-	//int res=fread(data, shdr->sh_size, 1, fp);
-	loa.cread((char*)data, shdr->sh_size* 1);
+	const char* data=shdr->get_data() ; // C(char*)malloc(shdr->sh_size);
 
-	for(int i=0;i<=shdr->sh_size;i++)
+	assert(arch_ptr_bytes()==4 || arch_ptr_bytes()==8);
+	for(int i=0;i+arch_ptr_bytes()<=shdr->get_size();i++)
 	{
-		/* careful not to overflow the segment */
-		if(i+sizeof(void*)<=shdr->sh_size)
-		{
-			int p=*(int*)&data[i];
-			possible_target(p);
-		}
+		int p=*(int*)&data[i];
+		possible_target(p);
 	}
 
 }
@@ -323,42 +321,29 @@ void add_num_handle_fn_watches(FileIR_t * firp)
 
 }
 
-void fill_in_indtargs(FileIR_t* firp, pqxxDB_t &pqxx_interface)
+void fill_in_indtargs(FileIR_t* firp, elfio* elfiop)
 {
 	// reset global vars
 	bounds.clear();
 	ranges.clear();
 	targets.clear();
 
-        IRDB_Elf_Off sec_hdr_off, sec_off;
-        IRDB_Elf_Half secnum, strndx, secndx;
-        IRDB_Elf_Word secsize;
-
-	int elfoid=firp->GetFile()->GetELFOID();
-	pqxx::largeobjectaccess loa(pqxx_interface.GetTransaction(), elfoid, PGSTD::ios::in);
-
-	/* allcoate memory  */
-        IRDB_Elf_Ehdr elfhdr;
+        Elf64_Off sec_hdr_off, sec_off;
+        Elf_Half secnum, strndx, secndx;
+        Elf_Word secsize;
 
         /* Read ELF header */
-        //int res=fread(&elfhdr, sizeof(IRDB_Elf_Ehdr), 1, fp);
-        loa.cread((char*)&elfhdr, sizeof(IRDB_Elf_Ehdr)* 1);
-        sec_hdr_off = elfhdr.e_shoff;
-        secnum = elfhdr.e_shnum;
-        strndx = elfhdr.e_shstrndx;
-
-        /* Read Section headers */
-        IRDB_Elf_Shdr *sechdrs=(IRDB_Elf_Shdr*)malloc(sizeof(IRDB_Elf_Shdr)*secnum);
-        loa.seek(sec_hdr_off, std::ios_base::beg);
-        loa.cread((char*)sechdrs, sizeof(IRDB_Elf_Shdr)* secnum);
+        sec_hdr_off = elfiop->get_sections_offset();
+        secnum = elfiop->sections.size();
+        strndx = elfiop->get_section_name_str_index();
 
 	/* look through each section and record bounds */
         for (secndx=1; secndx<secnum; secndx++)
-		get_executable_bounds(&sechdrs[secndx], loa, firp);
+		get_executable_bounds(firp, elfiop->sections[secndx]);
 
 	/* look through each section and look for target possibilities */
         for (secndx=1; secndx<secnum; secndx++)
-		infer_targets(&sechdrs[secndx], loa, firp);
+		infer_targets(firp, elfiop->sections[secndx]);
 
 	
 	cout<<"========================================="<<endl;
@@ -370,7 +355,7 @@ void fill_in_indtargs(FileIR_t* firp, pqxxDB_t &pqxx_interface)
 	get_instruction_targets(firp);
 
 	/* mark the entry point as a target */
-	possible_target(elfhdr.e_entry);
+	possible_target(elfiop->get_entry()); 
 
 
 	cout<<"========================================="<<endl;
@@ -379,8 +364,8 @@ void fill_in_indtargs(FileIR_t* firp, pqxxDB_t &pqxx_interface)
 	cout<<"========================================="<<endl;
 
 	/* Read the exception handler frame so that those indirect branches are accounted for */
-	void read_ehframe(FileIR_t* firp, pqxxDB_t& pqxx_interface);
-        read_ehframe(firp, pqxx_interface);
+	void read_ehframe(FileIR_t* firp, elfio* );
+        read_ehframe(firp, elfiop);
 
 	cout<<"========================================="<<endl;
 	cout<<"All targets from data+instruction+eh_header sections are: " << endl;
@@ -466,8 +451,19 @@ main(int argc, char* argv[])
 			// read the db  
 			firp=new FileIR_t(*pidp, this_file);
 
+			int elfoid=firp->GetFile()->GetELFOID();
+		        pqxx::largeobject lo(elfoid);
+        		lo.to_file(pqxx_interface.GetTransaction(),"readeh_tmp_file.exe");
+
+        		ELFIO::elfio*    elfiop=new ELFIO::elfio;
+        		elfiop->load("readeh_tmp_file.exe");
+		
+        		ELFIO::dump::header(cout,*elfiop);
+        		ELFIO::dump::section_headers(cout,*elfiop);
+
+
 			// find all indirect branch targets
-			fill_in_indtargs(firp, pqxx_interface);
+			fill_in_indtargs(firp, elfiop);
 	
 			// write the DB back and commit our changes 
 
diff --git a/libIRDB/test/find_strings.cpp b/libIRDB/test/find_strings.cpp
index a6fb7879d..5f7df4365 100644
--- a/libIRDB/test/find_strings.cpp
+++ b/libIRDB/test/find_strings.cpp
@@ -5,13 +5,19 @@
 #include <iostream>
 #include <stdlib.h>
 #include <cctype>
-#include <elf.h>
 #include <assert.h>
+
+#include "elfio/elfio.hpp"
+#include "elfio/elfio_dump.hpp"
+
 #include "targ-config.h"
 
+
 using namespace libIRDB;
 using namespace std;
+using namespace ELFIO;
 
+#define arch_ptr_bytes() (firp->GetArchitectureBitWidth()/8)
 
 bool is_string_character(char c)
 {
@@ -22,13 +28,12 @@ bool is_string_character(char c)
 
 /* the stuff we need for reading an elf file */
 typedef struct elf_info {
-       	IRDB_Elf_Off sec_hdr_off, sec_off;
-       	IRDB_Elf_Half secnum, strndx;
-       	IRDB_Elf_Ehdr elfhdr;
-       	IRDB_Elf_Word secsize;
-       	IRDB_Elf_Shdr *sechdrs;
-	char **sec_data;
-	IRDB_Elf_Addr got;
+       	Elf64_Off sec_hdr_off, sec_off;
+       	Elf_Half secnum, strndx;
+       	Elf_Word secsize;
+	char const **sec_data;
+	Elf64_Addr got;
+	elfio *elfiop;
 } elf_info_t;
 
 void found_string(string s, void* addr)
@@ -58,9 +63,9 @@ void found_string(string s, void* addr)
 	} while (p < buff + s.length());
 }
 
-void load_section(elf_info_t &ei, int i, pqxx::largeobjectaccess &loa, bool alloc)
+void load_section(elf_info_t &ei, int i, bool alloc)
 {
-	if( alloc && (ei.sechdrs[i].sh_flags & SHF_ALLOC) != SHF_ALLOC)
+	if( alloc && (ei.elfiop->sections[i]->get_flags() & SHF_ALLOC) != SHF_ALLOC)
 	{
 		cerr<<"Cannot load non-alloc section\n";
 		assert(0);
@@ -68,22 +73,16 @@ void load_section(elf_info_t &ei, int i, pqxx::largeobjectaccess &loa, bool allo
 
 	if(ei.sec_data[i]==NULL)
 	{
-		ei.sec_data[i]=(char*)calloc(ei.sechdrs[i].sh_size,1);
-		if(ei.sechdrs[i].sh_type==SHT_NOBITS)
+		ei.sec_data[i]=ei.elfiop->sections[i]->get_data(); 
+		if(ei.elfiop->sections[i]->get_type()==SHT_NOBITS)
 		{
 			/* no need to read anything for NOBITS sections */
-		}
-		else
-		{
-//			cout<<"Loading section "<<std::dec<<i<<" vaddr: "<<std::hex<<ei.sechdrs[i].sh_addr<< "  size: "
-//				<<std::dec<<ei.sechdrs[i].sh_size<< endl;
-        		loa.seek(ei.sechdrs[i].sh_offset, std::ios_base::beg);
-        		loa.cread((char*)ei.sec_data[i], ei.sechdrs[i].sh_size);
+			ei.sec_data[i]=(char*)calloc(ei.elfiop->sections[i]->get_size(),1);
 		}
 	}
 }
 
-void check_for_string(char* p, void* addr)
+void check_for_string(const char* p, void* addr)
 {
 	assert(p);
 	if(!is_string_character(*p))
@@ -100,22 +99,23 @@ void check_for_string(char* p, void* addr)
 	found_string(s, addr);
 }
 
-void is_string_pointer(void* addr, elf_info_t &ei, pqxx::largeobjectaccess &loa)
+void is_string_pointer(void* addr, elf_info_t &ei)
 {
 	long long int intaddr=(long long int)(addr);
 
 	for(int i=0;i<ei.secnum;i++)
 	{
 		/* only look at loaded sections */
-		if( (ei.sechdrs[i].sh_flags & SHF_ALLOC) != SHF_ALLOC)
+		if( (ei.elfiop->sections[i]->get_flags() & SHF_ALLOC) != SHF_ALLOC)
 			continue;
 
-		if(ei.sechdrs[i].sh_addr <= intaddr && intaddr <= (ei.sechdrs[i].sh_addr+ei.sechdrs[i].sh_size))
+		if(ei.elfiop->sections[i]->get_address() <= intaddr 
+			&& intaddr <= (ei.elfiop->sections[i]->get_address()+ei.elfiop->sections[i]->get_size()))
 		{
 			/* we found a pointer into a loadable segment */
-			load_section(ei,i,loa,true);
+			load_section(ei,i,true);
 //			cout<<"Checking address "<<std::hex<<addr<<endl;
-			check_for_string(ei.sec_data[i]+((long long int)addr-ei.sechdrs[i].sh_addr),addr);
+			check_for_string(ei.sec_data[i]+((long long int)addr-ei.elfiop->sections[i]->get_address()),addr);
 		}
 	}
 
@@ -158,38 +158,31 @@ void is_string_constant(DISASM& disasm)
 
 } 
 
-void handle_argument(ARGTYPE *arg, elf_info_t &ei, pqxx::largeobjectaccess &loa)
+void handle_argument(ARGTYPE *arg, elf_info_t &ei)
 {
         if( arg->ArgType == MEMORY_TYPE )
 	{
 		/* Only check without GOT offset if type is executable */
-		if ( ei.elfhdr.e_type == ET_EXEC )
-			is_string_pointer((void*)arg->Memory.Displacement,ei,loa);
+		if ( ei.elfiop->get_type() == ET_EXEC )
+			is_string_pointer((void*)arg->Memory.Displacement,ei);
 		/* Check with GOT offset if present */
 		if ( ei.got && arg->Memory.BaseRegister == REG3 /* ebx */ )
-			is_string_pointer((void*)(arg->Memory.Displacement + ei.got),ei,loa);
+			is_string_pointer((void*)(arg->Memory.Displacement + ei.got),ei);
 	}
 }
 
 
-void read_elf_info(elf_info_t &ei, FileIR_t* firp, pqxx::largeobjectaccess &loa)
+void read_elf_info(elf_info_t &ei, FileIR_t* firp)
 {
 
 
         /* Read ELF header */
-        loa.cread((char*)&ei.elfhdr, sizeof(IRDB_Elf_Ehdr)* 1);
-        ei.sec_hdr_off = ei.elfhdr.e_shoff;
-        ei.secnum = ei.elfhdr.e_shnum;
+        ei.sec_hdr_off = ei.elfiop->get_sections_offset();
+        ei.secnum = ei.elfiop->sections.size();
         assert(ei.secnum>0);
-        ei.strndx = ei.elfhdr.e_shstrndx;
+        ei.strndx = ei.elfiop->get_section_name_str_index();
 
-        /* Read Section headers */
-        ei.sechdrs=(IRDB_Elf_Shdr*)malloc(sizeof(IRDB_Elf_Shdr)*ei.secnum);
-	assert(ei.sechdrs!=NULL);
-        loa.seek(ei.sec_hdr_off, std::ios_base::beg);
-        loa.cread((char*)ei.sechdrs, sizeof(IRDB_Elf_Shdr)* ei.secnum);
-
-	ei.sec_data=(char**)calloc(ei.secnum,sizeof(void*));
+	ei.sec_data=(char const**)calloc(ei.secnum,sizeof(void*));
 
 	ei.got = 0;
 	/* Get .got or .got.plt address, if any */
@@ -199,21 +192,22 @@ void read_elf_info(elf_info_t &ei, FileIR_t* firp, pqxx::largeobjectaccess &loa)
 		if (ei.strndx < SHN_LORESERVE)
 			shstr_sec = ei.strndx;
 		else
-			shstr_sec = ei.sechdrs[0].sh_link;
+			shstr_sec = ei.elfiop->sections[0]->get_link();
 		assert(shstr_sec < ei.secnum);
-		load_section(ei,shstr_sec,loa,false);
-		IRDB_Elf_Shdr *shstr_sec_hdr = ei.sechdrs + shstr_sec;
+		load_section(ei,shstr_sec,false);
+//		IRDB_Elf_Shdr *shstr_sec_hdr = ei.sechdrs + shstr_sec;
 		for (int i=0;i<ei.secnum;i++)
 		{
-			assert(ei.sechdrs[i].sh_name < shstr_sec_hdr->sh_size);
-			if (!strcmp(ei.sec_data[shstr_sec]+ei.sechdrs[i].sh_name, ".got.plt"))
+// name works oddly here.  we can just get the name safely using elfio
+//			assert(ei.sechdrs[i].sh_name < shstr_sec_hdr->sh_size);
+			if (ei.elfiop->sections[i]->get_name()==".got.plt") // !strcmp(ei.sec_data[shstr_sec]+ei.sechdrs[i].sh_name, ".got.plt"))
 			{
 				// Prefer .got.plt to .got
-				ei.got = ei.sechdrs[i].sh_addr;
+				ei.got = ei.elfiop->sections[i]->get_address();
 				break;
 			}
-			if (!strcmp(ei.sec_data[shstr_sec]+ei.sechdrs[i].sh_name, ".got"))
-				ei.got = ei.sechdrs[i].sh_addr;
+			if (ei.elfiop->sections[i]->get_name()==".got") // if (!strcmp(ei.sec_data[shstr_sec]+ei.sechdrs[i].sh_name, ".got"))
+				ei.got = ei.elfiop->sections[i]->get_address();
 		}
 	}
 }
@@ -221,13 +215,10 @@ void read_elf_info(elf_info_t &ei, FileIR_t* firp, pqxx::largeobjectaccess &loa)
 void free_elf_info(elf_info_t &ei)
 {
 	#define FREE_IF_NOT_NULL(a) { if(a) { free(a); a=NULL; } }
-	FREE_IF_NOT_NULL(ei.sechdrs);
-	for(int i=0;i<ei.secnum;i++)	
-		FREE_IF_NOT_NULL(ei.sec_data[i]);
 	FREE_IF_NOT_NULL(ei.sec_data);
 }
 
-void find_strings_in_instructions(FileIR_t* firp, elf_info_t& ei, pqxx::largeobjectaccess &loa)
+void find_strings_in_instructions(FileIR_t* firp, elf_info_t& ei)
 {
 	set<Instruction_t*> visited_insns;
 
@@ -368,12 +359,12 @@ void find_strings_in_instructions(FileIR_t* firp, elf_info_t& ei, pqxx::largeobj
 		assert(res);
 
 		// check for immediate string pointers in non-PIC code
-		if ( ei.elfhdr.e_type == ET_EXEC )
-			is_string_pointer((void*)disasm.Instruction.Immediat,ei,loa);
+		if ( ei.elfiop->get_type() == ET_EXEC )
+			is_string_pointer((void*)disasm.Instruction.Immediat,ei);
 		// always check for string pointers in memory argument displacements
-		handle_argument(&disasm.Argument1,ei,loa);
-		handle_argument(&disasm.Argument2,ei,loa);
-		handle_argument(&disasm.Argument3,ei,loa);
+		handle_argument(&disasm.Argument1,ei);
+		handle_argument(&disasm.Argument2,ei);
+		handle_argument(&disasm.Argument3,ei);
 
 		// if not in a function, check for string in immediate
 		if (visited_insns.find(insn) != visited_insns.end())
@@ -390,44 +381,63 @@ void find_strings_in_instructions(FileIR_t* firp, elf_info_t& ei, pqxx::largeobj
 	}
 }
 
-void find_strings_in_data(FileIR_t* firp, elf_info_t& ei, pqxx::largeobjectaccess &loa)
+
+void find_strings_in_data(FileIR_t* firp, elf_info_t& ei)
 {
 	for(int i=0;i<ei.secnum;i++)
 	{
 		/* skip executable, hash, string table, nonloadable, and tiny sections */
-		if( (ei.sechdrs[i].sh_flags & SHF_EXECINSTR)
-		    || ei.sechdrs[i].sh_type == SHT_HASH
-		    || ei.sechdrs[i].sh_type == SHT_GNU_HASH
-		    || ei.sechdrs[i].sh_type == SHT_STRTAB
-		    || (ei.sechdrs[i].sh_flags & SHF_ALLOC) != SHF_ALLOC
-		    || ei.sechdrs[i].sh_size < sizeof(void*))
+		if( (ei.elfiop->sections[i]->get_flags() & SHF_EXECINSTR)
+		    || ei.elfiop->sections[i]->get_type() == SHT_HASH
+		    || ei.elfiop->sections[i]->get_type() == SHT_GNU_HASH
+		    || ei.elfiop->sections[i]->get_type() == SHT_STRTAB
+		    || (ei.elfiop->sections[i]->get_flags() & SHF_ALLOC) != SHF_ALLOC
+		    || ei.elfiop->sections[i]->get_size() < arch_ptr_bytes())
 			continue;
 
 		int offset = 0;
 		int step;
 		/* step over relocation info */
-		switch( ei.sechdrs[i].sh_type )
+		switch( ei.elfiop->sections[i]->get_type() )
 		{
 		case SHT_REL:
-			step = sizeof(IRDB_Elf_Rel);
+			if(arch_ptr_bytes()==4)
+				step = sizeof(::Elf32_Rel);
+			else
+				step = sizeof(::Elf64_Rel);
 			break;
 		case SHT_RELA:
-			step = sizeof(IRDB_Elf_Rela);
+			if(arch_ptr_bytes()==4)
+				step = sizeof(::Elf32_Rela);
+			else
+				step = sizeof(::Elf64_Rela);
 			break;
 		case SHT_SYMTAB:
 		case SHT_DYNSYM:
-			offset = sizeof(IRDB_Elf_Word);
-			step = sizeof(IRDB_Elf_Sym);
+			if(arch_ptr_bytes()==4)
+			{
+				offset = sizeof(::Elf32_Word);
+				step = sizeof(::Elf32_Sym);
+			}
+			else
+			{
+				offset = sizeof(::Elf64_Word);
+				step = sizeof(::Elf64_Sym);
+			}
 			break;
 		default:
 			step = 1;
 		}
 
-		load_section(ei,i,loa,true);
-        	for(int j=offset;j<=ei.sechdrs[i].sh_size-sizeof(void*);j+=step)
+		load_section(ei,i,true);
+        	for(int j=offset;j+arch_ptr_bytes()<=ei.elfiop->sections[i]->get_size();j+=step)
         	{
-                	void* p=*((void**)(ei.sec_data[i]+j));
-                	is_string_pointer(p,ei,loa);
+			void* p;
+			if(arch_ptr_bytes()==4)
+                		p=(void*)*((int*)(ei.sec_data[i]+j));
+			else
+                		p=*((void**)(ei.sec_data[i]+j));
+                	is_string_pointer(p,ei);
         	}
 
 		
@@ -445,14 +455,23 @@ void find_strings(VariantID_t *pidp, FileIR_t* firp)
 	/* get a handle to the binary file */
         int elfoid=firp->GetFile()->GetELFOID();
 	pqxxDB_t* pqxx_interface=dynamic_cast<pqxxDB_t*>(BaseObj_t::GetInterface());
-        pqxx::largeobjectaccess loa(pqxx_interface->GetTransaction(), elfoid, PGSTD::ios::in);
+
+	pqxx::largeobject lo(elfoid);
+	lo.to_file(pqxx_interface->GetTransaction(),"readeh_tmp_file.exe");
+	ELFIO::elfio    elfiop;
+	elfiop.load("readeh_tmp_file.exe");
+	ELFIO::dump::header(cout,elfiop);
+	ELFIO::dump::section_headers(cout,elfiop);
+
+
 
 
 	elf_info_t ei;
-	read_elf_info(ei,firp,loa);
+	ei.elfiop=&elfiop;
+	read_elf_info(ei,firp);
 
-	find_strings_in_instructions(firp, ei, loa);
-	find_strings_in_data(firp, ei, loa);
+	find_strings_in_instructions(firp, ei);
+	find_strings_in_data(firp, ei);
 
 	free_elf_info(ei);
 
diff --git a/libIRDB/test/read_ehframe.cpp b/libIRDB/test/read_ehframe.cpp
index 833b866b0..a300824cb 100644
--- a/libIRDB/test/read_ehframe.cpp
+++ b/libIRDB/test/read_ehframe.cpp
@@ -11,13 +11,17 @@
 #include <elf.h>
 #include "targ-config.h"
 
-
-
+#include "elfio/elfio.hpp"
+#include "elfio/elfio_dump.hpp"
 
 using namespace libIRDB;
 using namespace std;
 
 
+
+
+
+
 void* eh_frame_addr;
 char* eh_frame_data;
 int eh_offset;
@@ -660,11 +664,11 @@ void linear_search_fdes (struct object *ob, fde *this_fde, int offset)
   	return;
 }
 
-void read_ehframe(FileIR_t* virp, pqxxDB_t& pqxx_interface)
+void read_ehframe(FileIR_t* virp, ELFIO::elfio* elfiop)
 {
-
 	/* get first instruction */
 	Instruction_t* insn=*(virp->GetInstructions().begin());
+	assert(insn);
 
 	/* get its file ID */
 	db_id_t fileid=insn->GetAddress()->GetFileID();
@@ -676,41 +680,18 @@ void read_ehframe(FileIR_t* virp, pqxxDB_t& pqxx_interface)
 	/* get the OID of the file */
 	int elfoid=filep->GetELFOID();
 
-	/* parse out the elf headers, and strtab */
-	IRDB_Elf_Ehdr elfhdr;
-	IRDB_Elf_Off sec_hdr_off, sec_off;
-	IRDB_Elf_Half secnum, strndx, secndx;
-	IRDB_Elf_Word secsize;
-
-	pqxx::largeobjectaccess loa(pqxx_interface.GetTransaction(), elfoid, PGSTD::ios::in);
-
-
-	/* Read ELF header */
-	loa.cread((char*)&elfhdr, sizeof(IRDB_Elf_Ehdr)* 1);
-
-	sec_hdr_off = elfhdr.e_shoff;
-	secnum = elfhdr.e_shnum;
-	strndx = elfhdr.e_shstrndx;
-
-	/* Read Section headers */
-	IRDB_Elf_Shdr *sechdrs=(IRDB_Elf_Shdr*)malloc(sizeof(IRDB_Elf_Shdr)*secnum);
-	loa.seek(sec_hdr_off, std::ios_base::beg);
-	loa.cread((char*)sechdrs, sizeof(IRDB_Elf_Shdr)* secnum);
-
-
-       	/* Read Section String Table */
-       	sec_off = sechdrs[strndx].sh_offset;
-       	secsize = sechdrs[strndx].sh_size;
-       	loa.seek(sec_off, std::ios_base::beg);
-       	char* strtab = (char *)malloc(secsize);
-       	loa.cread(strtab, 1 * secsize);
+	int secndx=0;
+	int secnum=elfiop->sections.size(); 
+	ELFIO::Elf_Half strndx = elfiop->get_section_name_str_index();
+	const char* strtab=elfiop->sections[strndx]->get_data();
 
        	/* Locate desired section */
        	bool found=false;
 	int eh_frame_index;
        	for (secndx=1; secndx<secnum; secndx++)
        	{
-               	char *p=&strtab[ sechdrs[secndx].sh_name];
+		// cout<<"sechdrs["<<i<<"] name index="<<sechdrs[secndx].sh_name<<endl;
+               	const char *p=elfiop->sections[secndx]->get_name().c_str(); 
                	if (strcmp(".eh_frame",p)==0)
                	{
                        	found = true;
@@ -726,23 +707,23 @@ void read_ehframe(FileIR_t* virp, pqxxDB_t& pqxx_interface)
 	}
 	cout<<"Found .eh_frame is section "<<std::dec<<eh_frame_index<<endl;
 
-	char *p=&strtab[ sechdrs[secndx+1].sh_name];
+// 	char *p=&strtab[ sechdrs[secndx+1].sh_name];
+	const char *p=elfiop->sections[secndx+1]->get_name().c_str(); 
         if (strcmp(".gcc_except_table",p)!=0)
 	{
 		cout<<"Did not find .gcc_except_table immediately after .eh_frame\n";
 		return;
 	}
 
-	eh_frame_addr=(void*)sechdrs[eh_frame_index].sh_addr;
-	int total_size= ((int)sechdrs[eh_frame_index+1].sh_addr+(int)sechdrs[eh_frame_index+1].sh_size) - (int)eh_frame_addr;
+	eh_frame_addr=(void*)elfiop->sections[eh_frame_index]->get_address();
+	int total_size= 
+		(elfiop->sections[eh_frame_index+1]->get_address()+
+		 elfiop->sections[eh_frame_index+1]->get_size()   ) - (int)eh_frame_addr;
 	
-	/* read the frame data */
-	eh_frame_data=(char*)malloc(total_size);
-       	loa.seek((int)sechdrs[eh_frame_index].sh_offset, std::ios_base::beg);
-       	loa.cread(eh_frame_data, total_size);
+	eh_frame_data=elfiop->sections[eh_frame_index]->get_data();
 
-	int offset;
-	eh_offset=offset=(int)eh_frame_addr-(int)eh_frame_data;
+	uintptr_t offset;
+	eh_offset=offset=(uintptr_t)eh_frame_addr-(uintptr_t)eh_frame_data;
 
 
 	struct object ob;
@@ -752,9 +733,6 @@ void read_ehframe(FileIR_t* virp, pqxxDB_t& pqxx_interface)
 	linear_search_fdes (&ob,ob.u.single,offset); 
 
 	/* clean up memory */
-	free(sechdrs);
-	free(strtab);
-	free(eh_frame_data);
 
 }
 
diff --git a/third_party/elfio.patch b/third_party/elfio.patch
new file mode 100644
index 000000000..36d5926af
--- /dev/null
+++ b/third_party/elfio.patch
@@ -0,0 +1,131 @@
+diff -rpuN umbrella/uvadev.peasoup/security_transforms/third_party/ELFIO/elfio-2.2/elfio/elfio_header.hpp elfio/elfio_header.hpp
+--- umbrella/uvadev.peasoup/security_transforms/third_party/ELFIO/elfio-2.2/elfio/elfio_header.hpp	2012-11-27 04:34:09.000000000 -0500
++++ elfio/elfio_header.hpp	2013-11-22 10:03:00.640843581 -0500
+@@ -23,6 +23,7 @@ THE SOFTWARE.
+ #ifndef ELF_HEADER_HPP
+ #define ELF_HEADER_HPP
+ 
++#include <istream>
+ #include <fstream>
+ 
+ namespace ELFIO {
+@@ -31,7 +32,7 @@ class elf_header
+ {
+   public:
+     virtual ~elf_header() {};
+-    virtual bool load( std::ifstream& stream )       = 0;
++    virtual bool load( std::istream& stream )       = 0;
+     virtual bool save( std::ofstream& stream ) const = 0;
+ 
+     // ELF header functions
+@@ -98,7 +99,7 @@ template< class T > class elf_header_imp
+     }
+ 
+     bool
+-    load( std::ifstream& stream )
++    load( std::istream& stream )
+     {
+         stream.seekg( 0 );
+         stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );
+diff -rpuN umbrella/uvadev.peasoup/security_transforms/third_party/ELFIO/elfio-2.2/elfio/elfio.hpp elfio/elfio.hpp
+--- umbrella/uvadev.peasoup/security_transforms/third_party/ELFIO/elfio-2.2/elfio/elfio.hpp	2013-05-16 11:37:39.000000000 -0400
++++ elfio/elfio.hpp	2013-11-22 10:03:00.640843581 -0500
+@@ -35,6 +35,7 @@ THE SOFTWARE.
+ #include <algorithm>
+ #include <vector>
+ #include <typeinfo>
++#include <istream>
+ 
+ #include <elfio/elf_types.hpp>
+ #include <elfio/elfio_utils.hpp>
+@@ -99,7 +100,13 @@ class elfio
+         stream.open( file_name.c_str(), std::ios::in | std::ios::binary );
+         if ( !stream ) {
+             return false;
+-        }
++        }  
++	return load(stream);
++    }
++    bool load( std::istream &stream ) 
++    {
++	clean();
++
+ 
+         unsigned char e_ident[EI_NIDENT];
+ 
+@@ -323,7 +330,7 @@ class elfio
+     }
+ 
+ //------------------------------------------------------------------------------
+-    Elf_Half load_sections( std::ifstream& stream )
++    Elf_Half load_sections( std::istream& stream )
+     {
+         Elf_Half  entry_size = header->get_section_entry_size();
+         Elf_Half  num        = header->get_sections_num();
+@@ -355,7 +362,7 @@ class elfio
+     }
+ 
+ //------------------------------------------------------------------------------
+-    bool load_segments( std::ifstream& stream )
++    bool load_segments( std::istream& stream )
+     {
+         Elf_Half  entry_size = header->get_segment_entry_size();
+         Elf_Half  num        = header->get_segments_num();
+diff -rpuN umbrella/uvadev.peasoup/security_transforms/third_party/ELFIO/elfio-2.2/elfio/elfio_section.hpp elfio/elfio_section.hpp
+--- umbrella/uvadev.peasoup/security_transforms/third_party/ELFIO/elfio-2.2/elfio/elfio_section.hpp	2013-03-25 03:57:36.000000000 -0400
++++ elfio/elfio_section.hpp	2013-11-22 10:03:00.640843581 -0500
+@@ -25,6 +25,7 @@ THE SOFTWARE.
+ 
+ #include <string>
+ #include <fstream>
++#include <istream>
+ 
+ namespace ELFIO {
+ 
+@@ -55,7 +56,7 @@ class section
+ 
+   protected:
+     virtual void set_index( Elf_Half )                = 0;
+-    virtual void load( std::ifstream& f,
++    virtual void load( std::istream& f,
+                        std::streampos header_offset ) = 0;
+     virtual void save( std::ofstream& f,
+                        std::streampos header_offset,
+@@ -203,7 +204,7 @@ class section_impl : public section
+ 
+ //------------------------------------------------------------------------------
+     void
+-    load( std::ifstream& stream,
++    load( std::istream& stream,
+           std::streampos header_offset )
+     {
+         std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
+diff -rpuN umbrella/uvadev.peasoup/security_transforms/third_party/ELFIO/elfio-2.2/elfio/elfio_segment.hpp elfio/elfio_segment.hpp
+--- umbrella/uvadev.peasoup/security_transforms/third_party/ELFIO/elfio-2.2/elfio/elfio_segment.hpp	2013-05-01 15:17:01.000000000 -0400
++++ elfio/elfio_segment.hpp	2013-11-22 10:03:00.640843581 -0500
+@@ -23,6 +23,7 @@ THE SOFTWARE.
+ #ifndef ELFIO_SEGMENT_HPP
+ #define ELFIO_SEGMENT_HPP
+ 
++#include <istream>
+ #include <fstream>
+ #include <vector>
+ 
+@@ -52,7 +53,7 @@ class segment
+ 
+   protected:
+     virtual void set_index( Elf_Half )                                             = 0;
+-    virtual void load( std::ifstream& stream, std::streampos header_offset ) const = 0;
++    virtual void load( std::istream& stream, std::streampos header_offset ) const = 0;
+     virtual void save( std::ofstream& f, std::streampos header_offset,
+                        std::streampos data_offset )                                = 0;
+ };
+@@ -142,7 +143,7 @@ class segment_impl : public segment
+ 
+ //------------------------------------------------------------------------------
+     void
+-    load( std::ifstream& stream,
++    load( std::istream& stream,
+           std::streampos header_offset ) const
+     {
+         stream.seekg( header_offset );
-- 
GitLab