about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/core/objc.py105
-rw-r--r--test/expr_type/test_chandler.py4
2 files changed, 50 insertions, 59 deletions
diff --git a/miasm2/core/objc.py b/miasm2/core/objc.py
index e7d2f332..d6c100ca 100644
--- a/miasm2/core/objc.py
+++ b/miasm2/core/objc.py
@@ -865,44 +865,40 @@ class ExprToAccessC(ExprReducer):
         """
         if base_type.size == 0:
             missing_definition(base_type)
-            return []
+            return set()
 
 
         void_type = self.types_mngr.void_ptr
         if isinstance(base_type, ObjCStruct):
             if not 0 <= offset < base_type.size:
-                return []
+                return set()
 
             if offset == 0 and not deref:
                 # In this case, return the struct*
-                return [cgenobj]
+                return set([cgenobj])
 
-            out = []
             for fieldname, subtype, field_offset, size in base_type.fields:
                 if not field_offset <= offset < field_offset + size:
                     continue
                 fieldptr = CGenField(CGenDeref(cgenobj), fieldname, subtype,
                                      void_type.align, void_type.size)
-                ret = self.cgen_access(
-                    fieldptr, subtype, offset - field_offset, deref, lvl + 1)
-                for sname in ret:
-                    finalobj = sname
-                    out.append(finalobj)
-                new_type = out
+                new_type = self.cgen_access(fieldptr, subtype,
+                                            offset - field_offset,
+                                            deref, lvl + 1)
                 break
             else:
-                return []
+                return set()
         elif isinstance(base_type, ObjCArray):
             if base_type.objtype.size == 0:
                 missing_definition(base_type.objtype)
-                return []
+                return set()
             element_num = offset / (base_type.objtype.size)
             field_offset = offset % base_type.objtype.size
             if element_num >= base_type.elems:
-                return []
+                return set()
             if offset == 0 and not deref:
                 # In this case, return the array
-                return [cgenobj]
+                return set([cgenobj])
 
             curobj = CGenArray(cgenobj, element_num,
                                void_type.align,
@@ -910,43 +906,42 @@ class ExprToAccessC(ExprReducer):
             if field_offset == 0:
                 # We point to the start of the sub object,
                 # return it directly
-                ret = [curobj]
-            ret = self.cgen_access(curobj, base_type.objtype,
-                                   field_offset, deref, lvl + 1)
-            return ret
+                return set([curobj])
+            new_type = self.cgen_access(curobj, base_type.objtype,
+                                        field_offset, deref, lvl + 1)
 
         elif isinstance(base_type, ObjCDecl):
             if self.enforce_strict_access and offset % base_type.size != 0:
-                return []
+                return set()
             elem_num = offset / base_type.size
 
             nobj = CGenArray(cgenobj, elem_num,
                              void_type.align, void_type.size)
-            new_type = [(nobj)]
+            new_type = set([nobj])
 
         elif isinstance(base_type, ObjCUnion):
-            out = []
             if offset == 0 and not deref:
                 # In this case, return the struct*
-                return [cgenobj]
+                return set([cgenobj])
 
+            out = set()
             for fieldname, objtype, field_offset, size in base_type.fields:
                 if not field_offset <= offset < field_offset + size:
                     continue
                 field = CGenField(CGenDeref(cgenobj), fieldname, objtype,
                                   void_type.align, void_type.size)
-                new_type = self.cgen_access(
-                    field, objtype, offset - field_offset, deref, lvl + 1)
-                out += new_type
+                out.update(self.cgen_access(field, objtype,
+                                            offset - field_offset,
+                                            deref, lvl + 1))
             new_type = out
 
         elif isinstance(base_type, ObjCPtr):
             elem_num = offset / base_type.size
             if self.enforce_strict_access and offset % base_type.size != 0:
-                return []
+                return set()
             nobj = CGenArray(cgenobj, elem_num,
                              void_type.align, void_type.size)
-            new_type = [(nobj)]
+            new_type = set([nobj])
 
         else:
             raise NotImplementedError("deref type %r" % base_type)
@@ -956,7 +951,7 @@ class ExprToAccessC(ExprReducer):
         """Generate access for known expr"""
         if node.expr in ctxt:
             objcs = ctxt[node.expr]
-            return [CGenId(objc, str(node.expr)) for objc in objcs]
+            return set(CGenId(objc, str(node.expr)) for objc in objcs)
         return None
 
     def reduce_int(self, node, **kwargs):
@@ -964,7 +959,7 @@ class ExprToAccessC(ExprReducer):
 
         if not isinstance(node.expr, ExprInt):
             return None
-        return [CGenInt(int(node.expr))]
+        return set([CGenInt(int(node.expr))])
 
     def get_solo_type(self, node):
         """Return the type of the @node if it has only one possible type,
