diff options
Diffstat (limited to 'dwarfgen/irepframe.h')
-rw-r--r-- | dwarfgen/irepframe.h | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/dwarfgen/irepframe.h b/dwarfgen/irepframe.h new file mode 100644 index 0000000..3f598f8 --- /dev/null +++ b/dwarfgen/irepframe.h @@ -0,0 +1,154 @@ +/* + Copyright (C) 2010-2011 David Anderson. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. + +*/ + +// +// irepframe.h +// + +class IRCie { +public: + IRCie(): cie_byte_length_(0), version_(0), + code_alignment_factor_(1), + data_alignment_factor_(1), + return_address_register_rule_(0) + {}; + IRCie(Dwarf_Unsigned length, Dwarf_Unsigned version, + const std::string &augmentation, Dwarf_Unsigned code_align, + Dwarf_Signed data_align, Dwarf_Half return_reg_rule, + const void * init_instrs, Dwarf_Unsigned instrs_len): + cie_byte_length_(length), version_(version), + augmentation_(augmentation), code_alignment_factor_(code_align), + data_alignment_factor_(data_align), + return_address_register_rule_(return_reg_rule) + { + const Dwarf_Small *x = + reinterpret_cast<const Dwarf_Small *>(init_instrs); + for(Dwarf_Unsigned i = 0; i < instrs_len; ++i) { + initial_instructions_.push_back(x[i]); + } + } + void insert_fde_index(unsigned i) { fde_index_.push_back(i); }; + ~IRCie() {}; + void get_basic_cie_data(Dwarf_Unsigned * version, + std::string * aug, + Dwarf_Unsigned * code_align, + Dwarf_Signed * data_align, + Dwarf_Half * ret_addr_reg) { + *version = version_; + *aug = augmentation_; + *code_align = code_alignment_factor_; + *data_align = data_alignment_factor_; + *ret_addr_reg = return_address_register_rule_; + } + void get_init_instructions(Dwarf_Unsigned *len, + void **bytes) { + *len = initial_instructions_.size(); + *bytes = reinterpret_cast<void *>(&initial_instructions_[0]); + }; + +private: + // Byte length 0 if not known yet. + Dwarf_Unsigned cie_byte_length_; + Dwarf_Unsigned version_; + std::string augmentation_; + Dwarf_Unsigned code_alignment_factor_; + Dwarf_Signed data_alignment_factor_; + Dwarf_Half return_address_register_rule_; + std::vector<Dwarf_Small> initial_instructions_; + // fde_index is the array of indexes into fdedata_ + // that are fdes used by this cie. + std::vector<unsigned> fde_index_; +}; +class IRFde { +public: + IRFde(): low_pc_(0), func_length_(0), + cie_offset_(0), cie_index_(-1), + fde_offset_(0) {}; + IRFde(Dwarf_Addr low_pc,Dwarf_Unsigned func_length, + Dwarf_Ptr fde_bytes, Dwarf_Unsigned fde_length, + Dwarf_Off cie_offset,Dwarf_Signed cie_index, + Dwarf_Off fde_offset): low_pc_(low_pc), func_length_(func_length), + cie_offset_(cie_offset), cie_index_(cie_index), + fde_offset_(fde_offset) { + const Dwarf_Small *x = + reinterpret_cast<const Dwarf_Small *>(fde_bytes); + for(Dwarf_Unsigned i = 0; i < fde_length; ++i) { + fde_bytes_.push_back(x[i]); + } + }; + ~IRFde() {}; + Dwarf_Signed cie_index() { return cie_index_; }; + void get_fde_base_data(Dwarf_Addr *lowpc, Dwarf_Unsigned * funclen, + Dwarf_Signed *cie_index_input) { + *lowpc = low_pc_; + *funclen = func_length_; + *cie_index_input = cie_index_; + }; + void get_fde_instrs_into_ir(Dwarf_Ptr ip,Dwarf_Unsigned len ) { + const Dwarf_Small *x = + reinterpret_cast<const Dwarf_Small *>(ip); + for(Dwarf_Unsigned i = 0; i < len; ++i) { + fde_instrs_.push_back(x[i]); + } + }; + + void get_fde_instructions(Dwarf_Unsigned *len, + void **bytes) { + *len = fde_instrs_.size(); + *bytes = reinterpret_cast<void *>(&fde_instrs_[0]); + }; + void fde_instrs () { + }; + +private: + Dwarf_Addr low_pc_; + Dwarf_Unsigned func_length_; + // fde_bytes_ may be empty if content bytes not yet created. + std::vector<Dwarf_Small> fde_bytes_; + + std::vector<Dwarf_Small> fde_instrs_; + // cie_offset may be 0 if not known yet. + Dwarf_Off cie_offset_; + // cie_index is the index in ciedata_ of + // the applicable CIE. Begins with index 0. + Dwarf_Signed cie_index_; + // fde_offset may be 0 if not yet known. + Dwarf_Off fde_offset_; +}; + +class IRFrame { +public: + IRFrame() {}; + ~IRFrame() {}; + void insert_cie(IRCie &cie) { + ciedata_.push_back(cie); + } + void insert_fde(IRFde &fdedata) { + fdedata_.push_back(fdedata); + unsigned findex = fdedata_.size() -1; + Dwarf_Signed cindex = fdedata.cie_index(); + if( cindex != -1) { + IRCie & mycie = ciedata_[cindex]; + mycie.insert_fde_index(findex); + } + } + std::vector<IRCie> &get_cie_vec() { return ciedata_; }; + std::vector<IRFde> &get_fde_vec() { return fdedata_; }; +private: + std::vector<IRCie> ciedata_; + std::vector<IRFde> fdedata_; +}; |