Blame dwarfgen/irepframe.h

Packit cdaae3
/*
Packit cdaae3
  Copyright (C) 2010-2013 David Anderson.  All rights reserved.
Packit cdaae3
Packit cdaae3
  Redistribution and use in source and binary forms, with or without
Packit cdaae3
  modification, are permitted provided that the following conditions are met:
Packit cdaae3
  * Redistributions of source code must retain the above copyright
Packit cdaae3
    notice, this list of conditions and the following disclaimer.
Packit cdaae3
  * Redistributions in binary form must reproduce the above copyright
Packit cdaae3
    notice, this list of conditions and the following disclaimer in the
Packit cdaae3
    documentation and/or other materials provided with the distribution.
Packit cdaae3
  * Neither the name of the example nor the
Packit cdaae3
    names of its contributors may be used to endorse or promote products
Packit cdaae3
    derived from this software without specific prior written permission.
Packit cdaae3
Packit cdaae3
  THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY
Packit cdaae3
  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Packit cdaae3
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit cdaae3
  DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY
Packit cdaae3
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Packit cdaae3
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Packit cdaae3
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
Packit cdaae3
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit cdaae3
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Packit cdaae3
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit cdaae3
Packit cdaae3
*/
Packit cdaae3
Packit cdaae3
//
Packit cdaae3
// irepframe.h
Packit cdaae3
//
Packit cdaae3
Packit cdaae3
class IRCie {
Packit cdaae3
public:
Packit cdaae3
    IRCie(): cie_byte_length_(0), version_(0),
Packit cdaae3
        code_alignment_factor_(1),
Packit cdaae3
        data_alignment_factor_(1),
Packit cdaae3
        return_address_register_rule_(0)
Packit cdaae3
        {};
Packit cdaae3
    IRCie(Dwarf_Unsigned length, Dwarf_Unsigned version,
Packit cdaae3
        const std::string &augmentation, Dwarf_Unsigned code_align,
Packit cdaae3
        Dwarf_Signed data_align, Dwarf_Half return_reg_rule,
Packit cdaae3
        const void * init_instrs, Dwarf_Unsigned instrs_len):
Packit cdaae3
        cie_byte_length_(length), version_(version),
Packit cdaae3
        augmentation_(augmentation), code_alignment_factor_(code_align),
Packit cdaae3
        data_alignment_factor_(data_align),
Packit cdaae3
        return_address_register_rule_(return_reg_rule)
Packit cdaae3
        {
Packit cdaae3
            const Dwarf_Small *x =
Packit cdaae3
                reinterpret_cast<const Dwarf_Small *>(init_instrs);
Packit cdaae3
            for(Dwarf_Unsigned i = 0; i < instrs_len; ++i) {
Packit cdaae3
                initial_instructions_.push_back(x[i]);
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
    void insert_fde_index(unsigned i) { fde_index_.push_back(i); };
Packit cdaae3
    ~IRCie() {};
Packit cdaae3
    void get_basic_cie_data(Dwarf_Unsigned * version,
Packit cdaae3
        std::string  * aug,
Packit cdaae3
        Dwarf_Unsigned * code_align,
Packit cdaae3
        Dwarf_Signed * data_align,
Packit cdaae3
        Dwarf_Half   * ret_addr_reg) {
Packit cdaae3
            *version = version_;
Packit cdaae3
            *aug = augmentation_;
Packit cdaae3
            *code_align = code_alignment_factor_;
Packit cdaae3
            *data_align = data_alignment_factor_;
Packit cdaae3
            *ret_addr_reg = return_address_register_rule_;
Packit cdaae3
        }
Packit cdaae3
    void get_init_instructions(Dwarf_Unsigned *len,
Packit cdaae3
        void **bytes) {
Packit cdaae3
        *len = initial_instructions_.size();
Packit cdaae3
        *bytes = reinterpret_cast<void *>(&initial_instructions_[0]);
Packit cdaae3
        };
Packit cdaae3
Packit cdaae3
private:
Packit cdaae3
    //  Byte length  0 if not known yet.
Packit cdaae3
    Dwarf_Unsigned cie_byte_length_;
Packit cdaae3
    Dwarf_Unsigned version_;
Packit cdaae3
    std::string augmentation_;
Packit cdaae3
    Dwarf_Unsigned code_alignment_factor_;
Packit cdaae3
    Dwarf_Signed data_alignment_factor_;
Packit cdaae3
    Dwarf_Half   return_address_register_rule_;
Packit cdaae3
    std::vector<Dwarf_Small> initial_instructions_;
Packit cdaae3
    // fde_index is the array of indexes into fdedata_
Packit cdaae3
    // that are fdes used by this cie.
Packit cdaae3
    std::vector<unsigned>  fde_index_;
Packit cdaae3
};
Packit cdaae3
class IRFde {
Packit cdaae3
public:
Packit cdaae3
    IRFde(): low_pc_(0), func_length_(0),
Packit cdaae3
        cie_offset_(0), cie_index_(-1),
Packit cdaae3
        fde_offset_(0)  {};
Packit cdaae3
    IRFde(Dwarf_Addr low_pc,Dwarf_Unsigned func_length,
Packit cdaae3
        Dwarf_Ptr fde_bytes, Dwarf_Unsigned fde_length,
Packit cdaae3
        Dwarf_Off cie_offset,Dwarf_Signed cie_index,
Packit cdaae3
        Dwarf_Off fde_offset): low_pc_(low_pc), func_length_(func_length),
Packit cdaae3
        cie_offset_(cie_offset), cie_index_(cie_index),
Packit cdaae3
        fde_offset_(fde_offset)  {
Packit cdaae3
            const Dwarf_Small *x =
Packit cdaae3
                reinterpret_cast<const Dwarf_Small *>(fde_bytes);
Packit cdaae3
            for(Dwarf_Unsigned i = 0; i < fde_length; ++i) {
Packit cdaae3
                fde_bytes_.push_back(x[i]);
Packit cdaae3
            }
Packit cdaae3
        };
Packit cdaae3
    ~IRFde() {};
Packit cdaae3
    Dwarf_Signed cie_index() { return cie_index_; };
Packit cdaae3
    void get_fde_base_data(Dwarf_Addr *lowpc, Dwarf_Unsigned * funclen,
Packit cdaae3
        Dwarf_Signed *cie_index_input) {
Packit cdaae3
            *lowpc = low_pc_;
Packit cdaae3
            *funclen = func_length_;
Packit cdaae3
            *cie_index_input = cie_index_;
Packit cdaae3
        };
Packit cdaae3
    void get_fde_instrs_into_ir(Dwarf_Ptr ip,Dwarf_Unsigned len   )  {
Packit cdaae3
        const Dwarf_Small *x =
Packit cdaae3
        reinterpret_cast<const Dwarf_Small *>(ip);
Packit cdaae3
        for(Dwarf_Unsigned i = 0; i < len; ++i) {
Packit cdaae3
            fde_instrs_.push_back(x[i]);
Packit cdaae3
        }
Packit cdaae3
        };
Packit cdaae3
Packit cdaae3
    void get_fde_instructions(Dwarf_Unsigned *len,
Packit cdaae3
        void **bytes) {
Packit cdaae3
        *len = fde_instrs_.size();
Packit cdaae3
        *bytes = reinterpret_cast<void *>(&fde_instrs_[0]);
Packit cdaae3
        };
Packit cdaae3
    void fde_instrs () {
Packit cdaae3
        };
Packit cdaae3
Packit cdaae3
private:
Packit cdaae3
    Dwarf_Addr low_pc_;
Packit cdaae3
    Dwarf_Unsigned func_length_;
Packit cdaae3
    // fde_bytes_ may be empty if content bytes not yet created.
Packit cdaae3
    std::vector<Dwarf_Small> fde_bytes_;
Packit cdaae3
Packit cdaae3
    // fde_instrs_ is simply a vector of bytes.
Packit cdaae3
    // it might be good to actually parse the
Packit cdaae3
    // instructions.
Packit cdaae3
    std::vector<Dwarf_Small> fde_instrs_;
Packit cdaae3
    // cie_offset may be 0 if not known yet.
Packit cdaae3
    Dwarf_Off  cie_offset_;
Packit cdaae3
    // cie_index is the index in ciedata_  of
Packit cdaae3
    // the applicable CIE. Begins with index 0.
Packit cdaae3
    Dwarf_Signed cie_index_;
Packit cdaae3
    // fde_offset may be 0 if not yet known.
Packit cdaae3
    Dwarf_Off   fde_offset_;
Packit cdaae3
};
Packit cdaae3
Packit cdaae3
class IRFrame {
Packit cdaae3
public:
Packit cdaae3
    IRFrame() {};
Packit cdaae3
    ~IRFrame() {};
Packit cdaae3
    void insert_cie(IRCie &cie) {
Packit cdaae3
        ciedata_.push_back(cie);
Packit cdaae3
    }
Packit cdaae3
    void insert_fde(IRFde &fdedata) {
Packit cdaae3
        fdedata_.push_back(fdedata);
Packit cdaae3
        unsigned findex = fdedata_.size() -1;
Packit cdaae3
        Dwarf_Signed cindex = fdedata.cie_index();
Packit cdaae3
        if( cindex != -1) {
Packit cdaae3
            IRCie & mycie =  ciedata_[cindex];
Packit cdaae3
            mycie.insert_fde_index(findex);
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
    std::vector<IRCie> &get_cie_vec() { return ciedata_; };
Packit cdaae3
    std::vector<IRFde> &get_fde_vec() { return fdedata_; };
Packit cdaae3
private:
Packit cdaae3
    std::vector<IRCie> ciedata_;
Packit cdaae3
    std::vector<IRFde> fdedata_;
Packit cdaae3
};