Clean up whitespace
[pyelftools.git] / test / test_dwarf_expr.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
9 from elftools.dwarf.descriptions import ExprDumper, set_global_machine_arch
10 from elftools.dwarf.dwarf_expr import DWARFExprParser, DWARFExprOp
11 from elftools.dwarf.structs import DWARFStructs
12
13
14 class TestExprDumper(unittest.TestCase):
15 structs32 = DWARFStructs(
16 little_endian=True,
17 dwarf_format=32,
18 address_size=4)
19
20 def setUp(self):
21 self.visitor = ExprDumper(self.structs32)
22 set_global_machine_arch('x64')
23
24 def test_basic_single(self):
25 self.assertEqual(self.visitor.dump_expr([0x1b]),
26 'DW_OP_div')
27
28 self.assertEqual(self.visitor.dump_expr([0x74, 0x82, 0x01]),
29 'DW_OP_breg4 (rsi): 130')
30
31 self.assertEqual(self.visitor.dump_expr([0x91, 0x82, 0x01]),
32 'DW_OP_fbreg: 130')
33
34 self.assertEqual(self.visitor.dump_expr([0x51]),
35 'DW_OP_reg1 (rdx)')
36
37 self.assertEqual(self.visitor.dump_expr([0x90, 16]),
38 'DW_OP_regx: 16 (rip)')
39
40 self.assertEqual(self.visitor.dump_expr([0x9d, 0x8f, 0x0A, 0x90, 0x01]),
41 'DW_OP_bit_piece: 1295 144')
42
43 self.assertEqual(self.visitor.dump_expr([0x0e, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00]),
44 'DW_OP_const8u: 71777214294589695')
45
46 def test_basic_sequence(self):
47 self.assertEqual(self.visitor.dump_expr([0x03, 0x01, 0x02, 0, 0, 0x06, 0x06]),
48 'DW_OP_addr: 201; DW_OP_deref; DW_OP_deref')
49
50 self.assertEqual(self.visitor.dump_expr([0x15, 0xFF, 0x0b, 0xf1, 0xff]),
51 'DW_OP_pick: 255; DW_OP_const2s: -15')
52
53 self.assertEqual(self.visitor.dump_expr([0x1d, 0x1e, 0x1d, 0x1e, 0x1d, 0x1e]),
54 'DW_OP_mod; DW_OP_mul; DW_OP_mod; DW_OP_mul; DW_OP_mod; DW_OP_mul')
55
56 # 0xe0 maps to both DW_OP_GNU_push_tls_address and DW_OP_lo_user, so
57 # check for both to prevent non-determinism.
58 self.assertIn(self.visitor.dump_expr([0x08, 0x0f, 0xe0]),
59 ('DW_OP_const1u: 15; DW_OP_GNU_push_tls_address',
60 'DW_OP_const1u: 15; DW_OP_lo_user'))
61
62
63 class TestParseExpr(unittest.TestCase):
64 structs32 = DWARFStructs(
65 little_endian=True,
66 dwarf_format=32,
67 address_size=4)
68
69 def setUp(self):
70 set_global_machine_arch('x64')
71
72 def test_single(self):
73 p = DWARFExprParser(self.structs32)
74 lst = p.parse_expr([0x1b])
75 self.assertEqual(lst, [DWARFExprOp(op=0x1B, op_name='DW_OP_div', args=[], offset=0)])
76
77 lst = p.parse_expr([0x90, 16])
78 self.assertEqual(lst, [DWARFExprOp(op=0x90, op_name='DW_OP_regx', args=[16], offset=0)])
79
80 lst = p.parse_expr([0xe0])
81 self.assertEqual(len(lst), 1)
82 # 0xe0 maps to both DW_OP_GNU_push_tls_address and DW_OP_lo_user, so
83 # check for both to prevent non-determinism.
84 self.assertIn(lst[0], [
85 DWARFExprOp(op=0xe0, op_name='DW_OP_GNU_push_tls_address', args=[], offset=0),
86 DWARFExprOp(op=0xe0, op_name='DW_OP_lo_user', args=[], offset=0)])
87
88 # Real life example:
89 # push_object_address
90 # deref
91 # dup
92 # bra 4
93 # lit0
94 # skip 3
95 # lit4
96 # minus
97 # deref
98 lst = p.parse_expr([0x97,0x6,0x12,0x28,0x4,0x0,0x30,0x2F,0x3,0x0,0x34,0x1C,0x6])
99 self.assertEqual(len(lst), 9)
100 self.assertEqual(lst, [
101 DWARFExprOp(op=0x97, op_name='DW_OP_push_object_address', args=[], offset=0),
102 DWARFExprOp(op=0x6, op_name='DW_OP_deref', args=[], offset=1),
103 DWARFExprOp(op=0x12, op_name='DW_OP_dup', args=[], offset=2),
104 DWARFExprOp(op=0x28, op_name='DW_OP_bra', args=[4], offset=3),
105 DWARFExprOp(op=0x30, op_name='DW_OP_lit0', args=[], offset=6),
106 DWARFExprOp(op=0x2f, op_name='DW_OP_skip', args=[3], offset=7),
107 DWARFExprOp(op=0x34, op_name='DW_OP_lit4', args=[], offset=10),
108 DWARFExprOp(op=0x1c, op_name='DW_OP_minus', args=[], offset=11),
109 DWARFExprOp(op=0x6, op_name='DW_OP_deref', args=[], offset=12)])
110
111
112 if __name__ == '__main__':
113 unittest.main()