added some basic description capabilities for DWARF attributes in debug_info
authoreliben <devnull@localhost>
Wed, 26 Oct 2011 08:42:34 +0000 (10:42 +0200)
committereliben <devnull@localhost>
Wed, 26 Oct 2011 08:42:34 +0000 (10:42 +0200)
README.rst
elftools/dwarf/descriptions.py [new file with mode: 0644]
elftools/dwarf/die.py
scripts/readelf.py

index 920cafc93da7fa9362f9858d78c895f6e8a9267a..cb92a07c09c4c3343c320ea76b444f7fdf5aef12 100644 (file)
@@ -3,4 +3,4 @@ pyelftools
 \r
 Nice project, heh?\r
 \r
-This is **cool**, or is it?\r
+\r
diff --git a/elftools/dwarf/descriptions.py b/elftools/dwarf/descriptions.py
new file mode 100644 (file)
index 0000000..93cc2eb
--- /dev/null
@@ -0,0 +1,79 @@
+#-------------------------------------------------------------------------------\r
+# elftools: dwarf/descriptions.py\r
+#\r
+# Textual descriptions of the various values and enums of DWARF\r
+#\r
+# Eli Bendersky (eliben@gmail.com)\r
+# This code is in the public domain\r
+#-------------------------------------------------------------------------------\r
+from collections import defaultdict\r
+\r
+\r
+def describe_attr_value(attr, die, section_offset):\r
+    """ Given an AttributeValue extracted, return the textual representation of\r
+        its value, suitable for tools like readelf.\r
+        \r
+        To cover all cases, this function needs some extra arguments:\r
+\r
+        die: the DIE this attribute was extracted from\r
+        section_offset: offset in the stream of the section the DIE belongs to\r
+    """\r
+    descr_func = _ATTR_DESCRIPTION_MAP[attr.form]\r
+    return descr_func(attr, die, section_offset)\r
+\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+def _describe_attr_ref(attr, die, section_offset):
+    return '<0x%x>' % (attr.value + die.cu.cu_offset - section_offset)\r
+\r
+def _describe_attr_value_passthrough(attr, die, section_offset):
+    return attr.value\r
+\r
+def _describe_attr_hex(attr, die, section_offset):
+    return '0x%x' % (attr.value)\r
+\r
+def _describe_attr_hex_addr(attr, die, section_offset):\r
+    return '<0x%x>' % (attr.value)\r
+\r
+def _describe_attr_split_64bit(attr, die, section_offset):
+    low_word = attr.value & 0xFFFFFFFF\r
+    high_word = (attr.value >> 32) & 0xFFFFFFFF\r
+    return '0x%x 0x%x' % (low_word, high_word)\r
+\r
+def _describe_attr_strp(attr, die, section_offset):
+    return '(indirect string, offset: 0x%x): %s' % (attr.raw_value, attr.value)\r
+\r
+def _describe_attr_block(attr, die, section_offset):
+    s = '%s byte block: ' % len(attr.value)\r
+    s += ' '.join('%x' % item for item in attr.value)\r
+    return s\r
+    \r
+\r
+_ATTR_DESCRIPTION_MAP = defaultdict(\r
+    lambda: _describe_attr_value_passthrough, # default_factory\r
+    \r
+    DW_FORM_ref1=_describe_attr_ref,\r
+    DW_FORM_ref2=_describe_attr_ref,\r
+    DW_FORM_ref4=_describe_attr_ref,\r
+    DW_FORM_ref8=_describe_attr_split_64bit,\r
+    DW_FORM_ref_udata=_describe_attr_ref,        \r
+    DW_FORM_ref_addr=_describe_attr_hex_addr,\r
+    DW_FORM_data4=_describe_attr_hex,\r
+    DW_FORM_data8=_describe_attr_split_64bit,\r
+    DW_FORM_addr=_describe_attr_hex,\r
+    DW_FORM_sec_offset=_describe_attr_hex,\r
+    DW_FORM_flag_present=_describe_attr_value_passthrough,\r
+    DW_FORM_flag=_describe_attr_value_passthrough,\r
+    DW_FORM_data1=_describe_attr_value_passthrough,\r
+    DW_FORM_data2=_describe_attr_value_passthrough,\r
+    DW_FORM_sdata=_describe_attr_value_passthrough,\r
+    DW_FORM_udata=_describe_attr_value_passthrough,\r
+    DW_FORM_string=_describe_attr_value_passthrough,\r
+    DW_FORM_strp=_describe_attr_strp,\r
+    DW_FORM_block1=_describe_attr_block,\r
+    DW_FORM_block2=_describe_attr_block,\r
+    DW_FORM_block4=_describe_attr_block,\r
+    DW_FORM_block=_describe_attr_block,\r
+)\r
+\r
index ad818920c7c9650ee2e81c0ce710e9b218f77db8..f4f422e0a35f44c88990823ae4f1b466e365bb8d 100644 (file)
@@ -49,8 +49,7 @@ class DIE(object):
             
             attributes:
                 An ordered dictionary mapping attribute names to values. It's 
-                ordered to enable both efficient name->value mapping and
-                preserve the order of attributes in the section
+                ordered to preserve the order of attributes in the section
             
             has_children:
                 Specifies whether this DIE has children
@@ -190,5 +189,5 @@ class DIE(object):
         else:
             value = raw_value
         return value
-        
-         
\ No newline at end of file
+    
+
index b1fd9c43bf421d8339ab5b679a2075c74d65d191..02325f3082424e1f13171d56a47d0b35c893119d 100755 (executable)
@@ -34,6 +34,7 @@ from elftools.elf.descriptions import (
     describe_symbol_shndx, describe_reloc_type,
     )
 from elftools.dwarf.dwarfinfo import DWARFInfo, DebugSectionLocator
+from elftools.dwarf.descriptions import describe_attr_value
 
 
 class ReadElf(object):
@@ -512,11 +513,21 @@ class ReadElf(object):
                 if die.is_null():
                     die_depth -= 1
                     continue
-                self._emitline(' <%s><%x>: Abbrev Number: %s' % (
-                    die_depth, die.offset - section_offset, die.abbrev_code))
+                self._emitline(' <%s><%x>: Abbrev Number: %s (%s)' % (
+                    die_depth,
+                    die.offset - section_offset,
+                    die.abbrev_code,
+                    die.tag))
+                
+                for attrname, attr in die.attributes.iteritems():
+                    self._emitline('    <%2x>   %-18s: %s' % (
+                        attr.offset - section_offset,
+                        attrname,
+                        describe_attr_value(attr, die, section_offset)))
                 
                 if die.has_children:
                     die_depth += 1
+                    
 
     def _emit(self, s=''):
         """ Emit an object to output