diff --git a/SConscript b/SConscript
index 718e08038424c9fab7cc1c603d92e28bbe3091f8..529021a66d0ab99b16cd62e95542127071555b96 100644
--- a/SConscript
+++ b/SConscript
@@ -3,6 +3,19 @@ import os
 
 Import('env')
 
+env.Replace(debug=ARGUMENTS.get("debug",0))
+if int(env['debug']) == 1:
+        print "Setting debug mode"
+        env.Append(CFLAGS=" -g ")
+        env.Append(CXXFLAGS=" -g ")
+        env.Append(LINKFLAGS=" -g ")
+else:
+        print "Setting release mode"
+        env.Append(CFLAGS=" -O3 ")
+        env.Append(CXXFLAGS=" -O3 ")
+        env.Append(LINKFLAGS=" -O3 ")
+
+
 lib=SConscript("src/SConscript")
 
 Return('lib')
diff --git a/include/ehp.hpp b/include/ehp.hpp
index 827ce8221aa5c74dc7c4a53d2c3d93147b20afcb..bbdb80a84fba36a4cd815c08589e13b6c2994b41 100644
--- a/include/ehp.hpp
+++ b/include/ehp.hpp
@@ -92,6 +92,8 @@ class LSDACallSite_t
 	public:
 	virtual ~LSDACallSite_t() {}
 	virtual shared_ptr<LSDCallSiteActionVector_t> getActionTable() const =0;
+	virtual uint64_t getCallSiteAddress() const  =0;
+	virtual uint64_t getCallSiteEndAddress() const  =0;
 	virtual uint64_t getLandingPadAddress() const  =0;
 	virtual void print() const=0;
 };
@@ -140,8 +142,8 @@ class EHFrameParser_t
 	virtual const shared_ptr<FDEVector_t> getFDEs() const =0;
 	virtual const shared_ptr<CIEVector_t> getCIEs() const =0;
 
-	static unique_ptr<EHFrameParser_t> factory(const char* const filename);
-	static unique_ptr<EHFrameParser_t> factory(
+	static unique_ptr<const EHFrameParser_t> factory(const string filename);
+	static unique_ptr<const EHFrameParser_t> factory(
 		uint8_t ptrsize,
 		const string eh_frame_data, const uint64_t eh_frame_data_start_addr,
 		const string eh_frame_hdr_data, const uint64_t eh_frame_hdr_data_start_addr,
diff --git a/lib/.gitignore b/lib/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/SConscript b/src/SConscript
index 231f1e62cd11a32a96c38446eac353a2d94f061a..76e6b7eaa932659f60ebdc88b1737c7d72013c4d 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -9,6 +9,7 @@ files="ehp.cpp"
 
 cpppath='''
 	../include
+	../third-party/elfio-code
         '''
 
 
@@ -16,7 +17,7 @@ LIBPATH="$SECURITY_TRANSFORMS_HOME/lib"
 LIBS=Split("")
 
 myenv=myenv.Clone(CPPPATH=Split(cpppath))
-myenv.Append(CXXFLAGS = " -std=c++11 -Wall -Werror -fmax-errors=1")
+myenv.Append(CXXFLAGS = " -std=c++11 -Wall -Werror -fmax-errors=2")
 
 lib=myenv.Library("ehp",  Split(files), LIBPATH=LIBPATH, LIBS=LIBS)
 install=myenv.Install("../lib/", lib)
diff --git a/src/ehp.cpp b/src/ehp.cpp
index 161b22b4412aabc97a5b426322c2920cf3e122ce..cea2def260f65e223d8cbbbc3cca21c7877b1dc7 100644
--- a/src/ehp.cpp
+++ b/src/ehp.cpp
@@ -6,16 +6,19 @@
 #include <string.h>
 #include <map>
 #include <assert.h>
-#include <elf.h>
 #include <algorithm>
 #include <memory>
 
-#include "ehp.hpp"
+#include <ehp.hpp>
 #include "ehp_priv.hpp"
 #include "scoop_replacement.hpp"
 
+#include <elfio/elfio.hpp>
+#include <elf.h>
+
 using namespace std;
 using namespace EHP;
+using namespace ELFIO;
 
 #define ALLOF(s) begin(s), end(s)
 
@@ -1613,6 +1616,17 @@ void split_eh_frame_impl_t<ptrsize>::print() const
 	});
 }
 
