From 730f6414618e8c5fb1144748da54e45ec14dfc6d Mon Sep 17 00:00:00 2001
From: jdh8d <jdh8d@git.zephyr-software.com>
Date: Fri, 3 Jul 2015 18:45:44 +0000
Subject: [PATCH] added libEXEIO

Former-commit-id: 812dd37412fdf01854a20bf355e2d6a39fe30378
---
 .gitattributes                    |   7 ++
 SConscript                        |   1 +
 libEXEIO/SConscript               |   5 ++
 libEXEIO/SConstruct               |   6 ++
 libEXEIO/include/exeio.h          | 122 ++++++++++++++++++++++++++++++
 libEXEIO/include/exeio_elf.h      | 109 ++++++++++++++++++++++++++
 libEXEIO/src/SConscript           |  26 +++++++
 libEXEIO/src/SConstruct           |   6 ++
 libEXEIO/src/exeio_src.cpp        |  15 ++++
 libIRDB/test/SConscript           |   3 +-
 libIRDB/test/fill_in_indtargs.cpp |  81 ++++++++++----------
 libIRDB/test/read_ehframe.cpp     |  10 ++-
 tools/meds2pdb/SConscript         |   4 +-
 13 files changed, 351 insertions(+), 44 deletions(-)
 create mode 100644 libEXEIO/SConscript
 create mode 100644 libEXEIO/SConstruct
 create mode 100644 libEXEIO/include/exeio.h
 create mode 100644 libEXEIO/include/exeio_elf.h
 create mode 100644 libEXEIO/src/SConscript
 create mode 100644 libEXEIO/src/SConstruct
 create mode 100644 libEXEIO/src/exeio_src.cpp

diff --git a/.gitattributes b/.gitattributes
index e106ae388..9fdc8f2ba 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -182,6 +182,13 @@ beaengine/include/beaengine/macros.h -text
 include/i686/config.h -text
 include/i86pc/config.h -text
 include/x86_64/config.h -text
+libEXEIO/SConscript -text
+libEXEIO/SConstruct -text
+libEXEIO/include/exeio.h -text
+libEXEIO/include/exeio_elf.h -text
+libEXEIO/src/SConscript -text
+libEXEIO/src/SConstruct -text
+libEXEIO/src/exeio_src.cpp -text
 libIRDB/LICENSE.txt -text
 libIRDB/Makefile.in -text
 libIRDB/SConscript -text
diff --git a/SConscript b/SConscript
index 923f14cec..8336e266d 100644
--- a/SConscript
+++ b/SConscript
@@ -27,6 +27,7 @@ else:
 
 #print 'env='
 #print env.Dump()
+libEXEIO=SConscript("libEXEIO/SConscript", variant_dir='scons_build/libEXEIO')
 libbea=SConscript("beaengine/SConscript", variant_dir='scons_build/beaengine')
 libMEDSannotation=SConscript("libMEDSannotation/SConscript", variant_dir='scons_build/libMEDSannotation')
 libxform=SConscript("xform/SConscript", variant_dir='scons_build/libxform')
