Skip to content

Commit 64572a1

Browse files
danharelDorothy Chen
authored andcommitted
Started vtable analysis
1 parent d2a9925 commit 64572a1

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

app/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ def source_code_from_path():
311311
if request.form['lineno'] == "":
312312
return jsonify({})
313313

314-
path = os.path.join(app.config['SRC_DIR'] + request.form['src_path'])
314+
path = os.path.join(app.config['SRC_DIR'], request.form['src_path'])
315315
lineno = int(request.form['lineno'])
316316

317317
before = ""

app/die_information.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
from elftools.dwarf.die import DIE
1616

17+
from dwarf_expr import describe_DWARF_expr
18+
1719
# Maps of each DIE offset to the corresponding DIE.
1820
# Used when trying to follow DIE type references, i.e., a DW_TAG_typedef DIE that has a DW_AT_type
1921
# attribute that refers to a DW_TAG_base_type DIE.
@@ -52,7 +54,7 @@ def __init__(self, name, type, depth, offset, modifiers=None):
5254
type=type,
5355
depth=depth,
5456
offset=offset,
55-
modifiers=modifiers)
57+
modifiers=modifiers,)
5658

5759
@staticmethod
5860
def member(child, depth, offset):
@@ -95,6 +97,9 @@ def member(child, depth, offset):
9597
modifiers)
9698

9799
# 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.
98103
@staticmethod
99104
def parent(parent, depth, offset):
100105
if offset:
@@ -144,12 +149,15 @@ def __init__(self, die):
144149

145150
members = getMembers(die)
146151

152+
vtable = getVtable(die)
153+
147154
dict.__init__(self,
148155
name=name,
149156
tag=tag,
150157
size=size,
151158
subtype=subtype,
152-
members=members)
159+
members=members,
160+
vtable=vtable)
153161

154162
# Given a type DIE, get the full name of that type, e.g, mongo::Value
155163
def getFullTypeName(die):
@@ -221,3 +229,35 @@ def isType(die, typeName):
221229
if typeDie.tag == typeName:
222230
return True
223231
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

app/executable.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,6 @@ def get_type_info(self, addr):
579579
type_dies[dieInfo['name']] = dieInfo
580580
self.type_dies[CU.cu_offset] = type_dies
581581
print len(type_dies.keys())
582-
# return {}
583582
return type_dies
584583

585584
def printChildren(die):

0 commit comments

Comments
 (0)