Skip to content
Snippets Groups Projects
ehp_priv.hpp 20.7 KiB
Newer Older
// @HEADER_COMPONENT libehp
// @HEADER_LANG C++
// @HEADER_BEGIN

Jason Hiser's avatar
Jason Hiser committed
/*
   Copyright 2017-2019 University of Virginia
Jason Hiser's avatar
Jason Hiser committed

Jason Hiser's avatar
Jason Hiser committed
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
Jason Hiser's avatar
Jason Hiser committed

Jason Hiser's avatar
Jason Hiser committed
       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
Jason Hiser's avatar
Jason Hiser committed
*/

// @HEADER_END

#ifndef ehp_priv_hpp
#define ehp_priv_hpp

#include <iostream>
#include <iomanip>
#include <fstream>
#include <limits>
#include <stdlib.h>
#include <string.h>
#include <map>
#include <algorithm>
#include <memory>
Jason Hiser's avatar
Jason Hiser committed
#include <set>
#include <functional>
#include <stdexcept>
Jason Hiser's avatar
Jason Hiser committed
#include "ehp_dwarf2.hpp"
#include "scoop_replacement.hpp"
Jason Hiser's avatar
Jason Hiser committed
namespace EHP
{
Jason Hiser's avatar
Jason Hiser committed
using namespace std;
class eh_frame_util_t 
{
	public: 
	template <class T> 
	static bool read_type(T &value, uint64_t &position, const uint8_t* const data, const uint64_t max, const bool is_be);
	template <class T> 
Jason Hiser's avatar
Jason Hiser committed
	static bool read_type_with_encoding (
		const uint8_t encoding, T &value, 
		uint64_t &position,
		const uint8_t* const data, 
Jason Hiser's avatar
Jason Hiser committed
		const uint64_t section_start_addr,
		const bool is_be
	       	);
Jason Hiser's avatar
Jason Hiser committed
	static bool read_string (
		string &s, 
		uint64_t &position,
		const uint8_t* const data, 


	// see https://en.wikipedia.org/wiki/LEB128
	static bool read_uleb128 
Jason Hiser's avatar
Jason Hiser committed
		( 
		uint64_t &result, 
		uint64_t &position,
		const uint8_t* const data, 
Jason Hiser's avatar
Jason Hiser committed
		);

	// see https://en.wikipedia.org/wiki/LEB128
	static bool read_sleb128 ( 
		int64_t &result, 
		uint64_t &position,
		const uint8_t* const data, 
Jason Hiser's avatar
Jason Hiser committed
		);
	
	static bool read_length(
		uint64_t &act_length, 
		uint64_t &position,
		const uint8_t* const data, 
Jason Hiser's avatar
Jason Hiser committed
		const bool is_be
		);
};

template <int ptrsize>
class eh_program_insn_t  : public EHProgramInstruction_t
{
	public: 
	
	eh_program_insn_t() ;
Jason Hiser's avatar
Jason Hiser committed
	void print(uint64_t &pc, int64_t caf) const;
	tuple<string, int64_t, int64_t> decode() const;
	uint64_t getSize() const { return program_bytes.size(); }
	void push_byte(uint8_t c) ;

