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 _build_handle_function(functions): """ Wraps the switch statement in a function definition """ case_statement = _build_case(functions) available_check = c_ast.If( c_ast.BinaryOp( '<', c_ast.FuncCall( c_ast.ID('mailbox_available'), c_ast.ExprList([c_ast.Constant('int', '2')]) ), c_ast.Constant('int', '4') ), c_ast.Return(None), None ) handle_decl = c_ast.FuncDecl( None, c_ast.TypeDecl('_handle_events', [], c_ast.IdentifierType(['void'])), ) command_decl = c_ast.Decl('command', [], [], [], c_ast.TypeDecl('command', [], c_ast.IdentifierType(['int'])), [], []) command_read = _generate_read('command') body = c_ast.Compound([available_check, command_decl, command_read, case_statement]) return c_ast.FuncDef(handle_decl, [], body)
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 visit_FuncDef(self, node): # Skip if no loop counters exist if self.loop_counter_size == 0: return # Create loop_counter declaration/initialization constants = [c_ast.Constant("int", '0') for i in range(self.loop_counter_size)] init_list = c_ast.InitList(constants) identifier_type = c_ast.IdentifierType(["int"]) type_decl = c_ast.TypeDecl("loop_counter", [], identifier_type) dim = c_ast.Constant("int", str(self.loop_counter_size)) array_decl = c_ast.ArrayDecl(type_decl, dim, []) decl = c_ast.Decl("loop_counter", [], [], [], array_decl, init_list, None) node.body.block_items.insert(0, decl) # Label for return values to goto start_label = c_ast.Label("print_loop_counter", c_ast.EmptyStatement()) # Start and end labels used for inserting preprocessor commands for #if DEBUG_EN end_label = c_ast.Label("print_loop_counter_end", c_ast.EmptyStatement()) # Write to file if self.write_to_file: stmt = c_ast.ID("write_array(loop_counter, %d)\n" % (self.loop_counter_size)) compound = c_ast.Compound([start_label, stmt, end_label]) # Print to stdout else: # Add printf to the end of function # Start of printing stmt_start = c_ast.ID("printf(\"loop counter = (\")") # For loop # int i; identifier_type = c_ast.IdentifierType(["int"]) type_decl = c_ast.TypeDecl("i", [], identifier_type) for_decl = c_ast.Decl("i", [], [], [], type_decl, [], None) # i = 0 init = c_ast.Assignment("=", c_ast.ID("i"), c_ast.Constant("int", '0')) # i < self.loop_counter_size cond = c_ast.BinaryOp("<", c_ast.ID("i"), c_ast.Constant("int", str(self.loop_counter_size))) # i++ next_stmt = c_ast.UnaryOp("p++", c_ast.ID("i")) # printf in for stmt = c_ast.ID("printf(\"%d, \", loop_counter[i])") # Cosntruct for loop stmt_for = c_ast.For(init, cond, next_stmt, stmt) # End of printing stmt_end = c_ast.ID("printf(\")\\n\")") # Put it all together body = c_ast.Compound([stmt_start, for_decl, stmt_for, stmt_end]) # Surround with labels compound = c_ast.Compound([start_label, body, end_label]) node.body.block_items.append(compound)
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 nested_for_loop(node, inner_loop_body, loop_iterator_base, rename_index=0): """ Recursively create nested for loops for copying a multi-dimensional array. """ if isinstance(node.type.type, c_ast.ArrayDecl): # Multi-dimensional array, recurse to generate inner loop for_loop_body = nested_for_loop(node.type, inner_loop_body, loop_iterator_base, rename_index + 1) else: # Single or last dimension of array for_loop_body = [inner_loop_body] # Declare iterator loop_iterator = c_ast.ID("%s_i%d" % (loop_iterator_base, rename_index)) loop_iterator_decl = c_ast.Decl( loop_iterator.name, [], [], [], c_ast.TypeDecl(loop_iterator.name, [], c_ast.IdentifierType(["int"])), None, None) # For loop array_size = node.type.dim for_loop = c_ast.For( c_ast.Assignment('=', loop_iterator, c_ast.Constant("int", "0")), c_ast.BinaryOp('<', loop_iterator, array_size), c_ast.UnaryOp('p++', loop_iterator), c_ast.Compound(for_loop_body)) return [loop_iterator_decl, for_loop]
def __for_loop(self, depth: int) -> c_ast.For: """ A helper function to construct a for loop corresponding to allocating one dimension of an array. Recursively calls itself to generate next levels or generates an initialisation line if it is the last level. Example: for(i_2 = 0; i_2 < N; i_2++) { ... } :param depth: :return: C-ast.For """ i = self.counter_prefix + str(depth) init = c_ast.DeclList([ c_ast.Decl(c_ast.ID(i), [], [], [], c_ast.TypeDecl(i, [], c_ast.IdentifierType(['int'])), c_ast.Constant('int', '0'), '') ]) cond = c_ast.BinaryOp('<', c_ast.ID(i), self.sizes[depth]) nxt = c_ast.Assignment('++', c_ast.ID(i), None) stmt = c_ast.Compound([]) if depth < len(self.sizes) - 1: stmt.block_items = [ self.__malloc_assign(depth + 1), self.__for_loop(depth + 1) ] else: stmt.block_items = [self.initialiser(depth + 1)] return c_ast.For(init, cond, nxt, stmt)
def push_literal(lookup, stack, code, lit): name = gensym() const = c_ast.Constant(lit.type, lit.value) tdecl = c_ast.TypeDecl(name, [], c_ast.IdentifierType([lit.type])) decl = c_ast.Decl(name, [], [], [], tdecl, const, None) code.append(decl) stack.setdefault(lit.type, []).append(decl)
def _generate_decl(name, decl): """ Generates a new declaration with a difference name but same type as the provided decl. """ typedecl = c_ast.TypeDecl(name, [], decl.type) return c_ast.Decl(name, [], [], [], typedecl, [], [])
def visit_Decl(self, node): if not isinstance(node.type, c_ast.FuncDecl): return func_decl = node.type if not isinstance(func_decl.type, c_ast.TypeDecl) or not isinstance(func_decl.type.type, c_ast.IdentifierType) or func_decl.type.type.names != ['void']: self.functions[node.name] = node return_type=func_decl.type #node.return_type = return_type set_extra_attr(node, 'return_type', func_decl.type) #update declname it=return_type while it is not None: if isinstance(it, c_ast.TypeDecl): it.declname = 'return_of_the_jedi' it = None else: if hasattr(it, 'type'): it = it.type else: it = None func_decl.type = c_ast.TypeDecl(node.name, [], c_ast.IdentifierType(['void'])) result_type=deepcopy(return_type) result_type.type.names += '&' decl = create_simple_var(result_type, 'return_of_the_jedi', None) if func_decl.args is None: func_decl.args = c_ast.ParamList([]) #Handle the int f(void) case if len(func_decl.args.params) == 1 \ and isinstance(func_decl.args.params[0], c_ast.Typename) \ and isinstance(func_decl.args.params[0].type.type, c_ast.IdentifierType) \ and func_decl.args.params[0].type.type.names[0] == 'void': func_decl.args.params.pop() func_decl.args.params.append(decl)
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 astVeriNon(): veryidt = c_ast.IdentifierType(['int']) verytype = c_ast.TypeDecl('rand', [], veryidt) bifunc = c_ast.FuncCall(c_ast.ID('__VERIFIER_nondet'), None) verybina = c_ast.BinaryOp('%', bifunc, c_ast.ID('N')) simdecl = c_ast.Decl('rand', [], [], [], verytype, verybina, None, None) return simdecl
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 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 make_klee_symbolic(variable_name, trackingName): arg1 = c_ast.UnaryOp(op='&', expr=c_ast.ID(variable_name)) arg2 = c_ast.UnaryOp(op='sizeof', expr = c_ast.Typename(name=None, quals =[], type= c_ast.TypeDecl(declname=None,quals=[], type=c_ast.IdentifierType(names=['int'])))) arg3 = c_ast.Constant(type='string', value='\"'+ trackingName +'\"') return c_ast.FuncCall(name=c_ast.ID(name = "klee_make_symbolic"), args=c_ast.ExprList(exprs=[arg1,arg2,arg3]))
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 out_copy_member(name, param_dst, param_src): name = f'{name}_out_copy' return function_ptr_decl(name, void_type(name), [ param_dst, param_src, decl('size', c_ast.TypeDecl('size', [], c_ast.IdentifierType(['size_t']))) ])
def _generate_arraydecl(name, decl, length): """ Generates a new declaration with an array type base on an existing declaration """ typedecl = c_ast.TypeDecl(name, [], decl.type) arraydecl = c_ast.ArrayDecl(typedecl, length, []) return c_ast.Decl(name, [], [], [], arraydecl, [], [])
def in_assert_member(name, param_actual, param_expected): name = f'{name}_in_assert' return function_ptr_decl(name, void_type(name), [ param_actual, param_expected, decl('size', c_ast.TypeDecl('size', [], c_ast.IdentifierType(['size_t']))) ])
def do_create_simple_var(c_type, name, init=None): if isinstance(name, c_ast.ID): name = name.name if isinstance(c_type, c_ast.TypeDecl): c_type = deepcopy(c_type) c_type.declname = name elif isinstance(c_type, c_ast.PtrDecl): c_type = deepcopy(c_type) c_type.type.declname = name elif isinstance(c_type, c_ast.ArrayDecl): c_type = deepcopy(c_type) c_type.type.declname = name elif isinstance(c_type, str): c_type = c_ast.TypeDecl(name, [], c_ast.IdentifierType([c_type])) else: c_type = c_ast.TypeDecl(name, [], c_type) return c_ast.Decl(name, [], [], [], c_type, init, None)
def offsetof(self, struct_name, name): return c_ast.FuncCall( c_ast.ID('offsetof'), c_ast.ExprList([ c_ast.Typename( None, [], c_ast.TypeDecl(None, [], c_ast.Struct(struct_name, None))), c_ast.ID(name) ]))
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 new_ivar(self, name, init, c_type, parent=None): var_type = c_ast.IdentifierType([c_type]) decl_type = c_ast.TypeDecl(name, [], var_type) var = c_ast.Decl(name, [], [], [], decl_type, init, None) var.parent = parent var_type.parent = var decl_type.parent = var init.parent = var return var
def visit_FuncDef(self, node): label = c_ast.Label("predict_exec_time", c_ast.EmptyStatement()) decl = c_ast.Decl("exec_time", None, None, None, c_ast.TypeDecl("exec_time", None, c_ast.IdentifierType(["float"])), None, None) assignment = c_ast.Assignment('=', c_ast.ID("exec_time"), c_ast.Constant("int", 0)) ret = c_ast.Return(c_ast.ID("exec_time")) compound = c_ast.Compound([label, decl, assignment, ret]) node.body.block_items.append(compound)
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 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 state_function(self, name, parameters): return function_ptr_decl( name, node.PtrDecl( [], node.TypeDecl(name, ["const"], node.IdentifierType([self.state_type])), ), parameters, )
def global_log(ast_tree): global_log = c_ast.Decl( 'global_log', [], [], [], c_ast.TypeDecl('global_log', [], c_ast.Struct('Global_Log', None)), None, None) temp_ls1 = [] temp_ls1.append(global_log) temp_ls2 = [] temp_ls2 = copy.deepcopy(ast_tree.ext) global_log = c_ast.FileAST(temp_ls1 + temp_ls2) return global_log