| /* Copyright (C) 2007-2010 The Android Open Source Project |
| ** |
| ** This software is licensed under the terms of the GNU General Public |
| ** License version 2, as published by the Free Software Foundation, and |
| ** may be copied, distributed, and modified under those terms. |
| ** |
| ** This program is distributed in the hope that it will be useful, |
| ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
| ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| ** GNU General Public License for more details. |
| */ |
| |
| /* |
| * Contains declarations of classes defined for a variety of DWARF objects. |
| */ |
| |
| #ifndef ELFF_DWARF_DIE_H_ |
| #define ELFF_DWARF_DIE_H_ |
| |
| #include "dwarf_defs.h" |
| #include "elf_alloc.h" |
| |
| class ElfFile; |
| class DwarfCU; |
| |
| /* Encapsulates an object that wraps up a DIE, cached during |
| * ELF file parsing. |
| */ |
| class DIEObject : public DwarfAllocBase { |
| public: |
| /* Constructs DIEObject intance. |
| * Param: |
| * die - DIE represented with this instance. |
| * parent_cu - Compilation unit this DIE belongs to. |
| * parent_die - Parent DIE object for this DIE. This parameter can be NULL |
| * only for compilation unit DIEs. |
| */ |
| DIEObject(const Dwarf_DIE* die, DwarfCU* parent_cu, DIEObject* parent_die) |
| : die_(die), |
| parent_cu_(parent_cu), |
| parent_die_(parent_die), |
| last_child_(NULL), |
| prev_sibling_(NULL) { |
| } |
| |
| /* Destructs DIEObject intance. */ |
| ~DIEObject(); |
| |
| /* Gets ELF file this DIE belongs to. */ |
| ElfFile* elf_file() const; |
| |
| /* Gets DWARF tag (DW_TAG_Xxx) for the DIE represented with this instance. */ |
| Dwarf_Tag get_tag() const; |
| |
| /* Gets the best name for this DIE. |
| * Some DIEs (such as inline routine DIEs) may have no DW_AT_name property, |
| * but may reference to another DIE that may contain DIE name. This method |
| * tries its best to get DIE name by iterating through different methods of |
| * naming the DIE. |
| * Return: |
| * Name for this DIE, or NULL if it was not possible to find a relevant DIE |
| * with DW_AT_name property. |
| */ |
| const char* get_name() const; |
| |
| /* Gets DIE's attribute by its ID. |
| * Param: |
| * at_id - ID (DW_AT_Xxx) of the attribute to get. |
| * attr - Upon successful return contains requested attribute information. |
| * Return: |
| * true on success, or false if attribute for the given ID doesn't exist |
| * in the DIE's attribute list. |
| */ |
| bool get_attrib(Dwarf_At at, DIEAttrib* attr) const; |
| |
| /* Gets the leaf DIE object containing given address. |
| * See DwarfCU::get_leaf_die_for_address() for method details. |
| * See DIEObject::contains_address() for implementation details. |
| */ |
| DIEObject* get_leaf_for_address(Elf_Xword address); |
| |
| /* Finds a DIE object for the given die in the branch starting with |
| * this DIE object. |
| */ |
| DIEObject* find_die_object(const Dwarf_DIE* die_to_find); |
| |
| /* Dumps this object to stdout. |
| * Param: |
| * only_this - If true, only this object will be dumped. If this parameter |
| * is false, all the childs and siblings of this object will be dumped |
| * along with this object. |
| */ |
| void dump(bool only_this) const; |
| |
| protected: |
| /* Checks if this DIE object containing given address. |
| * Template param: |
| * AddrType - Type of compilation unin address (4, or 8 bytes), defined by |
| * address_size field of the CU header. Must be Elf_Xword for 8 bytes |
| * address, or Elf_Word for 4 bytes address. |
| * Param: |
| * address - Address ti check. |
| * Return: |
| * True, if this DIE address ranges (including low_pc, high_pc attributes) |
| * contain given address, or false otherwise. |
| */ |
| template <typename AddrType> |
| bool contains_address(Elf_Xword address); |
| |
| /* Advances to the DIE's property list. |
| * Param: |
| * at_abbr - Upon successful return contains a pointer to the beginning of |
| * DIE attribute abbreviation list. This parameter can be NULL, if the |
| * caller is not interested in attribute abbreviation list for this DIE. |
| * tag - Upon successful return contains DIE's tag. This parameter can be |
| * NULL, if the caller is not interested in the tag value for this DIE. |
| * Return: |
| * Pointer to the beginning of the DIE attribute list in mapped .debug_info |
| * section on success, or NULL on failure. |
| */ |
| const Elf_Byte* advance(const Dwarf_Abbr_AT** at_abbr, Dwarf_Tag* tag) const; |
| |
| public: |
| /* Gets DIE represented with this instance. */ |
| const Dwarf_DIE* die() const { |
| return die_; |
| } |
| |
| /* Gets compilation unit this DIE belongs to. */ |
| DwarfCU* parent_cu() const { |
| return parent_cu_; |
| } |
| |
| /* Gets parent DIE object for this die. */ |
| DIEObject* parent_die() const { |
| return parent_die_; |
| } |
| |
| /* Gets last child object in the list of this DIE's childs. NOTE: for better |
| * performace the list is created in reverse order (relatively to the order, |
| * in which children DIEs have been discovered). |
| */ |
| DIEObject* last_child() const { |
| return last_child_; |
| } |
| |
| /* Links next child to the list of this DIE childs. */ |
| void link_child(DIEObject* child) { |
| last_child_ = child; |
| } |
| |
| /* Gets previous sibling of this DIE in the parent's DIE object list. */ |
| DIEObject* prev_sibling() const { |
| return prev_sibling_; |
| } |
| |
| /* Links next sibling to the list of this DIE siblings. */ |
| void link_sibling(DIEObject* sibl) { |
| prev_sibling_ = sibl; |
| } |
| |
| /* Checks if this DIE object represents a CU DIE. |
| * We relay here on the fact that only CU DIE objects have no parent |
| * DIE objects. |
| */ |
| bool is_cu_die() const { |
| return parent_die_ == NULL; |
| } |
| |
| /* Gets this DIE level in the branch. |
| * DIE level defines DIE's distance from the CU DIE in the branch this DIE |
| * belongs to. In other words, DIE level defines how many parent DIEs exist |
| * between this DIE, and the CU DIE. For instance, the CU DIE has level 0, |
| * a subroutine a() in this compilation unit has level 1, a soubroutine b(), |
| * that has been inlined into subroutine a() will have level 2, a try/catch |
| * block in the inlined subroutine b() will have level 3, and so on. |
| */ |
| Elf_Word get_level() const { |
| return parent_die_ != NULL ? parent_die_->get_level() + 1 : 0; |
| } |
| |
| protected: |
| /* DIE that is represented with this instance. */ |
| const Dwarf_DIE* die_; |
| |
| /* Compilation unit this DIE belongs to. */ |
| DwarfCU* parent_cu_; |
| |
| /* Parent DIE object for this die. */ |
| DIEObject* parent_die_; |
| |
| /* Last child object in the list of this DIE's childs. NOTE: for better |
| * performace the list is created in reverse order (relatively to the order, |
| * in which children DIEs have been discovered). |
| */ |
| DIEObject* last_child_; |
| |
| /* Previous sibling of this DIE in the parent's DIE object list. */ |
| DIEObject* prev_sibling_; |
| }; |
| |
| #endif // ELFF_DWARF_DIE_H_ |