From 173beca81faecfed391fa4c6c881ccf8f49c002c Mon Sep 17 00:00:00 2001
From: Jason Hiser <jdhiser@gmail.com>
Date: Tue, 23 Apr 2019 10:10:48 -0400
Subject: [PATCH] simplified interface to just return const pointers instead of
 shared ptrs.  no one needs ownership of anything

---
 include/ehp.hpp  | 48 ++++++++++++++++----------------
 src/ehp.cpp      | 55 ++++++++++++++++++++++++++++++++-----
 src/ehp_priv.hpp | 71 ++++++++++++++++++++++++++++--------------------
 3 files changed, 115 insertions(+), 59 deletions(-)

diff --git a/include/ehp.hpp b/include/ehp.hpp
index d88a162..d707265 100644
--- a/include/ehp.hpp
+++ b/include/ehp.hpp
@@ -38,17 +38,17 @@ class EHProgramInstruction_t
 	EHProgramInstruction_t(const EHProgramInstruction_t&) {}
 	public: 
 	virtual ~EHProgramInstruction_t() {}
-	virtual void print(uint64_t &pc, int64_t caf=1) const=0;
-	virtual bool isNop() const =0;
-	virtual bool isDefCFAOffset() const =0;
-	virtual bool isRestoreState() const =0;
-	virtual bool isRememberState() const =0;
-	virtual const EHProgramInstructionByteVector_t& getBytes() const =0;
-        virtual bool advance(uint64_t &cur_addr, uint64_t CAF) const =0;
+	virtual void print(uint64_t &pc, int64_t caf=1) const = 0;
+	virtual bool isNop() const = 0;
+	virtual bool isDefCFAOffset() const = 0;
+	virtual bool isRestoreState() const = 0;
+	virtual bool isRememberState() const = 0;
+	virtual const EHProgramInstructionByteVector_t& getBytes() const = 0;
+        virtual bool advance(uint64_t &cur_addr, uint64_t CAF)     const = 0;
 
 };
 
-using EHProgramInstructionVector_t = vector<shared_ptr<EHProgramInstruction_t> >;
+using EHProgramInstructionVector_t = vector<const EHProgramInstruction_t*>;
 class EHProgram_t
 {
 	protected:
@@ -56,8 +56,8 @@ class EHProgram_t
 	EHProgram_t(const EHProgram_t&) {}
 	public:
 	virtual ~EHProgram_t() {}
-	virtual void print(const uint64_t start_addr, const int64_t caf) const=0;
-	virtual shared_ptr<EHProgramInstructionVector_t> getInstructions() const =0;
+	virtual void print(const uint64_t start_addr, const int64_t caf) const =0;
+	virtual const EHProgramInstructionVector_t* getInstructions()          const =0;
 };
 
 class CIEContents_t 
@@ -103,7 +103,7 @@ class LSDATypeTableEntry_t
 	
 };
 
-using LSDACallSiteActionVector_t=vector<shared_ptr<LSDACallSiteAction_t> >;
+using LSDACallSiteActionVector_t=vector<const LSDACallSiteAction_t*>;
 class LSDACallSite_t 
 {
 	protected:
@@ -111,15 +111,15 @@ class LSDACallSite_t
 	LSDACallSite_t(const LSDACallSite_t&) {}
 	public:
 	virtual ~LSDACallSite_t() {}
-	virtual shared_ptr<LSDACallSiteActionVector_t> getActionTable() const =0;
+	virtual const LSDACallSiteActionVector_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;
 };
 
-using CallSiteVector_t  = vector<shared_ptr<LSDACallSite_t> >;
-using TypeTableVector_t = vector<shared_ptr<LSDATypeTableEntry_t> >;
+using CallSiteVector_t  = vector<const LSDACallSite_t*>;
+using TypeTableVector_t = vector<const LSDATypeTableEntry_t*>;
 
 class LSDA_t 
 {
@@ -130,10 +130,12 @@ class LSDA_t
 	virtual ~LSDA_t() {}
 	virtual uint8_t getTTEncoding() const =0;
 	virtual void print() const=0;
-        virtual shared_ptr<CallSiteVector_t> getCallSites() const =0;
-        virtual shared_ptr<TypeTableVector_t> getTypeTable() const =0;
+        virtual const CallSiteVector_t* getCallSites() const =0;
+        virtual const TypeTableVector_t* getTypeTable() const =0;
+	unique_ptr<LSDA_t> factory(const string lsda_data, const uint64_t lsda_start_addr);
 };
 
