aboutsummaryrefslogtreecommitdiffstats
path: root/elff/dwarf_die.h
blob: ca2eeeba0232dd7254dc9375543bae7b01c13efc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/* 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_