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('')))
#-------------------------------------------------------------------------------
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,
)
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
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)
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)