+
 class FDEContents_t 
 {
 	protected:
@@ -145,15 +147,15 @@ class FDEContents_t
 	virtual uint64_t getEndAddress() const =0;
 	virtual const CIEContents_t& getCIE() const =0;
 	virtual const EHProgram_t& getProgram() const =0;
-	virtual shared_ptr<LSDA_t> getLSDA() const =0;
+	virtual const LSDA_t* getLSDA() const =0;
 	virtual uint64_t getLSDAAddress() const =0;
 	virtual void print() const=0;	// move to ostream?  toString?
 
 };
 
 
-using FDEVector_t = vector<shared_ptr<FDEContents_t> > ;
-using CIEVector_t = vector<shared_ptr<CIEContents_t> > ;
+using FDEVector_t = vector<const FDEContents_t*>;
+using CIEVector_t = vector<const CIEContents_t*>;
 class EHFrameParser_t 
 {
 	protected:
@@ -163,8 +165,8 @@ class EHFrameParser_t
 	virtual ~EHFrameParser_t() {}
 	virtual bool parse()=0;
 	virtual void print() const=0;
-	virtual const shared_ptr<FDEVector_t> getFDEs() const =0;
-	virtual const shared_ptr<CIEVector_t> getCIEs() const =0;
+	virtual const FDEVector_t* getFDEs() const =0;
+	virtual const CIEVector_t* getCIEs() const =0;
 	virtual const FDEContents_t* findFDE(uint64_t addr) const =0; 
 
 	static unique_ptr<const EHFrameParser_t> factory(const string filename);
@@ -177,8 +179,8 @@ class EHFrameParser_t
 };
 
 // e.g.
-// const auto & ehparser=EHFrameParse_t::factory("a.ncexe");
-// for(auto &b : ehparser->getFDES()) { ... } 
+// const auto &ehparser=EHFrameParse_t::factory("a.out");
+// for(const auto &fde : ehparser->getFDES()) { ... } 
 
 
 }
diff --git a/src/ehp.cpp b/src/ehp.cpp
index d2d4746..13f26f3 100644
--- a/src/ehp.cpp
+++ b/src/ehp.cpp
@@ -1173,12 +1173,19 @@ lsda_call_site_t<ptrsize>::lsda_call_site_t() :
 {}
 
 template <int ptrsize>
-shared_ptr<LSDACallSiteActionVector_t> lsda_call_site_t<ptrsize>::getActionTable() const       
+const LSDACallSiteActionVector_t* lsda_call_site_t<ptrsize>::getActionTable() const       
 { 
+	if(action_table_cache.size() == 0)
+	{
+		transform(ALLOF(action_table), back_inserter(action_table_cache), [](const lsda_call_site_action_t<ptrsize> &a) { return &a;});
+	}
+	return &action_table_cache;
+#if 0
 	auto ret=shared_ptr<LSDACallSiteActionVector_t>(new LSDACallSiteActionVector_t());
 	transform(ALLOF(action_table), back_inserter(*ret), 
 		[](const lsda_call_site_action_t<ptrsize> &a) { return shared_ptr<LSDACallSiteAction_t>(new lsda_call_site_action_t<ptrsize>(a));});
 	return shared_ptr<LSDACallSiteActionVector_t>(ret);
+#endif
 }
 
 
@@ -1654,52 +1661,86 @@ void split_eh_frame_impl_t<ptrsize>::print() const
 
 
 template <int ptrsize>
