Simplify handling of null DIEs (#209)
authorAnders Dellien <anders@andersdellien.se>
Thu, 20 Dec 2018 13:21:35 +0000 (14:21 +0100)
committerEli Bendersky <eliben@users.noreply.github.com>
Thu, 20 Dec 2018 13:21:35 +0000 (05:21 -0800)
The code that is intended to coalesce null DIEs into the DIE that
precedes them does not do that and is actually not needed as the
'unflattening' procedure takes care of any unexpected null DIEs.

Also added a unit test for verifying the DIE size calculation.

elftools/dwarf/die.py
test/test_die_size.py [new file with mode: 0644]
test/testfiles_for_unittests/trailing_null_dies.elf [new file with mode: 0644]

index 546d0000e8d740414ed756ab17c8f638c65acfbe..5d3ad995d0b72314426c6a2e9760412cda154a5e 100755 (executable)
@@ -188,19 +188,6 @@ class DIE(object):
                 raw_value=raw_value,
                 offset=attr_offset)
 
-        # Count and then consume any null termination bytes to avoid wrong die
-        # size calculation.
-        num_zero_terminators = 0
-        with preserve_stream_pos(self.stream):
-            while True:
-                if self.stream.read(1) == 0:
-                    num_zero_terminators += 1
-                else:
-                    break
-        if num_zero_terminators > 0:
-            # There was at least one zero termination -> consume all of them.
-            self.stream.read(num_zero_terminators)
-
         self.size = self.stream.tell() - self.offset
 
     def _translate_attr_value(self, form, raw_value):
diff --git a/test/test_die_size.py b/test/test_die_size.py
new file mode 100644 (file)
index 0000000..7579ce2
--- /dev/null
@@ -0,0 +1,32 @@
+#------------------------------------------------------------------------------
+# elftools tests
+#
+# Anders Dellien (anders@andersdellien.se)
+# This code is in the public domain
+#------------------------------------------------------------------------------
+import unittest
+import os
+
+from elftools.elf.elffile import ELFFile
+
+class TestDieSize(unittest.TestCase):
+    """ This test verifies that null DIEs are treated correctly - i.e.
+        removed when we 'unflatten' the linear list and build a tree.
+        The test file contains a CU with two non-null DIEs (both three bytes big),
+        where the second one is followed by three null DIEs.
+        We verify that the null DIEs are discarded and that the length of the second DIE
+        does not include the null entries that follow it.
+    """
+    def test_die_size(self):
+        with open(os.path.join('test',
+                               'testfiles_for_unittests', 'trailing_null_dies.elf'),
+                  'rb') as f:
+            elffile = ELFFile(f)
+            self.assertTrue(elffile.has_dwarf_info())
+            dwarfinfo = elffile.get_dwarf_info()
+            for CU in dwarfinfo.iter_CUs():
+                 for child in CU.get_top_DIE().iter_children():
+                     self.assertEquals(child.size, 3)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/test/testfiles_for_unittests/trailing_null_dies.elf b/test/testfiles_for_unittests/trailing_null_dies.elf
new file mode 100644 (file)
index 0000000..1bc7f5e
Binary files /dev/null and b/test/testfiles_for_unittests/trailing_null_dies.elf differ