	static void print_uleb_operand(
		const uint8_t* const data, 

	static void print_sleb_operand(
		const uint8_t* const data, 

	bool parse_insn(
		uint8_t opcode, 
		const uint8_t* const data, 
Jason Hiser's avatar
Jason Hiser committed
		const uint64_t &max,
		const bool is_be
		);
	bool isDefCFAOffset() const ;
	bool isRestoreState() const ;
	bool isRememberState() const ;

	bool advance(uint64_t &cur_addr, uint64_t CAF) const ;
	const vector<uint8_t>& getBytes() const ;
	vector<uint8_t>& getBytes() ;
};

template <int ptrsize>
bool operator<(const eh_program_insn_t<ptrsize>& a, const eh_program_insn_t<ptrsize>& b);

template <int ptrsize>
class eh_program_t : public EHProgram_t
{
	public:
	void push_insn(const eh_program_insn_t<ptrsize> &i); 

Jason Hiser's avatar
Jason Hiser committed
	void print(const uint64_t start_addr, const int64_t caf) const;
		const uint64_t& program_start_position,
		const uint8_t* const data, 
Jason Hiser's avatar
Jason Hiser committed
		const uint64_t &max_program_pos,
		const bool is_be
		);
        virtual const EHProgramInstructionVector_t* getInstructions() const ;
	vector<eh_program_insn_t <ptrsize> >& getInstructionsInternal() ;
	const vector<eh_program_insn_t <ptrsize> >& getInstructionsInternal() const ;
	vector<eh_program_insn_t <ptrsize> > instructions;
	mutable EHProgramInstructionVector_t instructions_cache;
};

template <int ptrsize>
bool operator<(const eh_program_t<ptrsize>& a, const eh_program_t<ptrsize>& b);

template <int ptrsize>
class cie_contents_t : public CIEContents_t, private eh_frame_util_t<ptrsize>
{
	private:
	uint64_t cie_position;
	uint64_t length;
Jason Hiser's avatar
Jason Hiser committed
	uint8_t  cie_id;
	uint8_t  cie_version;
	string   augmentation;
	uint64_t code_alignment_factor;
Jason Hiser's avatar
Jason Hiser committed
	int64_t  data_alignment_factor;
	uint64_t return_address_register_column;
	uint64_t augmentation_data_length;
Jason Hiser's avatar
Jason Hiser committed
	uint8_t  personality_encoding;
	uint64_t personality;
	uint64_t personality_pointer_position;
	uint64_t personality_pointer_size;
Jason Hiser's avatar
Jason Hiser committed
	uint8_t  lsda_encoding;
	uint8_t  fde_encoding;
	eh_program_t<ptrsize> eh_pgm;

	public:

	cie_contents_t() ;
	
	const eh_program_t<ptrsize>& getProgram() const ;
	uint64_t getPosition() const { return cie_position; }
	uint64_t getLength() const { return length; }
	uint64_t getCAF() const ;
Jason Hiser's avatar
Jason Hiser committed
	int64_t  getDAF() const ;
	uint8_t  getPersonalityEncoding() const { return personality_encoding; }
	uint64_t getPersonality() const ;
	uint64_t getPersonalityPointerPosition() const { return personality_pointer_position; };
	uint64_t getPersonalityPointerSize() const { return personality_pointer_size; };
	uint64_t getReturnRegister() const ;
	uint8_t getLSDAEncoding() const ;
	uint8_t getFDEEncoding() const ;
		const uint64_t &cie_position,
		const uint8_t* const data, 
Jason Hiser's avatar
Jason Hiser committed
		const uint64_t eh_addr,
		const bool is_be
		);
Jason Hiser's avatar
Jason Hiser committed
	void print(const uint64_t startAddr) const ;
class lsda_call_site_action_t : public LSDACallSiteAction_t, private eh_frame_util_t<ptrsize>
{
	private:
	int64_t action;

	public:
	lsda_call_site_action_t() ;
	int64_t getAction() const ;
Jason Hiser's avatar
Jason Hiser committed
	bool parse_lcsa(uint64_t &pos, const uint8_t* const data, const uint64_t max, bool &end, const bool is_be);
	void print() const;
};

template <int ptrsize>
bool operator< (const lsda_call_site_action_t <ptrsize> &lhs, const lsda_call_site_action_t <ptrsize> &rhs);

template <int ptrsize>
class lsda_type_table_entry_t: public LSDATypeTableEntry_t, private eh_frame_util_t<ptrsize>
{
	private:
	uint64_t pointer_to_typeinfo;
	uint64_t tt_encoding;
	uint64_t tt_encoding_size;

	public:
	lsda_type_table_entry_t() ; 

	uint64_t getTypeInfoPointer() const ;
	uint64_t getEncoding() const ;
	uint64_t getTTEncodingSize() const ;

	bool parse(
		const uint64_t p_tt_encoding, 	
		const uint64_t tt_pos,
		const uint64_t index,
		const uint8_t* const data, 
		const uint64_t max,  
Jason Hiser's avatar
Jason Hiser committed
		const uint64_t data_addr,
		const bool is_be
		);