diff --git a/libEXEIO/SConscript b/libEXEIO/SConscript
new file mode 100644
index 000000000..4440b8bb3
--- /dev/null
+++ b/libEXEIO/SConscript
@@ -0,0 +1,5 @@
+import os
+
+Import('env')
+
+SConscript("src/SConscript")
diff --git a/libEXEIO/SConstruct b/libEXEIO/SConstruct
new file mode 100644
index 000000000..c0dd68a00
--- /dev/null
+++ b/libEXEIO/SConstruct
@@ -0,0 +1,6 @@
+
+
+
+env=Environment()
+Export('env')
+SConscript("SConscript")
diff --git a/libEXEIO/include/exeio.h b/libEXEIO/include/exeio.h
new file mode 100644
index 000000000..c8d7d94fe
--- /dev/null
+++ b/libEXEIO/include/exeio.h
@@ -0,0 +1,122 @@
+#ifndef EXEIO_H
+#define EXEIO_H
+
+#include <ostream>
+#include <vector>
+#include <stddef.h>
+#include <stdint.h>
+#include <assert.h>
+
+
+namespace EXEIO
+{
+	class exeio_t; // forward decl
+
+	typedef enum { ELF64, ELF32 } execlass_t;
+
+	typedef int virtual_offset_t;
+
+
+
+	// create type to match elfio
+	class exeio_section_t
+	{
+		public: 
+			virtual bool isLoadable() const =0;
+			virtual bool isExecutable() const =0;
+			virtual bool isBSS() const =0;
+			virtual const char* get_data() const =0;
+			virtual std::string get_name() const =0;
+			virtual int get_size() const =0;
+			virtual EXEIO::virtual_offset_t get_address() const =0;
+			virtual bool mightContainStrings() const =0;
+	};		
+
+	// break naming rule for elfio compatibility
+	typedef exeio_section_t section;
+		
+	class exeio_backend_t
+	{
+		public:
+			virtual void dump_header(std::ostream& stream) =0;
+			virtual void dump_section_headers(std::ostream& stream) =0;
+			virtual void load(exeio_t* main, char* filename) =0;
+                        virtual execlass_t get_class() =0;
+			virtual virtual_offset_t get_entry() =0;
+			virtual void* get_elfio() { return NULL; }
+
+	};
+	
+	class exeio_sections_t
+	{
+		public:
+			exeio_section_t* operator[](int i) { return the_sections[i]; }
+			int size() const { return (int)the_sections.size(); }
+
+			void add_section(exeio_section_t* sec)
+			{
+				the_sections.push_back(sec);
+			}
+
+		private:
+		
+			std::vector<exeio_section_t*> the_sections;
+
+		friend class exeio_backend_t;
+		
+	};
+
+
+	class exeio_t
+	{
+		public:
+			// constructors
+			exeio_t()  { Init(); }
+			exeio_t(char* filename) { Init(); load(filename); }
+			~exeio_t() { delete backend; }
+
+                        virtual void load(std::string filename) { load((char*)filename.c_str()); }
+
+			// load the file
+			virtual void load(char* fn);
+
+			// trying to do minimal rewriting of code that uses
+			// ELFIO namespace.  
+			// This slightly odd construction of classes
+			// is used by ELFIO because it makes for nice looking code when using ELFIO.
+			// I quite like the results and there's a lot of code, so I'm mimicking it here.
+			// Unfortunately it means a less-than-clean interface for the class writer, 
+			// but we'll manage.
+			exeio_sections_t sections;
+
+			virtual virtual_offset_t get_entry() { assert(backend); return backend->get_entry(); }
+		
+			virtual void dump_header(std::ostream& stream) { assert(backend); backend->dump_header(stream); }
+			virtual void dump_section_headers(std::ostream& stream) { assert(backend); backend->dump_section_headers(stream); }
+                        virtual execlass_t get_class() { assert(backend); return backend->get_class(); }
+			virtual void* get_elfio() { assert(backend); return backend->get_elfio(); }
+
+		private:
+			void Init() { backend=NULL; }
+
+			exeio_backend_t* backend;
+
+		friend class exeio_backend;
+			
+	};
+
+	// intentionally breaking _t rule for ELFIO compatibility.
+	typedef exeio_t exeio;
+
+	// breaking _t rule for ELFIO compatibility
+	class dump_t
+	{
+		public:
+		static void header(std::ostream& stream, EXEIO::exeio_t &to_print) { to_print.dump_header(stream); }
+		static void section_headers(std::ostream& stream, EXEIO::exeio_t &to_print) { to_print.dump_section_headers(stream); }
+	};
+	
+	typedef dump_t dump;
+
+}
+#endif
diff --git a/libEXEIO/include/exeio_elf.h b/libEXEIO/include/exeio_elf.h
new file mode 100644
index 000000000..4a744a22c
--- /dev/null
+++ b/libEXEIO/include/exeio_elf.h
@@ -0,0 +1,109 @@
+#ifndef EXEIO_ELF_H
+#define EXEIO_ELF_H
+
+#include <iostream>
+#include <vector>
+#include <assert.h>
+
+
+#include "targ-config.h"
+#include "elfio/elfio.hpp"
+#include "elfio/elfio_dump.hpp"
+
+class exeio_backend;
+class exeio_section;
+
+
+namespace EXEIO
+{
+	class exeio_elf_section_t : public exeio_section_t
+	{
+		public:
+			exeio_elf_section_t(ELFIO::section *the_s) : s(the_s) { assert(s); }
+
+			bool isLoadable() const { return (s->get_flags() & SHF_ALLOC) == SHF_ALLOC; }
+			bool isExecutable() const { return (s->get_flags() & SHF_EXECINSTR) == SHF_EXECINSTR; }
+			bool isBSS() const { return (s->get_type() & SHT_NOBITS) == SHT_NOBITS; }
+			const char* get_data() const { return s->get_data(); }
+			std::string get_name() const { return s->get_name(); }
+			int get_size() const { return s->get_size(); }
+			EXEIO::virtual_offset_t get_address() const { return s->get_address(); }
+			bool mightContainStrings() const { assert(0); }
+
+		private:
+			ELFIO::section *s;
+	};
+
+	class exeio_elf_backend_t : public exeio_backend_t
+	{
+		public:
+			exeio_elf_backend_t() : e(NULL), main(NULL) {}
+			~exeio_elf_backend_t()
+			{
+				if(!main)
+					return;
+				// remove subclasses.
+				for(int i=0;i<e->sections.size(); ++i)
+				{
+					// copy each section into the main class' structure.
+					delete main->sections[i];
+				}
+
+				// remove the elfio class.
+				delete e;
+			}
+			void load(exeio* the_main, char* filename)
+			{
+				main=the_main;
+				e=new ELFIO::elfio;	
+				int res=e->load(filename);
+				assert(res);
+
+				// resize the sections.
+				for(int i=0;i<e->sections.size(); ++i)
+				{
+					// copy each section into the main class' structure.
+					main->sections.add_section(new EXEIO::exeio_elf_section_t(e->sections[i]));
+				}
+	
+			}
+                        virtual void dump_header(std::ostream& stream) 
+			{
+				assert(e);
+				ELFIO::dump::header(stream,*e);
+			}
+                        virtual void dump_section_headers(std::ostream& stream) 
+			{
+				assert(e);
+				ELFIO::dump::section_headers(stream,*e);
+			}
+                        virtual execlass_t get_class() 
+			{
+				assert(e);
+				switch(e->get_class())  
+				{ 
+					case ELFCLASS64: return ELF64;
+					case ELFCLASS32: return ELF32;
+					default: assert(0);
+				};
+			}
+
+			// get entry point of function.
+                        virtual virtual_offset_t get_entry()
+			{
+				assert(e);
+				return (virtual_offset_t)e->get_entry();
+			}
+
+			virtual void* get_elfio() { return (void*)e; }
+
+	
+		private:  
+			ELFIO::elfio* e;
+			EXEIO::exeio* main;
+	};
+	
+
+}
+
+#endif
diff --git a/libEXEIO/src/SConscript b/libEXEIO/src/SConscript
new file mode 100644
index 000000000..1cd34adcb
--- /dev/null
+++ b/libEXEIO/src/SConscript
@@ -0,0 +1,26 @@
+import os
+
+Import('env')
+myenv=env
+myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME'])
+
+
+libname="EXEIO"
+files=  '''
+	exeio_src.cpp
+	'''
+
+cpppath=''' 
+	.
+	$SECURITY_TRANSFORMS_HOME/include/
+	$SECURITY_TRANSFORMS_HOME/libEXEIO/include
+	'''
+
+myenv.Append(CCFLAGS="-Wp,-w -Wall")
+
+myenv=myenv.Clone(CPPPATH=Split(cpppath))
+lib=myenv.Library(libname, Split(files))
+
+install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib)
+Default(install)
+
diff --git a/libEXEIO/src/SConstruct b/libEXEIO/src/SConstruct
new file mode 100644
index 000000000..c0dd68a00
--- /dev/null
+++ b/libEXEIO/src/SConstruct
@@ -0,0 +1,6 @@
+
+
+
+env=Environment()
+Export('env')
+SConscript("SConscript")
diff --git a/libEXEIO/src/exeio_src.cpp b/libEXEIO/src/exeio_src.cpp
new file mode 100644
index 000000000..afecb4db3
--- /dev/null
+++ b/libEXEIO/src/exeio_src.cpp
@@ -0,0 +1,15 @@
+
+
+#include <exeio.h>
+#include <exeio_elf.h>
+
+
+using namespace EXEIO;
+using namespace std;
+
+void exeio::load(char* filename)
+{
+	backend=new exeio_elf_backend_t();
+	backend->load(this, filename);
+
+}
diff --git a/libIRDB/test/SConscript b/libIRDB/test/SConscript
index cba6a06be..dd0a1ab01 100644
--- a/libIRDB/test/SConscript
+++ b/libIRDB/test/SConscript
@@ -8,11 +8,12 @@ myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME'])
 cpppath=''' 
 	 $SECURITY_TRANSFORMS_HOME/include 
 	 $SECURITY_TRANSFORMS_HOME/libIRDB/include 
+	 $SECURITY_TRANSFORMS_HOME/libEXEIO/include 
 	 $SECURITY_TRANSFORMS_HOME/beaengine/include 
 	'''
 
 LIBPATH="$SECURITY_TRANSFORMS_HOME/lib"
