more work on location_expr
authorEli Bendersky <eliben@gmail.com>
Thu, 27 Oct 2011 19:02:24 +0000 (21:02 +0200)
committerEli Bendersky <eliben@gmail.com>
Thu, 27 Oct 2011 19:02:24 +0000 (21:02 +0200)
elftools/dwarf/location_expr.py
elftools/dwarf/structs.py

index 1a2d4f319fd755c9a20143c4dc96028d98d378eb..65e4f901ad05080d47bf64b3cedca3dd2d8d3e78 100644 (file)
@@ -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('')))
 
index 7fbd35737057fd3c6627d1e1bdd1ef0298c33320..91145a240c1946cfeba87bcc1f0562d3ea850ad7 100644 (file)
@@ -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)