	void print() const;
	
};

template <int ptrsize>
class lsda_call_site_t : public LSDACallSite_t, private eh_frame_util_t<ptrsize>
{
	private:
	uint64_t call_site_offset;
	uint64_t call_site_addr;
	uint64_t call_site_addr_position;
	uint64_t call_site_length;
	uint64_t call_site_end_addr;
	uint64_t call_site_end_addr_position;
	uint64_t landing_pad_offset;
	uint64_t landing_pad_addr;
	uint64_t landing_pad_addr_position;
	uint64_t landing_pad_addr_end_position;
	uint64_t action;
	uint64_t action_table_offset;
	uint64_t action_table_addr;

	vector<lsda_call_site_action_t <ptrsize> > action_table;
	mutable LSDACallSiteActionVector_t action_table_cache;
	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 getCallSiteAddressPosition() const { return call_site_addr_position; }
	uint64_t getCallSiteEndAddress() const  { return call_site_end_addr ; }
	uint64_t getCallSiteEndAddressPosition() const { return call_site_end_addr_position; }
	uint64_t getLandingPadAddress() const  { return landing_pad_addr ; }
	uint64_t getLandingPadAddressPosition() const { return landing_pad_addr_position; }
	uint64_t getLandingPadAddressEndPosition() const { return landing_pad_addr_end_position; }

	bool parse_lcs(	
		const uint64_t action_table_start_addr, 	
		const uint64_t cs_table_start_addr, 	
		const uint8_t cs_table_encoding, 
		const uint8_t* const data, 
		const uint64_t max,  /* call site table max */
		const uint64_t data_addr, 
		const uint64_t landing_pad_base_addr,
Jason Hiser's avatar
Jason Hiser committed
		const uint64_t gcc_except_table_max,
		const bool is_be
		);

	void print() const;


};


// short hand for a vector of call sites
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>
{
	private:
	uint8_t landing_pad_base_encoding;
	uint64_t landing_pad_base_addr; // often ommitted. when ommitted, filled in from FDE region start.
	uint8_t type_table_encoding;
	uint64_t type_table_offset;
	uint64_t type_table_addr;
	uint64_t type_table_addr_location;
	uint8_t cs_table_encoding;
	uint64_t cs_table_start_offset;
	uint64_t cs_table_start_addr;
	uint64_t cs_table_start_addr_location;
	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 ;

Jason Hiser's avatar
Jason Hiser committed
	bool parse_lsda(const uint64_t lsda_addr, 
			const ScoopReplacement_t* gcc_except_scoop_data,
Jason Hiser's avatar
Jason Hiser committed
	                const uint64_t fde_region_start,
			const bool is_be
Jason Hiser's avatar
Jason Hiser committed
	                );
	void print() const;
	uint64_t getLandingPadBaseAddress() const {  return landing_pad_base_addr; }
	const CallSiteVector_t* getCallSites() const ;
	uint64_t getCallSiteTableAddress() const { return cs_table_start_addr; }
	uint64_t getCallSiteTableAddressLocation() const { return cs_table_start_addr_location; }
	uint64_t getCallSiteTableLength() const { return cs_table_length; }
	uint8_t getCallSiteTableEncoding() const { return cs_table_encoding; }
	const call_site_table_t<ptrsize> getCallSitesInternal() const { return call_site_table;}
	const TypeTableVector_t* getTypeTable() const ;
	uint64_t getTypeTableAddress() const { return type_table_addr; }
	uint64_t getTypeTableAddressLocation() const { return type_table_addr_location; }
	uint8_t getTypeTableEncoding() const { return type_table_encoding; }
class fde_contents_t : public FDEContents_t, eh_frame_util_t<ptrsize> 
	uint64_t fde_position;
	uint64_t cie_position;
Jason Hiser's avatar
Jason Hiser committed
	uint8_t  id;
	uint64_t fde_start_addr;
	uint64_t fde_end_addr;
	uint64_t fde_range_len;
	uint64_t lsda_addr;
Jason Hiser's avatar
Jason Hiser committed
	uint64_t fde_start_addr_position;
	uint64_t fde_end_addr_position;
	uint64_t fde_end_addr_size;
	uint64_t fde_lsda_addr_position;
	uint64_t fde_lsda_addr_size;

	lsda_t<ptrsize> lsda;
	eh_program_t<ptrsize> eh_pgm;
	cie_contents_t<ptrsize> cie_info;

	public:
	fde_contents_t() ;
	fde_contents_t(const uint64_t start_addr, const uint64_t end_addr)
		: 
		fde_start_addr(start_addr),
		fde_end_addr(end_addr)
	{} 
	uint64_t getPosition() const { return fde_position; }
	uint64_t getLength() const { return length; }
	uint64_t getStartAddress() const { return fde_start_addr; } 
	uint64_t getEndAddress() const {return fde_end_addr; }

	uint64_t getFDEStartAddress() const { return fde_start_addr; } 
	uint64_t getFDEEndAddress() const {return fde_end_addr; }
	const cie_contents_t<ptrsize>& getCIE() const ;
	cie_contents_t<ptrsize>& getCIE() ;
	const eh_program_t<ptrsize>& getProgram() const ;
	eh_program_t<ptrsize>& getProgram() ;
	const LSDA_t* getLSDA() const { return &lsda; }
	const lsda_t<ptrsize>& getLSDAInternal() const { return lsda; }
Jason Hiser's avatar
Jason Hiser committed
	uint64_t getLSDAAddress() const { return lsda_addr; }
	uint64_t getStartAddressPosition() const { return fde_start_addr_position; }
	uint64_t getEndAddressPosition() const { return fde_end_addr_position; }
	uint64_t getEndAddressSize() const { return fde_end_addr_size; }
	uint64_t getLSDAAddressPosition() const { return fde_lsda_addr_position; }
	uint64_t getLSDAAddressSize() const { return fde_lsda_addr_size; }
		const uint64_t &fde_position,
		const uint64_t &cie_position,
		const uint8_t* const data, 
Brian Fairservice's avatar
Brian Fairservice committed
		const uint64_t max,
		const uint64_t eh_addr,
Jason Hiser's avatar
Jason Hiser committed
		const ScoopReplacement_t *gcc_except_scoop,
		const bool is_be);

