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