renamed 'tests' dir to 'test'
authorEli Bendersky <eliben@gmail.com>
Sat, 17 Dec 2011 12:34:02 +0000 (14:34 +0200)
committerEli Bendersky <eliben@gmail.com>
Sat, 17 Dec 2011 12:34:02 +0000 (14:34 +0200)
38 files changed:
test/run_all_unittests.py [new file with mode: 0755]
test/run_readelf_tests.py [new file with mode: 0755]
test/test_callframe.py [new file with mode: 0644]
test/test_dwarf_expr.py [new file with mode: 0644]
test/test_dwarf_lineprogram.py [new file with mode: 0644]
test/test_dwarf_structs.py [new file with mode: 0644]
test/test_utils.py [new file with mode: 0644]
test/testfiles/exe_simple32.elf [new file with mode: 0644]
test/testfiles/exe_simple64.elf [new file with mode: 0644]
test/testfiles/exe_stripped64.elf [new file with mode: 0644]
test/testfiles/libelf0_8_13_32bit.so.elf [new file with mode: 0644]
test/testfiles/obj_simple32.o.elf [new file with mode: 0644]
test/testfiles/penalty_32_gcc.o.elf [new file with mode: 0644]
test/testfiles/penalty_64_clang.o.elf [new file with mode: 0644]
test/testfiles/penalty_64_gcc.o.elf [new file with mode: 0644]
test/testfiles/update32.o.elf [new file with mode: 0644]
test/utils/Makefile [new file with mode: 0644]
test/utils/README.txt [new file with mode: 0644]
test/utils/elf_creator.c [new file with mode: 0644]
tests/run_all_unittests.py [deleted file]
tests/run_readelf_tests.py [deleted file]
tests/test_callframe.py [deleted file]
tests/test_dwarf_expr.py [deleted file]
tests/test_dwarf_lineprogram.py [deleted file]
tests/test_dwarf_structs.py [deleted file]
tests/test_utils.py [deleted file]
tests/testfiles/exe_simple32.elf [deleted file]
tests/testfiles/exe_simple64.elf [deleted file]
tests/testfiles/exe_stripped64.elf [deleted file]
tests/testfiles/libelf0_8_13_32bit.so.elf [deleted file]
tests/testfiles/obj_simple32.o.elf [deleted file]
tests/testfiles/penalty_32_gcc.o.elf [deleted file]
tests/testfiles/penalty_64_clang.o.elf [deleted file]
tests/testfiles/penalty_64_gcc.o.elf [deleted file]
tests/testfiles/update32.o.elf [deleted file]
tests/utils/Makefile [deleted file]
tests/utils/README.txt [deleted file]
tests/utils/elf_creator.c [deleted file]