	void print() const;


};

template <int ptrsize>
bool operator<(const fde_contents_t<ptrsize>& a, const fde_contents_t<ptrsize>& b) { return a.getFDEEndAddress()-1 < b.getFDEStartAddress(); }
class split_eh_frame_impl_t : public EHFrameParser_t
	unique_ptr<ScoopReplacement_t> eh_frame_scoop;
	unique_ptr<ScoopReplacement_t> eh_frame_hdr_scoop;
	unique_ptr<ScoopReplacement_t> gcc_except_table_scoop;

	vector<cie_contents_t <ptrsize> > cies;
	mutable CIEVector_t cies_cache;

	set<fde_contents_t <ptrsize> > fdes;
	mutable FDEVector_t fdes_cache;
Jason Hiser's avatar
Jason Hiser committed
	bool iterate_fdes(const bool is_be);
	split_eh_frame_impl_t
		(
		const ScoopReplacement_t &eh_frame,
		const ScoopReplacement_t &eh_frame_hdr,
		const ScoopReplacement_t &gcc_except_table 
		)
		:
			eh_frame_scoop(new ScoopReplacement_t(eh_frame)),
			eh_frame_hdr_scoop(new ScoopReplacement_t(eh_frame_hdr)),
			gcc_except_table_scoop(new ScoopReplacement_t(gcc_except_table))
	{
	}
Jason Hiser's avatar
Jason Hiser committed
	bool parse(const bool is_be);
	bool parse_arm(const bool is_be);
        virtual const FDEVector_t* getFDEs() const;
        virtual const CIEVector_t* getCIEs() const;
        virtual const FDEContents_t* findFDE(uint64_t addr) const; 
// overrides for arm-specific classes.
/*
template <int ptrsize>
class arm_lsda_t : public lsda_t<ptrsize>
{
	private:
	

	public:
	arm_lsda_t() : lsda_t<ptrsize>() {}
	bool parse_lsda(const uint64_t lsda_addr, 
			const ScoopReplacement_t* exidx_scoop,
	                const uint64_t fde_region_start,
			const bool is_be
	                );
	void print() const { lsda_t::print(); }

};
*/

template <int ptrsize>
class arm_cie_contents_t : public CIEContents_t, private eh_frame_util_t<ptrsize>
{
	private:
	uint64_t personality;

Jason Hiser's avatar
Jason Hiser committed
	// there's not really a CIE on arm mode,  so there's no pgm.
	// but we declare one so people cna inspect that it's empty.
	const eh_program_t<ptrsize> pgm; 
Jason Hiser's avatar
Jason Hiser committed
	arm_cie_contents_t() 
		: personality(0)
	{
	}
Jason Hiser's avatar
Jason Hiser committed
	const eh_program_t<ptrsize>& getProgram() const { return pgm; } 
	uint64_t getPosition() const { throw std::runtime_error( " not implemented"); }
	uint64_t getLength() const { throw std::runtime_error( " not implemented"); }
	uint64_t getCAF() const { return 4; }
	int64_t  getDAF() const { return 4; }
	uint8_t  getPersonalityEncoding() const { return 0; }
	uint64_t getPersonality() const { return personality; }
Jason Hiser's avatar
Jason Hiser committed
	uint64_t getPersonalityPointerPosition() const  { throw std::runtime_error( " not implemented"); }
	uint64_t getPersonalityPointerSize() const  { throw std::runtime_error( " not implemented"); }
	uint64_t getReturnRegister() const  { return 0; }
	string getAugmentation() const  { throw std::runtime_error( " not implemented"); }
	uint8_t getLSDAEncoding() const  { throw std::runtime_error( " not implemented"); }
	uint8_t getFDEEncoding() const  { throw std::runtime_error( " not implemented"); }