-LIBS=Split("IRDB-core IRDB-cfg IRDB-util pqxx BeaEngine_s_d pq")
+LIBS=Split("IRDB-core IRDB-cfg IRDB-util pqxx BeaEngine_s_d pq EXEIO")
 
 myenv=myenv.Clone(CPPPATH=Split(cpppath))
 pgm=myenv.Program("fill_in_indtargs.exe",  Split("read_ehframe.cpp fill_in_indtargs.cpp check_thunks.cpp"), LIBPATH=LIBPATH, LIBS=LIBS)
diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp
index 107fe8010..8ca51fe68 100644
--- a/libIRDB/test/fill_in_indtargs.cpp
+++ b/libIRDB/test/fill_in_indtargs.cpp
@@ -30,15 +30,13 @@
 // #include <elf.h>
 #include <ctype.h>
 
-#include "targ-config.h"
-#include "elfio/elfio.hpp"
-#include "elfio/elfio_dump.hpp"
+#include <exeio.h>
 #include "beaengine/BeaEngine.h"
 #include "check_thunks.hpp"
 
 using namespace libIRDB;
 using namespace std;
-using namespace ELFIO;
+using namespace EXEIO;
 
 #define HELLNODE_ID 0
 #define INDIRECT_CALLS_ID 1
@@ -66,15 +64,15 @@ map< Instruction_t* , set<Instruction_t*> > preds;
 // keep track of jmp tables
 map< Instruction_t*, set<Instruction_t*> > jmptables;
 
