From 1ed78f5fef91ecd792c42e6f805114ab5a38ba4f Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Mon, 1 Jun 2020 09:00:00 -0400 Subject: [PATCH] dwarf/dwarf_expr: Add support for DW_OP_GNU_push_tls_address (#315) * dwarf/dwarf_expr: Add support for DW_OP_GNU_push_tls_address * dwarf/dwarf_expr: Use a single 64-bit operand for const8x DWARFv4 2.5.1.1: this should be consumed as a single 64-bit operand, not as two 32-bit operands. * dwarf/descriptions: Fix descriptions for const8{u,s} * test: Add tests for changed OPs --- elftools/dwarf/descriptions.py | 11 +++++------ elftools/dwarf/dwarf_expr.py | 10 +++++----- test/test_dwarf_expr.py | 9 +++++++++ 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/elftools/dwarf/descriptions.py b/elftools/dwarf/descriptions.py index a7a7599..c3fa078 100644 --- a/elftools/dwarf/descriptions.py +++ b/elftools/dwarf/descriptions.py @@ -559,16 +559,15 @@ class ExprDumper(object): def _init_lookups(self): self._ops_with_decimal_arg = set([ 'DW_OP_const1u', 'DW_OP_const1s', 'DW_OP_const2u', 'DW_OP_const2s', - 'DW_OP_const4u', 'DW_OP_const4s', 'DW_OP_constu', 'DW_OP_consts', - 'DW_OP_pick', 'DW_OP_plus_uconst', 'DW_OP_bra', 'DW_OP_skip', - 'DW_OP_fbreg', 'DW_OP_piece', 'DW_OP_deref_size', - 'DW_OP_xderef_size', 'DW_OP_regx',]) + 'DW_OP_const4u', 'DW_OP_const4s', 'DW_OP_const8u', 'DW_OP_const8s', + 'DW_OP_constu', 'DW_OP_consts', 'DW_OP_pick', 'DW_OP_plus_uconst', + 'DW_OP_bra', 'DW_OP_skip', 'DW_OP_fbreg', 'DW_OP_piece', + 'DW_OP_deref_size', 'DW_OP_xderef_size', 'DW_OP_regx',]) for n in range(0, 32): self._ops_with_decimal_arg.add('DW_OP_breg%s' % n) - self._ops_with_two_decimal_args = set([ - 'DW_OP_const8u', 'DW_OP_const8s', 'DW_OP_bregx', 'DW_OP_bit_piece']) + self._ops_with_two_decimal_args = set(['DW_OP_bregx', 'DW_OP_bit_piece']) self._ops_with_hex_arg = set( ['DW_OP_addr', 'DW_OP_call2', 'DW_OP_call4', 'DW_OP_call_ref']) diff --git a/elftools/dwarf/dwarf_expr.py b/elftools/dwarf/dwarf_expr.py index c46c9af..bb85daa 100644 --- a/elftools/dwarf/dwarf_expr.py +++ b/elftools/dwarf/dwarf_expr.py @@ -83,6 +83,7 @@ DW_OP_name2opcode = dict( DW_OP_convert=0xa8, DW_OP_reinterpret=0xa9, DW_OP_lo_user=0xe0, + DW_OP_GNU_push_tls_address=0xe0, DW_OP_GNU_implicit_pointer=0xf2, DW_OP_GNU_entry_value=0xf3, DW_OP_GNU_const_type=0xf4, @@ -202,10 +203,8 @@ def _init_dispatch_table(structs): add('DW_OP_const2s', parse_arg_struct(structs.Dwarf_int16(''))) add('DW_OP_const4u', parse_arg_struct(structs.Dwarf_uint32(''))) add('DW_OP_const4s', parse_arg_struct(structs.Dwarf_int32(''))) - add('DW_OP_const8u', parse_arg_struct2(structs.Dwarf_uint32(''), - structs.Dwarf_uint32(''))) - add('DW_OP_const8s', parse_arg_struct2(structs.Dwarf_int32(''), - structs.Dwarf_int32(''))) + add('DW_OP_const8u', parse_arg_struct(structs.Dwarf_uint64(''))) + add('DW_OP_const8s', parse_arg_struct(structs.Dwarf_int64(''))) add('DW_OP_constu', parse_arg_struct(structs.Dwarf_uleb128(''))) add('DW_OP_consts', parse_arg_struct(structs.Dwarf_sleb128(''))) add('DW_OP_pick', parse_arg_struct(structs.Dwarf_uint8(''))) @@ -221,7 +220,8 @@ def _init_dispatch_table(structs): 'DW_OP_shra', 'DW_OP_xor', 'DW_OP_eq', 'DW_OP_ge', 'DW_OP_gt', 'DW_OP_le', 'DW_OP_lt', 'DW_OP_ne', 'DW_OP_nop', 'DW_OP_push_object_address', 'DW_OP_form_tls_address', - 'DW_OP_call_frame_cfa', 'DW_OP_stack_value']: + 'DW_OP_call_frame_cfa', 'DW_OP_stack_value', + 'DW_OP_GNU_push_tls_address']: add(opname, parse_noargs()) for n in range(0, 32): diff --git a/test/test_dwarf_expr.py b/test/test_dwarf_expr.py index 1d925f6..42186ba 100644 --- a/test/test_dwarf_expr.py +++ b/test/test_dwarf_expr.py @@ -40,6 +40,9 @@ class TestExprDumper(unittest.TestCase): self.assertEqual(self.visitor.dump_expr([0x9d, 0x8f, 0x0A, 0x90, 0x01]), 'DW_OP_bit_piece: 1295 144') + self.assertEqual(self.visitor.dump_expr([0x0e, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00]), + 'DW_OP_const8u: 71777214294589695') + def test_basic_sequence(self): self.assertEqual(self.visitor.dump_expr([0x03, 0x01, 0x02, 0, 0, 0x06, 0x06]), 'DW_OP_addr: 201; DW_OP_deref; DW_OP_deref') @@ -50,6 +53,9 @@ class TestExprDumper(unittest.TestCase): self.assertEqual(self.visitor.dump_expr([0x1d, 0x1e, 0x1d, 0x1e, 0x1d, 0x1e]), 'DW_OP_mod; DW_OP_mul; DW_OP_mod; DW_OP_mul; DW_OP_mod; DW_OP_mul') + self.assertEqual(self.visitor.dump_expr([0x08, 0x0f, 0xe0]), + 'DW_OP_const1u: 15; DW_OP_GNU_push_tls_address') + class TestParseExpr(unittest.TestCase): structs32 = DWARFStructs( @@ -68,6 +74,9 @@ class TestParseExpr(unittest.TestCase): lst = p.parse_expr([0x90, 16]) self.assertEqual(lst, [DWARFExprOp(op=0x90, op_name='DW_OP_regx', args=[16])]) + lst = p.parse_expr([0xe0]) + self.assertEqual(lst, [DWARFExprOp(op=0xe0, op_name='DW_OP_GNU_push_tls_address', args=[])]) + if __name__ == '__main__': unittest.main() -- 2.30.2