	virtual void print(const uint64_t startAddr) const
	{
		cout << "personality=" << hex << personality << endl;
	}

	void setPersonality(uint64_t pers) { personality=pers; }

};

Jason Hiser's avatar
Jason Hiser committed
template <int ptrsize>
class arm_eh_program_insn_t  : public EHProgramInstruction_t
{
	public: 
	
	arm_eh_program_insn_t() ;
	arm_eh_program_insn_t(const vector<uint8_t> &v) 
Jason Hiser's avatar
Jason Hiser committed
		:	
		program_bytes(begin(v),end(v))
Jason Hiser's avatar
Jason Hiser committed
	{
	}


	virtual ~arm_eh_program_insn_t() {}
        virtual void print(uint64_t &pc, int64_t caf=1) const ;
        virtual tuple<string, int64_t, int64_t> decode() const { throw std::runtime_error("not implemented"); }
        virtual uint64_t getSize() const { return program_bytes.size(); }
        virtual bool isNop() const { return false; }
        virtual bool isDefCFAOffset() const { return false; }
        virtual bool isRestoreState() const { return false; }
        virtual bool isRememberState() const { return false; }
        virtual const EHProgramInstructionByteVector_t& getBytes() const { return program_bytes; }
Jason Hiser's avatar
Jason Hiser committed
        virtual bool advance(uint64_t &cur_addr, uint64_t CAF)     const { return false; /* no advance operations for arm */ }
Jason Hiser's avatar
Jason Hiser committed

	private:

	vector<uint8_t> program_bytes;
};

template <int ptrsize>
class arm_eh_program_t : public EHProgram_t
{
	public:
	arm_eh_program_t(const vector<uint8_t>&  unwind_pgm={}); 
        virtual const EHProgramInstructionVector_t* getInstructions() const;
	vector<arm_eh_program_insn_t <ptrsize> >& getInstructionsInternal() { return instructions; }
	const vector<eh_program_insn_t <ptrsize> >& getInstructionsInternal() const { return instructions; }
	void print(const uint64_t start_addr, const int64_t caf) const;

