blob: 8c1786a1faecdf769529108c75cc8c98ed6aba79 [file] [log] [blame]
#------------------------------------------------------------------------------
# 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 (
GNUVerNeedSection, GNUVerDefSection,
GNUVerSymSection)
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, GNUVerSymSection):
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, GNUVerNeedSection):
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, GNUVerDefSection):
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()