b9e88747fce954e8534a5c301ff626fcf22a427c
[pyelftools.git] / test / test_refaddr_bitness.py
1 #------------------------------------------------------------------------------
2 # elftools tests
3 #
4 # Seva Alekseyev (sevaa@sprynet.com)
5 # This code is in the public domain
6 #
7 # The error that motivated this fix was in an iOS binary in Mach-O format. It
8 # had v2 DWARF data, but it was targeting a 64 bit architecture. Before the fix,
9 # pyelftools would assume that DW_FORM_ref_addr attribute took 4 bytes and
10 # misparse the DWARF data in the binary.
11 #
12 # Since pyelftools doesn't work with Mach-O files, I've taken a sample binary
13 # apart, and saved the three relevant sections - info, abbrev, and str as flat
14 # files. The metadata (the fact that it's targeting ARM64) is hard-coded, since
15 # the Mach-O header isn't preserved.
16 #------------------------------------------------------------------------------
17
18 import unittest
19 import os, sys, io
20
21 from elftools.dwarf.dwarfinfo import DWARFInfo, DebugSectionDescriptor, DwarfConfig
22
23 class TestRefAddrOnDWARFv2With64BitTarget(unittest.TestCase):
24 def test_main(self):
25 # Read the three saved sections as bytestreams
26 with open(os.path.join('test', 'testfiles_for_unittests', 'arm64_on_dwarfv2.info.dat'), 'rb') as f:
27 info = f.read()
28 with open(os.path.join('test', 'testfiles_for_unittests', 'arm64_on_dwarfv2.abbrev.dat'), 'rb') as f:
29 abbrev = f.read()
30 with open(os.path.join('test', 'testfiles_for_unittests', 'arm64_on_dwarfv2.str.dat'), 'rb') as f:
31 str = f.read()
32
33 # Parse the DWARF info
34 di = DWARFInfo(
35 config = DwarfConfig(little_endian = True, default_address_size = 8, machine_arch = "ARM64"),
36 debug_info_sec = DebugSectionDescriptor(io.BytesIO(info), '__debug_info', None, len(info), 0),
37 debug_aranges_sec = None,
38 debug_abbrev_sec = DebugSectionDescriptor(io.BytesIO(abbrev), '__debug_abbrev', None, len(abbrev), 0),
39 debug_frame_sec = None,
40 eh_frame_sec = None,
41 debug_str_sec = DebugSectionDescriptor(io.BytesIO(str), '__debug_str', None, len(str), 0),
42 debug_loc_sec = None,
43 debug_ranges_sec = None,
44 debug_line_sec = None,
45 debug_pubtypes_sec = None,
46 debug_pubnames_sec = None,
47 debug_addr_sec=None,
48 debug_str_offsets_sec=None,
49 )
50
51 CUs = [cu for cu in di.iter_CUs()]
52 # Locate a CU that I know has a reference in DW_FORM_ref_addr form
53 CU = CUs[21]
54 self.assertEqual(CU['version'], 2)
55 # Make sure pyelftools appreciates the difference between the target address size and DWARF inter-DIE offset size
56 self.assertEqual(CU.structs.dwarf_format, 32)
57 self.assertEqual(CU['address_size'], 8)
58 DIEs = [die for die in CU.iter_DIEs()]
59 # Before the patch, DIE #2 is misparsed, the current offset is off, the rest are misparsed too
60 self.assertEqual(len(DIEs), 15)
61 # It was 9 before the patch, which was wrong.
62
63 if __name__ == '__main__':
64 unittest.main()