|
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 |
};
|