-shared_ptr<EHProgramInstructionVector_t> eh_program_t<ptrsize>::getInstructions() const 
+const EHProgramInstructionVector_t* eh_program_t<ptrsize>::getInstructions() const 
 {
+	if(instructions_cache.size()==0)
+	{
+		transform(ALLOF(instructions), back_inserter(instructions_cache), [](const eh_program_insn_t<ptrsize> &a) { return &a;});
+	}
+	return &instructions_cache;
+#if 0
 	auto ret=shared_ptr<EHProgramInstructionVector_t>(new EHProgramInstructionVector_t());
 	transform(ALLOF(getInstructionsInternal()), back_inserter(*ret), 
 		[](const eh_program_insn_t<ptrsize> &a) { return shared_ptr<EHProgramInstruction_t>(new eh_program_insn_t<ptrsize>(a));});
 	return shared_ptr<EHProgramInstructionVector_t>(ret);
+#endif
 	
 }
 
-
 template <int ptrsize>
-shared_ptr<TypeTableVector_t> lsda_t<ptrsize>::getTypeTable() const 
+const TypeTableVector_t* lsda_t<ptrsize>::getTypeTable() const 
 {
+	if(type_table_cache.size()==0)
+	{
+		transform(ALLOF(type_table), back_inserter(type_table_cache), [](const lsda_type_table_entry_t<ptrsize> &a) { return &a; });
+	}
+	return &type_table_cache;
+#if 0
 	auto ret=shared_ptr<TypeTableVector_t>(new TypeTableVector_t());
 	transform(ALLOF(type_table), back_inserter(*ret), 
 		[](const lsda_type_table_entry_t<ptrsize> &a) { return shared_ptr<LSDATypeTableEntry_t>(new lsda_type_table_entry_t<ptrsize>(a));});
 	return shared_ptr<TypeTableVector_t>(ret);
+#endif
 }
 
 
 template <int ptrsize>
-shared_ptr<CallSiteVector_t> lsda_t<ptrsize>::getCallSites() const 
+const CallSiteVector_t* lsda_t<ptrsize>::getCallSites() const 
 {
+	if(call_site_table_cache.size()==0)
+	{
+		transform(ALLOF(call_site_table), back_inserter(call_site_table_cache), [](const lsda_call_site_t<ptrsize> &a) { return &a;});
+	}
+	return &call_site_table_cache;
+#if 0
 	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);
+#endif
 }
 
 
 template <int ptrsize>
-const shared_ptr<FDEVector_t>  split_eh_frame_impl_t<ptrsize>::getFDEs() const
+const FDEVector_t*  split_eh_frame_impl_t<ptrsize>::getFDEs() const
 {
+	if(fdes_cache.size()==0)
+	{
+		transform(ALLOF(fdes), back_inserter(fdes_cache), [](const fde_contents_t<ptrsize> &a) { return &a; });
+	}
+	return &fdes_cache;
+#if 0
 	auto ret=shared_ptr<FDEVector_t>(new FDEVector_t());
 	transform(ALLOF(fdes), back_inserter(*ret), 
 		[](const fde_contents_t<ptrsize> &a) { return shared_ptr<FDEContents_t>(new fde_contents_t<ptrsize>(a));});
 	return shared_ptr<FDEVector_t>(ret);
+#endif
 }
 
 template <int ptrsize>
-const shared_ptr<CIEVector_t>  split_eh_frame_impl_t<ptrsize>::getCIEs() const
+const CIEVector_t*  split_eh_frame_impl_t<ptrsize>::getCIEs() const
 {
+	if(cies_cache.size()==0)
+	{
+		transform(ALLOF(cies), back_inserter(cies_cache), [](const cie_contents_t<ptrsize> &a) { return &a; });
+	}
+	return &cies_cache;
+#if 0
 	auto ret=shared_ptr<CIEVector_t>(new CIEVector_t());
 	transform(ALLOF(cies), back_inserter(*ret), 
 		[](const cie_contents_t<ptrsize> &a){ return shared_ptr<CIEContents_t>(new cie_contents_t<ptrsize>(a));});
 	return ret;
+#endif
 }
 
 template <int ptrsize>
