1 /* Copyright (C) 2007-2010 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 13 /* 14 * Contains declarations of classes defined for a variety of DWARF objects. 15 */ 16 17 #ifndef ELFF_DWARF_DIE_H_ 18 #define ELFF_DWARF_DIE_H_ 19 20 #include "dwarf_defs.h" 21 #include "elf_alloc.h" 22 23 class ElfFile; 24 class DwarfCU; 25 26 /* Encapsulates an object that wraps up a DIE, cached during 27 * ELF file parsing. 28 */ 29 class DIEObject : public DwarfAllocBase { 30 public: 31 /* Constructs DIEObject intance. 32 * Param: 33 * die - DIE represented with this instance. 34 * parent_cu - Compilation unit this DIE belongs to. 35 * parent_die - Parent DIE object for this DIE. This parameter can be NULL 36 * only for compilation unit DIEs. 37 */ DIEObject(const Dwarf_DIE * die,DwarfCU * parent_cu,DIEObject * parent_die)38 DIEObject(const Dwarf_DIE* die, DwarfCU* parent_cu, DIEObject* parent_die) 39 : die_(die), 40 parent_cu_(parent_cu), 41 parent_die_(parent_die), 42 last_child_(NULL), 43 prev_sibling_(NULL) { 44 } 45 46 /* Destructs DIEObject intance. */ 47 ~DIEObject(); 48 49 /* Gets ELF file this DIE belongs to. */ 50 ElfFile* elf_file() const; 51 52 /* Gets DWARF tag (DW_TAG_Xxx) for the DIE represented with this instance. */ 53 Dwarf_Tag get_tag() const; 54 55 /* Gets the best name for this DIE. 56 * Some DIEs (such as inline routine DIEs) may have no DW_AT_name property, 57 * but may reference to another DIE that may contain DIE name. This method 58 * tries its best to get DIE name by iterating through different methods of 59 * naming the DIE. 60 * Return: 61 * Name for this DIE, or NULL if it was not possible to find a relevant DIE 62 * with DW_AT_name property. 63 */ 64 const char* get_name() const; 65 66 /* Gets DIE's attribute by its ID. 67 * Param: 68 * at_id - ID (DW_AT_Xxx) of the attribute to get. 69 * attr - Upon successful return contains requested attribute information. 70 * Return: 71 * true on success, or false if attribute for the given ID doesn't exist 72 * in the DIE's attribute list. 73 */ 74 bool get_attrib(Dwarf_At at, DIEAttrib* attr) const; 75 76 /* Gets the leaf DIE object containing given address. 77 * See DwarfCU::get_leaf_die_for_address() for method details. 78 * See DIEObject::contains_address() for implementation details. 79 */ 80 DIEObject* get_leaf_for_address(Elf_Xword address); 81 82 /* Finds a DIE object for the given die in the branch starting with 83 * this DIE object. 84 */ 85 DIEObject* find_die_object(const Dwarf_DIE* die_to_find); 86 87 /* Dumps this object to stdout. 88 * Param: 89 * only_this - If true, only this object will be dumped. If this parameter 90 * is false, all the childs and siblings of this object will be dumped 91 * along with this object. 92 */ 93 void dump(bool only_this) const; 94 95 protected: 96 /* Checks if this DIE object containing given address. 97 * Template param: 98 * AddrType - Type of compilation unin address (4, or 8 bytes), defined by 99 * address_size field of the CU header. Must be Elf_Xword for 8 bytes 100 * address, or Elf_Word for 4 bytes address. 101 * Param: 102 * address - Address ti check. 103 * Return: 104 * True, if this DIE address ranges (including low_pc, high_pc attributes) 105 * contain given address, or false otherwise. 106 */ 107 template <typename AddrType> 108 bool contains_address(Elf_Xword address); 109 110 /* Advances to the DIE's property list. 111 * Param: 112 * at_abbr - Upon successful return contains a pointer to the beginning of 113 * DIE attribute abbreviation list. This parameter can be NULL, if the 114 * caller is not interested in attribute abbreviation list for this DIE. 115 * tag - Upon successful return contains DIE's tag. This parameter can be 116 * NULL, if the caller is not interested in the tag value for this DIE. 117 * Return: 118 * Pointer to the beginning of the DIE attribute list in mapped .debug_info 119 * section on success, or NULL on failure. 120 */ 121 const Elf_Byte* advance(const Dwarf_Abbr_AT** at_abbr, Dwarf_Tag* tag) const; 122 123 public: 124 /* Gets DIE represented with this instance. */ die()125 const Dwarf_DIE* die() const { 126 return die_; 127 } 128 129 /* Gets compilation unit this DIE belongs to. */ parent_cu()130 DwarfCU* parent_cu() const { 131 return parent_cu_; 132 } 133 134 /* Gets parent DIE object for this die. */ parent_die()135 DIEObject* parent_die() const { 136 return parent_die_; 137 } 138 139 /* Gets last child object in the list of this DIE's childs. NOTE: for better 140 * performace the list is created in reverse order (relatively to the order, 141 * in which children DIEs have been discovered). 142 */ last_child()143 DIEObject* last_child() const { 144 return last_child_; 145 } 146 147 /* Links next child to the list of this DIE childs. */ link_child(DIEObject * child)148 void link_child(DIEObject* child) { 149 last_child_ = child; 150 } 151 152 /* Gets previous sibling of this DIE in the parent's DIE object list. */ prev_sibling()153 DIEObject* prev_sibling() const { 154 return prev_sibling_; 155 } 156 157 /* Links next sibling to the list of this DIE siblings. */ link_sibling(DIEObject * sibl)158 void link_sibling(DIEObject* sibl) { 159 prev_sibling_ = sibl; 160 } 161 162 /* Checks if this DIE object represents a CU DIE. 163 * We relay here on the fact that only CU DIE objects have no parent 164 * DIE objects. 165 */ is_cu_die()166 bool is_cu_die() const { 167 return parent_die_ == NULL; 168 } 169 170 /* Gets this DIE level in the branch. 171 * DIE level defines DIE's distance from the CU DIE in the branch this DIE 172 * belongs to. In other words, DIE level defines how many parent DIEs exist 173 * between this DIE, and the CU DIE. For instance, the CU DIE has level 0, 174 * a subroutine a() in this compilation unit has level 1, a soubroutine b(), 175 * that has been inlined into subroutine a() will have level 2, a try/catch 176 * block in the inlined subroutine b() will have level 3, and so on. 177 */ get_level()178 Elf_Word get_level() const { 179 return parent_die_ != NULL ? parent_die_->get_level() + 1 : 0; 180 } 181 182 protected: 183 /* DIE that is represented with this instance. */ 184 const Dwarf_DIE* die_; 185 186 /* Compilation unit this DIE belongs to. */ 187 DwarfCU* parent_cu_; 188 189 /* Parent DIE object for this die. */ 190 DIEObject* parent_die_; 191 192 /* Last child object in the list of this DIE's childs. NOTE: for better 193 * performace the list is created in reverse order (relatively to the order, 194 * in which children DIEs have been discovered). 195 */ 196 DIEObject* last_child_; 197 198 /* Previous sibling of this DIE in the parent's DIE object list. */ 199 DIEObject* prev_sibling_; 200 }; 201 202 #endif // ELFF_DWARF_DIE_H_ 203