-void check_for_PIC_switch_table32_type2(Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop, const set<int>& thunk_bases);
-void check_for_PIC_switch_table32_type3(Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop, const set<int>& thunk_bases);
-void check_for_PIC_switch_table32(FileIR_t*, Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop, const set<int>& thunk_bases);
-void check_for_PIC_switch_table64(FileIR_t*, Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop);
+void check_for_PIC_switch_table32_type2(Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<int>& thunk_bases);
+void check_for_PIC_switch_table32_type3(Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<int>& thunk_bases);
+void check_for_PIC_switch_table32(FileIR_t*, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<int>& thunk_bases);
+void check_for_PIC_switch_table64(FileIR_t*, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop);
 
 // get switch table structure, determine ib targets
 // handle both 32 and 64 bit
-void check_for_nonPIC_switch_table(FileIR_t*, Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop);
-void check_for_nonPIC_switch_table_pattern2(FileIR_t*, Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop);
+void check_for_nonPIC_switch_table(FileIR_t*, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop);
+void check_for_nonPIC_switch_table_pattern2(FileIR_t*, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop);
 
 void check_for_indirect_jmp(FileIR_t* const firp, Instruction_t* const insn);
 void check_for_indirect_call(FileIR_t* const firp, Instruction_t* const insn);
@@ -181,11 +179,11 @@ bool is_possible_target(uintptr_t p, uintptr_t addr)
 
 }
 
