def insertTest(self,block,functionName,varVals,varTypes,timer): #Fork call cFork=c_ast.Assignment( lvalue=c_ast.ID(name='child_pid'), op='=', rvalue=c_ast.FuncCall( c_ast.ID(name='fork'), args=None)) #Child if self.functype=='int' or self.functype=="bool": printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"') elif self.functype=='float' or self.functype=='double': printLeft=c_ast.Constant(type="char",value='"'+"%f" +'"') else: printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"') expressList = list(c_ast.Constant(type=varTypes[i],value=str(varVals[i])) for i in range(len(varVals))) funcCall = c_ast.FuncCall(c_ast.ID(name=functionName),c_ast.ExprList(expressList)) expressList = [printLeft,funcCall] funcCall = c_ast.FuncCall(c_ast.ID(name="printf"),c_ast.ExprList(expressList)) funcCall2 = c_ast.FuncCall(c_ast.ID(name="exit"),c_ast.ExprList([c_ast.Constant(type='int',value='0')])) #Parent cAlarm=c_ast.FuncCall( c_ast.ID(name='alarm'),c_ast.ExprList([c_ast.Constant(type='int',value=str(timer))])) cWait=c_ast.FuncCall( c_ast.ID(name='wait'),c_ast.ExprList([c_ast.ID(name='0')])) #IFs if_false= c_ast.If( c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),op='==',right= c_ast.Constant(type='int',value='0')), c_ast.Compound([funcCall,funcCall2]),iffalse=None) if_ini=c_ast.If( c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),op='>',right= c_ast.Constant(type='int',value='0')), c_ast.Compound([cAlarm,cWait]),iffalse=if_false) block.body.block_items.insert(1,if_ini) block.body.block_items.insert(1,cFork)
def visit_Return(self, node): align, _ = _DistanceGenerator(self._types).visit(node.expr) if align != '0': raise ReturnDistanceNotZero(node.coord, _code_generator.visit(node.expr), align) # insert assert(__SHADOWDP_v_epsilon <= epsilon); epsilon, *_ = self._parameters if self._set_epsilon and self._set_epsilon.isdigit(): epsilon_node = c_ast.Constant(type='float', value=self._set_epsilon) elif self._set_epsilon and not self._set_epsilon.isdigit(): epsilon_node = c_ast.ID(name=self._set_epsilon) else: epsilon_node = c_ast.ID(epsilon) if self._set_goal: assert_node = c_ast.FuncCall( c_ast.ID(self._func_map['assert']), args=c_ast.ExprList( [c_ast.BinaryOp('<=', c_ast.ID(name='__SHADOWDP_v_epsilon'), c_ast.BinaryOp(op='*', left=epsilon_node, right=convert_to_ast(self._set_goal)))])) else: assert_node = c_ast.FuncCall(c_ast.ID(self._func_map['assert']), args=c_ast.ExprList([c_ast.BinaryOp('<=', c_ast.ID('__SHADOWDP_v_epsilon'), epsilon_node)])) self._parents[node].block_items.insert(self._parents[node].block_items.index(node), assert_node) self._inserted.add(assert_node) # because we have inserted a statement before Return statement while iterating, it will be a forever loop # add the current node to the set to not visit this same node again self._inserted.add(node)
def __malloc(self, depth: int) -> c_ast.FuncCall: """ A helper function to generate the call of malloc function with proper arguments. Note that a constant of 2 is added to the number of allocated cells. This is meant to compensate minor errors in size estimation. Example: malloc((N + 2) * sizeof(int*)) :param depth: Which dimension of the array we want to allocate. Used to generate the argument of sizeof(). :return: c_ast.FuncCall """ size_expr = \ c_ast.BinaryOp( '+', self.sizes[depth], c_ast.Constant('int', '2') ) sizeof = \ c_ast.FuncCall( c_ast.ID('sizeof'), c_ast.ExprList([c_ast.ID(self.dtype.name + '*' * (len(self.sizes) - depth - 1))]) ) arg = c_ast.BinaryOp('*', size_expr, sizeof) return c_ast.FuncCall(c_ast.ID('malloc'), c_ast.ExprList([arg]))
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 p_postfix_expression_gnu_bioo(self, p): """ primary_expression : __BUILTIN_OFFSETOF \ LPAREN type_name COMMA offsetof_member_designator RPAREN """ coord = self._coord(p.lineno(1)) p[0] = c_ast.FuncCall(c_ast.ID(p[1], coord), c_ast.ExprList([p[3], p[5]], coord), coord)
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 _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 add_to_expression(self, expression: c_ast.Node, operator: str, addition: c_ast.ExprList = None): """ Adds the additional expression to the given expression, concatenated with the given operator. If the additional expression is None, the operator is assumed to be unary. :param expression: The expression to add to. :param operator: An operator on expression, e.g. "&&" or "!". :param addition: The expression to add. :return: The merged expression. :rtype: c_ast.ExprList """ expressions = [] if type(expression) is c_ast.ExprList: for expr in expression.exprs: if addition is None: expressions.append( c_ast.UnaryOp(operator, copy.deepcopy(expr))) else: expressions.append( c_ast.BinaryOp(operator, copy.deepcopy(expr), addition)) else: if addition is None: expressions.append( c_ast.UnaryOp(operator, copy.deepcopy(expression))) else: expressions.append( c_ast.BinaryOp(operator, copy.deepcopy(expression), addition)) return c_ast.ExprList(expressions)
def __init__(self, linenum): self.linenum = linenum self.path = [] self.reached = False expressList = [c_ast.Constant(type='int', value='0')] self.funcCall = c_ast.FuncCall(c_ast.ID(name="assert"), c_ast.ExprList(expressList))
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 insertTest(self, block, functionName, varVals, varTypes): expressList = list( c_ast.Constant(type=varTypes[i], value=str(varVals[i])) for i in range(len(varVals))) funcCall = c_ast.FuncCall(c_ast.ID(name=functionName), c_ast.ExprList(expressList)) block.body.block_items.insert(0, funcCall)
def work(self, new_stuffs): for parent, child in self.target_location: if isinstance(child, c_ast.Return): new_stuffs_copy = new_stuffs[:-1] + [ c_ast.FuncCall( name=c_ast.ID(name="_RETTYPE"), args=c_ast.ExprList(exprs=[ child.expr, c_ast.Constant(type='int', value=str(len(new_stuffs) - 1)) ])) ] + new_stuffs[-1:] else: new_stuffs_copy = new_stuffs if isinstance(parent, c_ast.Compound): child_loc = parent.block_items.index(child) parent.block_items = parent.block_items[: child_loc] + new_stuffs_copy + parent.block_items[ child_loc + 1:] elif isinstance(parent, c_ast.If): if parent.iftrue == child: parent.iftrue = c_ast.Compound(block_items=new_stuffs_copy) elif parent.iffalse == child: parent.iffalse = c_ast.Compound( block_items=new_stuffs_copy) elif isinstance(parent, c_ast.While): parent.stmt = c_ast.Compound(block_items=new_stuffs_copy) elif isinstance(parent, c_ast.For): parent.stmt = c_ast.Compound(block_items=new_stuffs_copy) elif isinstance(parent, c_ast.DoWhile): parent.stmt = c_ast.Compound(block_items=new_stuffs_copy) elif isinstance(parent, c_ast.Label): parent.stmt = c_ast.Compound(block_items=new_stuffs_copy)
def visit_Assignment(self, node): if isinstance(node.rvalue, c_ast.ArrayRef) and self.get_array_name( node.rvalue) + '_get' in self.registry.function_templates: if self.debug: print "Converting array reference %s" % self.get_array_name( node.rvalue) self.remove_node('Compound') decl = c_ast.FuncCall( c_ast.ID(self.get_array_name(node.rvalue) + '_get'), c_ast.ExprList([node.rvalue.subscript, node.lvalue])) self.insert_node_after(decl, 'Compound') elif isinstance(node.rvalue, c_ast.ArrayRef) and self.get_array_name( node.rvalue) in self.registry.function_templates: if self.debug: print "Converting array reference %s" % self.get_array_name( node.rvalue) self.remove_node('Compound') decl = c_ast.FuncCall( c_ast.ID(self.get_array_name(node.rvalue)), c_ast.ExprList([node.rvalue.subscript, node.lvalue])) self.insert_node_after(decl, 'Compound') elif isinstance(node.lvalue, c_ast.ArrayRef) and self.get_array_name( node.lvalue) + '_set' in self.registry.function_templates: if self.debug: print "Converting array assignment %s" % self.get_array_name( node.lvalue) self.remove_node('Compound') template = self.registry.function_templates[ self.get_array_name(node.lvalue) + '_set'] dummy_name = 'dummy_%d' % self.id self.id += 1 decl = c_ast.Decl( '', [], [], [], c_ast.TypeDecl( dummy_name, [], c_ast.IdentifierType(template.array_type.split())), None, None) self.insert_node_after(decl, 'Compound') decl = c_ast.FuncCall( c_ast.ID(self.get_array_name(node.lvalue) + '_set'), c_ast.ExprList([ node.lvalue.subscript, c_ast.Constant('int', '1'), node.rvalue, c_ast.ID(dummy_name) ])) self.insert_node_after(decl, 'Compound')
def astDequeue(queue): #the type of exprs is String exdeq = [c_ast.ID(queue)] exprs = c_ast.ExprList(exdeq) dequeue = c_ast.FuncCall(c_ast.ID('Dequeue'), exprs) # astseq.ext[167].body.block_items[2].args.exprs[0] = c_ast.ID(queue) # dequeue=astseq.ext[167].body.block_items[2] # print ("\033[1;5;32;45;1mFuncCall Dequeue\033[0m") # dequeue.show() return dequeue
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 makeScopeOutLog(coord): (file, line) = getLocation(coord) return c_ast.FuncCall( c_ast.ID('fprintf'), c_ast.ExprList([ c_ast.ID('stderr'), c_ast.Constant('string', '"{0}:{1}:scope_out\\n"'.format(file, line)) ]))
def new_fcall(fname, args): fname = c_ast.ID(fname) args_list = [] for arg in args: if isinstance(arg, str): args_list.append(c_ast.ID(arg)) else: args_list.append(arg) args = c_ast.ExprList(args_list) return c_ast.FuncCall(fname, args)
def astEnqueue(elemtype, queue): #the type of exprs is String exenq = [c_ast.Constant('int', elemtype), c_ast.ID(queue)] exprs = c_ast.ExprList(exenq) enqueue = c_ast.FuncCall(c_ast.ID('Enqueue'), exprs) # astseq.ext[166].body.block_items[5].args.exprs[0] = c_ast.Constant('int', elemtype) # astseq.ext[166].body.block_items[5].args.exprs[1] = c_ast.ID(queue) # enqueue=astseq.ext[166].body.block_items[5] # print ("\033[1;5;32;45;1mFuncCall Enqueue\033[0m") # enqueue.show() return enqueue
def set_outdated(ast_tree, ext_index, bock_item_index, func_name): new_node = c_ast.FuncCall( c_ast.ID('set_outdated'), c_ast.ExprList([ c_ast.UnaryOp('&', c_ast.ID('global_log')), c_ast.Constant('string', '"' + func_name + '"'), c_ast.Constant('int', str(len(func_name))) ])) return merge_ast_tree(ast_tree, ext_index, bock_item_index, new_node, "insert_before")
def makeFuncCallLog(func): return c_ast.FuncCall( c_ast.ID('fprintf'), c_ast.ExprList([ c_ast.ID('stderr'), c_ast.Constant( 'string', '"{0}:{1}:call({2})\\n"'.format(func['file'], func['line'], func['name'])) ]))
def createOutputIf(self, expr): expressList = [c_ast.Constant(type='int', value='0')] funcCall = c_ast.FuncCall(c_ast.ID(name="assert"), c_ast.ExprList(expressList)) if_all = c_ast.If(c_ast.BinaryOp(left=c_ast.ID(name='__out_var'), op='==', right=expr), c_ast.Compound([funcCall]), iffalse=None) return (if_all)
def max_set_recur(exprs): if len(exprs) == 0: return None if len(exprs) == 1: return exprs[0] else: half = int(len(exprs) / 2) a = max_set_recur(exprs[:half]) b = max_set_recur(exprs[half:]) return c_ast.FuncCall(c_ast.ID('MAX'), c_ast.ExprList([a, b]))
def addTestFunction(ast, expectedOutput, testFxn, initVars, initList): varList = [] exprList = [] fxnName = '' inFxn = False listi = 0 for i in range(len(initVars)): v = initVars[i] if inFxn: exprList.append(c_ast.Constant('int', initList[listi])) listi += 1 if (')' in v): inFxn = False newVar = c_ast.FuncCall(c_ast.ID(fxnName), c_ast.ExprList(exprList)) varList.append(newVar) exprList = [] else: if ('(' in v): fxnName = v[:v.index('(')] if (v[v.index('(')+1] != ')'): inFxn = True exprList.append(c_ast.Constant('int', initList[listi])) listi += 1 else: newVar = c_ast.FuncCall(c_ast.ID(fxnName), c_ast.ExprList([])) varList.append(newVar) else: newVar = c_ast.Assignment('=', c_ast.ID(v), c_ast.Constant('int', initList[listi])) listi += 1 varList.append(newVar) fxnDecl = c_ast.FuncDecl(None, c_ast.TypeDecl('klee_test_entry', [], c_ast.IdentifierType(['void']))) fxnCall = c_ast.FuncCall(c_ast.ID(testFxn), c_ast.ExprList([])) binaryOp = c_ast.BinaryOp('==', fxnCall, c_ast.Constant('int', expectedOutput)) ifFalse = c_ast.Compound([c_ast.FuncCall(c_ast.ID('klee_silent_exit'), c_ast.ExprList([c_ast.Constant('int', '0')]))]) ifTrue = c_ast.Compound([]) blockItems = [] for v in varList: blockItems.append(v) blockItems.append(c_ast.If(binaryOp, ifTrue, ifFalse)) fxnBody = c_ast.Compound(blockItems) fxnNode = c_ast.FuncDef(fxnDecl, None, fxnBody) ast.ext.append(fxnNode)
def visit_While(self, node: c_ast.While): before_pc = self._pc self._pc = self._update_pc(self._pc, self._type_system, node.cond) before_types = deepcopy(self._type_system) fixed_types = None # don't output logs while doing iterations logger.disabled = True self._loop_level += 1 while fixed_types != self._type_system: fixed_types = deepcopy(self._type_system) self.generic_visit(node) self._type_system.merge(fixed_types) logger.disabled = False self._loop_level -= 1 if self._loop_level == 0: logger.debug( f'Line {node.coord.line}: while({generate(node.cond)})') logger.debug(f'types(fixed point): {self._type_system}') # generate assertion under While if aligned distance is not zero is_aligned_divergent, _ = is_divergent(self._type_system, node.cond) if is_aligned_divergent: aligned_cond = ExpressionReplacer(self._type_system, True).visit( deepcopy(node.cond)) assertion = c_ast.FuncCall( name=c_ast.ID(constants.ASSERT), args=c_ast.ExprList(exprs=[aligned_cond])) node.stmt.block_items.insert(0, assertion) self.generic_visit(node) after_visit = deepcopy(self._type_system) self._type_system = deepcopy(before_types) self._type_system.merge(fixed_types) # instrument c_s part c_s = self._instrument(before_types, self._type_system, self._pc) self._insert_at(node, c_s, after=False) # instrument c'' part update_statements = self._instrument(after_visit, self._type_system, self._pc) block_items = node.stmt.block_items block_items.extend(update_statements) # TODO: while shadow branch if self._enable_shadow and self._pc and not before_pc: pass self._pc = before_pc
def MakePrintfCall(fmt_str, arg_node: Optional[c_ast.Node], use_specialized_printf): args = [c_ast.Constant("string", '"' + fmt_str + '"')] if arg_node: args.append(arg_node) name = GetSingleArgPrintForFormat(fmt_str) else: name = "print" if not use_specialized_printf: name = "printf" return c_ast.FuncCall(c_ast.ID(name), c_ast.ExprList(args))
def create_function_call(self, name: str, parameters: c_ast.Node = c_ast.ExprList([])): """ Creates a function call containing the given parameters. Does not change the AST. :param name: The name of the function. :param parameters: The parameters of the call. Defaults to no parameters. :return: A function call. :rtype: c_ast.FuncCall """ return c_ast.FuncCall(c_ast.ID(name), parameters)
def __init__(self, decl, typedefs): self.return_interface = _type_to_interface(decl.type, typedefs) self.name = decl.type.declname self.docstring = _get_docstring(decl.coord) self.arg_interfaces = [] self.args = [] self.blocks = False self.coord = decl.coord block_contents = [] post_block_contents = [] func_args = [] if decl.args: for i, arg in enumerate(decl.args.params): if type(arg) is c_ast.EllipsisParam: raise RuntimeError("vararg functions not supported") interface = _type_to_interface(arg.type, typedefs) if type(interface) is VoidWrapper: continue block_contents.extend(interface.pre_argument('arg' + str(i))) post_block_contents.extend( interface.post_argument('arg' + str(i))) func_args.append(c_ast.ID('arg' + str(i))) self.arg_interfaces.append(interface) self.blocks = self.blocks | interface.blocks if arg.name: self.args.append(arg.name) else: self.args.append(f'arg{len(self.args)}') function_call = c_ast.FuncCall(c_ast.ID(self.name), c_ast.ExprList(func_args)) self.returns = type(self.return_interface) is not VoidWrapper if self.returns: ret_assign = c_ast.Decl('ret', [], [], [], c_ast.TypeDecl('ret', [], decl.type.type), function_call, []) block_contents.append(ret_assign) block_contents.append(_generate_write('return_command')) block_contents.extend(post_block_contents) block_contents.append(_generate_write('ret')) self.blocks = True else: block_contents.append(function_call) if self.blocks: block_contents.append(_generate_write('return_command')) else: block_contents.append(_generate_write('void_command')) block_contents.extend(post_block_contents) self.call_ast = c_ast.Compound(block_contents) self.filename = decl.coord.file
def _generate_write(name, address=True): """ Helper function generate write functions """ if address: target = c_ast.UnaryOp('&', c_ast.ID(name)) else: target = c_ast.ID(name) return c_ast.FuncCall( c_ast.ID('_rpc_write'), c_ast.ExprList([target, c_ast.UnaryOp('sizeof', c_ast.ID(name))]))
def test_to_type_with_cpp(self): generator = c_generator.CGenerator() test_fun = c_ast.FuncCall(c_ast.ID('test_fun'), c_ast.ExprList([])) memmgr_path = self._find_file('memmgr.h') ast2 = parse_file(memmgr_path, use_cpp=True) void_ptr_type = ast2.ext[-3].type.type void_type = void_ptr_type.type self.assertEqual(generator.visit(c_ast.Cast(void_ptr_type, test_fun)), '(void *) test_fun()') self.assertEqual(generator.visit(c_ast.Cast(void_type, test_fun)), '(void) test_fun()')
def test_to_type(self): src = 'int *x;' generator = c_generator.CGenerator() test_fun = c_ast.FuncCall(c_ast.ID('test_fun'), c_ast.ExprList([])) ast1 = parse_to_ast(src) int_ptr_type = ast1.ext[0].type int_type = int_ptr_type.type self.assertEqual(generator.visit(c_ast.Cast(int_ptr_type, test_fun)), '(int *) test_fun()') self.assertEqual(generator.visit(c_ast.Cast(int_type, test_fun)), '(int) test_fun()')