Skip to content

Commit

Permalink
dwarf/dwarf_expr: Add support for DW_OP_GNU_push_tls_address (eliben#315
Browse files Browse the repository at this point in the history
)

* 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
  • Loading branch information
woodruffw authored Jun 1, 2020
1 parent 9f12da5 commit 1ed78f5
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 11 deletions.
11 changes: 5 additions & 6 deletions elftools/dwarf/descriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,16 +559,15 @@ def dump_expr(self, expr, cu_offset=None):
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'])
Expand Down
10 changes: 5 additions & 5 deletions elftools/dwarf/dwarf_expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
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,
Expand Down Expand Up @@ -202,10 +203,8 @@ def parse_typedblob():
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('')))
Expand All @@ -221,7 +220,8 @@ def parse_typedblob():
'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):
Expand Down
9 changes: 9 additions & 0 deletions test/test_dwarf_expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def test_basic_single(self):
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')
Expand All @@ -50,6 +53,9 @@ def test_basic_sequence(self):
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(
Expand All @@ -68,6 +74,9 @@ def test_single(self):
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()

0 comments on commit 1ed78f5

Please sign in to comment.