14
14
15
15
from elftools .dwarf .die import DIE
16
16
17
+ from dwarf_expr import describe_DWARF_expr
18
+
17
19
# Maps of each DIE offset to the corresponding DIE.
18
20
# Used when trying to follow DIE type references, i.e., a DW_TAG_typedef DIE that has a DW_AT_type
19
21
# attribute that refers to a DW_TAG_base_type DIE.
@@ -52,7 +54,7 @@ def __init__(self, name, type, depth, offset, modifiers=None):
52
54
type = type ,
53
55
depth = depth ,
54
56
offset = offset ,
55
- modifiers = modifiers )
57
+ modifiers = modifiers , )
56
58
57
59
@staticmethod
58
60
def member (child , depth , offset ):
@@ -95,6 +97,9 @@ def member(child, depth, offset):
95
97
modifiers )
96
98
97
99
# Creates a MemberInformation dict for a DIE that's known to be the parent of another DIE.
100
+ # The only real difference is that we repalce the name field with '(parent)', and that we can
101
+ # assume that it won't be an anonymous union.
102
+ # Since most of the code is so similar, this should later be refactored.
98
103
@staticmethod
99
104
def parent (parent , depth , offset ):
100
105
if offset :
@@ -144,12 +149,15 @@ def __init__(self, die):
144
149
145
150
members = getMembers (die )
146
151
152
+ vtable = getVtable (die )
153
+
147
154
dict .__init__ (self ,
148
155
name = name ,
149
156
tag = tag ,
150
157
size = size ,
151
158
subtype = subtype ,
152
- members = members )
159
+ members = members ,
160
+ vtable = vtable )
153
161
154
162
# Given a type DIE, get the full name of that type, e.g, mongo::Value
155
163
def getFullTypeName (die ):
@@ -221,3 +229,35 @@ def isType(die, typeName):
221
229
if typeDie .tag == typeName :
222
230
return True
223
231
return False
232
+
233
+ def getVtable (typeDie ):
234
+ global die_list
235
+ vtable = {}
236
+ for child in typeDie .iter_children ():
237
+ # Get the vtable entries from the parents
238
+ if child .tag == 'DW_TAG_inheritance' :
239
+ parentRef = child .attributes .get ('DW_AT_type' ).value
240
+ parentDie = die_list [child .cu .cu_offset + parentRef ]
241
+ parentVtable = getVtable (parentDie )
242
+ vtable = dict (vtable .items () + parentVtable .items ())
243
+ for child in typeDie .iter_children ():
244
+ if child .tag == 'DW_TAG_subprogram' \
245
+ and child .attributes .get ('DW_AT_virtuality' ) \
246
+ and child .attributes .get ('DW_AT_vtable_elem_location' ):
247
+ elem_location = child .attributes .get ('DW_AT_vtable_elem_location' )
248
+ if elem_location .form == 'DW_FORM_exprloc' :
249
+ loc_pieces = describe_DWARF_expr (elem_location .value , child .cu .structs )
250
+ # Not 100% sure what loc_pieces represents right now...
251
+ index = loc_pieces [0 ]
252
+ if child .attributes .get ('DW_AT_linkage_name' ):
253
+ name = child .attributes .get ('DW_AT_linkage_name' ).value
254
+ elif child .attributes .get ('DW_AT_name' ):
255
+ name = child .attributes .get ('DW_AT_name' ).value
256
+ else :
257
+ name = "(Cannot determine name)"
258
+ vtable [index ] = name
259
+ elif elem_location .form == 'DW_FORM_loclistptr' :
260
+ print 'Cannot currently handle form DW_FORM_loclistptr'
261
+ else :
262
+ print 'Unexpected form {} for vtable_elem_location' .format (elem_location .form )
263
+ return vtable
0 commit comments