1 #-------------------------------------------------------------------------------
4 # Eli Bendersky (eliben@gmail.com)
5 # This code is in the public domain
6 #-------------------------------------------------------------------------------
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
17 class TestDynamicTag(unittest
.TestCase
):
18 """Tests for the DynamicTag class."""
20 def test_requires_stringtable(self
):
21 with self
.assertRaises(ELFError
):
22 dt
= DynamicTag('', None)
24 def test_tag_priority(self
):
25 for tag
in _low_priority_D_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
:
33 self
.assertNotEqual(ENUM_D_TAG
[tag2
], val
)
36 class TestDynamic(unittest
.TestCase
):
37 """Tests for the Dynamic class."""
39 def test_missing_sections(self
):
40 """Verify we can get dynamic strings w/out section headers"""
43 with
open(os
.path
.join('test', 'testfiles_for_unittests',
44 'aarch64_super_stripped.elf'), 'rb') as f
:
46 for segment
in elf
.iter_segments():
47 if segment
.header
.p_type
!= 'PT_DYNAMIC':
50 for t
in segment
.iter_tags():
51 if t
.entry
.d_tag
== 'DT_NEEDED':
55 self
.assertEqual(libs
, exp
)
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
:
63 for segment
in elf
.iter_segments():
64 if segment
.header
.p_type
!= 'PT_DYNAMIC':
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')
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
)
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
:
84 for segment
in elf
.iter_segments():
85 if segment
.header
.p_type
!= 'PT_DYNAMIC':
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')
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
)
101 def test_sunw_tags(self
):
102 def extract_sunw(filename
):
103 with
open(filename
, 'rb') as f
:
105 dyn
= elf
.get_section_by_name('.dynamic')
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
)
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())
122 if __name__
== '__main__':