To get the top-level DIE describing the compilation unit, call the
get_top_DIE method.
"""
- def __init__(self, header, dwarfinfo, structs, cu_die_offset):
+ def __init__(self, header, dwarfinfo, structs, cu_offset, cu_die_offset):
""" header:
CU header for this compile unit
structs:
A DWARFStructs instance suitable for this compile unit
+ cu_offset:
+ Offset in the stream to the beginning of this CU (its header)
+
cu_die_offset:
Offset in the stream of the top DIE of this CU
"""
self.dwarfinfo = dwarfinfo
self.header = header
self.structs = structs
+ self.cu_offset = cu_offset
self.cu_die_offset = cu_die_offset
# The abbreviation table for this CU. Filled lazily when DIEs are
# requested.
self._abbrev_table = None
+ # A list of DIEs belonging to this CU. Lazily parsed.
+ self._dielist = []
+
def get_abbrev_table(self):
""" Get the abbreviation table (AbbrevTable object) for this CU
"""
""" Get the top DIE (which is either a DW_TAG_compile_unit or
DW_TAG_partial_unit) of this CU
"""
- return DIE(
- cu=self,
- stream=self.dwarfinfo.stream,
- offset=self.cu_die_offset)
+ return self._get_DIE(0)
def __getitem__(self, name):
""" Implement dict-like access to header entries
"""
return self.header[name]
-
\ No newline at end of file
+ def _get_DIE(self, index):
+ """ Get the DIE at the given index
+ """
+ if len(self._dielist) == 0:
+ self._parse_DIEs()
+ return self._dielist[index]
+
+ def _parse_DIEs(self):
+ # Compute the boundary (one byte past the bounds) of this CU in the
+ # stream
+ cu_boundary = ( self.cu_offset +
+ self['unit_length'] +
+ self.structs.initial_length_field_size())
+
+ die_offset = self.cu_die_offset
+ while die_offset < cu_boundary:
+ die = DIE(cu=self, stream=self.dwarfinfo.stream, offset=die_offset)
+ self._dielist.append(die)
+ die_offset += die.size
+
header=cu_header,
dwarfinfo=self,
structs=cu_structs,
+ cu_offset=offset,
cu_die_offset=cu_die_offset))
# Compute the offset of the next CU in the section. The unit_length
# field of the CU header contains its size not including the length
# field itself.
offset = ( offset +
cu_header['unit_length'] +
- cu_structs.initial_lenght_field_size())
+ cu_structs.initial_length_field_size())
return CUlist
def _is_supported_version(self, version):
# read a little-endian, 64-bit file
es = ELFStructs(True, 64)
-stream = open('tests/testfiles/z.elf', 'rb')
+stream = open('tests/testfiles/exe_simple64.elf', 'rb')
#stream = open('binfiles/z32.elf', 'rb')
efile = ELFFile(stream)
dwarfinfo = efile.get_dwarf_info()
tt = dwarfinfo.structs.Dwarf_dw_form['DW_FORM_block1'].parse('\x03\x12\x34\x46')
-cu = dwarfinfo.get_CU(0)
+cu = dwarfinfo.get_CU(1)
print 'CU header', cu.header
topdie = cu.get_top_DIE()
-print topdie.size, topdie.tag
-for attrname, val in topdie.attributes.iteritems():
- print attrname, val
+for die in cu._dielist:
+ print 'DIE %s, size=%s' % (die.tag, die.size)
+ for attrname, val in die.attributes.iteritems():
+ print ' ', attrname, val
+
+#~ topdie = cu.get_top_DIE()
+
+#~ print topdie.size, topdie.tag
+
+#~ print len(cu._dielist)
#~ print dwarfinfo.structs.Dwarf_abbrev_entry.parse('\x13\x01\x01\x03\x50\x04\x00\x00')