	private:
	vector<arm_eh_program_insn_t <ptrsize> > instructions;
	mutable EHProgramInstructionVector_t instructions_cache;
};


template <int ptrsize>
class arm_fde_contents_t : public FDEContents_t, eh_frame_util_t<ptrsize> 
{
	uint64_t fde_start_addr=0;
	uint64_t fde_end_addr=0;
	uint64_t fde_lsda_addr=0;
	uint32_t can_unwind=false;
	lsda_t<ptrsize> lsda;
Jason Hiser's avatar
Jason Hiser committed
	arm_eh_program_t<ptrsize> eh_pgm;
	arm_cie_contents_t<ptrsize> cie;
	public:
	arm_fde_contents_t( uint64_t fde_start,uint64_t lsda_addr,bool p_can_unwind) :
		fde_start_addr(fde_start),
		fde_lsda_addr(lsda_addr),
		can_unwind(p_can_unwind)
	{}
	arm_fde_contents_t(const uint64_t start_addr, const uint64_t end_addr)
		: 
		fde_start_addr(start_addr),
		fde_end_addr(end_addr)
	{} 

Jason Hiser's avatar
Jason Hiser committed
        virtual uint64_t getPosition() const { throw std::runtime_error( " not implemented"); }
        virtual uint64_t getLength() const { return fde_end_addr-fde_start_addr+1; }
        virtual uint64_t getStartAddress() const { return fde_start_addr; }
        virtual uint64_t getEndAddress() const { return fde_end_addr; }
	virtual uint64_t getFDEStartAddress() const { return fde_start_addr; } 
	virtual uint64_t getFDEEndAddress() const {return fde_end_addr; }
        virtual const CIEContents_t& getCIE() const { return cie; }
Jason Hiser's avatar
Jason Hiser committed
        virtual const EHProgram_t& getProgram() const { return eh_pgm; }
        virtual const LSDA_t* getLSDA() const { return &lsda; }
        virtual uint64_t getLSDAAddress() const { return fde_lsda_addr; }
Jason Hiser's avatar
Jason Hiser committed
        virtual uint64_t getStartAddressPosition() const { throw std::runtime_error(" not implemented"); }
        virtual uint64_t getEndAddressPosition() const { throw std::runtime_error(" not implemented"); }
        virtual uint64_t getEndAddressSize() const { throw std::runtime_error(" not implemented"); }
        virtual uint64_t getLSDAAddressPosition() const { throw std::runtime_error(" not implemented"); }
        virtual uint64_t getLSDAAddressSize() const { throw std::runtime_error(" not implemented"); }
        virtual void print() const ;

	void setEndAddress(uint64_t end) { fde_end_addr = end; }
	bool getCanUnwind() const { return can_unwind; }
	void setPersonality(uint64_t pers) { cie.setPersonality(pers); }
Jason Hiser's avatar
Jason Hiser committed
	void setProgram(const arm_eh_program_t<ptrsize>&  pgm) { eh_pgm=pgm; }

	bool parse_lsda(const uint64_t lsda_addr, 
			const ScoopReplacement_t* extab_scoop,
	                const uint64_t fde_region_start,
			const bool is_be
	                )
	{
		return lsda.parse_lsda(lsda_addr,extab_scoop,fde_region_start,is_be);
	}


};

template <int ptrsize>
bool operator<(const arm_fde_contents_t<ptrsize>& a, const arm_fde_contents_t<ptrsize>& b) { return a.getFDEEndAddress()-1 < b.getFDEStartAddress(); }

template <int ptrsize>
class split_arm_eh_frame_impl_t : public EHFrameParser_t
{
	private: 

	unique_ptr<ScoopReplacement_t> extab_scoop;
	unique_ptr<ScoopReplacement_t> exidx_scoop;
	unique_ptr<ScoopReplacement_t> lnk_scoop;
	set<arm_fde_contents_t <ptrsize> > fdes;

	mutable CIEVector_t cies_cache;
	mutable FDEVector_t fdes_cache;

Jason Hiser's avatar
Jason Hiser committed
	vector<uint8_t> parse_arm_eh_pgm(const uint64_t lsda_addr, const ScoopReplacement_t *lsda_scoop, arm_fde_contents_t<ptrsize> &fde, const bool is_be);

	public:

	split_arm_eh_frame_impl_t
		(
		const ScoopReplacement_t &extab,
		const ScoopReplacement_t &exidx,
		const ScoopReplacement_t &lnk 
		)
		:
			extab_scoop(new ScoopReplacement_t(extab)),
			exidx_scoop(new ScoopReplacement_t(exidx)),
			lnk_scoop  (new ScoopReplacement_t(lnk))
		{
		}

	bool parse(const bool is_be);
	void print() const {};

        virtual const FDEVector_t* getFDEs() const ;
        virtual const CIEVector_t* getCIEs() const ;
        virtual const FDEContents_t* findFDE(uint64_t addr) const ;



};


Jason Hiser's avatar
Jason Hiser committed
}
Jason Hiser's avatar
Jason Hiser committed