Home | History | Annotate | Download | only in elff
      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    */
     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. */
    125   const Dwarf_DIE* die() const {
    126     return die_;
    127   }
    128 
    129   /* Gets compilation unit this DIE belongs to. */
    130   DwarfCU* parent_cu() const {
    131     return parent_cu_;
    132   }
    133 
    134   /* Gets parent DIE object for this 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    */
    143   DIEObject* last_child() const {
    144     return last_child_;
    145   }
    146 
    147   /* Links next child to the list of this DIE childs. */
    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. */
    153   DIEObject* prev_sibling() const {
    154     return prev_sibling_;
    155   }
    156 
    157   /* Links next sibling to the list of this DIE siblings. */
    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    */
    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    */
    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