implemented string dumping, with tests
authorEli Bendersky <eliben@gmail.com>
Sun, 18 Sep 2011 03:04:30 +0000 (06:04 +0300)
committerEli Bendersky <eliben@gmail.com>
Sun, 18 Sep 2011 03:04:30 +0000 (06:04 +0300)
scripts/readelf.py
tests/run_tests.py

index 9b81fb73fa4c17f571be027a3356b2ee1e9b4ebf..44e15db71e80fe253eb94f36bda7be35018d662f 100755 (executable)
@@ -7,8 +7,10 @@
 # Eli Bendersky (eliben@gmail.com)
 # This code is in the public domain
 #-------------------------------------------------------------------------------
-import sys
+import os, sys
 from optparse import OptionParser
+import string
+
 
 # If elftools is not installed, maybe we're running from the root or scripts
 # dir of the source distribution
@@ -308,6 +310,46 @@ class ReadElf(object):
 
         self._emitline()
 
+    def display_string_dump(self, section_spec):
+        """ Display a strings dump of a section. section_spec is either a
+            section number or a name.
+        """
+        secnum = self._section_num_from_spec(section_spec)
+        if secnum is None:
+            self._emitline("Section '%s' does not exist in the file!" % (
+                section_spec))
+            return
+
+        printables = set(string.printable)
+
+        section = self.elffile.get_section(secnum)
+        self._emitline("\nString dump of section '%s':" % section.name)
+
+        found = False
+        data = section.data()
+        dataptr = 0
+
+        while dataptr < len(data):
+            while dataptr < len(data) and data[dataptr] not in printables:
+                dataptr += 1
+
+            if dataptr >= len(data):
+                break
+
+            endptr = dataptr
+            while endptr < len(data) and data[endptr] != '\x00':
+                endptr += 1
+
+            found = True
+            self._emitline('  [%6x]  %s' % (
+                dataptr, data[dataptr:endptr]))
+
+            dataptr = endptr
+
+        if not found:
+            self._emitline('  No strings found in this section.')
+        else:
+            self._emitline()
 
     def _format_hex(self, addr, fieldsize=None, fullhex=False, lead0x=True):
         """ Format an address into a hexadecimal string.
@@ -391,6 +433,10 @@ def main():
     optparser.add_option('-x', '--hex-dump',
             action='store', dest='show_hex_dump', metavar='<number|name>',
             help='Dump the contents of section <number|name> as bytes')
+    optparser.add_option('-p', '--string-dump',
+            action='store', dest='show_string_dump', metavar='<number|name>',
+            help='Dump the contents of section <number|name> as strings')
+
     options, args = optparser.parse_args()
 
     if options.help or len(args) == 0:
@@ -419,6 +465,8 @@ def main():
                 readelf.display_symbol_tables()
             if options.show_hex_dump:
                 readelf.display_hex_dump(options.show_hex_dump)
+            if options.show_string_dump:
+                readelf.display_string_dump(options.show_string_dump)
         except ELFError as ex:
             sys.stderr.write('ELF error: %s\n' % ex)
             sys.exit(1)
index 85a9a4159ce88c38054568f8dd6d88214fb9975b..ccc459eb0641cf5d0fcbb3435040e30e848da1fb 100755 (executable)
@@ -44,10 +44,12 @@ def run_exe(exe_path, args):
     
 
 def run_test_on_file(filename):
-    """ Runs a test on the given input filename
+    """ Runs a test on the given input filename. Return True if all test
+        runs succeeded.
     """
+    success = True
     testlog.info("Running test on file '%s'" % filename)
-    for option in ['-e', '-s', '-x.text']:
+    for option in ['-e', '-s', '-x.text', '-p.shstrtab']:
         testlog.info("..option='%s'" % option)
         # stdouts will be a 2-element list: output of readelf and output 
         # of scripts/readelf.py
@@ -66,9 +68,11 @@ def run_test_on_file(filename):
         if success:
             testlog.info('.......................SUCCESS')
         else:
+            success = False
             testlog.info('.......................FAIL')
             testlog.info('@@ ' + errmsg)
             dump_output_to_temp_files(*stdouts)
+    return success
 
 
 def compare_output(s1, s2):
@@ -141,8 +145,14 @@ def main():
     if not is_in_rootdir():
         die('Please run me from the root dir of pyelftools!')
 
+    success = True
     for filename in discover_testfiles('tests/testfiles'):
-        run_test_on_file(filename)
+        success = success and run_test_on_file(filename)
+
+    if success:
+        testlog.info('\nConclusion: SUCCESS')
+    else:
+        testlog.info('\nConclusion: FAIL')
 
 
 if __name__ == '__main__':