/* 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(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(&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 initial_instructions_; // fde_index is the array of indexes into fdedata_ // that are fdes used by this cie. std::vector 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(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(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(&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 fde_bytes_; std::vector 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 &get_cie_vec() { return ciedata_; }; std::vector &get_fde_vec() { return fdedata_; }; private: std::vector ciedata_; std::vector fdedata_; };