def _standardize_value(arg, ty, state, alloc): check = ty is not None if isinstance(arg, s_action_object.SimActionObject): return SimCC._standardize_value(arg.ast, ty, state, alloc) elif isinstance(arg, PointerWrapper): if check and not isinstance(ty, s_type.SimTypePointer): raise TypeError( "Type mismatch: expected %s, got pointer-wrapper" % ty.name) real_value = SimCC._standardize_value(arg.value, ty.pts_to if check else None, state, alloc) return alloc(real_value, state) elif isinstance(arg, str): # TODO: when we switch to py3, distinguish between str and bytes # by null-terminating str but not bytes :/ arg += '\0' ref = False if check: if isinstance(ty, s_type.SimTypePointer) and \ isinstance(ty.pts_to, s_type.SimTypeChar): ref = True elif isinstance(ty, s_type.SimTypeFixedSizeArray) and \ isinstance(ty.elem_type, s_type.SimTypeChar): ref = False if len(arg) > ty.length: raise TypeError("String %s is too long for %s" % (repr(arg), ty.name)) arg = arg.ljust(ty.length, '\0') elif isinstance(ty, s_type.SimTypeArray) and \ isinstance(ty.elem_type, s_type.SimTypeChar): ref = True if ty.length is not None: if len(arg) > ty.length: raise TypeError("String %s is too long for %s" % (repr(arg), ty.name)) arg = arg.ljust(ty.length, '\0') elif isinstance(ty, s_type.SimTypeString): ref = False if len(arg) > ty.length + 1: raise TypeError("String %s is too long for %s" % (repr(arg), ty.name)) arg = arg.ljust(ty.length + 1, '\0') else: raise TypeError("Type mismatch: Expected %s, got char*" % ty.name) val = SimCC._standardize_value( map(ord, arg), s_type.SimTypeFixedSizeArray(s_type.SimTypeChar(), len(arg)), state, alloc) if ref: val = alloc(val, state) return val elif isinstance(arg, list): ref = False subty = None if check: if isinstance(ty, s_type.SimTypePointer): ref = True subty = ty.pts_to elif isinstance(ty, s_type.SimTypeFixedSizeArray): ref = False subty = ty.elem_type if len(arg) != ty.length: raise TypeError("Array %s is the wrong length for %s" % (repr(arg), ty.name)) elif isinstance(ty, s_type.SimTypeArray): ref = True subty = ty.elem_type if ty.length is not None: if len(arg) != ty.length: raise TypeError( "Array %s is the wrong length for %s" % (repr(arg), ty.name)) else: raise TypeError("Type mismatch: Expected %s, got char*" % ty.name) else: types = map(type, arg) if types[1:] != types[:-1]: raise TypeError( "All elements of list must be of same type") val = claripy.Concat(*[ SimCC._standardize_value(sarg, subty, state, alloc) for sarg in arg ]) if ref: val = alloc(val, state) return val elif isinstance(arg, tuple): if check: if not isinstance(ty, s_type.SimStruct): raise TypeError( "Type mismatch: Expected %s, got tuple (i.e. struct)" % ty.name) if len(arg) != len(ty.fields): raise TypeError( "Wrong number of fields in struct, expected %d got %d" % (len(ty.fields), len(arg))) return claripy.Concat(*[ SimCC._standardize_value(sarg, sty, state, alloc) for sarg, sty in zip(arg, ty.fields.values()) ]) else: return claripy.Concat(*[ SimCC._standardize_value(sarg, None, state, alloc) for sarg in arg ]) elif isinstance(arg, (int, long)): if check and isinstance(ty, s_type.SimTypeFloat): return SimCC._standardize_value(float(arg), ty, state, alloc) val = state.se.BVV(arg, ty.size if check else state.arch.bits) if state.arch.memory_endness == 'Iend_LE': val = val.reversed return val elif isinstance(arg, float): sort = claripy.FSORT_FLOAT if check: if isinstance(ty, s_type.SimTypeDouble): sort = claripy.FSORT_DOUBLE elif isinstance(ty, s_type.SimTypeFloat): pass else: raise TypeError("Type mismatch: expectd %s, got float" % ty.name) else: sort = claripy.FSORT_DOUBLE if state.arch.bits == 64 else claripy.FSORT_FLOAT val = claripy.fpToIEEEBV(claripy.FPV(arg, sort)) if state.arch.memory_endness == 'Iend_LE': val = val.reversed # pylint: disable=no-member return val elif isinstance(arg, claripy.ast.Base): # yikes if state.arch.memory_endness == 'Iend_LE' and arg.length == state.arch.bits: arg = arg.reversed return arg else: raise TypeError("I don't know how to serialize %s." % repr(arg))
def _standardize_value(arg, ty, state, alloc): check = ty is not None if isinstance(arg, s_action_object.SimActionObject): return SimCC._standardize_value(arg.ast, ty, state, alloc) elif isinstance(arg, PointerWrapper): if check and not isinstance(ty, s_type.SimTypePointer): raise TypeError("Type mismatch: expected %s, got pointer-wrapper" % ty.name) real_value = SimCC._standardize_value(arg.value, ty.pts_to if check else None, state, alloc) return alloc(real_value, state) elif isinstance(arg, str): # TODO: when we switch to py3, distinguish between str and bytes # by null-terminating str but not bytes :/ arg += '\0' ref = False if check: if isinstance(ty, s_type.SimTypePointer) and \ isinstance(ty.pts_to, s_type.SimTypeChar): ref = True elif isinstance(ty, s_type.SimTypeFixedSizeArray) and \ isinstance(ty.elem_type, s_type.SimTypeChar): ref = False if len(arg) > ty.length: raise TypeError("String %s is too long for %s" % (repr(arg), ty.name)) arg = arg.ljust(ty.length, '\0') elif isinstance(ty, s_type.SimTypeArray) and \ isinstance(ty.elem_type, s_type.SimTypeChar): ref = True if ty.length is not None: if len(arg) > ty.length: raise TypeError("String %s is too long for %s" % (repr(arg), ty.name)) arg = arg.ljust(ty.length, '\0') elif isinstance(ty, s_type.SimTypeString): ref = False if len(arg) > ty.length + 1: raise TypeError("String %s is too long for %s" % (repr(arg), ty.name)) arg = arg.ljust(ty.length + 1, '\0') else: raise TypeError("Type mismatch: Expected %s, got char*" % ty.name) val = SimCC._standardize_value(map(ord, arg), s_type.SimTypeFixedSizeArray(s_type.SimTypeChar(), len(arg)), state, alloc) if ref: val = alloc(val, state) return val elif isinstance(arg, list): ref = False subty = None if check: if isinstance(ty, s_type.SimTypePointer): ref = True subty = ty.pts_to elif isinstance(ty, s_type.SimTypeFixedSizeArray): ref = False subty = ty.elem_type if len(arg) != ty.length: raise TypeError("Array %s is the wrong length for %s" % (repr(arg), ty.name)) elif isinstance(ty, s_type.SimTypeArray): ref = True subty = ty.elem_type if ty.length is not None: if len(arg) != ty.length: raise TypeError("Array %s is the wrong length for %s" % (repr(arg), ty.name)) else: raise TypeError("Type mismatch: Expected %s, got char*" % ty.name) else: types = map(type, arg) if types[1:] != types[:-1]: raise TypeError("All elements of list must be of same type") val = claripy.Concat(*[SimCC._standardize_value(sarg, subty, state, alloc) for sarg in arg]) if ref: val = alloc(val, state) return val elif isinstance(arg, tuple): if check: if not isinstance(ty, s_type.SimStruct): raise TypeError("Type mismatch: Expected %s, got tuple (i.e. struct)" % ty.name) if len(arg) != len(ty.fields): raise TypeError("Wrong number of fields in struct, expected %d got %d" % (len(ty.fields), len(arg))) return claripy.Concat(*[SimCC._standardize_value(sarg, sty, state, alloc) for sarg, sty in zip(arg, ty.fields.values())]) else: return claripy.Concat(*[SimCC._standardize_value(sarg, None, state, alloc) for sarg in arg]) elif isinstance(arg, (int, long)): if check and isinstance(ty, s_type.SimTypeFloat): return SimCC._standardize_value(float(arg), ty, state, alloc) val = state.se.BVV(arg, ty.size if check else state.arch.bits) if state.arch.memory_endness == 'Iend_LE': val = val.reversed return val elif isinstance(arg, float): sort = claripy.FSORT_FLOAT if check: if isinstance(ty, s_type.SimTypeDouble): sort = claripy.FSORT_DOUBLE elif isinstance(ty, s_type.SimTypeFloat): pass else: raise TypeError("Type mismatch: expectd %s, got float" % ty.name) else: sort = claripy.FSORT_DOUBLE if state.arch.bits == 64 else claripy.FSORT_FLOAT val = claripy.fpToIEEEBV(claripy.FPV(arg, sort)) if state.arch.memory_endness == 'Iend_LE': val = val.reversed # pylint: disable=no-member return val elif isinstance(arg, claripy.ast.Base): # yikes if state.arch.memory_endness == 'Iend_LE' and arg.length == state.arch.bits: arg = arg.reversed return arg else: raise TypeError("I don't know how to serialize %s." % repr(arg))