--- /dev/null
+#------------------------------------------------------------------------------
+# elftools tests
+#
+# Yann Rouillard (yann@pleiades.fr.eu.org)
+# This code is in the public domain
+#------------------------------------------------------------------------------
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+import os
+
+from utils import setup_syspath
+setup_syspath()
+from elftools.elf.elffile import ELFFile
+from elftools.elf.constants import VER_FLAGS
+from elftools.elf.gnuversions import (
+ GNUVerNeedTableSection, GNUVerDefTableSection,
+ GNUVerSymTableSection)
+
+
+class TestSymbolVersioning(unittest.TestCase):
+
+ versym_reference_data = [
+ {'name': b'', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': b'', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': b'_ITM_deregisterTMCloneTable', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': b'puts', 'ndx': 5},
+ {'name': b'strlcat', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': b'__stack_chk_fail', 'ndx': 6},
+ {'name': b'__gmon_start__', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': b'gzoffset', 'ndx': 7},
+ {'name': b'_Jv_RegisterClasses', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': b'_ITM_registerTMCloneTable', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': b'__cxa_finalize', 'ndx': 5},
+ {'name': b'_edata', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': b'VER_1.0', 'ndx': 2},
+ {'name': b'function1_ver1_1', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': b'_end', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': b'function1', 'ndx': 4 | 0x8000},
+ {'name': b'__bss_start', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': b'function1', 'ndx': 2},
+ {'name': b'VER_1.1', 'ndx': 3},
+ {'name': b'_init', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': b'function1_ver1_0', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': b'_fini', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': b'VER_1.2', 'ndx': 4},
+ {'name': b'function2', 'ndx': 3},
+ ]
+
+ def test_versym_section(self):
+
+ reference_data = TestSymbolVersioning.versym_reference_data
+
+ with open(os.path.join('test', 'testfiles_for_unittests',
+ 'lib_versioned64.so.1.elf'), 'rb') as f:
+ elf = ELFFile(f)
+ versym_section = None
+ for section in elf.iter_sections():
+ if isinstance(section, GNUVerSymTableSection):
+ versym_section = section
+ break
+
+ self.assertIsNotNone(versym_section)
+
+ for versym, ref_versym in zip(section.iter_symbols(),
+ reference_data):
+ self.assertEqual(versym.name, ref_versym['name'])
+ self.assertEqual(versym['ndx'], ref_versym['ndx'])
+
+ verneed_reference_data = [
+ {'name': b'libz.so.1', 'vn_version': 1, 'vn_cnt': 1,
+ 'vernaux': [
+ {'name': b'ZLIB_1.2.3.5', 'vna_flags': 0, 'vna_other': 7}]},
+ {'name': b'libc.so.6', 'vn_version': 1, 'vn_cnt': 2,
+ 'vernaux': [
+ {'name': b'GLIBC_2.4', 'vna_flags': 0, 'vna_other': 6},
+ {'name': b'GLIBC_2.2.5', 'vna_flags': 0, 'vna_other': 5}]},
+ ]
+
+ def test_verneed_section(self):
+
+ reference_data = TestSymbolVersioning.verneed_reference_data
+
+ with open(os.path.join('test', 'testfiles_for_unittests',
+ 'lib_versioned64.so.1.elf'), 'rb') as f:
+ elf = ELFFile(f)
+ verneed_section = None
+ for section in elf.iter_sections():
+ if isinstance(section, GNUVerNeedTableSection):
+ verneed_section = section
+ break
+
+ self.assertIsNotNone(verneed_section)
+
+ for (verneed, vernaux_iter), ref_verneed in zip(
+ section.iter_versions(), reference_data):
+
+ self.assertEqual(verneed.name, ref_verneed['name'])
+ self.assertEqual(verneed['vn_cnt'], ref_verneed['vn_cnt'])
+ self.assertEqual(verneed['vn_version'],
+ ref_verneed['vn_version'])
+
+ for vernaux, ref_vernaux in zip(
+ vernaux_iter, ref_verneed['vernaux']):
+
+ self.assertEqual(vernaux.name, ref_vernaux['name'])
+ self.assertEqual(vernaux['vna_flags'],
+ ref_vernaux['vna_flags'])
+ self.assertEqual(vernaux['vna_other'],
+ ref_vernaux['vna_other'])
+
+ verdef_reference_data = [
+ {'vd_ndx': 1, 'vd_version': 1, 'vd_flags': VER_FLAGS.VER_FLG_BASE,
+ 'vd_cnt': 1,
+ 'verdaux': [
+ {'name': b'lib_versioned.so.1'}]},
+ {'vd_ndx': 2, 'vd_version': 1, 'vd_flags': 0, 'vd_cnt': 1,
+ 'verdaux': [
+ {'name': b'VER_1.0'}]},
+ {'vd_ndx': 3, 'vd_version': 1, 'vd_flags': 0, 'vd_cnt': 2,
+ 'verdaux': [
+ {'name': b'VER_1.1'},
+ {'name': b'VER_1.0'}]},
+ {'vd_ndx': 4, 'vd_version': 1, 'vd_flags': 0, 'vd_cnt': 2,
+ 'verdaux': [
+ {'name': b'VER_1.2'},
+ {'name': b'VER_1.1'}]},
+ ]
+
+ def test_verdef_section(self):
+
+ reference_data = TestSymbolVersioning.verdef_reference_data
+
+ with open(os.path.join('test', 'testfiles_for_unittests',
+ 'lib_versioned64.so.1.elf'), 'rb') as f:
+ elf = ELFFile(f)
+ verneed_section = None
+ for section in elf.iter_sections():
+ if isinstance(section, GNUVerDefTableSection):
+ verdef_section = section
+ break
+
+ self.assertIsNotNone(verdef_section)
+
+ for (verdef, verdaux_iter), ref_verdef in zip(
+ section.iter_versions(), reference_data):
+
+ self.assertEqual(verdef['vd_ndx'], ref_verdef['vd_ndx'])
+ self.assertEqual(verdef['vd_version'],
+ ref_verdef['vd_version'])
+ self.assertEqual(verdef['vd_flags'], ref_verdef['vd_flags'])
+ self.assertEqual(verdef['vd_cnt'], ref_verdef['vd_cnt'])
+
+ for verdaux, ref_verdaux in zip(
+ verdaux_iter, ref_verdef['verdaux']):
+ self.assertEqual(verdaux.name, ref_verdaux['name'])
+
+if __name__ == '__main__':
+ unittest.main()