/* 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_ |