@@ -972,7 +967,7 @@ class ExprToAccessC(ExprReducer):
         """
         if node.info is None or len(node.info) != 1:
             return None
-        return type(node.info[0].ctype)
+        return type(list(node.info)[0].ctype)
 
     def reduce_op(self, node, lvl=0, **kwargs):
         """Generate access for ExprOp"""
@@ -985,7 +980,7 @@ class ExprToAccessC(ExprReducer):
         if arg0.info is None:
             return None
         void_type = self.types_mngr.void_ptr
-        out = []
+        out = set()
         ptr_offset = int(arg1.expr)
         for info in arg0.info:
             if isinstance(info.ctype, ObjCArray):
@@ -997,7 +992,7 @@ class ExprToAccessC(ExprReducer):
             target_type = info.ctype.objtype
 
             # Array-like: int* ptr; ptr[1] = X
-            out += self.cgen_access(info, field_type, ptr_offset, False, lvl)
+            out.update(self.cgen_access(info, field_type, ptr_offset, False, lvl))
         return out
 
     def reduce_mem(self, node, lvl=0, **kwargs):
@@ -1011,9 +1006,9 @@ class ExprToAccessC(ExprReducer):
             return None
         if node.arg.info is None:
             return None
-        assert isinstance(node.arg.info, list)
+        assert isinstance(node.arg.info, set)
         void_type = self.types_mngr.void_ptr
-        found = []
+        found = set()
         for subcgenobj in node.arg.info:
             if isinstance(subcgenobj.ctype, ObjCArray):
                 nobj = CGenArray(subcgenobj, 0,
@@ -1024,7 +1019,7 @@ class ExprToAccessC(ExprReducer):
                     assert isinstance(finalcgenobj.ctype, ObjCPtr)
                     if self.enforce_strict_access and finalcgenobj.ctype.objtype.size != node.expr.size / 8:
                         continue
-                    found.append(CGenDeref(finalcgenobj))
+                    found.add(CGenDeref(finalcgenobj))
 
             elif isinstance(subcgenobj.ctype, ObjCPtr):
                 target = subcgenobj.ctype.objtype
@@ -1034,15 +1029,16 @@ class ExprToAccessC(ExprReducer):
                         target = finalcgenobj.ctype.objtype
                         if self.enforce_strict_access and target.size != node.expr.size / 8:
                             continue
-                        found.append(CGenDeref(finalcgenobj))
+                        found.add(CGenDeref(finalcgenobj))
                 elif isinstance(target, ObjCArray):
                     if self.enforce_strict_access and subcgenobj.ctype.size != node.expr.size / 8:
                         continue
-                    found += self.cgen_access(CGenDeref(subcgenobj), target, 0, False, lvl)
+                    found.update(self.cgen_access(CGenDeref(subcgenobj), target,
+                                                  0, False, lvl))
                 else:
                     if self.enforce_strict_access and target.size != node.expr.size / 8:
                         continue
-                    found.append(CGenDeref(subcgenobj))
+                    found.add(CGenDeref(subcgenobj))
         if not found:
             return None
         return found
@@ -1063,7 +1059,7 @@ class ExprToAccessC(ExprReducer):
             expr_context = self.expr_types
         ret = self.reduce(expr, ctxt=expr_context)
         if ret.info is None:
-            return []
+            return set()
         return ret.info
 
 
@@ -1603,8 +1599,7 @@ class CHandler(object):
     def expr_to_c_access(self, expr, expr_context=None):
         """Generate the C access object(s) for a given native Miasm expression.
         @expr: Miasm expression
