1#------------------------------------------------------------------------------- 2# elftools tests 3# 4# Eli Bendersky (eliben@gmail.com) 5# This code is in the public domain 6#------------------------------------------------------------------------------- 7import unittest 8 9from elftools.dwarf.descriptions import ExprDumper, set_global_machine_arch 10from elftools.dwarf.dwarf_expr import DWARFExprParser, DWARFExprOp 11from elftools.dwarf.structs import DWARFStructs 12 13 14class 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 63class 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=[])]) 76 77 lst = p.parse_expr([0x90, 16]) 78 self.assertEqual(lst, [DWARFExprOp(op=0x90, op_name='DW_OP_regx', args=[16])]) 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=[]), 86 DWARFExprOp(op=0xe0, op_name='DW_OP_lo_user', args=[])]) 87 88 89if __name__ == '__main__': 90 unittest.main() 91