+
+template <int ptrsize>
+shared_ptr<CallSiteVector_t> lsda_t<ptrsize>::getCallSites() const 
+{
+	auto ret=shared_ptr<CallSiteVector_t>(new CallSiteVector_t());
+	transform(ALLOF(call_site_table), back_inserter(*ret), 
+		[](const lsda_call_site_t<ptrsize> &a) { return shared_ptr<LSDACallSite_t>(new lsda_call_site_t<ptrsize>(a));});
+	return shared_ptr<CallSiteVector_t>(ret);
+}
+
+
 template <int ptrsize>
 const shared_ptr<FDEVector_t>  split_eh_frame_impl_t<ptrsize>::getFDEs() const
 {
@@ -1633,12 +1647,41 @@ const shared_ptr<CIEVector_t>  split_eh_frame_impl_t<ptrsize>::getCIEs() const
 	
 
 
-unique_ptr<EHFrameParser_t> EHFrameParser_t::factory(const char* const filename)
+unique_ptr<const EHFrameParser_t> EHFrameParser_t::factory(const string filename)
 {
-	assert(0);
+	auto elfiop=unique_ptr<elfio>(new elfio);
+	if(!elfiop->load(filename))
+	{
+		throw invalid_argument(string() + "Cannot open file: " + filename);
+	}
+
+	auto get_info=[&](const string name) -> pair<string,uint64_t>
+		{
+			const auto &sec=elfiop->sections[name.c_str()];
+			auto contents=string(sec->get_data(), sec->get_size());
+			auto addr=sec->get_address();
+			return {contents,addr};	
+
+		};
+
+	const auto eh_frame_section=get_info(".eh_frame");
+	const auto eh_frame_hdr_section=get_info(".eh_frame_hdr");
+	const auto gcc_except_table_section=get_info(".gcc_except_table");
+
+	const auto ptrsize = elfiop->get_class()==ELFCLASS64 ? 8 :
+	                     elfiop->get_class()==ELFCLASS32 ? 4 : 
+	                     0; 
+	if(ptrsize==0)
+		throw invalid_argument(string() + "Invalid ELF class in : " + filename);
+
+	return EHFrameParser_t::factory(ptrsize,
+			eh_frame_section.first, eh_frame_section.second,
+			eh_frame_hdr_section.first, eh_frame_hdr_section.second,
+			gcc_except_table_section.first, gcc_except_table_section.second);
+
 }
 
-unique_ptr<EHFrameParser_t> EHFrameParser_t::factory(
+unique_ptr<const EHFrameParser_t> EHFrameParser_t::factory(
 	uint8_t ptrsize,
 	const string eh_frame_data, const uint64_t eh_frame_data_start_addr,
 	const string eh_frame_hdr_data, const uint64_t eh_frame_hdr_data_start_addr,
@@ -1648,13 +1691,17 @@ unique_ptr<EHFrameParser_t> EHFrameParser_t::factory(
 	const auto eh_frame_sr=ScoopReplacement_t(eh_frame_data,eh_frame_data_start_addr);
 	const auto eh_frame_hdr_sr=ScoopReplacement_t(eh_frame_hdr_data,eh_frame_hdr_data_start_addr);
 	const auto gcc_except_table_sr=ScoopReplacement_t(gcc_except_table_data,gcc_except_table_data_start_addr);
+	auto ret_val=(EHFrameParser_t*)nullptr;
 	if(ptrsize==4)
-		return unique_ptr<EHFrameParser_t>(new split_eh_frame_impl_t<4>(eh_frame_sr,eh_frame_hdr_sr,gcc_except_table_sr));
+		ret_val=new split_eh_frame_impl_t<4>(eh_frame_sr,eh_frame_hdr_sr,gcc_except_table_sr);
 	else if(ptrsize==8)
-		return unique_ptr<EHFrameParser_t>(new split_eh_frame_impl_t<8>(eh_frame_sr,eh_frame_hdr_sr,gcc_except_table_sr));
+		ret_val=new split_eh_frame_impl_t<8>(eh_frame_sr,eh_frame_hdr_sr,gcc_except_table_sr);
 	else
 		throw std::out_of_range("ptrsize must be 4 or 8");
-	
+
+	ret_val->parse();
+
+	return unique_ptr<const EHFrameParser_t>(ret_val);
 }
 
 	
diff --git a/src/ehp_priv.hpp b/src/ehp_priv.hpp
index 832384d68af152e093a5fddeee214a6b6cd357f7..4864b3b08f1e9ee87dc9eada16118a9596f8fa13 100644
--- a/src/ehp_priv.hpp
+++ b/src/ehp_priv.hpp
@@ -9,7 +9,6 @@
 #include <string.h>
 #include <map>
 #include <assert.h>
-#include <elf.h>
 #include <algorithm>
 #include <memory>
 #include <set>
@@ -243,6 +242,8 @@ class lsda_call_site_t : public LSDACallSite_t, private eh_frame_util_t<ptrsize>
 	const std::vector<lsda_call_site_action_t <ptrsize> >& getActionTableInternal() const { return action_table; }
 	      std::vector<lsda_call_site_action_t <ptrsize> >& getActionTableInternal()       { return action_table; }
 
+	uint64_t getCallSiteAddress() const  { return call_site_addr ; } 
+	uint64_t getCallSiteEndAddress() const  { return call_site_end_addr ; } 
 	uint64_t getLandingPadAddress() const  { return landing_pad_addr ; } 
 
 	bool parse_lcs(	
@@ -267,7 +268,7 @@ class lsda_call_site_t : public LSDACallSite_t, private eh_frame_util_t<ptrsize>
 template <int ptrsize>  using call_site_table_t = std::vector<lsda_call_site_t <ptrsize> > ;
 
 template <int ptrsize>
-class lsda_t : private LSDA_t, private eh_frame_util_t<ptrsize>
+class lsda_t : public LSDA_t, private eh_frame_util_t<ptrsize>
 {
 	private:
 	uint8_t landing_pad_base_encoding;
@@ -296,7 +297,7 @@ class lsda_t : private LSDA_t, private eh_frame_util_t<ptrsize>
 	                );
 	void print() const;
 
-        shared_ptr<CallSiteVector_t> getCallSites() const { assert(0); } 
+        shared_ptr<CallSiteVector_t> getCallSites() const ;
         const call_site_table_t<ptrsize> getCallSitesInternal() const { return call_site_table;}
 
 };
@@ -342,7 +343,7 @@ class fde_contents_t : public FDEContents_t, eh_frame_util_t<ptrsize>
 	const eh_program_t<ptrsize>& getProgram() const ;
 	eh_program_t<ptrsize>& getProgram() ;
 
-	shared_ptr<LSDA_t> getLSDA() const { assert(0); }
+	shared_ptr<LSDA_t> getLSDA() const { return shared_ptr<LSDA_t>(new lsda_t<ptrsize>(lsda)) ;  }
 	const lsda_t<ptrsize>& getLSDAInternal() const { return lsda; }
 
 	bool parse_fde(
diff --git a/test/test.cpp b/test/test.cpp
index c23a3cb79e395f9a840e9f6af328c5865df1bde2..58333e8f5faa7ba17e687497736caa6935df9fa0 100644
--- a/test/test.cpp
+++ b/test/test.cpp
@@ -2,6 +2,7 @@
 
 #include <ehp.hpp>
 #include <iostream>
+#include <assert.h>
 
 using namespace std;
 using namespace EHP;
@@ -13,6 +14,28 @@ void usage(int argc, char* argv[])
 }
 
 
+
+void print_lps(const EHFrameParser_t* ehp)
+{
+	const auto fdes=ehp->getFDEs();
+	cout<<hex;
+	for(const auto fde : *fdes)
+	{
+		cout<<"Found FDE at : " << fde->getStartAddress() << "-"<<fde->getEndAddress()<<endl;
+		const auto lsda=fde->getLSDA();
+		assert(lsda);
+		const auto callsites=lsda->getCallSites();
+		assert(callsites);
+
+		for(const auto cs : *callsites)
+		{
+			cout<<"\tCall site (0x"<<cs->getCallSiteAddress()<<"-"<<cs->getCallSiteEndAddress()
+			    <<") with landing pad=0x"<<cs->getLandingPadAddress()<<endl;
+		}
+	}
+	cout<<dec;
+}
+
 int main(int argc, char* argv[])
 {
 
@@ -24,5 +47,8 @@ int main(int argc, char* argv[])
 	auto ehp = EHFrameParser_t::factory(argv[1]);
 	ehp->print();
 
+
+	print_lps(ehp.get());
+
 	return 0;
 }