Blame dwarfgen/irepdie.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
//
Packit cdaae3
// irepdie.h
Packit cdaae3
//
Packit cdaae3
//
Packit cdaae3
class IRCUdata;
Packit cdaae3
class IRDie;
Packit cdaae3
Packit cdaae3
class IRAttr {
Packit cdaae3
public:
Packit cdaae3
    IRAttr():attr_(0),finalform_(0),initialform_(0),
Packit cdaae3
        formclass_(DW_FORM_CLASS_UNKNOWN),formdata_(0) {
Packit cdaae3
        };
Packit cdaae3
    IRAttr(Dwarf_Half attr,Dwarf_Half finalform, Dwarf_Half initialform):
Packit cdaae3
        attr_(attr),finalform_(finalform),initialform_(initialform),
Packit cdaae3
        formclass_(DW_FORM_CLASS_UNKNOWN),formdata_(0) {
Packit cdaae3
    };
Packit cdaae3
    IRAttr(const IRAttr &r) {
Packit cdaae3
        attr_ = r.attr_;
Packit cdaae3
        finalform_ = r.finalform_;
Packit cdaae3
        initialform_ = r.initialform_;
Packit cdaae3
        formclass_ = r.formclass_;
Packit cdaae3
        if(r.formdata_) {
Packit cdaae3
            formdata_ =  r.formdata_->clone();
Packit cdaae3
        } else {
Packit cdaae3
            formdata_ = 0;
Packit cdaae3
        }
Packit cdaae3
    };
Packit cdaae3
    ~IRAttr() { delete formdata_; };
Packit cdaae3
    IRAttr & operator=( const IRAttr &r) {
Packit cdaae3
        if(this == &r) {
Packit cdaae3
            return *this;
Packit cdaae3
        }
Packit cdaae3
        attr_ = r.attr_;
Packit cdaae3
        finalform_ = r.finalform_;
Packit cdaae3
        initialform_ = r.initialform_;
Packit cdaae3
        formclass_ = r.formclass_;
Packit cdaae3
        if(r.formdata_) {
Packit cdaae3
            formdata_ =  r.formdata_->clone();
Packit cdaae3
        } else {
Packit cdaae3
            formdata_ = 0;
Packit cdaae3
        }
Packit cdaae3
        return *this;
Packit cdaae3
    }
Packit cdaae3
    void setBaseData(Dwarf_Half attr, Dwarf_Half finalform,
Packit cdaae3
        Dwarf_Half initialform){
Packit cdaae3
        attr_ = attr;
Packit cdaae3
        finalform_ = finalform;
Packit cdaae3
        initialform_ = initialform;
Packit cdaae3
    };
Packit cdaae3
    void setFormClass(enum Dwarf_Form_Class cl) {
Packit cdaae3
        formclass_ = cl;
Packit cdaae3
    };
Packit cdaae3
    enum Dwarf_Form_Class getFormClass() const {return formclass_; };
Packit cdaae3
    void setFormData(IRForm *f) { formdata_ = f; };
Packit cdaae3
    Dwarf_Half getFinalForm() const { return initialform_; };
Packit cdaae3
    Dwarf_Half getDirectForm() const { return finalform_; };
Packit cdaae3
    Dwarf_Half getAttrNum() const { return attr_; };
Packit cdaae3
    IRForm * getFormData() { return formdata_;};
Packit cdaae3
private:
Packit cdaae3
    Dwarf_Half attr_;
Packit cdaae3
    Dwarf_Half finalform_;
Packit cdaae3
    // In most cases finalform == initialform form.
Packit cdaae3
    // Otherwise, initialform == DW_FORM_indirect.
Packit cdaae3
    Dwarf_Half initialform_;
Packit cdaae3
    enum Dwarf_Form_Class formclass_;
Packit cdaae3
    IRForm *formdata_;
Packit cdaae3
};
Packit cdaae3
Packit cdaae3
class IRDie {
Packit cdaae3
public:
Packit cdaae3
    IRDie():tag_(0),globalOffset_(0), cuRelativeOffset_(0),
Packit cdaae3
        generatedDie_(0) {};
Packit cdaae3
    ~IRDie() {};
Packit cdaae3
    void addChild(const IRDie & newdie ) {
Packit cdaae3
        children_.push_back(newdie);
Packit cdaae3
    };
Packit cdaae3
    std::string  getName() {
Packit cdaae3
        std::list<IRAttr>::iterator it = attrs_.begin();
Packit cdaae3
        for( ; it != attrs_.end() ; ++it) {
Packit cdaae3
            if (it->getAttrNum() == DW_AT_name) {
Packit cdaae3
                IRForm *f = it->getFormData();
Packit cdaae3
                const IRFormString * isv =
Packit cdaae3
                    dynamic_cast<const IRFormString *>(f);
Packit cdaae3
                if(isv) {
Packit cdaae3
                    return isv->getString();
Packit cdaae3
                }
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
        return "";
Packit cdaae3
    };
Packit cdaae3
    std::list<IRAttr> & getAttributes() {return attrs_; };
Packit cdaae3
    std::list<IRDie> & getChildren() {return children_; };
Packit cdaae3
    bool hasNewestChild(IRDie **lastch) { size_t N = children_.size();
Packit cdaae3
        if(N < 1) {
Packit cdaae3
            return false;
Packit cdaae3
        }
Packit cdaae3
        *lastch = &children_.back();
Packit cdaae3
        return true;
Packit cdaae3
    };
Packit cdaae3
    // lastChild and lastAttr will throw if no entry exists.
Packit cdaae3
    IRDie &lastChild() { return children_.back(); };
Packit cdaae3
    IRAttr &lastAttr() { return attrs_.back(); };
Packit cdaae3
    void setBaseData(Dwarf_Half tag,Dwarf_Unsigned goff,
Packit cdaae3
        Dwarf_Unsigned cuoff) {
Packit cdaae3
        tag_ = tag;
Packit cdaae3
        globalOffset_=goff;
Packit cdaae3
        cuRelativeOffset_ = cuoff;
Packit cdaae3
    };
Packit cdaae3
    Dwarf_Unsigned getGlobalOffset() const { return globalOffset_;};
Packit cdaae3
    Dwarf_Unsigned getCURelativeOffset() const { return cuRelativeOffset_;};
Packit cdaae3
    void setGeneratedDie(Dwarf_P_Die p_die) {
Packit cdaae3
        generatedDie_ = p_die;};
Packit cdaae3
    Dwarf_P_Die getGeneratedDie() const { return generatedDie_;};
Packit cdaae3
    unsigned getTag() {return tag_; }
Packit cdaae3
Packit cdaae3
private:
Packit cdaae3
   // We rely on the IRDie container being one which does not
Packit cdaae3
   // invalidate pointers with addition/deletion.
Packit cdaae3
   std::list<IRDie>  children_;
Packit cdaae3
Packit cdaae3
   std::list<IRAttr> attrs_;
Packit cdaae3
   unsigned tag_;
Packit cdaae3
   // The following are data from input.
Packit cdaae3
   Dwarf_Unsigned globalOffset_;
Packit cdaae3
   Dwarf_Unsigned cuRelativeOffset_;
Packit cdaae3
Packit cdaae3
   // the following is generated during output.
Packit cdaae3
   Dwarf_P_Die generatedDie_;
Packit cdaae3
};
Packit cdaae3
Packit cdaae3
Packit cdaae3
struct OffsetFormEntry {
Packit cdaae3
    OffsetFormEntry(): off_(0),form_(0){};
Packit cdaae3
    OffsetFormEntry(Dwarf_Unsigned o,
Packit cdaae3
        IRFormReference* f): off_(o),form_(f){};
Packit cdaae3
    ~OffsetFormEntry(){};
Packit cdaae3
Packit cdaae3
    Dwarf_Unsigned  off_;
Packit cdaae3
    IRFormReference *form_;
Packit cdaae3
};
Packit cdaae3
struct ClassReferenceFixupData {
Packit cdaae3
    ClassReferenceFixupData():
Packit cdaae3
        dbg_(0),
Packit cdaae3
        attrnum_(0),
Packit cdaae3
        sourcedie_(0),
Packit cdaae3
        target_(0) {}
Packit cdaae3
    ~ClassReferenceFixupData(){};
Packit cdaae3
    ClassReferenceFixupData(
Packit cdaae3
        Dwarf_P_Debug dbg,
Packit cdaae3
        Dwarf_Half attrnum,
Packit cdaae3
        Dwarf_P_Die sourcedie,
Packit cdaae3
        IRDie *d):
Packit cdaae3
        dbg_(dbg),
Packit cdaae3
        attrnum_(attrnum),
Packit cdaae3
        sourcedie_(sourcedie),
Packit cdaae3
        target_(d) {};
Packit cdaae3
    Dwarf_P_Debug dbg_;
Packit cdaae3
    //  The source die and attrnum suffice because the definition of
Packit cdaae3
    //  DWARF guarantees only one attribute of any given attribute number
Packit cdaae3
    //  can exist on a given DIE.
Packit cdaae3
    Dwarf_Half attrnum_;
Packit cdaae3
    Dwarf_P_Die sourcedie_;
Packit cdaae3
    IRDie *target_;
Packit cdaae3
};
Packit cdaae3
Packit cdaae3
class IRCUdata {
Packit cdaae3
public:
Packit cdaae3
    IRCUdata():
Packit cdaae3
        cu_header_length_(0),
Packit cdaae3
        abbrev_offset_(0),
Packit cdaae3
        next_cu_header_offset_(0),
Packit cdaae3
        version_stamp_(0),
Packit cdaae3
        address_size_(0),
Packit cdaae3
        length_size_(0),
Packit cdaae3
        extension_size_(0),
Packit cdaae3
        has_macrodata_(false),
Packit cdaae3
        macrodata_offset_(0),
Packit cdaae3
        has_linedata_(false),
Packit cdaae3
        linedata_offset_(0),
Packit cdaae3
        cudie_offset_(0)
Packit cdaae3
        {};
Packit cdaae3
    IRCUdata(Dwarf_Unsigned len,Dwarf_Half version,
Packit cdaae3
        Dwarf_Unsigned abbrev_offset,
Packit cdaae3
        Dwarf_Half addr_size,
Packit cdaae3
        Dwarf_Half length_size,
Packit cdaae3
        Dwarf_Half extension_size,
Packit cdaae3
        Dwarf_Unsigned next_cu_header):
Packit cdaae3
            cu_header_length_(len),
Packit cdaae3
            abbrev_offset_(abbrev_offset),
Packit cdaae3
            next_cu_header_offset_(addr_size),
Packit cdaae3
            version_stamp_(version),
Packit cdaae3
            address_size_(addr_size),
Packit cdaae3
            length_size_(length_size),
Packit cdaae3
            extension_size_(extension_size),
Packit cdaae3
            has_macrodata_(false),
Packit cdaae3
            macrodata_offset_(0),
Packit cdaae3
            has_linedata_(false),
Packit cdaae3
            linedata_offset_(0),
Packit cdaae3
            cudie_offset_(0) {};
Packit cdaae3
    ~IRCUdata() { };
Packit cdaae3
    bool hasMacroData(Dwarf_Unsigned *offset_out,Dwarf_Unsigned *cudie_off) {
Packit cdaae3
        *offset_out = macrodata_offset_;
Packit cdaae3
        *cudie_off = cudie_offset_;
Packit cdaae3
        return has_macrodata_;
Packit cdaae3
    }
Packit cdaae3
    bool hasLineData(Dwarf_Unsigned *offset_out,Dwarf_Unsigned *cudie_off) {
Packit cdaae3
        *offset_out = linedata_offset_;
Packit cdaae3
        *cudie_off = cudie_offset_;
Packit cdaae3
        return has_linedata_;
Packit cdaae3
    }
Packit cdaae3
    void setMacroData(Dwarf_Unsigned offset,Dwarf_Unsigned cudieoff) {
Packit cdaae3
        has_macrodata_ = true;
Packit cdaae3
        macrodata_offset_ = offset;
Packit cdaae3
        cudie_offset_ = cudieoff;
Packit cdaae3
    };
Packit cdaae3
    void setLineData(Dwarf_Unsigned offset,Dwarf_Unsigned cudieoff) {
Packit cdaae3
        has_linedata_ = true;
Packit cdaae3
        linedata_offset_ = offset;
Packit cdaae3
        cudie_offset_ = cudieoff;
Packit cdaae3
    };
Packit cdaae3
    IRDie & baseDie() { return cudie_; };
Packit cdaae3
    Dwarf_Half getVersionStamp() { return version_stamp_; };
Packit cdaae3
    Dwarf_Half getOffsetSize() { return length_size_; };
Packit cdaae3
    Dwarf_Unsigned getCUdieOffset() { return cudie_offset_; };
Packit cdaae3
    IRCULineData & getCULines() { return cu_lines_; };
Packit cdaae3
Packit cdaae3
    void insertLocalDieOffset(Dwarf_Unsigned localoff,IRDie* dieptr) {
Packit cdaae3
        cuOffInLocalToIRDie_[localoff] = dieptr;
Packit cdaae3
    };
Packit cdaae3
    void insertLocalReferenceAttrTargetRef(Dwarf_Unsigned localoff,
Packit cdaae3
        IRFormReference* attrptr) {
Packit cdaae3
Packit cdaae3
        cuOffInLocalToIRFormRef_.push_back(OffsetFormEntry(localoff,
Packit cdaae3
            attrptr));
Packit cdaae3
    };
Packit cdaae3
    IRDie * getLocalDie(Dwarf_Unsigned localoff) {
Packit cdaae3
        std::map<Dwarf_Unsigned,IRDie*>::iterator pos;
Packit cdaae3
        pos = cuOffInLocalToIRDie_.find(localoff);
Packit cdaae3
        if(pos != cuOffInLocalToIRDie_.end()) {
Packit cdaae3
            return pos->second;
Packit cdaae3
        }
Packit cdaae3
        return NULL;
Packit cdaae3
    };
Packit cdaae3
    void insertClassReferenceFixupData(ClassReferenceFixupData &c) {
Packit cdaae3
        classReferenceFixupList_.push_back(c);
Packit cdaae3
    }
Packit cdaae3
    void updateClassReferenceTargets();
Packit cdaae3
    std::string  getCUName() {
Packit cdaae3
        return cudie_.getName();
Packit cdaae3
    };
Packit cdaae3
    // Use  cuOffInLocalToIRDie_ and
Packit cdaae3
    // cuOffInLocalToIRAttr_ to update attr targets.
Packit cdaae3
    void updateReferenceAttrDieTargets() {
Packit cdaae3
        for(std::list<OffsetFormEntry>::iterator it =
Packit cdaae3
            cuOffInLocalToIRFormRef_.begin();
Packit cdaae3
            it != cuOffInLocalToIRFormRef_.end();
Packit cdaae3
            ++it) {
Packit cdaae3
            IRFormReference* r = it->form_;
Packit cdaae3
            IRDie * tdie = getLocalDie(it->off_);
Packit cdaae3
            if(tdie) {
Packit cdaae3
                r->setTargetInDie(tdie);
Packit cdaae3
            } else {
Packit cdaae3
                // Missing die in r
Packit cdaae3
                // Should be impossible.
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
private:
Packit cdaae3
    Dwarf_Unsigned cu_header_length_;
Packit cdaae3
    Dwarf_Unsigned abbrev_offset_;
Packit cdaae3
    Dwarf_Unsigned next_cu_header_offset_;
Packit cdaae3
    Dwarf_Half  version_stamp_;
Packit cdaae3
    Dwarf_Half address_size_;
Packit cdaae3
    Dwarf_Half length_size_;
Packit cdaae3
    Dwarf_Half extension_size_;
Packit cdaae3
    bool has_macrodata_;
Packit cdaae3
    Dwarf_Unsigned macrodata_offset_;
Packit cdaae3
    bool has_linedata_;
Packit cdaae3
    Dwarf_Unsigned linedata_offset_;
Packit cdaae3
    Dwarf_Unsigned cudie_offset_;
Packit cdaae3
    IRCULineData      cu_lines_;
Packit cdaae3
Packit cdaae3
    // If true, is 32bit dwarf,else 64bit. Gives the size of a reference.
Packit cdaae3
    bool dwarf32bit_;
Packit cdaae3
Packit cdaae3
    IRDie   cudie_;
Packit cdaae3
Packit cdaae3
    // Refers to cu-local offsets in the input CU and which DIE
Packit cdaae3
    // in the input they target for this CU.
Packit cdaae3
    // Used to find the target DIE for the IRAttrs
Packit cdaae3
    // referenced by  cuOffInLocalToIRAttr_
Packit cdaae3
    std::map<Dwarf_Unsigned,IRDie*> cuOffInLocalToIRDie_;
Packit cdaae3
Packit cdaae3
    // Refers to IRAttrs which make a CU local reference
Packit cdaae3
    // meaning CLASS_REFERENCE IRFormReference to a cu-local die
Packit cdaae3
    // Once Input dies read in this and cuOffInLocalToIRDie_
Packit cdaae3
    // are used to update the IRAttr itself.
Packit cdaae3
    std::list<OffsetFormEntry> cuOffInLocalToIRFormRef_;
Packit cdaae3
Packit cdaae3
    // The data needed to get the Dwarf_P_Die  set for
Packit cdaae3
    // some class reference instances.
Packit cdaae3
    std::list<ClassReferenceFixupData> classReferenceFixupList_;
Packit cdaae3
};
Packit cdaae3
Packit cdaae3
class IRDInfo {
Packit cdaae3
public:
Packit cdaae3
   IRDInfo() {};
Packit cdaae3
   ~IRDInfo() {};
Packit cdaae3
   IRCUdata &lastCU() { return cudata_.back(); }
Packit cdaae3
   std::list<IRCUdata>& getCUData() {return cudata_; };
Packit cdaae3
private:
Packit cdaae3
   std::list<IRCUdata>  cudata_;
Packit cdaae3
};
Packit cdaae3