diff --git a/src/ehp_priv.hpp b/src/ehp_priv.hpp
index dba5759..49cbb6d 100644
--- a/src/ehp_priv.hpp
+++ b/src/ehp_priv.hpp
@@ -53,7 +53,7 @@ class eh_frame_util_t
 		const uint64_t section_start_addr );
 
 	static bool read_string 
-		(std::string &s, 
+		(string &s, 
 		uint32_t & position, 
 		const uint8_t* const data, 
 		const uint32_t max);
@@ -86,7 +86,7 @@ class eh_program_insn_t  : public EHProgramInstruction_t
 	public: 
 	
 	eh_program_insn_t() ;
-	eh_program_insn_t(const std::string &s) ;
+	eh_program_insn_t(const string &s) ;
 
 	void print(uint64_t &pc, int64_t caf) const;
 
@@ -115,12 +115,12 @@ class eh_program_insn_t  : public EHProgramInstruction_t
 
 	bool advance(uint64_t &cur_addr, uint64_t CAF) const ;
 
-	const std::vector<uint8_t>& getBytes() const ;
-	std::vector<uint8_t>& getBytes() ;
+	const vector<uint8_t>& getBytes() const ;
+	vector<uint8_t>& getBytes() ;
 
 	private:
 
-	std::vector<uint8_t> program_bytes;
+	vector<uint8_t> program_bytes;
 };
 
 template <int ptrsize>
@@ -138,12 +138,13 @@ class eh_program_t : public EHProgram_t
 		const uint32_t& program_start_position, 
 		const uint8_t* const data, 
 		const uint32_t &max_program_pos);
-        virtual shared_ptr<EHProgramInstructionVector_t> getInstructions() const ;
-	std::vector<eh_program_insn_t <ptrsize> >& getInstructionsInternal() ;
-	const std::vector<eh_program_insn_t <ptrsize> >& getInstructionsInternal() const ;
+        virtual const EHProgramInstructionVector_t* getInstructions() const ;
+	vector<eh_program_insn_t <ptrsize> >& getInstructionsInternal() ;
+	const vector<eh_program_insn_t <ptrsize> >& getInstructionsInternal() const ;
 
 	private:
-	std::vector<eh_program_insn_t <ptrsize> > instructions;
+	vector<eh_program_insn_t <ptrsize> > instructions;
+	mutable EHProgramInstructionVector_t instructions_cache;
 };
 
 template <int ptrsize>
@@ -157,7 +158,7 @@ class cie_contents_t : public CIEContents_t, private eh_frame_util_t<ptrsize>
 	uint64_t length;
 	uint8_t cie_id;
 	uint8_t cie_version;
-	std::string augmentation;
+	string augmentation;
 	uint64_t code_alignment_factor;
 	int64_t data_alignment_factor;
 	uint64_t return_address_register_column;
@@ -178,7 +179,7 @@ class cie_contents_t : public CIEContents_t, private eh_frame_util_t<ptrsize>
 	uint64_t getPersonality() const ;
 	uint64_t getReturnRegister() const ;
 
-	std::string getAugmentation() const ;
+	string getAugmentation() const ;
 	uint8_t getLSDAEncoding() const ;
 	uint8_t getFDEEncoding() const ;
 
@@ -249,14 +250,15 @@ class lsda_call_site_t : public LSDACallSite_t, private eh_frame_util_t<ptrsize>
 	uint64_t action_table_offset;
 	uint64_t action_table_addr;
 
-	std::vector<lsda_call_site_action_t <ptrsize> > action_table;
+	vector<lsda_call_site_action_t <ptrsize> > action_table;
+	mutable LSDACallSiteActionVector_t action_table_cache;
 
 	public:
 	lsda_call_site_t() ;
 
-	shared_ptr<LSDACallSiteActionVector_t> getActionTable() const;
-	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; }
+	const LSDACallSiteActionVector_t* getActionTable() const;
+	const vector<lsda_call_site_action_t <ptrsize> >& getActionTableInternal() const { return action_table; }
+	      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 ; } 
@@ -280,8 +282,8 @@ class lsda_call_site_t : public LSDACallSite_t, private eh_frame_util_t<ptrsize>
 
 
 // short hand for a vector of call sites