diff --git a/test/run_all_unittests.py b/test/run_all_unittests.py
new file mode 100755 (executable)
index 0000000..555b0d2
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+#-------------------------------------------------------------------------------
+# tests/run_all_unittests.py
+#
+# Run all unit tests (alternative to running 'python -m unittest discover ...')
+#
+# Eli Bendersky (eliben@gmail.com)
+# This code is in the public domain
+#-------------------------------------------------------------------------------
+from unittest import TestLoader, TextTestRunner
+
+
+if __name__ == '__main__':
+    try:
+        tests = TestLoader().discover('tests', 'test*.py', 'tests')
+        TextTestRunner().run(tests)
+    except ImportError as err:
+        print err
+        print '!! Please execute from the root directory of pyelfutils'
+
diff --git a/test/run_readelf_tests.py b/test/run_readelf_tests.py
new file mode 100755 (executable)
index 0000000..3592f40
--- /dev/null
@@ -0,0 +1,213 @@
+#!/usr/bin/env python
+#-------------------------------------------------------------------------------
+# tests/run_readelf_tests.py
+#
+# Automatic test runner for elftools & readelf
+#
+# Eli Bendersky (eliben@gmail.com)
+# This code is in the public domain
+#-------------------------------------------------------------------------------
+import os, sys
+import re
+from difflib import SequenceMatcher
+import logging
+import subprocess
+import tempfile
+import platform
+
+
+# Create a global logger object
+#
+testlog = logging.getLogger('run_tests')
+testlog.setLevel(logging.DEBUG)
+testlog.addHandler(logging.StreamHandler(sys.stdout))
+
+
+def discover_testfiles(rootdir):
+    """ Discover test files in the given directory. Yield them one by one.
+    """
+    for filename in os.listdir(rootdir):
+        _, ext = os.path.splitext(filename)
+        if ext == '.elf':
+            yield os.path.join(rootdir, filename)
+
+
+def run_exe(exe_path, args):
+    """ Runs the given executable as a subprocess, given the
+        list of arguments. Captures its return code (rc) and stdout and
+        returns a pair: rc, stdout_str
+    """
+    popen_cmd = [exe_path] + args
+    if os.path.splitext(exe_path)[1] == '.py':
+        popen_cmd.insert(0, 'python')
+    proc = subprocess.Popen(popen_cmd, stdout=subprocess.PIPE)
+    proc_stdout = proc.communicate()[0]
+    return proc.returncode, proc_stdout
+    
+
+def run_test_on_file(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', '-r', '-x.text', '-p.shstrtab',
+            '--debug-dump=info', '--debug-dump=decodedline',
+            '--debug-dump=frames', '--debug-dump=frames-interp']:
+        testlog.info("..option='%s'" % option)
+        # stdouts will be a 2-element list: output of readelf and output 
+        # of scripts/readelf.py
+        stdouts = []
+        for exe_path in ['readelf', 'scripts/readelf.py']:
+            args = [option, filename]
+            testlog.info("....executing: '%s %s'" % (
+                exe_path, ' '.join(args)))
+            rc, stdout = run_exe(exe_path, args)
+            if rc != 0:
+                testlog.error("@@ aborting - '%s' returned '%s'" % (exe_path, rc))
+                return False
+            stdouts.append(stdout)
+        testlog.info('....comparing output...')
+        rc, errmsg = compare_output(*stdouts)
+        if rc:
+            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):
+    """ Compare stdout strings s1 and s2.
+        s1 is from readelf, s2 from elftools readelf.py
+        Return pair success, errmsg. If comparison succeeds, success is True
+        and errmsg is empty. Otherwise success is False and errmsg holds a
+        description of the mismatch.
+
+        Note: this function contains some rather horrible hacks to ignore
+        differences which are not important for the verification of pyelftools.
+        This is due to some intricacies of binutils's readelf which pyelftools
+        doesn't currently implement, or silly inconsistencies in the output of
+        readelf, which I was reluctant to replicate.
+        Read the documentation for more details.
+    """
+    def prepare_lines(s):
+        return [line for line in s.lower().splitlines() if line.strip() != '']
+    def filter_readelf_lines(lines):
+        filter_out = False
+        for line in lines:
+            if 'of the .eh_frame section' in line:
+                filter_out = True
+            elif 'of the .debug_frame section' in line:
+                filter_out = False
+            if not filter_out:
+                if not line.startswith('unknown: length'):
+                    yield line
+        
+    lines1 = prepare_lines(s1)
+    lines2 = prepare_lines(s2)
+
+    lines1 = list(filter_readelf_lines(lines1))
+
+    flag_after_symtable = False
+
+    if len(lines1) != len(lines2):
+        return False, 'Number of lines different: %s vs %s' % (
+                len(lines1), len(lines2))
+
+    for i in range(len(lines1)):
+        if 'symbol table' in lines1[i]:
+            flag_after_symtable = True
+
+        # Compare ignoring whitespace
+        lines1_parts = lines1[i].split()
+        lines2_parts = lines2[i].split()
+        if ''.join(lines1_parts) != ''.join(lines2_parts):
+            ok = False
+            sm = SequenceMatcher()
+            sm.set_seqs(lines1[i], lines2[i])
+            changes = sm.get_opcodes()
+            if flag_after_symtable:
+                # Detect readelf's adding @ with lib and version after 
+                # symbol name.
+                if (    len(changes) == 2 and changes[1][0] == 'delete' and
+                        lines1[i][changes[1][1]] == '@'):
+                    ok = True
+            elif 'at_const_value' in lines1[i]:
+                # On 32-bit machines, readelf doesn't correctly represent
+                # some boundary LEB128 numbers
+                num2 = int(lines2_parts[-1])
+                if num2 <= -2**31 and '32' in platform.architecture()[0]:
+                    ok = True
+            elif 'os/abi' in lines1[i]:
+                if 'unix - gnu' in lines1[i] and 'unix - linux' in lines2[i]:
+                    ok = True
+            else: 
+                for s in ('t (tls)', 'l (large)'):
+                    if s in lines1[i] or s in lines2[i]:
+                        ok = True
+                        break
+            if not ok:
+                errmsg = 'Mismatch on line #%s:\n>>%s<<\n>>%s<<\n' % (
+                    i, lines1[i], lines2[i])
+                return False, errmsg
+    return True, ''
+    
+
+def dump_output_to_temp_files(*args):
+    """ Dumps the output strings given in 'args' to temp files: one for each
+        arg.
+    """
+    for i, s in enumerate(args):
+        fd, path = tempfile.mkstemp(
+                prefix='out' + str(i + 1) + '_',
+                suffix='.stdout')
+        file = os.fdopen(fd, 'w')
+        file.write(s)
+        file.close()
+        testlog.info('@@ Output #%s dumped to file: %s' % (i + 1, path))
+    
+
+def die(msg):
+    testlog.error('Error: %s' % msg)
+    sys.exit(1)
+
+
+def is_in_rootdir():
+    """ Check whether the current dir is the root dir of pyelftools
+    """
+    dirstuff = os.listdir('.')
+    return 'test' in dirstuff and 'elftools' in dirstuff
+    
+
+def main():
+    if not is_in_rootdir():
+        die('Please run me from the root dir of pyelftools!')
+
+    # If file names are given as command-line arguments, only these files
+    # are taken as inputs. Otherwise, autodiscovery is performed.
+    #
+    if len(sys.argv) > 1:
+        filenames = sys.argv[1:]
+    else:
+        filenames = list(discover_testfiles('test/testfiles'))
+
+    success = True
+    for filename in filenames:
+        success = success and run_test_on_file(filename)
+
+    if success:
+        testlog.info('\nConclusion: SUCCESS')
+    else:
+        testlog.info('\nConclusion: FAIL')
+
+
+if __name__ == '__main__':
+    main()
+
+
+
+
diff --git a/test/test_callframe.py b/test/test_callframe.py
new file mode 100644 (file)
index 0000000..30e405b
--- /dev/null
@@ -0,0 +1,147 @@
+import sys, unittest
+from cStringIO import StringIO
+
+sys.path.extend(['.', '..'])
+from elftools.dwarf.callframe import (
+    CallFrameInfo, CIE, FDE, instruction_name, CallFrameInstruction,
+    RegisterRule)
+from elftools.dwarf.structs import DWARFStructs
+from elftools.dwarf.descriptions import (describe_CFI_instructions,
+    set_global_machine_arch)
+
+
+class TestCallFrame(unittest.TestCase):
+    def assertInstruction(self, instr, name, args):
+        self.assertIsInstance(instr, CallFrameInstruction)
+        self.assertEqual(instruction_name(instr.opcode), name)
+        self.assertEqual(instr.args, args)
+       
+    def test_spec_sample_d6(self):
+        # D.6 sample in DWARFv3
+        s = StringIO()
+        data = ('' +
+            # first comes the CIE
+            '\x20\x00\x00\x00' +        # length
+            '\xff\xff\xff\xff' +        # CIE_id
+            '\x03\x00\x04\x7c' +        # version, augmentation, caf, daf
+            '\x08' +                    # return address
+            '\x0c\x07\x00' +
+            '\x08\x00' +
+            '\x07\x01' +
+            '\x07\x02' +
+            '\x07\x03' +
+            '\x08\x04' +
+            '\x08\x05' +
+            '\x08\x06' +
+            '\x08\x07' +
+            '\x09\x08\x01' +
+            '\x00' +
+            
+            # then comes the FDE
+            '\x28\x00\x00\x00' +        # length
+            '\x00\x00\x00\x00' +        # CIE_pointer (to CIE at 0)
+            '\x44\x33\x22\x11' +        # initial_location
+            '\x54\x00\x00\x00' +        # address range
+            '\x41' +
+            '\x0e\x0c' + '\x41' +
+            '\x88\x01' + '\x41' +
+            '\x86\x02' + '\x41' +
+            '\x0d\x06' + '\x41' +
+            '\x84\x03' + '\x4b' +
+            '\xc4' + '\x41' +
+            '\xc6' +
+            '\x0d\x07' + '\x41' +
+            '\xc8' + '\x41' +
+            '\x0e\x00' +
+            '\x00\x00'
+            )
+        s.write(data)
+
+        structs = DWARFStructs(little_endian=True, dwarf_format=32, address_size=4)
+        cfi = CallFrameInfo(s, len(data), structs)
+        entries = cfi.get_entries()
+
+        self.assertEqual(len(entries), 2)
+        self.assertIsInstance(entries[0], CIE)
+        self.assertEqual(entries[0]['length'], 32)
+        self.assertEqual(entries[0]['data_alignment_factor'], -4)
+        self.assertEqual(entries[0]['return_address_register'], 8)
+        self.assertEqual(len(entries[0].instructions), 11)
+        self.assertInstruction(entries[0].instructions[0],
+            'DW_CFA_def_cfa', [7, 0])
+        self.assertInstruction(entries[0].instructions[8],
+            'DW_CFA_same_value', [7])
+        self.assertInstruction(entries[0].instructions[9],
+            'DW_CFA_register', [8, 1])
+
+        self.assertTrue(isinstance(entries[1], FDE))
+        self.assertEqual(entries[1]['length'], 40)
+        self.assertEqual(entries[1]['CIE_pointer'], 0)
+        self.assertEqual(entries[1]['address_range'], 84)
+        self.assertIs(entries[1].cie, entries[0])
+        self.assertEqual(len(entries[1].instructions), 21)
+        self.assertInstruction(entries[1].instructions[0],
+            'DW_CFA_advance_loc', [1])
+        self.assertInstruction(entries[1].instructions[1],
+            'DW_CFA_def_cfa_offset', [12])
+        self.assertInstruction(entries[1].instructions[9],
+            'DW_CFA_offset', [4, 3])
+        self.assertInstruction(entries[1].instructions[18],
+            'DW_CFA_def_cfa_offset', [0])
+        self.assertInstruction(entries[1].instructions[20],
+            'DW_CFA_nop', [])
+
+        # Now let's decode it...
+        decoded_CIE = entries[0].get_decoded()
+        self.assertEqual(decoded_CIE.reg_order, list(range(9)))
+        self.assertEqual(len(decoded_CIE.table), 1)
+        self.assertEqual(decoded_CIE.table[0]['cfa'].reg, 7)
+        self.assertEqual(decoded_CIE.table[0]['pc'], 0)
+        self.assertEqual(decoded_CIE.table[0]['cfa'].offset, 0)
+        self.assertEqual(decoded_CIE.table[0][4].type, RegisterRule.SAME_VALUE)
+        self.assertEqual(decoded_CIE.table[0][8].type, RegisterRule.REGISTER)
+        self.assertEqual(decoded_CIE.table[0][8].arg, 1)
+
+        decoded_FDE = entries[1].get_decoded()
+        self.assertEqual(decoded_FDE.reg_order, list(range(9)))
+        self.assertEqual(decoded_FDE.table[0]['cfa'].reg, 7)
+        self.assertEqual(decoded_FDE.table[0]['cfa'].offset, 0)
+        self.assertEqual(decoded_FDE.table[0]['pc'], 0x11223344)
+        self.assertEqual(decoded_FDE.table[0][8].type, RegisterRule.REGISTER)
+        self.assertEqual(decoded_FDE.table[0][8].arg, 1)
+        self.assertEqual(decoded_FDE.table[1]['cfa'].reg, 7)
+        self.assertEqual(decoded_FDE.table[1]['cfa'].offset, 12)
+        self.assertEqual(decoded_FDE.table[2][8].type, RegisterRule.OFFSET)
+        self.assertEqual(decoded_FDE.table[2][8].arg, -4)
+        self.assertEqual(decoded_FDE.table[2][4].type, RegisterRule.SAME_VALUE)
+        self.assertEqual(decoded_FDE.table[5]['pc'], 0x11223344 + 20)
+        self.assertEqual(decoded_FDE.table[5][4].type, RegisterRule.OFFSET)
+        self.assertEqual(decoded_FDE.table[5][4].arg, -12)
+        self.assertEqual(decoded_FDE.table[6]['pc'], 0x11223344 + 64)
+        self.assertEqual(decoded_FDE.table[9]['pc'], 0x11223344 + 76)
+
+    def test_describe_CFI_instructions(self):
+        # The data here represents a single CIE 
+        data = ('' +
+            '\x16\x00\x00\x00' +        # length
+            '\xff\xff\xff\xff' +        # CIE_id
+            '\x03\x00\x04\x7c' +        # version, augmentation, caf, daf
+            '\x08' +                    # return address
+            '\x0c\x07\x02' +
+            '\x10\x02\x07\x03\x01\x02\x00\x00\x06\x06')
+        s = StringIO(data)
+
+        structs = DWARFStructs(little_endian=True, dwarf_format=32, address_size=4)
+        cfi = CallFrameInfo(s, len(data), structs)
+        entries = cfi.get_entries()
+
+        set_global_machine_arch('x86')
+        self.assertEqual(describe_CFI_instructions(entries[0]),
+            (   '  DW_CFA_def_cfa: r7 (edi) ofs 2\n' + 
+                '  DW_CFA_expression: r2 (edx) (DW_OP_addr: 201; DW_OP_deref; DW_OP_deref)\n'))
+
+
+if __name__ == '__main__':
+    unittest.main()
+
+
diff --git a/test/test_dwarf_expr.py b/test/test_dwarf_expr.py
new file mode 100644 (file)
index 0000000..8e293db
--- /dev/null
@@ -0,0 +1,68 @@
+import sys, unittest
+from cStringIO import StringIO
+
+sys.path.extend(('..', '.'))
+from elftools.dwarf.descriptions import ExprDumper, set_global_machine_arch
+from elftools.dwarf.structs import DWARFStructs
+
+
+class TestExprDumper(unittest.TestCase):
+    structs32 = DWARFStructs(
+            little_endian=True,
+            dwarf_format=32,
+            address_size=4)
+
+    def setUp(self):
+        self.visitor = ExprDumper(self.structs32)
+        set_global_machine_arch('x64')
+
+    def test_basic_single(self):
+        self.visitor.process_expr([0x1b])
+        self.assertEqual(self.visitor.get_str(),
+            'DW_OP_div')
+        
+        self.setUp()
+        self.visitor.process_expr([0x74, 0x82, 0x01])
+        self.assertEqual(self.visitor.get_str(),
+            'DW_OP_breg4 (rsi): 130')
+        
+        self.setUp()
+        self.visitor.process_expr([0x91, 0x82, 0x01])
+        self.assertEqual(self.visitor.get_str(),
+            'DW_OP_fbreg: 130')
+
+        self.setUp()
+        self.visitor.process_expr([0x51])
+        self.assertEqual(self.visitor.get_str(),
+            'DW_OP_reg1 (rdx)')
+
+        self.setUp()
+        self.visitor.process_expr([0x90, 16])
+        self.assertEqual(self.visitor.get_str(),
+            'DW_OP_regx: 16 (rip)')
+
+        self.setUp()
+        self.visitor.process_expr([0x9d, 0x8f, 0x0A, 0x90, 0x01])
+        self.assertEqual(self.visitor.get_str(),
+            'DW_OP_bit_piece: 1295 144')
+
+    def test_basic_sequence(self):
+        self.visitor.process_expr([0x03, 0x01, 0x02, 0, 0, 0x06, 0x06])
+        self.assertEqual(self.visitor.get_str(),
+            'DW_OP_addr: 201; DW_OP_deref; DW_OP_deref')
+
+        self.setUp()
+        self.visitor.process_expr([0x15, 0xFF, 0x0b, 0xf1, 0xff])
+        self.assertEqual(self.visitor.get_str(),
+            'DW_OP_pick: 255; DW_OP_const2s: -15')
+
+        self.setUp()
+        self.visitor.process_expr([0x1d, 0x1e, 0x1d, 0x1e, 0x1d, 0x1e])
+        self.assertEqual(self.visitor.get_str(),
+            'DW_OP_mod; DW_OP_mul; DW_OP_mod; DW_OP_mul; DW_OP_mod; DW_OP_mul')
+
+
+if __name__ == '__main__':
+    unittest.main()
+
+
diff --git a/test/test_dwarf_lineprogram.py b/test/test_dwarf_lineprogram.py
new file mode 100644 (file)
index 0000000..56d96c3
--- /dev/null
@@ -0,0 +1,101 @@
+import sys, unittest
+from cStringIO import StringIO
+
+sys.path.extend(['.', '..'])
+from elftools.dwarf.lineprogram import LineProgram, LineState, LineProgramEntry
+from elftools.dwarf.structs import DWARFStructs
+from elftools.dwarf.constants import *
+
+
+class TestLineProgram(unittest.TestCase):
+    def _make_program_in_stream(self, stream):
+        """ Create a LineProgram from the given program encoded in a stream
+        """
+        ds = DWARFStructs(little_endian=True, dwarf_format=32, address_size=4)
+        header = ds.Dwarf_lineprog_header.parse(
+            '\x04\x10\x00\x00' +    # initial lenght
+            '\x03\x00' +            # version
+            '\x20\x00\x00\x00' +    # header length
+            '\x01\x01\x01\x0F' +    # flags
+            '\x0A' +                # opcode_base
+            '\x00\x01\x04\x08\x0C\x01\x01\x01\x00' + # standard_opcode_lengths
+            # 2 dir names followed by a NULL
+            '\x61\x62\x00\x70\x00\x00' + 
+            # a file entry
+            '\x61\x72\x00\x0C\x0D\x0F' + 
+            # and another entry
+            '\x45\x50\x51\x00\x86\x12\x07\x08' +
+            # followed by NULL
+            '\x00')
+
+        lp = LineProgram(header, stream, ds, 0, len(stream.getvalue()))
+        return lp
+        
+    def assertLineState(self, state, **kwargs):
+        """ Assert that the state attributes specified in kwargs have the given
+            values (the rest are default).
+        """
+        for k, v in kwargs.iteritems():
+            self.assertEqual(getattr(state, k), v)
+        
+    def test_spec_sample_59(self):
+        # Sample in figure 59 of DWARFv3
+        s = StringIO()
+        s.write(
+            '\x02\xb9\x04' +
+            '\x0b' +
+            '\x38' +
+            '\x82' +
+            '\x73' +
+            '\x02\x02' +
+            '\x00\x01\x01')
+
+        lp = self._make_program_in_stream(s)
+        linetable = lp.get_entries()
+
+        self.assertEqual(len(linetable), 7)
+        self.assertIs(linetable[0].state, None)  # doesn't modify state
+        self.assertEqual(linetable[0].command, DW_LNS_advance_pc)
+        self.assertEqual(linetable[0].args, [0x239])
+        self.assertLineState(linetable[1].state, address=0x239, line=3)
+        self.assertEqual(linetable[1].command, 0xb)
+        self.assertEqual(linetable[1].args, [2, 0])
+        self.assertLineState(linetable[2].state, address=0x23c, line=5)
+        self.assertLineState(linetable[3].state, address=0x244, line=6)
+        self.assertLineState(linetable[4].state, address=0x24b, line=7, end_sequence=False)
+        self.assertEqual(linetable[5].command, DW_LNS_advance_pc)
+        self.assertEqual(linetable[5].args, [2])
+        self.assertLineState(linetable[6].state, address=0x24d, line=7, end_sequence=True)
+
+    def test_spec_sample_60(self):
+        # Sample in figure 60 of DWARFv3
+        s = StringIO()
+        s.write(
+            '\x09\x39\x02' +
+            '\x0b' +
+            '\x09\x03\x00' +
+            '\x0b' +
+            '\x09\x08\x00' +
+            '\x0a' +
+            '\x09\x07\x00' +
+            '\x0a' +
+            '\x09\x02\x00' +
+            '\x00\x01\x01')
+
+        lp = self._make_program_in_stream(s)
+        linetable = lp.get_entries()
+
+        self.assertEqual(len(linetable), 10)
+        self.assertIs(linetable[0].state, None)  # doesn't modify state
+        self.assertEqual(linetable[0].command, DW_LNS_fixed_advance_pc)
+        self.assertEqual(linetable[0].args, [0x239])
+        self.assertLineState(linetable[1].state, address=0x239, line=3)
+        self.assertLineState(linetable[3].state, address=0x23c, line=5)
+        self.assertLineState(linetable[5].state, address=0x244, line=6)
+        self.assertLineState(linetable[7].state, address=0x24b, line=7, end_sequence=False)
+        self.assertLineState(linetable[9].state, address=0x24d, line=7, end_sequence=True)
+
+
+if __name__ == '__main__':
+    unittest.main()
+
diff --git a/test/test_dwarf_structs.py b/test/test_dwarf_structs.py
new file mode 100644 (file)
index 0000000..a1e30d7
--- /dev/null
@@ -0,0 +1,39 @@
+import sys, unittest
+
+sys.path.extend(['.', '..'])
+from elftools.dwarf.structs import DWARFStructs
+
+
+class TestDWARFStructs(unittest.TestCase):
+    def test_lineprog_header(self):
+        ds = DWARFStructs(little_endian=True, dwarf_format=32, address_size=4)
+
+        c = ds.Dwarf_lineprog_header.parse(
+            '\x04\x10\x00\x00' +    # initial lenght
+            '\x05\x02' +            # version
+            '\x20\x00\x00\x00' +    # header length
+            '\x05\x10\x40\x50' +    # until and including line_range
+            '\x06' +                # opcode_base
+            '\x00\x01\x04\x08\x0C' + # standard_opcode_lengths
+            # 2 dir names followed by a NULL
+            '\x61\x62\x00\x70\x00\x00' + 
+            # a file entry
+            '\x61\x72\x00\x0C\x0D\x0F' + 
+            # and another entry
+            '\x45\x50\x51\x00\x86\x12\x07\x08' +
+            # followed by NULL
+            '\x00')
+
+        self.assertEqual(c.version, 0x205)
+        self.assertEqual(c.opcode_base, 6)
+        self.assertEqual(c.standard_opcode_lengths, [0, 1, 4, 8, 12])
+        self.assertEqual(c.include_directory, ['ab', 'p'])
+        self.assertEqual(len(c.file_entry), 2)
+        self.assertEqual(c.file_entry[0].name, 'ar')
+        self.assertEqual(c.file_entry[1].name, 'EPQ')
+        self.assertEqual(c.file_entry[1].dir_index, 0x12 * 128 + 6)
+
+
+if __name__ == '__main__':
+    unittest.main()
+
diff --git a/test/test_utils.py b/test/test_utils.py
new file mode 100644 (file)
index 0000000..54a09bb
--- /dev/null
@@ -0,0 +1,56 @@
+import sys, unittest
+from cStringIO import StringIO
+from random import randint
+
+sys.path.extend(['.', '..'])
+from elftools.common.utils import (parse_cstring_from_stream,
+        preserve_stream_pos)
+
+
+class Test_parse_cstring_from_stream(unittest.TestCase):
+    def _make_random_string(self, n):
+        return ''.join(chr(randint(32, 127)) for i in range(n))
+        
+    def test_small1(self):
+        sio = StringIO('abcdefgh\x0012345')
+        self.assertEqual(parse_cstring_from_stream(sio), 'abcdefgh')
+        self.assertEqual(parse_cstring_from_stream(sio, 2), 'cdefgh')
+        self.assertEqual(parse_cstring_from_stream(sio, 8), '')
+
+    def test_small2(self):
+        sio = StringIO('12345\x006789\x00abcdefg\x00iii')
+        self.assertEqual(parse_cstring_from_stream(sio), '12345')
+        self.assertEqual(parse_cstring_from_stream(sio, 5), '')
+        self.assertEqual(parse_cstring_from_stream(sio, 6), '6789')
+
+    def test_large1(self):
+        text = 'i' * 400 + '\x00' + 'bb'
+        sio = StringIO(text)
+        self.assertEqual(parse_cstring_from_stream(sio), 'i' * 400)
+        self.assertEqual(parse_cstring_from_stream(sio, 150), 'i' * 250)
+
+    def test_large2(self):
+        text = self._make_random_string(5000) + '\x00' + 'jujajaja'
+        sio = StringIO(text)
+        self.assertEqual(parse_cstring_from_stream(sio), text[:5000])
+        self.assertEqual(parse_cstring_from_stream(sio, 2348), text[2348:5000])
+
+
+class Test_preserve_stream_pos(object):
+    def test_basic(self):
+        sio = StringIO('abcdef')
+        with preserve_stream_pos(sio):
+            sio.seek(4)
+        self.assertEqual(stream.tell(), 0)
+
+        sio.seek(5)
+        with preserve_stream_pos(sio):
+            sio.seek(0)
+        self.assertEqual(stream.tell(), 5)
+
+
+if __name__ == '__main__':
+    unittest.main()
+
+
+
diff --git a/test/testfiles/exe_simple32.elf b/test/testfiles/exe_simple32.elf
new file mode 100644 (file)
index 0000000..d6b3cd1
Binary files /dev/null and b/test/testfiles/exe_simple32.elf differ
diff --git a/test/testfiles/exe_simple64.elf b/test/testfiles/exe_simple64.elf
new file mode 100644 (file)
index 0000000..ccfa6ae
Binary files /dev/null and b/test/testfiles/exe_simple64.elf differ
diff --git a/test/testfiles/exe_stripped64.elf b/test/testfiles/exe_stripped64.elf
new file mode 100644 (file)
index 0000000..841b3f8
Binary files /dev/null and b/test/testfiles/exe_stripped64.elf differ
diff --git a/test/testfiles/libelf0_8_13_32bit.so.elf b/test/testfiles/libelf0_8_13_32bit.so.elf
new file mode 100644 (file)
index 0000000..c236625
Binary files /dev/null and b/test/testfiles/libelf0_8_13_32bit.so.elf differ
diff --git a/test/testfiles/obj_simple32.o.elf b/test/testfiles/obj_simple32.o.elf
new file mode 100644 (file)
index 0000000..5ce4182
Binary files /dev/null and b/test/testfiles/obj_simple32.o.elf differ
diff --git a/test/testfiles/penalty_32_gcc.o.elf b/test/testfiles/penalty_32_gcc.o.elf
new file mode 100644 (file)
index 0000000..4c5c5de
Binary files /dev/null and b/test/testfiles/penalty_32_gcc.o.elf differ
diff --git a/test/testfiles/penalty_64_clang.o.elf b/test/testfiles/penalty_64_clang.o.elf
new file mode 100644 (file)
index 0000000..91d207d
Binary files /dev/null and b/test/testfiles/penalty_64_clang.o.elf differ
diff --git a/test/testfiles/penalty_64_gcc.o.elf b/test/testfiles/penalty_64_gcc.o.elf
new file mode 100644 (file)
index 0000000..aca100b
Binary files /dev/null and b/test/testfiles/penalty_64_gcc.o.elf differ
diff --git a/test/testfiles/update32.o.elf b/test/testfiles/update32.o.elf
new file mode 100644 (file)
index 0000000..ae68ef9
Binary files /dev/null and b/test/testfiles/update32.o.elf differ
diff --git a/test/utils/Makefile b/test/utils/Makefile
new file mode 100644 (file)
index 0000000..fd44b8e
--- /dev/null
@@ -0,0 +1,18 @@
+CFLAGS = -Wall --std=c99
+# This is where `make install` from libelf places its stuff
+LIBELF_HEADERS = /usr/local/include/libelf/
+LIBELF_LIBS = /usr/local/lib/
+
+all: elf_creator
+
+elf_creator: elf_creator.c
+       gcc $(CFLAGS) -o elf_creator elf_creator.c \
+               -I$(LIBELF_HEADERS) -L$(LIBELF_LIBS) -Wl,-rpath,$(LIBELF_LIBS) -lelf
+
+clean:
+       rm -f *.o
+       rm -f *.so
+       rm -f *.a
+       rm -f elf_creator
+
+
diff --git a/test/utils/README.txt b/test/utils/README.txt
new file mode 100644 (file)
index 0000000..a6c496a
--- /dev/null
@@ -0,0 +1,2 @@
+Some utilities that use libelf to create synthetic ELF files
+
diff --git a/test/utils/elf_creator.c b/test/utils/elf_creator.c
new file mode 100644 (file)
index 0000000..1fd1b56
--- /dev/null
@@ -0,0 +1,204 @@
+/* Loosely based on the code in a Knol by Roberto Garcia Lopez:
+** 
+** http://knol.google.com/k/roberto-garca-lpez/creating-elf-relocatable-object-files/1ohwel4gqkcn2/3#
+**
+** Note: This file is released under the terms of the LGPL2 license.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <libelf.h>
+#include <err.h>
+#include <sysexits.h>
+
+
+const char* OUTFILE = "generated.o";
+
+// Definition of the default string table section ".shstrtab"
+const char defaultStrTable[] = 
+{
+    /* offset 00 */ '\0',  // The NULL section
+    /* offset 01 */ '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0',
+    /* offset 11 */ '.', 's', 't', 'r', 't', 'a', 'b', '\0',
+    /* offset 19 */ '.', 's', 'y', 'm', 't', 'a', 'b', '\0',
+    /* offset 27 */ '.', 'c', 'o', 'm', 'm', 'e', 'n', 't', '\0',
+    /* offset 36 */ '.', 'b', 's', 's', '\0',
+    /* offset 41 */ '.', 'd', 'a', 't', 'a', '\0',
+    /* offset 47 */ '.', 'r', 'e', 'l', '.', 't', 'e', 'x', 't', '\0',
+    /* offset 57 */ '.', 't', 'e', 'x', 't', '\0'
+};
+
+const char defaultStrTableLen = sizeof(defaultStrTable);
+
+// Offsets of section names in the string table
+const char _shstrtab_offset = 1;
+const char _strtab_offset = 11;
+const char _symtab_offset = 19;
+const char _text_offset = 57;
+
+// Position of sections within the object file
+const char _shstrtab = 1;
+const char _strtab = 2;
+const char _symtab = 3;
+const char _text = 4;
+
+const char TEXT_CONTENTS[] = {0x91, 0x92, 0x93, 0x94};
+
+
+//----------------------------------------------------------------------------
+
+int main()
+{
+    int FileDes;
+    Elf *pElf;
+    Elf32_Ehdr *pEhdr;
+    Elf32_Shdr *pShdr;
+    Elf_Scn *pScn;
+    Elf_Data *pData;
+
+    // Create the ELF header
+    if (elf_version(EV_CURRENT) == EV_NONE) // It must appear before "elf_begin()"
+        errx(EX_SOFTWARE, "ELF library initialization failed: %s", elf_errmsg(-1));
+
+    if ((FileDes = open(OUTFILE, O_CREAT | O_WRONLY | O_TRUNC, 0777)) < 0)
+        errx(EX_OSERR, "open \"%s\" failed", "compiled.o");
+
+    if ((pElf = elf_begin(FileDes, ELF_C_WRITE, NULL)) == NULL)  // 3rd argument is ignored for "ELF_C_WRITE"
+        errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1));
+
+    if ((pEhdr = elf32_newehdr(pElf)) == NULL)
+        errx(EX_SOFTWARE, "elf32_newehdr() failed: %s", elf_errmsg(-1));
+
+    pEhdr->e_ident[EI_CLASS] = ELFCLASS32;  // Defined by Intel architecture
+    pEhdr->e_ident[EI_DATA] = ELFDATA2LSB;  // Defined by Intel architecture
+    pEhdr->e_machine = EM_386;  // Intel architecture
+    pEhdr->e_type = ET_REL;   // Relocatable file (object file)
+    pEhdr->e_shstrndx = _shstrtab;    // Point to the shstrtab section
+
+    // Create the section "default section header string table (.shstrtab)"
+    if ((pScn = elf_newscn(pElf)) == NULL)
+        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
+    if ((pData = elf_newdata(pScn)) == NULL)
+        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
+
+    pData->d_align = 1;
+    pData->d_buf = (void *) defaultStrTable;
+    pData->d_type = ELF_T_BYTE;
+    pData->d_size = defaultStrTableLen;
+
+    if ((pShdr = elf32_getshdr(pScn)) == NULL)
+        errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
+
+    pShdr->sh_name = _shstrtab_offset;  // Point to the name of the section
+    pShdr->sh_type = SHT_STRTAB;
+    pShdr->sh_flags = 0;
+
+    // Create the section ".strtab"
+    if ((pScn = elf_newscn(pElf)) == NULL)
+        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
+    if ((pData = elf_newdata(pScn)) == NULL)
+        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
+
+    const char strtab[] = {0, 'g', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', '.','x', 0, '_', 's', 't', 'a', 'r', 't', 0};
+
+    pData->d_align = 1;
+    pData->d_buf = (void *) strtab;
+    pData->d_type = ELF_T_BYTE;
+    pData->d_size = sizeof(strtab);
+
+    if ((pShdr = elf32_getshdr(pScn)) == NULL)
+        errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
+
+    pShdr->sh_name = _strtab_offset;
+    pShdr->sh_type = SHT_STRTAB;
+    pShdr->sh_flags = 0;
+
+    // Create the section ".symtab"
+    if ((pScn = elf_newscn(pElf)) == NULL)
+        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
+    if ((pData = elf_newdata(pScn)) == NULL)
+        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
+
+    Elf32_Sym x[4];
+
+    // Definition of the undefined section (this must be the first item by the definition of TIS ELF)
+    x[0].st_name = 0;
+    x[0].st_value = 0;
+    x[0].st_size = 0;
+    x[0].st_info = 0;
+    x[0].st_other = 0;
+    x[0].st_shndx = SHN_UNDEF;
+
+    // Definition of the name of the source file (this must be the second item by the definition in TIS ELF)
+    x[1].st_name = 1;
+    x[1].st_value = 0;
+    x[1].st_size = 0;
+    x[1].st_info = ELF32_ST_INFO(STB_LOCAL, STT_FILE); // This is the value that st_info must have (because of TIS ELF)
+    x[1].st_other = 0;
+    x[1].st_shndx = SHN_ABS;  // The section where the symbol is
+
+    // Definition of the ".text" section as a section in the ".symtab" section
+    x[2].st_name = 0;
+    x[2].st_value = 0;
+    x[2].st_size = 0;
+    x[2].st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
+    x[2].st_other = 0;
+    x[2].st_shndx = _text;  // The section where the symbol is
+
+    // Definition of the "_start" symbol
+    x[3].st_name = 13;  // Offset in the "strtab" section where the name start
+    x[3].st_value = 0;
+    x[3].st_size = 0;
+    x[3].st_info = ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE);
+    x[3].st_other = 0;
+    x[3].st_shndx = _text;  // The section where the symbol is
+
+    pData->d_align = 4;
+    pData->d_buf = (void *) x;
+    pData->d_type = ELF_T_BYTE;
+    pData->d_size = sizeof(x);
+
+    if ((pShdr = elf32_getshdr(pScn)) == NULL)
+        errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
+
+    pShdr->sh_name = _symtab_offset;  // Point to the name of the section
+    pShdr->sh_type = SHT_SYMTAB;
+    pShdr->sh_flags = 0;
+    pShdr->sh_link = _strtab;  // point to the section .strtab (the section that contain the strings)
+    pShdr->sh_info = ELF32_ST_INFO(STB_LOCAL, 3);  // the second argument is beause of TIS ELF (One greater than the symbol table index of the last local symbol (binding STB_LOCAL))
+
+    // Create many sections named .text
+    for (int i = 0; i < 70000; ++i) {
+        if ((pScn = elf_newscn(pElf)) == NULL)
+            errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
+        if ((pData = elf_newdata(pScn)) == NULL)
+            errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
+
+        pData->d_align = 4;
+        pData->d_buf = (void *)TEXT_CONTENTS;
+        pData->d_type = ELF_T_BYTE;
+        pData->d_size = sizeof(TEXT_CONTENTS);
+
+        if ((pShdr = elf32_getshdr(pScn)) == NULL)
+            errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
+
+        pShdr->sh_name = _text_offset;
+        pShdr->sh_type = SHT_PROGBITS;
+        pShdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
+    }
+
+    // Update the sections internally
+    if (elf_update(pElf, ELF_C_NULL) < 0)
+        errx(EX_SOFTWARE, "elf_update(NULL) failed: %s.", elf_errmsg(-1));
+    // Write the object file
+    if (elf_update(pElf, ELF_C_WRITE) < 0)
+        errx(EX_SOFTWARE, "elf_update() failed: %s.", elf_errmsg(-1));
+    // Close all handles
+    elf_end(pElf);
+    close(FileDes);
+    printf("Generated file: %s\n", OUTFILE);
+    
+    return 0;
+}
+
diff --git a/tests/run_all_unittests.py b/tests/run_all_unittests.py
deleted file mode 100755 (executable)
index 555b0d2..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-#-------------------------------------------------------------------------------
-# tests/run_all_unittests.py
-#
-# Run all unit tests (alternative to running 'python -m unittest discover ...')
-#
-# Eli Bendersky (eliben@gmail.com)
-# This code is in the public domain
-#-------------------------------------------------------------------------------
-from unittest import TestLoader, TextTestRunner
-
-
-if __name__ == '__main__':
-    try:
-        tests = TestLoader().discover('tests', 'test*.py', 'tests')
-        TextTestRunner().run(tests)
-    except ImportError as err:
-        print err
-        print '!! Please execute from the root directory of pyelfutils'
-
diff --git a/tests/run_readelf_tests.py b/tests/run_readelf_tests.py
deleted file mode 100755 (executable)
index 61cfbee..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-#!/usr/bin/env python
-#-------------------------------------------------------------------------------
-# tests/run_readelf_tests.py
-#
-# Automatic test runner for elftools & readelf
-#
-# Eli Bendersky (eliben@gmail.com)
-# This code is in the public domain
-#-------------------------------------------------------------------------------
-import os, sys
-import re
-from difflib import SequenceMatcher
-import logging
-import subprocess
-import tempfile
-import platform
-
-
-# Create a global logger object
-#
-testlog = logging.getLogger('run_tests')
-testlog.setLevel(logging.DEBUG)
-testlog.addHandler(logging.StreamHandler(sys.stdout))
-
-
-def discover_testfiles(rootdir):
-    """ Discover test files in the given directory. Yield them one by one.
-    """
-    for filename in os.listdir(rootdir):
-        _, ext = os.path.splitext(filename)
-        if ext == '.elf':
-            yield os.path.join(rootdir, filename)
-
-
-def run_exe(exe_path, args):
-    """ Runs the given executable as a subprocess, given the
-        list of arguments. Captures its return code (rc) and stdout and
-        returns a pair: rc, stdout_str
-    """
-    popen_cmd = [exe_path] + args
-    if os.path.splitext(exe_path)[1] == '.py':
-        popen_cmd.insert(0, 'python')
-    proc = subprocess.Popen(popen_cmd, stdout=subprocess.PIPE)
-    proc_stdout = proc.communicate()[0]
-    return proc.returncode, proc_stdout
-    
-
-def run_test_on_file(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', '-r', '-x.text', '-p.shstrtab',
-            '--debug-dump=info', '--debug-dump=decodedline',
-            '--debug-dump=frames', '--debug-dump=frames-interp']:
-        testlog.info("..option='%s'" % option)
-        # stdouts will be a 2-element list: output of readelf and output 
-        # of scripts/readelf.py
-        stdouts = []
-        for exe_path in ['readelf', 'scripts/readelf.py']:
-            args = [option, filename]
-            testlog.info("....executing: '%s %s'" % (
-                exe_path, ' '.join(args)))
-            rc, stdout = run_exe(exe_path, args)
-            if rc != 0:
-                testlog.error("@@ aborting - '%s' returned '%s'" % (exe_path, rc))
-                return False
-            stdouts.append(stdout)
-        testlog.info('....comparing output...')
-        rc, errmsg = compare_output(*stdouts)
-        if rc:
-            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):
-    """ Compare stdout strings s1 and s2.
-        s1 is from readelf, s2 from elftools readelf.py
-        Return pair success, errmsg. If comparison succeeds, success is True
-        and errmsg is empty. Otherwise success is False and errmsg holds a
-        description of the mismatch.
-
-        Note: this function contains some rather horrible hacks to ignore
-        differences which are not important for the verification of pyelftools.
-        This is due to some intricacies of binutils's readelf which pyelftools
-        doesn't currently implement, or silly inconsistencies in the output of
-        readelf, which I was reluctant to replicate.
-        Read the documentation for more details.
-    """
-    def prepare_lines(s):
-        return [line for line in s.lower().splitlines() if line.strip() != '']
-    def filter_readelf_lines(lines):
-        filter_out = False
-        for line in lines:
-            if 'of the .eh_frame section' in line:
-                filter_out = True
-            elif 'of the .debug_frame section' in line:
-                filter_out = False
-            if not filter_out:
-                if not line.startswith('unknown: length'):
-                    yield line
-        
-    lines1 = prepare_lines(s1)
-    lines2 = prepare_lines(s2)
-
-    lines1 = list(filter_readelf_lines(lines1))
-
-    flag_after_symtable = False
-
-    if len(lines1) != len(lines2):
-        return False, 'Number of lines different: %s vs %s' % (
-                len(lines1), len(lines2))
-
-    for i in range(len(lines1)):
-        if 'symbol table' in lines1[i]:
-            flag_after_symtable = True
-
-        # Compare ignoring whitespace
-        lines1_parts = lines1[i].split()
-        lines2_parts = lines2[i].split()
-        if ''.join(lines1_parts) != ''.join(lines2_parts):
-            ok = False
-            sm = SequenceMatcher()
-            sm.set_seqs(lines1[i], lines2[i])
-            changes = sm.get_opcodes()
-            if flag_after_symtable:
-                # Detect readelf's adding @ with lib and version after 
-                # symbol name.
-                if (    len(changes) == 2 and changes[1][0] == 'delete' and
-                        lines1[i][changes[1][1]] == '@'):
-                    ok = True
-            elif 'at_const_value' in lines1[i]:
-                # On 32-bit machines, readelf doesn't correctly represent
-                # some boundary LEB128 numbers
-                num2 = int(lines2_parts[-1])
-                if num2 <= -2**31 and '32' in platform.architecture()[0]:
-                    ok = True
-            elif 'os/abi' in lines1[i]:
-                if 'unix - gnu' in lines1[i] and 'unix - linux' in lines2[i]:
-                    ok = True
-            else: 
-                for s in ('t (tls)', 'l (large)'):
-                    if s in lines1[i] or s in lines2[i]:
-                        ok = True
-                        break
-            if not ok:
-                errmsg = 'Mismatch on line #%s:\n>>%s<<\n>>%s<<\n' % (
-                    i, lines1[i], lines2[i])
-                return False, errmsg
-    return True, ''
-    
-
-def dump_output_to_temp_files(*args):
-    """ Dumps the output strings given in 'args' to temp files: one for each
-        arg.
-    """
-    for i, s in enumerate(args):
-        fd, path = tempfile.mkstemp(
-                prefix='out' + str(i + 1) + '_',
-                suffix='.stdout')
-        file = os.fdopen(fd, 'w')
-        file.write(s)
-        file.close()
-        testlog.info('@@ Output #%s dumped to file: %s' % (i + 1, path))
-    
-
-def die(msg):
-    testlog.error('Error: %s' % msg)
-    sys.exit(1)
-
-
-def is_in_rootdir():
-    """ Check whether the current dir is the root dir of pyelftools
-    """
-    dirstuff = os.listdir('.')
-    return 'tests' in dirstuff and 'elftools' in dirstuff
-    
-
-def main():
-    if not is_in_rootdir():
-        die('Please run me from the root dir of pyelftools!')
-
-    # If file names are given as command-line arguments, only these files
-    # are taken as inputs. Otherwise, autodiscovery is performed.
-    #
-    if len(sys.argv) > 1:
-        filenames = sys.argv[1:]
-    else:
-        filenames = list(discover_testfiles('tests/testfiles'))
-
-    success = True
-    for filename in filenames:
-        success = success and run_test_on_file(filename)
-
-    if success:
-        testlog.info('\nConclusion: SUCCESS')
-    else:
-        testlog.info('\nConclusion: FAIL')
-
-
-if __name__ == '__main__':
-    #import os
-    #os.chdir('..')
-    main()
-    #testlog.info(list(discover_testfiles('tests/testfiles'))) 
-    #print run_exe('scripts/readelf.py', ['-h', 'tests/testfiles/z32.o.elf'])
-
-
-
-
diff --git a/tests/test_callframe.py b/tests/test_callframe.py
deleted file mode 100644 (file)
index 30e405b..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-import sys, unittest
-from cStringIO import StringIO
-
-sys.path.extend(['.', '..'])
-from elftools.dwarf.callframe import (
-    CallFrameInfo, CIE, FDE, instruction_name, CallFrameInstruction,
-    RegisterRule)
-from elftools.dwarf.structs import DWARFStructs
-from elftools.dwarf.descriptions import (describe_CFI_instructions,
-    set_global_machine_arch)
-
-
-class TestCallFrame(unittest.TestCase):
-    def assertInstruction(self, instr, name, args):
-        self.assertIsInstance(instr, CallFrameInstruction)
-        self.assertEqual(instruction_name(instr.opcode), name)
-        self.assertEqual(instr.args, args)
-       
-    def test_spec_sample_d6(self):
-        # D.6 sample in DWARFv3
-        s = StringIO()
-        data = ('' +
-            # first comes the CIE
-            '\x20\x00\x00\x00' +        # length
-            '\xff\xff\xff\xff' +        # CIE_id
-            '\x03\x00\x04\x7c' +        # version, augmentation, caf, daf
-            '\x08' +                    # return address
-            '\x0c\x07\x00' +
-            '\x08\x00' +
-            '\x07\x01' +
-            '\x07\x02' +
-            '\x07\x03' +
-            '\x08\x04' +
-            '\x08\x05' +
-            '\x08\x06' +
-            '\x08\x07' +
-            '\x09\x08\x01' +
-            '\x00' +
-            
-            # then comes the FDE
-            '\x28\x00\x00\x00' +        # length
-            '\x00\x00\x00\x00' +        # CIE_pointer (to CIE at 0)
-            '\x44\x33\x22\x11' +        # initial_location
-            '\x54\x00\x00\x00' +        # address range
-            '\x41' +
-            '\x0e\x0c' + '\x41' +
-            '\x88\x01' + '\x41' +
-            '\x86\x02' + '\x41' +
-            '\x0d\x06' + '\x41' +
-            '\x84\x03' + '\x4b' +
-            '\xc4' + '\x41' +
-            '\xc6' +
-            '\x0d\x07' + '\x41' +
-            '\xc8' + '\x41' +
-            '\x0e\x00' +
-            '\x00\x00'
-            )
-        s.write(data)
-
-        structs = DWARFStructs(little_endian=True, dwarf_format=32, address_size=4)
-        cfi = CallFrameInfo(s, len(data), structs)
-        entries = cfi.get_entries()
-
-        self.assertEqual(len(entries), 2)
-        self.assertIsInstance(entries[0], CIE)
-        self.assertEqual(entries[0]['length'], 32)
-        self.assertEqual(entries[0]['data_alignment_factor'], -4)
-        self.assertEqual(entries[0]['return_address_register'], 8)
-        self.assertEqual(len(entries[0].instructions), 11)
-        self.assertInstruction(entries[0].instructions[0],
-            'DW_CFA_def_cfa', [7, 0])
-        self.assertInstruction(entries[0].instructions[8],
-            'DW_CFA_same_value', [7])
-        self.assertInstruction(entries[0].instructions[9],
-            'DW_CFA_register', [8, 1])
-
-        self.assertTrue(isinstance(entries[1], FDE))
-        self.assertEqual(entries[1]['length'], 40)
-        self.assertEqual(entries[1]['CIE_pointer'], 0)
-        self.assertEqual(entries[1]['address_range'], 84)
-        self.assertIs(entries[1].cie, entries[0])
-        self.assertEqual(len(entries[1].instructions), 21)
-        self.assertInstruction(entries[1].instructions[0],
-            'DW_CFA_advance_loc', [1])
-        self.assertInstruction(entries[1].instructions[1],
-            'DW_CFA_def_cfa_offset', [12])
-        self.assertInstruction(entries[1].instructions[9],
-            'DW_CFA_offset', [4, 3])
-        self.assertInstruction(entries[1].instructions[18],
-            'DW_CFA_def_cfa_offset', [0])
-        self.assertInstruction(entries[1].instructions[20],
-            'DW_CFA_nop', [])
-
-        # Now let's decode it...
-        decoded_CIE = entries[0].get_decoded()
-        self.assertEqual(decoded_CIE.reg_order, list(range(9)))
-        self.assertEqual(len(decoded_CIE.table), 1)
-        self.assertEqual(decoded_CIE.table[0]['cfa'].reg, 7)
-        self.assertEqual(decoded_CIE.table[0]['pc'], 0)
-        self.assertEqual(decoded_CIE.table[0]['cfa'].offset, 0)
-        self.assertEqual(decoded_CIE.table[0][4].type, RegisterRule.SAME_VALUE)
-        self.assertEqual(decoded_CIE.table[0][8].type, RegisterRule.REGISTER)
-        self.assertEqual(decoded_CIE.table[0][8].arg, 1)
-
-        decoded_FDE = entries[1].get_decoded()
-        self.assertEqual(decoded_FDE.reg_order, list(range(9)))
-        self.assertEqual(decoded_FDE.table[0]['cfa'].reg, 7)
-        self.assertEqual(decoded_FDE.table[0]['cfa'].offset, 0)
-        self.assertEqual(decoded_FDE.table[0]['pc'], 0x11223344)
-        self.assertEqual(decoded_FDE.table[0][8].type, RegisterRule.REGISTER)
-        self.assertEqual(decoded_FDE.table[0][8].arg, 1)
-        self.assertEqual(decoded_FDE.table[1]['cfa'].reg, 7)
-        self.assertEqual(decoded_FDE.table[1]['cfa'].offset, 12)
-        self.assertEqual(decoded_FDE.table[2][8].type, RegisterRule.OFFSET)
-        self.assertEqual(decoded_FDE.table[2][8].arg, -4)
-        self.assertEqual(decoded_FDE.table[2][4].type, RegisterRule.SAME_VALUE)
-        self.assertEqual(decoded_FDE.table[5]['pc'], 0x11223344 + 20)
-        self.assertEqual(decoded_FDE.table[5][4].type, RegisterRule.OFFSET)
-        self.assertEqual(decoded_FDE.table[5][4].arg, -12)
-        self.assertEqual(decoded_FDE.table[6]['pc'], 0x11223344 + 64)
-        self.assertEqual(decoded_FDE.table[9]['pc'], 0x11223344 + 76)
-
-    def test_describe_CFI_instructions(self):
-        # The data here represents a single CIE 
-        data = ('' +
-            '\x16\x00\x00\x00' +        # length
-            '\xff\xff\xff\xff' +        # CIE_id
-            '\x03\x00\x04\x7c' +        # version, augmentation, caf, daf
-            '\x08' +                    # return address
-            '\x0c\x07\x02' +
-            '\x10\x02\x07\x03\x01\x02\x00\x00\x06\x06')
-        s = StringIO(data)
-
-        structs = DWARFStructs(little_endian=True, dwarf_format=32, address_size=4)
-        cfi = CallFrameInfo(s, len(data), structs)
-        entries = cfi.get_entries()
-
-        set_global_machine_arch('x86')
-        self.assertEqual(describe_CFI_instructions(entries[0]),
-            (   '  DW_CFA_def_cfa: r7 (edi) ofs 2\n' + 
-                '  DW_CFA_expression: r2 (edx) (DW_OP_addr: 201; DW_OP_deref; DW_OP_deref)\n'))
-
-
-if __name__ == '__main__':
-    unittest.main()
-
-
diff --git a/tests/test_dwarf_expr.py b/tests/test_dwarf_expr.py
deleted file mode 100644 (file)
index 8e293db..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-import sys, unittest
-from cStringIO import StringIO
-
-sys.path.extend(('..', '.'))
-from elftools.dwarf.descriptions import ExprDumper, set_global_machine_arch
-from elftools.dwarf.structs import DWARFStructs
-
-
-class TestExprDumper(unittest.TestCase):
-    structs32 = DWARFStructs(
-            little_endian=True,
-            dwarf_format=32,
-            address_size=4)
-
-    def setUp(self):
-        self.visitor = ExprDumper(self.structs32)
-        set_global_machine_arch('x64')
-
-    def test_basic_single(self):
-        self.visitor.process_expr([0x1b])
-        self.assertEqual(self.visitor.get_str(),
-            'DW_OP_div')
-        
-        self.setUp()
-        self.visitor.process_expr([0x74, 0x82, 0x01])
-        self.assertEqual(self.visitor.get_str(),
-            'DW_OP_breg4 (rsi): 130')
-        
-        self.setUp()
-        self.visitor.process_expr([0x91, 0x82, 0x01])
-        self.assertEqual(self.visitor.get_str(),
-            'DW_OP_fbreg: 130')
-
-        self.setUp()
-        self.visitor.process_expr([0x51])
-        self.assertEqual(self.visitor.get_str(),
-            'DW_OP_reg1 (rdx)')
-
-        self.setUp()
-        self.visitor.process_expr([0x90, 16])
-        self.assertEqual(self.visitor.get_str(),
-            'DW_OP_regx: 16 (rip)')
-
-        self.setUp()
-        self.visitor.process_expr([0x9d, 0x8f, 0x0A, 0x90, 0x01])
-        self.assertEqual(self.visitor.get_str(),
-            'DW_OP_bit_piece: 1295 144')
-
-    def test_basic_sequence(self):
-        self.visitor.process_expr([0x03, 0x01, 0x02, 0, 0, 0x06, 0x06])
-        self.assertEqual(self.visitor.get_str(),
-            'DW_OP_addr: 201; DW_OP_deref; DW_OP_deref')
-
-        self.setUp()
-        self.visitor.process_expr([0x15, 0xFF, 0x0b, 0xf1, 0xff])
-        self.assertEqual(self.visitor.get_str(),
-            'DW_OP_pick: 255; DW_OP_const2s: -15')
-
-        self.setUp()
-        self.visitor.process_expr([0x1d, 0x1e, 0x1d, 0x1e, 0x1d, 0x1e])
-        self.assertEqual(self.visitor.get_str(),
-            'DW_OP_mod; DW_OP_mul; DW_OP_mod; DW_OP_mul; DW_OP_mod; DW_OP_mul')
-
-
-if __name__ == '__main__':
-    unittest.main()
-
-
diff --git a/tests/test_dwarf_lineprogram.py b/tests/test_dwarf_lineprogram.py
deleted file mode 100644 (file)
index 56d96c3..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-import sys, unittest
-from cStringIO import StringIO
-
-sys.path.extend(['.', '..'])
-from elftools.dwarf.lineprogram import LineProgram, LineState, LineProgramEntry
-from elftools.dwarf.structs import DWARFStructs
-from elftools.dwarf.constants import *
-
-
-class TestLineProgram(unittest.TestCase):
-    def _make_program_in_stream(self, stream):
-        """ Create a LineProgram from the given program encoded in a stream
-        """
-        ds = DWARFStructs(little_endian=True, dwarf_format=32, address_size=4)
-        header = ds.Dwarf_lineprog_header.parse(
-            '\x04\x10\x00\x00' +    # initial lenght
-            '\x03\x00' +            # version
-            '\x20\x00\x00\x00' +    # header length
-            '\x01\x01\x01\x0F' +    # flags
-            '\x0A' +                # opcode_base
-            '\x00\x01\x04\x08\x0C\x01\x01\x01\x00' + # standard_opcode_lengths
-            # 2 dir names followed by a NULL
-            '\x61\x62\x00\x70\x00\x00' + 
-            # a file entry
-            '\x61\x72\x00\x0C\x0D\x0F' + 
-            # and another entry
-            '\x45\x50\x51\x00\x86\x12\x07\x08' +
-            # followed by NULL
-            '\x00')
-
-        lp = LineProgram(header, stream, ds, 0, len(stream.getvalue()))
-        return lp
-        
-    def assertLineState(self, state, **kwargs):
-        """ Assert that the state attributes specified in kwargs have the given
-            values (the rest are default).
-        """
-        for k, v in kwargs.iteritems():
-            self.assertEqual(getattr(state, k), v)
-        
-    def test_spec_sample_59(self):
-        # Sample in figure 59 of DWARFv3
-        s = StringIO()
-        s.write(
-            '\x02\xb9\x04' +
-            '\x0b' +
-            '\x38' +
-            '\x82' +
-            '\x73' +
-            '\x02\x02' +
-            '\x00\x01\x01')
-
-        lp = self._make_program_in_stream(s)
-        linetable = lp.get_entries()
-
-        self.assertEqual(len(linetable), 7)
-        self.assertIs(linetable[0].state, None)  # doesn't modify state
-        self.assertEqual(linetable[0].command, DW_LNS_advance_pc)
-        self.assertEqual(linetable[0].args, [0x239])
-        self.assertLineState(linetable[1].state, address=0x239, line=3)
-        self.assertEqual(linetable[1].command, 0xb)
-        self.assertEqual(linetable[1].args, [2, 0])
-        self.assertLineState(linetable[2].state, address=0x23c, line=5)
-        self.assertLineState(linetable[3].state, address=0x244, line=6)
-        self.assertLineState(linetable[4].state, address=0x24b, line=7, end_sequence=False)
-        self.assertEqual(linetable[5].command, DW_LNS_advance_pc)
-        self.assertEqual(linetable[5].args, [2])
-        self.assertLineState(linetable[6].state, address=0x24d, line=7, end_sequence=True)
-
-    def test_spec_sample_60(self):
-        # Sample in figure 60 of DWARFv3
-        s = StringIO()
-        s.write(
-            '\x09\x39\x02' +
-            '\x0b' +
-            '\x09\x03\x00' +
-            '\x0b' +
-            '\x09\x08\x00' +
-            '\x0a' +
-            '\x09\x07\x00' +
-            '\x0a' +
-            '\x09\x02\x00' +
-            '\x00\x01\x01')
-
-        lp = self._make_program_in_stream(s)
-        linetable = lp.get_entries()
-
-        self.assertEqual(len(linetable), 10)
-        self.assertIs(linetable[0].state, None)  # doesn't modify state
-        self.assertEqual(linetable[0].command, DW_LNS_fixed_advance_pc)
-        self.assertEqual(linetable[0].args, [0x239])
-        self.assertLineState(linetable[1].state, address=0x239, line=3)
-        self.assertLineState(linetable[3].state, address=0x23c, line=5)
-        self.assertLineState(linetable[5].state, address=0x244, line=6)
-        self.assertLineState(linetable[7].state, address=0x24b, line=7, end_sequence=False)
-        self.assertLineState(linetable[9].state, address=0x24d, line=7, end_sequence=True)
-
-
-if __name__ == '__main__':
-    unittest.main()
-
diff --git a/tests/test_dwarf_structs.py b/tests/test_dwarf_structs.py
deleted file mode 100644 (file)
index a1e30d7..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-import sys, unittest
-
-sys.path.extend(['.', '..'])
-from elftools.dwarf.structs import DWARFStructs
-
-
-class TestDWARFStructs(unittest.TestCase):
-    def test_lineprog_header(self):
-        ds = DWARFStructs(little_endian=True, dwarf_format=32, address_size=4)
-
-        c = ds.Dwarf_lineprog_header.parse(
-            '\x04\x10\x00\x00' +    # initial lenght
-            '\x05\x02' +            # version
-            '\x20\x00\x00\x00' +    # header length
-            '\x05\x10\x40\x50' +    # until and including line_range
-            '\x06' +                # opcode_base
-            '\x00\x01\x04\x08\x0C' + # standard_opcode_lengths
-            # 2 dir names followed by a NULL
-            '\x61\x62\x00\x70\x00\x00' + 
-            # a file entry
-            '\x61\x72\x00\x0C\x0D\x0F' + 
-            # and another entry
-            '\x45\x50\x51\x00\x86\x12\x07\x08' +
-            # followed by NULL
-            '\x00')
-
-        self.assertEqual(c.version, 0x205)
-        self.assertEqual(c.opcode_base, 6)
-        self.assertEqual(c.standard_opcode_lengths, [0, 1, 4, 8, 12])
-        self.assertEqual(c.include_directory, ['ab', 'p'])
-        self.assertEqual(len(c.file_entry), 2)
-        self.assertEqual(c.file_entry[0].name, 'ar')
-        self.assertEqual(c.file_entry[1].name, 'EPQ')
-        self.assertEqual(c.file_entry[1].dir_index, 0x12 * 128 + 6)
-
-
-if __name__ == '__main__':
-    unittest.main()
-
diff --git a/tests/test_utils.py b/tests/test_utils.py
deleted file mode 100644 (file)
index 54a09bb..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-import sys, unittest
-from cStringIO import StringIO
-from random import randint
-
-sys.path.extend(['.', '..'])
-from elftools.common.utils import (parse_cstring_from_stream,
-        preserve_stream_pos)
-
-
-class Test_parse_cstring_from_stream(unittest.TestCase):
-    def _make_random_string(self, n):
-        return ''.join(chr(randint(32, 127)) for i in range(n))
-        
-    def test_small1(self):
-        sio = StringIO('abcdefgh\x0012345')
-        self.assertEqual(parse_cstring_from_stream(sio), 'abcdefgh')
-        self.assertEqual(parse_cstring_from_stream(sio, 2), 'cdefgh')
-        self.assertEqual(parse_cstring_from_stream(sio, 8), '')
-
-    def test_small2(self):
-        sio = StringIO('12345\x006789\x00abcdefg\x00iii')
-        self.assertEqual(parse_cstring_from_stream(sio), '12345')
-        self.assertEqual(parse_cstring_from_stream(sio, 5), '')
-        self.assertEqual(parse_cstring_from_stream(sio, 6), '6789')
-
-    def test_large1(self):
-        text = 'i' * 400 + '\x00' + 'bb'
-        sio = StringIO(text)
-        self.assertEqual(parse_cstring_from_stream(sio), 'i' * 400)
-        self.assertEqual(parse_cstring_from_stream(sio, 150), 'i' * 250)
-
-    def test_large2(self):
-        text = self._make_random_string(5000) + '\x00' + 'jujajaja'
-        sio = StringIO(text)
-        self.assertEqual(parse_cstring_from_stream(sio), text[:5000])
-        self.assertEqual(parse_cstring_from_stream(sio, 2348), text[2348:5000])
-
-
-class Test_preserve_stream_pos(object):
-    def test_basic(self):
-        sio = StringIO('abcdef')
-        with preserve_stream_pos(sio):
-            sio.seek(4)
-        self.assertEqual(stream.tell(), 0)
-
-        sio.seek(5)
-        with preserve_stream_pos(sio):
-            sio.seek(0)
-        self.assertEqual(stream.tell(), 5)
-
-
-if __name__ == '__main__':
-    unittest.main()
-
-
-
diff --git a/tests/testfiles/exe_simple32.elf b/tests/testfiles/exe_simple32.elf
deleted file mode 100644 (file)
index d6b3cd1..0000000
Binary files a/tests/testfiles/exe_simple32.elf and /dev/null differ
diff --git a/tests/testfiles/exe_simple64.elf b/tests/testfiles/exe_simple64.elf
deleted file mode 100644 (file)
index ccfa6ae..0000000
Binary files a/tests/testfiles/exe_simple64.elf and /dev/null differ
diff --git a/tests/testfiles/exe_stripped64.elf b/tests/testfiles/exe_stripped64.elf
deleted file mode 100644 (file)
index 841b3f8..0000000
Binary files a/tests/testfiles/exe_stripped64.elf and /dev/null differ
diff --git a/tests/testfiles/libelf0_8_13_32bit.so.elf b/tests/testfiles/libelf0_8_13_32bit.so.elf
deleted file mode 100644 (file)
index c236625..0000000
Binary files a/tests/testfiles/libelf0_8_13_32bit.so.elf and /dev/null differ
diff --git a/tests/testfiles/obj_simple32.o.elf b/tests/testfiles/obj_simple32.o.elf
deleted file mode 100644 (file)
index 5ce4182..0000000
Binary files a/tests/testfiles/obj_simple32.o.elf and /dev/null differ
diff --git a/tests/testfiles/penalty_32_gcc.o.elf b/tests/testfiles/penalty_32_gcc.o.elf
deleted file mode 100644 (file)
index 4c5c5de..0000000
Binary files a/tests/testfiles/penalty_32_gcc.o.elf and /dev/null differ
diff --git a/tests/testfiles/penalty_64_clang.o.elf b/tests/testfiles/penalty_64_clang.o.elf
deleted file mode 100644 (file)
index 91d207d..0000000
Binary files a/tests/testfiles/penalty_64_clang.o.elf and /dev/null differ
diff --git a/tests/testfiles/penalty_64_gcc.o.elf b/tests/testfiles/penalty_64_gcc.o.elf
deleted file mode 100644 (file)
index aca100b..0000000
Binary files a/tests/testfiles/penalty_64_gcc.o.elf and /dev/null differ
diff --git a/tests/testfiles/update32.o.elf b/tests/testfiles/update32.o.elf
deleted file mode 100644 (file)
index ae68ef9..0000000
Binary files a/tests/testfiles/update32.o.elf and /dev/null differ
diff --git a/tests/utils/Makefile b/tests/utils/Makefile
deleted file mode 100644 (file)
index fd44b8e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-CFLAGS = -Wall --std=c99
-# This is where `make install` from libelf places its stuff
-LIBELF_HEADERS = /usr/local/include/libelf/
-LIBELF_LIBS = /usr/local/lib/
-
-all: elf_creator
-
-elf_creator: elf_creator.c
-       gcc $(CFLAGS) -o elf_creator elf_creator.c \
-               -I$(LIBELF_HEADERS) -L$(LIBELF_LIBS) -Wl,-rpath,$(LIBELF_LIBS) -lelf
-
-clean:
-       rm -f *.o
-       rm -f *.so
-       rm -f *.a
-       rm -f elf_creator
-
-
diff --git a/tests/utils/README.txt b/tests/utils/README.txt
deleted file mode 100644 (file)
index a6c496a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Some utilities that use libelf to create synthetic ELF files
-
diff --git a/tests/utils/elf_creator.c b/tests/utils/elf_creator.c
deleted file mode 100644 (file)
index 1fd1b56..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/* Loosely based on the code in a Knol by Roberto Garcia Lopez:
-** 
-** http://knol.google.com/k/roberto-garca-lpez/creating-elf-relocatable-object-files/1ohwel4gqkcn2/3#
-**
-** Note: This file is released under the terms of the LGPL2 license.
-*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <libelf.h>
-#include <err.h>
-#include <sysexits.h>
-
-
-const char* OUTFILE = "generated.o";
-
-// Definition of the default string table section ".shstrtab"
-const char defaultStrTable[] = 
-{
-    /* offset 00 */ '\0',  // The NULL section
-    /* offset 01 */ '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0',
-    /* offset 11 */ '.', 's', 't', 'r', 't', 'a', 'b', '\0',
-    /* offset 19 */ '.', 's', 'y', 'm', 't', 'a', 'b', '\0',
-    /* offset 27 */ '.', 'c', 'o', 'm', 'm', 'e', 'n', 't', '\0',
-    /* offset 36 */ '.', 'b', 's', 's', '\0',
-    /* offset 41 */ '.', 'd', 'a', 't', 'a', '\0',
-    /* offset 47 */ '.', 'r', 'e', 'l', '.', 't', 'e', 'x', 't', '\0',
-    /* offset 57 */ '.', 't', 'e', 'x', 't', '\0'
-};
-
-const char defaultStrTableLen = sizeof(defaultStrTable);
-
-// Offsets of section names in the string table
-const char _shstrtab_offset = 1;
-const char _strtab_offset = 11;
-const char _symtab_offset = 19;
-const char _text_offset = 57;
-
-// Position of sections within the object file
-const char _shstrtab = 1;
-const char _strtab = 2;
-const char _symtab = 3;
-const char _text = 4;
-
-const char TEXT_CONTENTS[] = {0x91, 0x92, 0x93, 0x94};
-
-
-//----------------------------------------------------------------------------
-
-int main()
-{
-    int FileDes;
-    Elf *pElf;
-    Elf32_Ehdr *pEhdr;
-    Elf32_Shdr *pShdr;
-    Elf_Scn *pScn;
-    Elf_Data *pData;
-
-    // Create the ELF header
-    if (elf_version(EV_CURRENT) == EV_NONE) // It must appear before "elf_begin()"
-        errx(EX_SOFTWARE, "ELF library initialization failed: %s", elf_errmsg(-1));
-
-    if ((FileDes = open(OUTFILE, O_CREAT | O_WRONLY | O_TRUNC, 0777)) < 0)
-        errx(EX_OSERR, "open \"%s\" failed", "compiled.o");
-
-    if ((pElf = elf_begin(FileDes, ELF_C_WRITE, NULL)) == NULL)  // 3rd argument is ignored for "ELF_C_WRITE"
-        errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1));
-
-    if ((pEhdr = elf32_newehdr(pElf)) == NULL)
-        errx(EX_SOFTWARE, "elf32_newehdr() failed: %s", elf_errmsg(-1));
-
-    pEhdr->e_ident[EI_CLASS] = ELFCLASS32;  // Defined by Intel architecture
-    pEhdr->e_ident[EI_DATA] = ELFDATA2LSB;  // Defined by Intel architecture
-    pEhdr->e_machine = EM_386;  // Intel architecture
-    pEhdr->e_type = ET_REL;   // Relocatable file (object file)
-    pEhdr->e_shstrndx = _shstrtab;    // Point to the shstrtab section
-
-    // Create the section "default section header string table (.shstrtab)"
-    if ((pScn = elf_newscn(pElf)) == NULL)
-        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
-    if ((pData = elf_newdata(pScn)) == NULL)
-        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
-
-    pData->d_align = 1;
-    pData->d_buf = (void *) defaultStrTable;
-    pData->d_type = ELF_T_BYTE;
-    pData->d_size = defaultStrTableLen;
-
-    if ((pShdr = elf32_getshdr(pScn)) == NULL)
-        errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
-
-    pShdr->sh_name = _shstrtab_offset;  // Point to the name of the section
-    pShdr->sh_type = SHT_STRTAB;
-    pShdr->sh_flags = 0;
-
-    // Create the section ".strtab"
-    if ((pScn = elf_newscn(pElf)) == NULL)
-        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
-    if ((pData = elf_newdata(pScn)) == NULL)
-        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
-
-    const char strtab[] = {0, 'g', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', '.','x', 0, '_', 's', 't', 'a', 'r', 't', 0};
-
-    pData->d_align = 1;
-    pData->d_buf = (void *) strtab;
-    pData->d_type = ELF_T_BYTE;
-    pData->d_size = sizeof(strtab);
-
-    if ((pShdr = elf32_getshdr(pScn)) == NULL)
-        errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
-
-    pShdr->sh_name = _strtab_offset;
-    pShdr->sh_type = SHT_STRTAB;
-    pShdr->sh_flags = 0;
-
-    // Create the section ".symtab"
-    if ((pScn = elf_newscn(pElf)) == NULL)
-        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
-    if ((pData = elf_newdata(pScn)) == NULL)
-        errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
-
-    Elf32_Sym x[4];
-
-    // Definition of the undefined section (this must be the first item by the definition of TIS ELF)
-    x[0].st_name = 0;
-    x[0].st_value = 0;
-    x[0].st_size = 0;
-    x[0].st_info = 0;
-    x[0].st_other = 0;
-    x[0].st_shndx = SHN_UNDEF;
-
-    // Definition of the name of the source file (this must be the second item by the definition in TIS ELF)
-    x[1].st_name = 1;
-    x[1].st_value = 0;
-    x[1].st_size = 0;
-    x[1].st_info = ELF32_ST_INFO(STB_LOCAL, STT_FILE); // This is the value that st_info must have (because of TIS ELF)
-    x[1].st_other = 0;
-    x[1].st_shndx = SHN_ABS;  // The section where the symbol is
-
-    // Definition of the ".text" section as a section in the ".symtab" section
-    x[2].st_name = 0;
-    x[2].st_value = 0;
-    x[2].st_size = 0;
-    x[2].st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
-    x[2].st_other = 0;
-    x[2].st_shndx = _text;  // The section where the symbol is
-
-    // Definition of the "_start" symbol
-    x[3].st_name = 13;  // Offset in the "strtab" section where the name start
-    x[3].st_value = 0;
-    x[3].st_size = 0;
-    x[3].st_info = ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE);
-    x[3].st_other = 0;
-    x[3].st_shndx = _text;  // The section where the symbol is
-
-    pData->d_align = 4;
-    pData->d_buf = (void *) x;
-    pData->d_type = ELF_T_BYTE;
-    pData->d_size = sizeof(x);
-
-    if ((pShdr = elf32_getshdr(pScn)) == NULL)
-        errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
-
-    pShdr->sh_name = _symtab_offset;  // Point to the name of the section
-    pShdr->sh_type = SHT_SYMTAB;
-    pShdr->sh_flags = 0;
-    pShdr->sh_link = _strtab;  // point to the section .strtab (the section that contain the strings)
-    pShdr->sh_info = ELF32_ST_INFO(STB_LOCAL, 3);  // the second argument is beause of TIS ELF (One greater than the symbol table index of the last local symbol (binding STB_LOCAL))
-
-    // Create many sections named .text
-    for (int i = 0; i < 70000; ++i) {
-        if ((pScn = elf_newscn(pElf)) == NULL)
-            errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
-        if ((pData = elf_newdata(pScn)) == NULL)
-            errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
-
-        pData->d_align = 4;
-        pData->d_buf = (void *)TEXT_CONTENTS;
-        pData->d_type = ELF_T_BYTE;
-        pData->d_size = sizeof(TEXT_CONTENTS);
-
-        if ((pShdr = elf32_getshdr(pScn)) == NULL)
-            errx(EX_SOFTWARE, "elf32_etshdr() failed: %s.", elf_errmsg(-1));
-
-        pShdr->sh_name = _text_offset;
-        pShdr->sh_type = SHT_PROGBITS;
-        pShdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
-    }
-
-    // Update the sections internally
-    if (elf_update(pElf, ELF_C_NULL) < 0)
-        errx(EX_SOFTWARE, "elf_update(NULL) failed: %s.", elf_errmsg(-1));
-    // Write the object file
-    if (elf_update(pElf, ELF_C_WRITE) < 0)
-        errx(EX_SOFTWARE, "elf_update() failed: %s.", elf_errmsg(-1));
-    // Close all handles
-    elf_end(pElf);
-    close(FileDes);
-    printf("Generated file: %s\n", OUTFILE);
-    
-    return 0;
-}
-