From 8a235ad281cbcadd5ec2a8957306cf44a277d65c Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Thu, 27 Oct 2011 21:02:24 +0200 Subject: [PATCH] more work on location_expr --- elftools/dwarf/location_expr.py | 59 +++++++++++++++++++++++++++++---- elftools/dwarf/structs.py | 14 ++++++-- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/elftools/dwarf/location_expr.py b/elftools/dwarf/location_expr.py index 1a2d4f3..65e4f90 100644 --- a/elftools/dwarf/location_expr.py +++ b/elftools/dwarf/location_expr.py @@ -154,16 +154,63 @@ class GenericLocationExprVisitor(object): def _visit_OP_with_no_args(self, opcode, opcode_name): self._cur_args = [] - def _visit_OP_addr(self, opcode, opcode_name): - self._cur_args = [ - struct_parse(self.structs.Dwarf_target_addr(''), self.stream)] + def _make_visitor_for_struct(self, struct): + """ Make a visitor function that parses a single argument from the + stream, based on the given struct. + """ + def visitor(opcode, opcode_name): + self._cur_args = [struct_parse(struct, self.stream)] + return visitor def _init_dispatch_table(self): self._dispatch_table = {} def add(opcode_name, func): self._dispatch_table[DW_OP_name2opcode[opcode_name]] = func - add('DW_OP_addr', self._visit_OP_addr) - add('DW_OP_deref', self._visit_OP_with_no_args) - + for op in ( + 'DW_OP_deref', 'DW_OP_dup', 'DW_OP_drop', 'DW_OP_over', + 'DW_OP_swap', 'DW_OP_rot', 'DW_OP_xderef', 'DW_OP_abs', + 'DW_OP_and', 'DW_OP_div', 'DW_OP_minus', 'DW_OP_mod', + 'DW_OP_mul', 'DW_OP_neg', 'DW_OP_not', 'DW_OP_or', + 'DW_OP_eq', 'DW_OP_ge', 'DW_OP_gt', 'DW_OP_le', 'DW_OP_lt', + 'DW_OP_ne', 'DW_OP_plus', 'DW_OP_shl', 'DW_OP_shr', + 'DW_OP_shra'): + add(op, self._visit_OP_with_no_args) + + add('DW_OP_addr', self._make_visitor_for_struct( + self.structs.Dwarf_target_addr(''))) + add('DW_OP_const1u', self._make_visitor_for_struct( + self.structs.Dwarf_uint8(''))) + add('DW_OP_const1s', self._make_visitor_for_struct( + self.structs.Dwarf_int8(''))) + add('DW_OP_const2u', self._make_visitor_for_struct( + self.structs.Dwarf_uint16(''))) + add('DW_OP_const2s', self._make_visitor_for_struct( + self.structs.Dwarf_int16(''))) + add('DW_OP_const4u', self._make_visitor_for_struct( + self.structs.Dwarf_uint32(''))) + add('DW_OP_const4s', self._make_visitor_for_struct( + self.structs.Dwarf_int32(''))) + add('DW_OP_const8u', self._make_visitor_for_struct( + self.structs.Dwarf_uint64(''))) + add('DW_OP_const8s', self._make_visitor_for_struct( + self.structs.Dwarf_int64(''))) + add('DW_OP_constu', self._make_visitor_for_struct( + self.structs.Dwarf_uleb128(''))) + add('DW_OP_consts', self._make_visitor_for_struct( + self.structs.Dwarf_sleb128(''))) + add('DW_OP_plus_uconst', self._make_visitor_for_struct( + self.structs.Dwarf_uleb128(''))) + add('DW_OP_pick', self._make_visitor_for_struct( + self.structs.Dwarf_uint8(''))) + add('DW_OP_bra', self._make_visitor_for_struct( + self.structs.Dwarf_int16(''))) + add('DW_OP_skip', self._make_visitor_for_struct( + self.structs.Dwarf_int16(''))) + + for i in range(32): + add('DW_OP_lit%s' % i, self._visit_OP_with_no_args) + add('DW_OP_reg%s' % i, self._visit_OP_with_no_args) + add('DW_OP_breg%s' % i, self._make_visitor_for_struct( + self.structs.Dwarf_sleb128(''))) diff --git a/elftools/dwarf/structs.py b/elftools/dwarf/structs.py index 7fbd357..91145a2 100644 --- a/elftools/dwarf/structs.py +++ b/elftools/dwarf/structs.py @@ -9,6 +9,7 @@ #------------------------------------------------------------------------------- from ..construct import ( UBInt8, UBInt16, UBInt32, UBInt64, ULInt8, ULInt16, ULInt32, ULInt64, + SBInt8, SBInt16, SBInt32, SBInt64, SLInt8, SLInt16, SLInt32, SLInt64, Adapter, Struct, ConstructError, If, RepeatUntil, Field, Rename, Enum, PrefixedArray, CString, ) @@ -27,8 +28,9 @@ class DWARFStructs(object): Accessible attributes (mostly as described in chapter 7 of the DWARF spec v3): - Dwarf_uint{8,16,32,64): - Data chunks of the common sizes + Dwarf_uint{8,16,32,64}: + Dwarf_int{8,16,32,64} + Data chunks of the common sizes (unsigned and signed) Dwarf_offset: 32-bit or 64-bit word, depending on dwarf_format @@ -86,6 +88,10 @@ class DWARFStructs(object): self.Dwarf_uint16 = ULInt16 self.Dwarf_uint32 = ULInt32 self.Dwarf_uint64 = ULInt64 + self.Dwarf_int8 = SLInt8 + self.Dwarf_int16 = SLInt16 + self.Dwarf_int32 = SLInt32 + self.Dwarf_int64 = SLInt64 self.Dwarf_offset = ULInt32 if self.dwarf_format == 32 else ULInt64 self.Dwarf_target_addr = ( ULInt32 if self.address_size == 4 else ULInt64) @@ -94,6 +100,10 @@ class DWARFStructs(object): self.Dwarf_uint16 = UBInt16 self.Dwarf_uint32 = UBInt32 self.Dwarf_uint64 = UBInt64 + self.Dwarf_int8 = SBInt8 + self.Dwarf_int16 = SBInt16 + self.Dwarf_int32 = SBInt32 + self.Dwarf_int64 = SBInt64 self.Dwarf_offset = UBInt32 if self.dwarf_format == 32 else UBInt64 self.Dwarf_target_addr = ( UBInt32 if self.address_size == 4 else UBInt64) -- 2.30.2