-        @expr_context: a dictionnary linking known expressions to their
-        types. An expression is linked to a tuple of types.
+        @expr_context: a dictionnary linking known expressions to a set of types
         """
 
         if expr_context is None:
@@ -1615,38 +1610,36 @@ class CHandler(object):
     def expr_to_c_and_types(self, expr, expr_context=None):
         """Generate the C access string and corresponding type for a given
         native Miasm expression.
-        @expr_context: a dictionnary linking known expressions to their
-        types. An expression is linked to a tuple of types.
+        @expr_context: a dictionnary linking known expressions to a set of types
         """
 
-        accesses = []
+        accesses = set()
         for access in self.expr_to_c_access(expr, expr_context):
             c_str = access_str(access.to_expr().visit(self.simplify_c))
-            accesses.append((c_str, access.ctype))
+            accesses.add((c_str, access.ctype))
         return accesses
 
     def expr_to_c(self, expr, expr_context=None):
         """Convert a Miasm @expr into it's C equivalent string
-        @expr_context: a dictionnary linking known expressions to their
-        types. An expression is linked to a tuple of types.
+        @expr_context: a dictionnary linking known expressions to a set of types
         """
 
-        return [access[0] for access in self.expr_to_c_and_types(expr, expr_context)]
+        return set(access[0]
+                   for access in self.expr_to_c_and_types(expr, expr_context))
 
     def expr_to_types(self, expr, expr_context=None):
         """Get the possible types of the Miasm @expr
-        @expr_context: a dictionnary linking known expressions to their
-        types. An expression is linked to a tuple of types.
+        @expr_context: a dictionnary linking known expressions to a set of types
         """
 
-        return [access.ctype for access in self.expr_to_c_access(expr, expr_context)]
+        return set(access.ctype
+                   for access in self.expr_to_c_access(expr, expr_context))
 
     def c_to_expr_and_type(self, c_str, c_context):
         """Convert a C string expression to a Miasm expression and it's
         corresponding c type
         @c_str: C string
-        @c_context: a dictionnary linking known tokens (strings) to their
-        types. A token is linked to only one type.
+        @c_context: a dictionnary linking known tokens (strings) to its type.
         """
 
         ast = parse_access(c_str)
@@ -1656,8 +1649,7 @@ class CHandler(object):
     def c_to_expr(self, c_str, c_context):
         """Convert a C string expression to a Miasm expression
         @c_str: C string
-        @c_context: a dictionnary linking known tokens (strings) to their
-        types. A token is linked to only one type.
+        @c_context: a dictionnary linking known tokens (strings) to its type.
         """
 
         expr, _ = self.c_to_expr_and_type(c_str, c_context)
@@ -1666,8 +1658,7 @@ class CHandler(object):
     def c_to_type(self, c_str, c_context):
         """Get the type of a C string expression
         @expr: Miasm expression
-        @c_context: a dictionnary linking known tokens (strings) to their
-        types. A token is linked to only one type.
+        @c_context: a dictionnary linking known tokens (strings) to its type.
         """
 
         _, ctype = self.c_to_expr_and_type(c_str, c_context)
diff --git a/test/expr_type/test_chandler.py b/test/expr_type/test_chandler.py
index 2fa3f979..8070841d 100644
--- a/test/expr_type/test_chandler.py
+++ b/test/expr_type/test_chandler.py
@@ -208,8 +208,8 @@ assert obj_test_context.size > obj_test_st.size
 assert cmp(obj_test_st, obj_recurse) != 0
 
 
-expr_types = {ptr_test: (obj_test,),
-              ptr_recurse: (obj_recurse,)}
+expr_types = {ptr_test: set([obj_test]),
+              ptr_recurse: set([obj_recurse])}
 
 
 c_context = {ptr_test.name: obj_test,