Fix for mixed version loclists, tests (#521)
[pyelftools.git] / test / test_dynamic.py
1 #-------------------------------------------------------------------------------
2 # elftools tests
3 #
4 # Eli Bendersky (eliben@gmail.com)
5 # This code is in the public domain
6 #-------------------------------------------------------------------------------
7 import unittest
8 import os
9
10 from elftools.elf.elffile import ELFFile
11 from elftools.common.exceptions import ELFError
12 from elftools.elf.dynamic import DynamicTag
13 from elftools.elf.enums import ENUM_D_TAG
14 from elftools.elf.descriptions import _DESCR_D_TAG, _low_priority_D_TAG
15
16
17 class TestDynamicTag(unittest.TestCase):
18 """Tests for the DynamicTag class."""
19
20 def test_requires_stringtable(self):
21 with self.assertRaises(ELFError):
22 dt = DynamicTag('', None)
23
24 def test_tag_priority(self):
25 for tag in _low_priority_D_TAG:
26 val = ENUM_D_TAG[tag]
27 # if the low priority tag is present in the descriptions,
28 # assert that it has not overridden any other tag
29 if _DESCR_D_TAG[val] == tag:
30 for tag2 in ENUM_D_TAG:
31 if tag2 == tag:
32 continue
33 self.assertNotEqual(ENUM_D_TAG[tag2], val)
34
35
36 class TestDynamic(unittest.TestCase):
37 """Tests for the Dynamic class."""
38
39 def test_missing_sections(self):
40 """Verify we can get dynamic strings w/out section headers"""
41
42 libs = []
43 with open(os.path.join('test', 'testfiles_for_unittests',
44 'aarch64_super_stripped.elf'), 'rb') as f:
45 elf = ELFFile(f)
46 for segment in elf.iter_segments():
47 if segment.header.p_type != 'PT_DYNAMIC':
48 continue
49
50 for t in segment.iter_tags():
51 if t.entry.d_tag == 'DT_NEEDED':
52 libs.append(t.needed)
53
54 exp = ['libc.so.6']
55 self.assertEqual(libs, exp)
56
57 def test_reading_symbols_elf_hash(self):
58 """ Verify we can read symbol table without SymbolTableSection but with
59 a SYSV-style symbol hash table"""
60 with open(os.path.join('test', 'testfiles_for_unittests',
61 'aarch64_super_stripped.elf'), 'rb') as f:
62 elf = ELFFile(f)
63 for segment in elf.iter_segments():
64 if segment.header.p_type != 'PT_DYNAMIC':
65 continue
66
67 num_symbols = segment.num_symbols()
68 symbol_names = [x.name for x in segment.iter_symbols()]
69 symbol_at_index_3 = segment.get_symbol(3)
70 symbols_abort = segment.get_symbol_by_name('abort')
71
72 self.assertEqual(num_symbols, 4)
73 exp = ['', '__libc_start_main', '__gmon_start__', 'abort']
74 self.assertEqual(symbol_names, exp)
75 self.assertEqual(symbol_at_index_3.name, 'abort')
76 self.assertIsNotNone(symbols_abort)
77
78 def test_reading_symbols_gnu_hash(self):
79 """ Verify we can read symbol table without SymbolTableSection but with
80 a GNU symbol hash table"""
81 with open(os.path.join('test', 'testfiles_for_unittests',
82 'android_dyntags.elf'), 'rb') as f:
83 elf = ELFFile(f)
84 for segment in elf.iter_segments():
85 if segment.header.p_type != 'PT_DYNAMIC':
86 continue
87
88 num_symbols = segment.num_symbols()
89 symbol_names = [x.name for x in segment.iter_symbols()]
90 symbol_at_index_3 = segment.get_symbol(3)
91 symbols_atfork = segment.get_symbol_by_name('__register_atfork')
92
93 self.assertEqual(num_symbols, 212)
94 exp = ['', '__cxa_finalize' , '__cxa_atexit', '__register_atfork',
95 '__stack_chk_fail', '_ZNK7android7RefBase9decStrongEPKv',
96 '_ZN7android7RefBaseD2Ev', '_ZdlPv', 'pthread_mutex_lock']
97 self.assertEqual(symbol_names[:9], exp)
98 self.assertEqual(symbol_at_index_3.name, '__register_atfork')
99 self.assertIsNotNone(symbols_atfork)
100
101 def test_sunw_tags(self):
102 def extract_sunw(filename):
103 with open(filename, 'rb') as f:
104 elf = ELFFile(f)
105 dyn = elf.get_section_by_name('.dynamic')
106
107 seen = set()
108 for tag in dyn.iter_tags():
109 if type(tag.entry.d_tag) is str and \
110 tag.entry.d_tag.startswith("DT_SUNW"):
111 seen.add(tag.entry.d_tag)
112
113 return seen
114
115 f1 = extract_sunw(os.path.join('test', 'testfiles_for_unittests',
116 'exe_solaris32_cc.sparc.elf'))
117 f2 = extract_sunw(os.path.join('test', 'testfiles_for_unittests',
118 'android_dyntags.elf'))
119 self.assertEqual(f1, {'DT_SUNW_STRPAD', 'DT_SUNW_LDMACH'})
120 self.assertEqual(f2, set())
121
122 if __name__ == '__main__':
123 unittest.main()