-ELFIO::section*  find_section(int addr, ELFIO::elfio *elfiop)
+EXEIO::section*  find_section(int addr, EXEIO::exeio *elfiop)
 {
          for ( int i = 0; i < elfiop->sections.size(); ++i )
          {   
-                 ELFIO::section* pSec = elfiop->sections[i];
+                 EXEIO::section* pSec = elfiop->sections[i];
                  assert(pSec);
                  if(pSec->get_address() > addr)
                          continue;
@@ -273,7 +271,7 @@ void mark_targets(FileIR_t *firp)
 	}
 }
 
-void get_instruction_targets(FileIR_t *firp, ELFIO::elfio* elfiop, const set<int>& thunk_bases)
+void get_instruction_targets(FileIR_t *firp, EXEIO::exeio* elfiop, const set<int>& thunk_bases)
 {
 
         for(
@@ -328,14 +326,13 @@ void get_instruction_targets(FileIR_t *firp, ELFIO::elfio* elfiop, const set<int
 
 void get_executable_bounds(FileIR_t *firp, const section* shdr)
 {
-	int flags = shdr->get_flags();
 
 	/* not a loaded section */
-	if( (flags & SHF_ALLOC) != SHF_ALLOC)
+	if( !shdr->isLoadable()) 
 		return;
 
 	/* loaded, and contains instruction, record the bounds */
-	if( (flags & SHF_EXECINSTR) != SHF_EXECINSTR)
+	if( !shdr->isExecutable() )
 		return;
 
 	int first=shdr->get_address();
@@ -348,18 +345,18 @@ void get_executable_bounds(FileIR_t *firp, const section* shdr)
 
 void infer_targets(FileIR_t *firp, section* shdr)
 {
-	int flags = shdr->get_flags();
+//	int flags = shdr->get_flags();
 
-	if( (flags & SHF_ALLOC) != SHF_ALLOC)
+	if( ! shdr->isLoadable()) // (flags & SHF_ALLOC) != SHF_ALLOC)
 		/* not a loaded section */
 		return;
 
-	if( (flags & SHF_EXECINSTR) == SHF_EXECINSTR)
+	if( shdr->isExecutable() ) //(flags & SHF_EXECINSTR) == SHF_EXECINSTR)
 		/* loaded, but contains instruction.  we'll look through the VariantIR for this section. */
 		return;
 
 	/* if the type is NOBITS, then there's no actual data to look through */
-	if(shdr->get_type()==SHT_NOBITS)
+	if(shdr->isBSS() ) // get_type()==SHT_NOBITS)
 		return;
 
 	const char* data=shdr->get_data() ; // C(char*)malloc(shdr->sh_size);
@@ -506,7 +503,7 @@ bool backup_until(const char* insn_type_regex, Instruction_t *& prev, Instructio
 /*
  * check_for_PIC_switch_table32 - look for switch tables in PIC code for 32-bit code.
  */
-void check_for_PIC_switch_table32(FileIR_t *firp, Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop, const set<int> &thunk_bases)
+void check_for_PIC_switch_table32(FileIR_t *firp, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<int> &thunk_bases)
 {
 #if 0
 
@@ -587,7 +584,7 @@ cout<<hex<<"Found switch dispatch at "<<I3->GetAddress()->GetVirtualOffset()<< "
 		int table_base=*it+table_offset;
 
 		// find the section with the data table
-        	ELFIO::section *pSec=find_section(table_base,elfiop);
+        	EXEIO::section *pSec=find_section(table_base,elfiop);
 		if(!pSec)
 			continue;
 
@@ -660,7 +657,7 @@ cout<<hex<<"Found switch dispatch at "<<I3->GetAddress()->GetVirtualOffset()<< "
 
 }
 
-void check_for_PIC_switch_table32_type2(Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop, const set<int> &thunk_bases)
+void check_for_PIC_switch_table32_type2(Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<int> &thunk_bases)
 {
 #if 0
 
@@ -715,7 +712,7 @@ cout<<hex<<"Found (type2) switch dispatch at "<<I3->GetAddress()->GetVirtualOffs
 		int table_base=*it+table_offset;
 
 		// find the section with the data table
-        	ELFIO::section *pSec=find_section(table_base,elfiop);
+        	EXEIO::section *pSec=find_section(table_base,elfiop);
 		if(!pSec)
 			continue;
 
@@ -771,7 +768,7 @@ cout<<"Checking target base:" << std::hex << table_base+table_entry << ", " << t
 
 }
 
-void check_for_PIC_switch_table32_type3(Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop, const set<int> &thunk_bases)
+void check_for_PIC_switch_table32_type3(Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<int> &thunk_bases)
 {
 #if 0
 
@@ -801,7 +798,7 @@ cout<<hex<<"Found (type3) switch dispatch at "<<I5->GetAddress()->GetVirtualOffs
 		
 	{
 		// find the section with the data table
-        	ELFIO::section *pSec=find_section(table_base,elfiop);
+        	EXEIO::section *pSec=find_section(table_base,elfiop);
 		if(!pSec)
 			return;
 
@@ -863,7 +860,7 @@ cout<<"Checking target base:" << std::hex << table_entry << ", " << table_base+i
  * if so, see if we can trace back a few instructions to find a
  * the start of the table.
  */
-void check_for_PIC_switch_table64(FileIR_t* firp, Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop)
+void check_for_PIC_switch_table64(FileIR_t* firp, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop)
 {
 
         /* here's the pattern we're looking for */
@@ -945,7 +942,7 @@ DN:   0x4824e0: .long 0x4824e0-LN
         int D1=strtol(disasm.Argument2.ArgMnemonic, NULL, 16);
 
         // find the section with the data table
-        ELFIO::section *pSec=find_section(D1,elfiop);
+        EXEIO::section *pSec=find_section(D1,elfiop);
 
         // sanity check there's a section
         if(!pSec)
@@ -1032,7 +1029,7 @@ DN:   0x4824e0: .long 0x4824e0-LN
 
 	nb: handles both 32 and 64 bit
 */
-void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop)
+void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop)
 {
 	Instruction_t *I1 = NULL;
 	Instruction_t *IJ = insn;
@@ -1075,7 +1072,7 @@ void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn,
 	cout<<"(nonPIC-pattern2): size of jmp table: "<< table_size << endl;
 
 	// find the section with the data table
-    ELFIO::section *pSec=find_section(table_offset,elfiop);
+    EXEIO::section *pSec=find_section(table_offset,elfiop);
 	if(!pSec)
 	{
 		return;
@@ -1133,7 +1130,7 @@ void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn,
 
 	nb: handles both 32 and 64 bit
 */
-void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop)
+void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop)
 {
 	Instruction_t *I1 = NULL;
 	Instruction_t *I2 = NULL;
@@ -1193,7 +1190,7 @@ void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DISASM d
 		cout<<"(nonPIC): size of jmp table: "<< table_size << endl;
 
 	// find the section with the data table
-	ELFIO::section *pSec=find_section(table_offset,elfiop);
+	EXEIO::section *pSec=find_section(table_offset,elfiop);
 	if(!pSec)
 	{
 		cout<<hex<<"(nonPIC): could not find jump table in section"<<endl;
@@ -1350,7 +1347,7 @@ void calc_preds(FileIR_t* firp)
 }
 
 
-void fill_in_indtargs(FileIR_t* firp, elfio* elfiop)
+void fill_in_indtargs(FileIR_t* firp, exeio* elfiop)
 {
 	if(getenv("IB_VERBOSE")!=0)
         	for(
@@ -1377,14 +1374,18 @@ void fill_in_indtargs(FileIR_t* firp, elfio* elfiop)
 
 	calc_preds(firp);
 
+#if 0
+/* info gotten from EXEIO class now. */
         ::Elf64_Off sec_hdr_off, sec_off;
         ::Elf_Half secnum, strndx, secndx;
         ::Elf_Word secsize;
 
         /* Read ELF header */
-        sec_hdr_off = elfiop->get_sections_offset();
-        secnum = elfiop->sections.size();
-        strndx = elfiop->get_section_name_str_index();
+        virtual_offset_t sec_hdr_off = elfiop->get_sections_offset();
+        virtual_offset_t strndx = elfiop->get_section_name_str_index();
+#endif
+        int secnum = elfiop->sections.size();
+	int secndx=0;
 
 	/* look through each section and record bounds */
         for (secndx=1; secndx<secnum; secndx++)
@@ -1415,7 +1416,7 @@ void fill_in_indtargs(FileIR_t* firp, elfio* elfiop)
 	cout<<"========================================="<<endl;
 
 	/* Read the exception handler frame so that those indirect branches are accounted for */
-	void read_ehframe(FileIR_t* firp, elfio* );
+	void read_ehframe(FileIR_t* firp, EXEIO::exeio* );
         read_ehframe(firp, elfiop);
 
 	cout<<"========================================="<<endl;
@@ -1509,11 +1510,11 @@ main(int argc, char* argv[])
 
 			jmptables.clear();
 
-        		ELFIO::elfio*    elfiop=new ELFIO::elfio;
+        		EXEIO::exeio*    elfiop=new EXEIO::exeio;
         		elfiop->load("readeh_tmp_file.exe");
 		
-        		ELFIO::dump::header(cout,*elfiop);
-        		ELFIO::dump::section_headers(cout,*elfiop);
+        		EXEIO::dump::header(cout,*elfiop);
+        		EXEIO::dump::section_headers(cout,*elfiop);
 
 
 			// find all indirect branch targets
diff --git a/libIRDB/test/read_ehframe.cpp b/libIRDB/test/read_ehframe.cpp
index 94166f356..fdb0bdf66 100644
--- a/libIRDB/test/read_ehframe.cpp
+++ b/libIRDB/test/read_ehframe.cpp
@@ -29,10 +29,13 @@
 #include <assert.h>
 #include <string.h>
 
+#include <exeio.h>
+
 #include "targ-config.h"
 #include "elfio/elfio.hpp"
 #include "elfio/elfio_dump.hpp"
 
+
 using namespace libIRDB;
 using namespace std;
 
@@ -689,8 +692,13 @@ void linear_search_fdes (struct object *ob, fde *this_fde, int offset)
   	return;
 }
 
-void read_ehframe(FileIR_t* virp, ELFIO::elfio* elfiop)
+void read_ehframe(FileIR_t* virp, EXEIO::exeio* exeiop)
 {
+	assert(exeiop);
+	ELFIO::elfio *elfiop=reinterpret_cast<ELFIO::elfio*>(exeiop->get_elfio());
+	if(!elfiop)
+		return;	// skip entire analysis for non-elf files as eh-frame is way different.
+
 	/* get first instruction */
 	Instruction_t* insn=*(virp->GetInstructions().begin());
 	assert(insn);
diff --git a/tools/meds2pdb/SConscript b/tools/meds2pdb/SConscript
index 2a0d6a5b1..3081b582f 100644
--- a/tools/meds2pdb/SConscript
+++ b/tools/meds2pdb/SConscript
@@ -24,8 +24,8 @@ LIBPATH="$SECURITY_TRANSFORMS_HOME/lib"
 LIBS=Split("IRDB-core IRDB-cfg IRDB-util pqxx xform BeaEngine_s_d rewrite MEDSannotation ") 
 myenv=myenv.Clone(CPPPATH=Split(cpppath))
 pgm=myenv.Program(pgm,  files,  LIBPATH=LIBPATH, LIBS=LIBS)
-install=myenv.Install("$SECURITY_TRANSFORMS_HOME/bin/", pgm)
-Default(install)
+Default(myenv.Install("$SECURITY_TRANSFORMS_HOME/bin/", pgm))
+Default(myenv.Install("$SECURITY_TRANSFORMS_HOME/tools/meds2pdb/", pgm))
 
 	
 	
-- 
GitLab