-template <int ptrsize>  using call_site_table_t = std::vector<lsda_call_site_t <ptrsize> > ;
-template <int ptrsize>  using lsda_type_table_t = std::vector<lsda_type_table_entry_t <ptrsize> > ;
+template <int ptrsize>  using call_site_table_t = vector<lsda_call_site_t <ptrsize> > ;
+template <int ptrsize>  using lsda_type_table_t = vector<lsda_type_table_entry_t <ptrsize> > ;
 
 template <int ptrsize>
 class lsda_t : public LSDA_t, private eh_frame_util_t<ptrsize>
@@ -298,25 +300,33 @@ class lsda_t : public LSDA_t, private eh_frame_util_t<ptrsize>
 	uint64_t cs_table_length;
 	uint64_t cs_table_end_addr;
 	uint64_t action_table_start_addr;
+
 	call_site_table_t<ptrsize>  call_site_table;
+	// this is a vector of pointers into the call site table.
+	// and is the thing we return when getCallSites is called.
+	// this is marked as mutable so we can cache it between calls.
+	mutable CallSiteVector_t call_site_table_cache ;
+
 	lsda_type_table_t<ptrsize> type_table;
 
+	// this is a vector of pointers into the type_table
+	// and is the thing we return when getTypeTable is called.
+	// this is marked as mutable so we can cache it between calls.
+	mutable TypeTableVector_t type_table_cache ;
+
 	public:
 
-	uint8_t getTTEncoding() const ;
-	
-	lsda_t() ;
+	lsda_t();
 
+	uint8_t getTTEncoding() const ;
 	bool parse_lsda(const uint64_t lsda_addr, 
 			const ScoopReplacement_t* gcc_except_scoop_data,
 	                const uint64_t fde_region_start
 	                );
 	void print() const;
-
-        shared_ptr<CallSiteVector_t> getCallSites() const ;
+        const CallSiteVector_t* getCallSites() const ;
         const call_site_table_t<ptrsize> getCallSitesInternal() const { return call_site_table;}
-
-        shared_ptr<TypeTableVector_t> getTypeTable() const ;
+        const TypeTableVector_t* getTypeTable() const ;
 
 };
 
@@ -360,7 +370,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 { return shared_ptr<LSDA_t>(new lsda_t<ptrsize>(lsda)) ;  }
+	const LSDA_t* getLSDA() const { return &lsda; } // shared_ptr<LSDA_t>(new lsda_t<ptrsize>(lsda)) ;  }
 	const lsda_t<ptrsize>& getLSDAInternal() const { return lsda; }
 
         uint64_t getLSDAAddress() const { return lsda_addr; }  
@@ -391,8 +401,11 @@ class split_eh_frame_impl_t : public EHFrameParser_t
 	unique_ptr<ScoopReplacement_t> eh_frame_hdr_scoop;
 	unique_ptr<ScoopReplacement_t> gcc_except_table_scoop;
 
-	std::vector<cie_contents_t <ptrsize> > cies;
-	std::set<fde_contents_t <ptrsize> > fdes;
+	vector<cie_contents_t <ptrsize> > cies;
+	mutable CIEVector_t cies_cache;
+
+	set<fde_contents_t <ptrsize> > fdes;
+	mutable FDEVector_t fdes_cache;
 
 
 	bool iterate_fdes();
@@ -415,8 +428,8 @@ class split_eh_frame_impl_t : public EHFrameParser_t
 	bool parse();
 	void print() const;
 
-        virtual const shared_ptr<FDEVector_t> getFDEs() const;
-        virtual const shared_ptr<CIEVector_t> getCIEs() const;
+        virtual const FDEVector_t* getFDEs() const;
+        virtual const CIEVector_t* getCIEs() const;
         virtual const FDEContents_t* findFDE(uint64_t addr) const; 
 
 
-- 
GitLab