def createMain(self): #Main Function #Declaration z1 = c_ast.TypeDecl('args',[],c_ast.IdentifierType(['int'])) args = c_ast.Decl('args',[],[],[],z1,None,None) z2= c_ast.PtrDecl([],c_ast.TypeDecl('argv',[],c_ast.IdentifierType(['char']))) z3=c_ast.ArrayDecl(z2,None,[]) argv = c_ast.Decl('argv',[],[],[],z3,None,None) params=c_ast.ParamList([args,argv]) mainDec=c_ast.FuncDecl(params,c_ast.TypeDecl('main',[],c_ast.IdentifierType(['int']))) # insertTest(functionName,varVals,varTypes) #Body ##Signal sigalrm=c_ast.ID(name="14") funcCast=c_ast.TypeDecl(declname = None,quals=[],type=c_ast.IdentifierType(['void'])) paramCast=c_ast.ParamList([c_ast.Typename(name=None,quals=[],type=c_ast.TypeDecl(declname = None,quals=[],type=c_ast.IdentifierType(['int'])))]) typeFunc=c_ast.PtrDecl(type=c_ast.FuncDecl(paramCast,funcCast),quals=[]) kchild=c_ast.Cast(to_type=c_ast.Typename(name=None, quals=[],type=typeFunc),expr=c_ast.ID(name="kill_child")) expressList = [sigalrm,kchild] signalStmt=c_ast.FuncCall(c_ast.ID(name="signal"),c_ast.ExprList(expressList)) ##Return returnStmt=c_ast.Return(c_ast.Constant(type="int",value="0")) comp=c_ast.Compound([signalStmt,returnStmt]) return c_ast.FuncDef(mainDec,None,comp)
def pre_argument(self, name): commands = [] commands.append( _generate_decl( name + '_int', c_ast.TypeDecl(name + '_int', [], c_ast.IdentifierType(['unsigned', 'int'])))) commands.append(_generate_read(name + '_int')) commands.append( c_ast.Assignment('|=', c_ast.ID(name + '_int'), c_ast.Constant('int', PTR_OFFSET))) commands.append( c_ast.Decl( name, [], [], [], c_ast.PtrDecl( [], c_ast.TypeDecl(name, [], c_ast.IdentifierType(['void'])), ), c_ast.Cast( c_ast.Typename( None, [], c_ast.PtrDecl([], c_ast.TypeDecl( None, [], c_ast.IdentifierType(['void'])))), c_ast.ID(name + '_int')), [])) return commands
def MakePtrType(t): # add missing ones as needed if isinstance(t, c_ast.IdentifierType): return c_ast.PtrDecl([], c_ast.TypeDecl(None, [], t)) elif isinstance(t, c_ast.PtrDecl): return c_ast.PtrDecl([], t) elif isinstance(t, (c_ast.Struct, c_ast.Union)): return c_ast.PtrDecl([], t) elif isinstance(t, c_ast.FuncDecl): # we treat function and function pointers the same return c_ast.PtrDecl([], t) else: assert False, t
def MakePrintfStyleDecl(name: str, type_names: List[str], is_pointer=False): parameter_format = c_ast.Decl( "format", [], [], [], c_ast.PtrDecl([], MakeSimpleTypeDecl("format", ["char"])), None, None) parameter_value = c_ast.Decl("value", [], [], [], MakeSimpleTypeDecl("value", type_names), None, None) if is_pointer: parameter_value.type = c_ast.PtrDecl([], parameter_value.type) fun_result = MakeSimpleTypeDecl(name, ["int"]) return c_ast.Decl( name, [], [], [], c_ast.FuncDecl(c_ast.ParamList([parameter_format, parameter_value]), fun_result), None, None)
def make_mutator_decl_from_arg_type(arg_type, generator=CGenerator(), seen={}, point=True, change_name=False): # memoize if arg_type in seen: return seen[arg_type] mut_name = "fffc_mutator_for_target_type" # change the type declname if change_name: change_declname(arg_type, "storage") # first, wrap the type in a pointer to match the necessary mutator semantics if point: arg_type_ptr = c_ast.PtrDecl([], arg_type) else: arg_type_ptr = arg_type # next, wrap that in a decl with the right name arg_decl = c_ast.ParamList( [c_ast.Decl("storage", [], [], [], arg_type_ptr, None, None)]) # next, generate the desired decl ret_type = c_ast.IdentifierType(["int"]) ret_decl = c_ast.TypeDecl(mut_name, [], ret_type) desired_decl = c_ast.FuncDecl(arg_decl, ret_decl) # now build the mangled name desired_name = generator.visit(desired_decl) suffix = encode_hash(desired_name) actual_name = "_Z_fffc_mutator_" + suffix desired_decl.type.declname = actual_name # build the output out = c_ast.Decl(actual_name, [], [], [], desired_decl, None, None) # save the result seen[arg_type] = (desired_name, out) # and go home return desired_name, out
def create_mock_params(self): mock_params = [] for param, expanded_param in self.params: if is_char_pointer(expanded_param.type): mock_params.append(param) elif is_pointer_or_array(expanded_param.type): pass elif is_va_list(expanded_param.type): pass elif is_struct_or_union(expanded_param.type): pass else: mock_params.append(param) if not self.is_void(self.return_value_decl): mock_params.append(self.return_value_decl) if self.is_variadic_func: mock_params.append( decl( None, c_ast.PtrDecl([], c_ast.TypeDecl( 'vafmt_p', ['const'], c_ast.IdentifierType(['char']))))) mock_params.append(decl(None, c_ast.EllipsisParam())) return mock_params
def addPointer(node, val): #adds the pointer as per the value of val ori = node val = int(val) for i in xrange(val): ori.type = c_ast.PtrDecl([], None) ori = ori.type return ori
def check_value(ast_tree, ext_index, bock_item_index, var_name, func_name): Cast = c_ast.Cast( c_ast.Typename( None, [], c_ast.PtrDecl([], c_ast.TypeDecl(None, [], c_ast.IdentifierType(['void'])))), c_ast.ID(var_name)) func_call = c_ast.FuncCall( c_ast.ID('check_value'), c_ast.ExprList([ c_ast.UnaryOp('&', c_ast.ID('global_log')), Cast, c_ast.Constant('string', '"' + var_name + '"'), c_ast.Constant('string', '"' + func_name + '"'), c_ast.Constant('int', str(len(var_name))), c_ast.Constant('int', str(len(func_name))) ])) new_node = c_ast.If( c_ast.BinaryOp('==', func_call, c_ast.Constant('int', '0')), c_ast.Compound([ c_ast.FuncCall( c_ast.ID('printf'), c_ast.ExprList([ c_ast.Constant('string', '"%s\\n"'), c_ast.Constant('string', '"Attack Detected"') ])), c_ast.FuncCall(c_ast.ID('exit'), c_ast.ExprList([c_ast.Constant('int', '1')])) ]), None) return merge_ast_tree(ast_tree, ext_index, bock_item_index, new_node, "insert_before")
def define_sizeof_modifier_type(t): # setup the toplevel call if t.get_typename(): argument_ast = t.get_reference()("storage") else: argument_ast = t.define("storage") prefix = "fffc_get_sizeof_" desired_name = CGenerator().visit(argument_ast) suffix = encode_hash(desired_name) function_name = prefix + suffix # build the underlying function call underlying_call = get_sizeof_pointer_to_type(t.underlying_type, c_ast.ID("storage")) # build this just as above, except with the call in place of the sizeof storage_tdecl = c_ast.Decl("storage", [], [], [], c_ast.PtrDecl([], argument_ast), None, None) func_tdecl = c_ast.TypeDecl( function_name, [], c_ast.IdentifierType(["long", "long", "unsigned"])) funcdecl = c_ast.FuncDecl(c_ast.ParamList([storage_tdecl]), func_tdecl) funcdef = c_ast.FuncDef( c_ast.Decl(function_name, [], [], [], funcdecl, None, None), None, c_ast.Compound([c_ast.Return(underlying_call)]), ) comment = "/* " + desired_name + "*/\n" kr_funcdecl = c_ast.FuncDecl(c_ast.ParamList([]), func_tdecl) return comment, kr_funcdecl, funcdef
def rename_array_args(funcdef): """ Rename and copy arrays passed as arguments to funcdef. """ # For each argument for param in funcdef.decl.type.args.params: if isinstance(param.type, c_ast.ArrayDecl): # Rename and copy array arg_decl = copy.deepcopy(param) # Rename array v = inline.RenameVisitor() v.new_visit(get_decl_name(param), get_decl_name(param) + "_rename", funcdef.body) # Add copy and declarations funcdef.body.block_items = rename_array_decl( arg_decl) + funcdef.body.block_items elif isinstance(param.type, c_ast.TypeDecl): # Simple variable passing, don't need to handle pass elif isinstance(param.type, c_ast.PtrDecl): # Don't copy pointer arguments return """ Param of form: type *var is copied in the function body using: type var_rename _temp = *var; type *var_rename = &var_rename_temp; """ # General pointer arguments old_name = get_decl_name(param) new_name = old_name + "_rename" temp_name = new_name + "_temp" # Rename variable use in function body v = inline.RenameVisitor() v.new_visit(old_name, new_name, funcdef.body) # type var_rename_temp = *var; decl1 = c_ast.Decl( temp_name, None, None, None, c_ast.TypeDecl(temp_name, None, param.type.type.type), c_ast.UnaryOp('*', c_ast.ID(old_name)), None) # type *var_rename = &var_rename_temp; decl2 = c_ast.Decl( new_name, None, None, None, c_ast.PtrDecl([], c_ast.TypeDecl(new_name, None, param.type.type.type)), c_ast.UnaryOp('&', c_ast.ID(temp_name)), None) # Insert into function body funcdef.body.block_items.insert(0, decl2) funcdef.body.block_items.insert(0, decl1) else: print_node(param) param.show(nodenames=True, showcoord=True) raise Exception( "Unhandled argument type %s. Implement or verify that it can be ignored." % (type(param.type)))
def make_func_ptr(func, with_name=True): """Create a node of pointer-to-function type.""" if not with_name: node = rename_func(func, None) else: node = copy.deepcopy(func) node.type = c_ast.PtrDecl(quals=[], type=node.type) return node
def createDecl(api): apitype = 'sai_' + api + '_api_t' apivar = 'sai_' + api + '_api_tbl' return c_ast.Decl( apivar, list(), list(), list(), c_ast.PtrDecl( list(), c_ast.TypeDecl(apivar, list(), c_ast.IdentifierType([ apitype, ]))), None, None)
def replace_target_decl(self): raw = self.template_data placeholder = b"___FFFC_TARGET_DECL___" # Now you need to declare a pointer to the function whose name is FFFC_replacement funcref = self.func.declare("FFFC_target") funcptr = c_ast.PtrDecl([], funcref) ast = c_ast.Decl("FFFC_target", [], [], [], funcptr, None, None) replacement = self.generator.visit(ast) + ";" raw = raw.replace(placeholder, bytes(replacement, "utf-8")) self.template_data = raw
def declare_func(self, func): # e.g. "HPy (*ctx_Module_Create)(HPyContext *ctx, HPyModuleDef *def)" # # turn the function declaration into a function POINTER declaration newnode = deepcopy(func.node) newnode.type = c_ast.PtrDecl(type=newnode.type, quals=[]) # fix the name of the function pointer typedecl = find_typedecl(newnode) typedecl.declname = func.ctx_name() return toC(newnode)
def state_function(self, name, parameters): return function_ptr_decl( name, node.PtrDecl( [], node.TypeDecl(name, ["const"], node.IdentifierType([self.state_type])), ), parameters, )
def visit_Return(self, node): if node.expr is not None: decl = c_ast.Assignment('=', c_ast.ID('return_of_the_jedi'), node.expr) self.insert_node_before(decl) node.expr = None if hasattr(self._currentFunc.decl, 'poroto_type'): return_type = self._currentFunc.decl.poroto_type.dereference() reference_type = c_ast.PtrDecl([], return_type.user_type_tree) reference_type.type.poroto_type = return_type poroto_type = types.PointerDescriptor(reference_type, None, None) decl.lvalue.poroto_type = poroto_type
def assign_results(outargs, code): ptroutargs = [deepcopy(arg) for arg in outargs] rename = RenameVisitor("out") for arg in ptroutargs: rename.visit(arg) arg.type = c_ast.PtrDecl([], arg.type) arg.init = None for ptr, var in zip(ptroutargs, outargs): code.append( c_ast.Assignment('=', c_ast.UnaryOp('*', c_ast.ID(ptr.name)), c_ast.ID(var.name)))
def replace_placeholder_type(self, dwarf_type): for node in self.get_nodes(self.ast): try: if self.placeholder_type_name in node.type.type.names: if dwarf_type.get_typename(): replacement = dwarf_type.get_reference()( node.type.declname) else: replacement = dwarf_type.define(node.type.declname) replacement_pointer = c_ast.PtrDecl([], replacement) node.type = replacement if type(node) == c_ast.Typename: if self.placeholder_type_name in node.type.type.names: if dwarf_type.get_typename(): replacement = dwarf_type.get_reference()() else: replacement = dwarf_type.define() replacement_pointer = c_ast.PtrDecl([], replacement) node.type = replacement except AttributeError as ex: continue
def addPointer(node, val): #adds the pointer as per the value of val #print 'hello' ori = node #sub = node.type val = int(val) for i in xrange(val): ori.type = c_ast.PtrDecl([], None) ori = ori.type #print(ori) #node.show() #assert False return ori
def _build_nondet_type_decl(self, var_name, var_type): if type(var_type) is a.IdentifierType: return var_type elif type(var_type) is a.TypeDecl: return a.TypeDecl( var_name, list(), self._build_nondet_type_decl(var_name, var_type.type)) elif type(var_type) is a.PtrDecl: return a.PtrDecl([], self._build_nondet_type_decl( var_name, var_type.type)) else: raise AssertionError("Unhandled type: " + str(type(var_type)))
def replace_funcs(self, dwarf_type): decls = [] defns = "" # build the decl and defn for node in self.get_nodes(self.ast): if type(node) == c_ast.FuncDef: argtype = node.decl.type.args.params[0].type for i in range(self.pointer_depth): node_copy = copy.deepcopy(node) node_copy.decl.type.args.params[0].type = argtype decl, defn = make_commented_mutator_defn(node_copy) decls.append(decl) defns += defn argtype = c_ast.PtrDecl([], argtype) return decls, defns
def createTest(block,functionName,varVals,varTypes): #Main Function #Declaration z1 = c_ast.TypeDecl('args',[],c_ast.IdentifierType(['int'])) args = c_ast.Decl('args',[],[],[],z1,None,None) z2= c_ast.PtrDecl([],c_ast.TypeDecl('argv',[],c_ast.IdentifierType(['char']))) z3=c_ast.ArrayDecl(z2,None,[]) argv = c_ast.Decl('argv',[],[],[],z3,None,None) params=c_ast.ParamList([args,argv]) mainDec=c_ast.FuncDecl(params,c_ast.TypeDecl('main',[],c_ast.IdentifierType(['int']))) insertTest(functionName,varVals,varTypes) #Body returnStmt=c_ast.Return(c_ast.Constant(type="int",value="0")) comp=c_ast.Compound([returnStmt]) main= c_ast.FuncDef(mainDec,None,comp) insertTest(main,"func",['1','2'],['int','int'])
def visit_Decl(self, node): if not isinstance(node.type, c_ast.FuncDecl): return func_decl = node.type set_extra_attr(node, 'orig_decl', deepcopy(node.type)) for arg in func_decl.args.params: if isinstance(arg.type, c_ast.ArrayDecl): depth = 0 inner_type = arg.type while isinstance(inner_type, c_ast.ArrayDecl): depth += 1 inner_type = inner_type.type new_type=inner_type while depth > 0: new_type=c_ast.PtrDecl([], new_type, arg.type.coord) depth -= 1 arg.type=new_type
def visit_FileAST(self, node): for i, item in enumerate(node.ext): if type(item) is not c_ast.Decl or type(item.type) is not c_ast.ArrayDecl: continue type_decl = item.type while type(type_decl) is c_ast.ArrayDecl: type_decl = type_decl.type dim = self.dims[type_decl.declname] decl_node = type_decl for _ in range(dim): decl_node = c_ast.PtrDecl([], decl_node) node.ext[i].type = decl_node
def __str__(self) -> str: type = self.get_representative() size = type.size or 32 sign = "s" if type.sign & Type.SIGNED else "u" if type.kind == Type.K_ANY: if type.size is not None: return f"?{size}" return "?" if type.kind == Type.K_PTR: if type.ptr_to is not None: if isinstance(type.ptr_to, Type): return (str(type.ptr_to) + " *").replace("* *", "**") return type_to_string(ca.PtrDecl([], type.ptr_to)) return "void *" if type.kind == Type.K_FLOAT: return f"f{size}" return f"{sign}{size}"
def ctx_decl(self): # e.g. "HPy (*ctx_Module_Create)(HPyContext ctx, HPyModuleDef *def)" # # turn the function declaration into a function POINTER declaration newnode = deepcopy(self.node) newnode.type = c_ast.PtrDecl(type=newnode.type, quals=[]) # fix the name of the function pointer typedecl = self._find_typedecl(newnode) # replace an ellipsis with a 'va_list _vl' argument if self.is_varargs(): arg = c_ast.Decl('_vl', [], [], [], c_ast.TypeDecl('_vl', [], c_ast.IdentifierType(['va_list'])), None, None) newnode.type.type.args.params[-1] = arg # typedecl.declname = self.ctx_name() return toC(newnode)
def make_internal_fn_decl(name): '''str -> c_ast''' # don't you wish python had a macro system? return c_ast.Decl( name, [], [], [], c_ast.FuncDecl( c_ast.ParamList([ c_ast.Decl( utils.args_tag, [], [], [], c_ast.PtrDecl([], c_ast.TypeDecl( utils.args_tag, [], c_ast.IdentifierType([ '%s%s' % (utils.decomp_tag, utils.args_tag) ]))), None, None) ]), c_ast.TypeDecl(name, [], c_ast.IdentifierType(['void']))), None, None)
def create_svcomp_function_declaration(self, name: str): """ Creates a declaration for the given SV comp function name, e.g. "__VERIFIER_nondet_int". :param name: The SV comp function name. :return: c_ast.Decl """ return_type = self.get_c_type(name.replace("__VERIFIER_nondet_", "")) # Need to handle pointers separately. if "*" in return_type: return_type.remove("*") return_code = c_ast.PtrDecl( [], c_ast.TypeDecl(name, [], c_ast.IdentifierType(list(return_type)))) else: return_code = c_ast.TypeDecl(name, [], c_ast.IdentifierType(return_type)) return c_ast.Decl(name, [], ["extern"], [], c_ast.FuncDecl(None, return_code), None, None)
def visit_ParamList(self, node): for i, p in enumerate(node.params): if self._instrument[i][0]: p.storage.append(self._instrument[i][0]) if self._instrument[i][1]: p.type.quals.append(self._instrument[i][1]) self.visit(p) for cst in self._constants: if cst._is_scalar: t = c_ast.TypeDecl(cst._name, [], c_ast.IdentifierType([cst._cl_type])) else: t = c_ast.PtrDecl( [], c_ast.TypeDecl(cst._name, ["__constant"], c_ast.IdentifierType([cst._cl_type]))) decl = c_ast.Decl(cst._name, [], [], [], t, None, 0) node.params.append(decl)
def fndecl(name, inargs, outargs, code): ptroutargs = [deepcopy(arg) for arg in outargs] rename = RenameVisitor("out") for arg in ptroutargs: rename.visit(arg) arg.type = c_ast.PtrDecl([], arg.type) arg.init = None fdecl = c_ast.FuncDecl( c_ast.ParamList(inargs + ptroutargs), c_ast.TypeDecl(name, [], c_ast.IdentifierType(['void']))) decl = c_ast.Decl(name, [], [], [], fdecl, None, None) assign = [] for ptr, var in zip(ptroutargs, outargs): assign.append( c_ast.Assignment('=', c_ast.UnaryOp('*', c_ast.ID(ptr.name)), c_ast.ID(var.name))) comp = c_ast.Compound(code + assign) return c_ast.FuncDef(decl, None, comp)