From d87f1e5ffe135984172175239db34fc343adaf6c Mon Sep 17 00:00:00 2001 From: eliben Date: Thu, 22 Sep 2011 14:55:19 +0300 Subject: [PATCH] cleanup and cosmetics - for a healthy future!! er... what? --- elftools/dwarf/compileunit.py | 17 +++++++++++++++++ elftools/dwarf/die.py | 16 +++++++++++++--- elftools/dwarf/dwarfinfo.py | 15 +++++++++++---- z.py | 5 +++-- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/elftools/dwarf/compileunit.py b/elftools/dwarf/compileunit.py index 8852fac..ec04f7d 100644 --- a/elftools/dwarf/compileunit.py +++ b/elftools/dwarf/compileunit.py @@ -10,6 +10,23 @@ from .die import DIE class CompileUnit(object): + """ A DWARF compilation unit (CU). + + A normal compilation unit typically represents the text and data + contributed to an executable by a single relocatable object file. + It may be derived from several source files, + including pre-processed "include files" + + Serves as a container and context to DIEs that describe objects and code + belonging to a compilation unit. + + CU header entries can be accessed as dict keys from this object, i.e. + cu = CompileUnit(...) + cu['version'] # version field of the CU header + + 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): """ header: CU header for this compile unit diff --git a/elftools/dwarf/die.py b/elftools/dwarf/die.py index fba5ed2..26e9dba 100644 --- a/elftools/dwarf/die.py +++ b/elftools/dwarf/die.py @@ -25,7 +25,11 @@ from ..common.utils import struct_parse, preserve_stream_pos # Raw value as parsed from the section - used for debugging and presentation # (e.g. for a DW_FORM_strp it's the raw string offset into the table) # -AttributeValue = namedtuple('AttributeValue', 'form value raw_value') +# offset: +# Offset of this attribute's value in the stream +# +AttributeValue = namedtuple( + 'AttributeValue', 'form value raw_value offset') class DIE(object): @@ -73,6 +77,8 @@ class DIE(object): """ return self.tag is None + #------ PRIVATE ------# + def _parse_DIE(self): """ Parses the DIE info from the section, based on the abbreviation table of the CU @@ -101,10 +107,14 @@ class DIE(object): # values from the stream. # for name, form in abbrev_decl.iter_attr_specs(): - print '**', self.stream.tell() + attr_offset = self.stream.tell() raw_value = struct_parse(structs.Dwarf_dw_form[form], self.stream) value = self._translate_attr_value(form, raw_value) - self.attributes[name] = AttributeValue(form, value, raw_value) + self.attributes[name] = AttributeValue( + form=form, + value=value, + raw_value=raw_value, + offset=attr_offset) self.size = self.stream.tell() - self.offset diff --git a/elftools/dwarf/dwarfinfo.py b/elftools/dwarf/dwarfinfo.py index 4301643..7a4bbc0 100644 --- a/elftools/dwarf/dwarfinfo.py +++ b/elftools/dwarf/dwarfinfo.py @@ -51,14 +51,19 @@ class DWARFInfo(object): self.little_endian = little_endian # This is the DWARFStructs the context uses, so it doesn't depend on - # DWARF format and address_size (these are determined per CU) - so we - # set them to default values. + # DWARF format and address_size (these are determined per CU) - set them + # to default values. self.structs = DWARFStructs( little_endian=self.little_endian, dwarf_format=32, address_size=4) - # Populate the list with CUs found in debug_info + # Populate the list with CUs found in debug_info. For each CU only its + # header is parsed immediately (the abbrev table isn't loaded before + # it's being referenced by one of the CU's DIEs). + # Since there usually aren't many CUs in a single object, this + # shouldn't present a performance problem. + # self._CU = self._parse_CUs() # Cache for abbrev tables: a dict keyed by offset @@ -121,6 +126,8 @@ class DWARFInfo(object): self.stream, stream_pos=self.debug_str_loc.offset + offset) + #------ PRIVATE ------# + def _parse_CUs(self): """ Parse CU entries from debug_info. """ @@ -157,7 +164,7 @@ class DWARFInfo(object): cu_structs = DWARFStructs( little_endian=self.little_endian, dwarf_format=dwarf_format, - address_size=8) + address_size=8) cu_die_offset = self.stream.tell() dwarf_assert( diff --git a/z.py b/z.py index ea7c762..5e5e775 100644 --- a/z.py +++ b/z.py @@ -22,12 +22,13 @@ print efile.has_dwarf_info() dwarfinfo = efile.get_dwarf_info() tt = dwarfinfo.structs.Dwarf_dw_form['DW_FORM_block1'].parse('\x03\x12\x34\x46') -cu = dwarfinfo.get_CU(1) +cu = dwarfinfo.get_CU(0) print 'CU header', cu.header topdie = cu.get_top_DIE() print topdie.size, topdie.tag -print topdie.attributes +for attrname, val in topdie.attributes.iteritems(): + print attrname, val #~ print dwarfinfo.structs.Dwarf_abbrev_entry.parse('\x13\x01\x01\x03\x50\x04\x00\x00') -- 2.30.2