Add ELFFile.address_offsets() to get file offsets from a memory address
authorMartin Panter <vadmium à gmail·com>
Wed, 12 Feb 2014 03:02:04 +0000 (03:02 +0000)
committerMartin Panter <vadmium à gmail·com>
Sat, 31 May 2014 03:46:11 +0000 (03:46 +0000)
elftools/elf/elffile.py
test/test_elffile.py [new file with mode: 0644]

index ed168ccff83ca4434ae197cd4476998199a0ac67..320a23212e45d81cc1e102b26b07d854b9eaf331 100644 (file)
@@ -107,6 +107,16 @@ class ELFFile(object):
         """
         for i in range(self.num_segments()):
             yield self.get_segment(i)
+    
+    def address_offsets(self, start, size=1):
+        """ Yield a file offset for each ELF segment matching a memory region
+        """
+        end = start + size
+        for seg in self.iter_segments():
+            if (start >= seg['p_vaddr'] and
+                    end <= seg['p_vaddr'] + seg['p_filesz']):
+                # Region is contained completely within this segment
+                yield start - seg['p_vaddr'] + seg['p_offset']
 
     def has_dwarf_info(self):
         """ Check whether this file appears to have debugging information.
diff --git a/test/test_elffile.py b/test/test_elffile.py
new file mode 100644 (file)
index 0000000..662d518
--- /dev/null
@@ -0,0 +1,50 @@
+#-------------------------------------------------------------------------------
+# elftools tests
+#
+# Eli Bendersky (eliben@gmail.com)
+# This code is in the public domain
+#-------------------------------------------------------------------------------
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from utils import setup_syspath; setup_syspath()
+from elftools.elf.elffile import ELFFile
+
+class TestMap(unittest.TestCase):
+    def runTest(self):
+        class MockELF(ELFFile):
+            __init__ = object.__init__
+            def iter_segments(self):
+                return iter((
+                    dict(p_vaddr=0x10200, p_filesz=0x200, p_offset=0x100),
+                    dict(p_vaddr=0x10100, p_filesz=0x100, p_offset=0x400),
+                ))
+        
+        elf = MockELF()
+        
+        self.assertEqual(tuple(elf.address_offsets(0x10100)), (0x400,))
+        self.assertEqual(tuple(elf.address_offsets(0x10120)), (0x420,))
+        self.assertEqual(tuple(elf.address_offsets(0x101FF)), (0x4FF,))
+        self.assertEqual(tuple(elf.address_offsets(0x10200)), (0x100,))
+        self.assertEqual(tuple(elf.address_offsets(0x100FF)), ())
+        self.assertEqual(tuple(elf.address_offsets(0x10400)), ())
+        
+        self.assertEqual(
+            tuple(elf.address_offsets(0x10100, 0x100)), (0x400,))
+        self.assertEqual(tuple(elf.address_offsets(0x10100, 4)), (0x400,))
+        self.assertEqual(tuple(elf.address_offsets(0x10120, 4)), (0x420,))
+        self.assertEqual(tuple(elf.address_offsets(0x101FC, 4)), (0x4FC,))
+        self.assertEqual(tuple(elf.address_offsets(0x10200, 4)), (0x100,))
+        self.assertEqual(tuple(elf.address_offsets(0x10100, 0x200)), ())
+        self.assertEqual(tuple(elf.address_offsets(0x10000, 0x800)), ())
+        self.assertEqual(tuple(elf.address_offsets(0x100FC, 4)), ())
+        self.assertEqual(tuple(elf.address_offsets(0x100FE, 4)), ())
+        self.assertEqual(tuple(elf.address_offsets(0x101FE, 4)), ())
+        self.assertEqual(tuple(elf.address_offsets(0x103FE, 4)), ())
+        self.assertEqual(tuple(elf.address_offsets(0x10400, 4)), ())
+
+
+if __name__ == '__main__':
+    unittest.main()