def on_pass_execution(p, data): if p.name == 'visibility': vars = gcc.get_variables() print('len(gcc.get_variables()) is %i' % len(gcc.get_variables())) for i, var in enumerate(vars): print('%i: var.decl.name = %r' % (i, var.decl.name)) assert isinstance(var.decl, gcc.VarDecl) print(' var.decl.type: %s' % var.decl.type) assert isinstance(var.decl.type, gcc.ArrayType) print(' var.decl.type.type: %s' % var.decl.type.type) if var.decl.initial: assert isinstance(var.decl.initial, gcc.Constructor) print(' len(var.decl.initial.elements): %s' % len(var.decl.initial.elements)) assert isinstance(var.decl.initial.elements, list) for j, (idx, value) in enumerate(var.decl.initial.elements): assert isinstance(idx, gcc.IntegerCst) # FIXME: value ought to be j print(' elements[%i]:' % j) print(' value: %s' % value) for k, (idx2, value2) in enumerate(value.elements): print(' elements[%i].elements[%i]:' % (j, k)) print(' idx2: %r' % idx2) print(' value2: %s' % value2) if isinstance(idx2, gcc.Declaration): print(' idx2.name: %r' % idx2.name)
def init_global_variables(self): global_variables = {} for variable in gcc.get_variables(): name, type = variable.decl.name, variable.decl.type global_variables[name] = self.init_variable( name, type, visibility=Location.VISIBILITY_GLOBAL) return global_variables
def get_all_PyMethodDef_initializers(): """ Locate all initializers for PyMethodDef, returning a list of StructInitializer instances """ log('get_all_PyMethodDef_initializers') result = [] vars = gcc.get_variables() for var in vars: if isinstance(var.decl, gcc.VarDecl): if isinstance(var.decl.type, gcc.ArrayType): if str(var.decl.type.type) == 'struct PyMethodDef': if var.decl.initial: table = [] for idx, ctor in var.decl.initial.elements: #print idx, ctor si = PyMethodDefInitializer(ctor) table.append(si) # Warn about missing sentinel entry with # ml->ml_name == NULL ml_name = table[-1].char_ptr_field('ml_name') if 0: print('final ml_name: %r' % ml_name) if ml_name is not None: gcc.warning(table[-1].get_location(), 'missing NULL sentinel value at end of PyMethodDef table') result += table return result
def init_variables(self, fun): def init_variable(name, vtype): if isinstance(vtype, gcc.PointerType): faked = '{}_location'.format(name) variable = init_variable(faked, vtype.type) return Variable(name=name, type=PointerType(type=variable.type), value=Address(variable)) return Variable(name=name, type=Type(name=str(vtype))) variables, shared = {}, [] # initialize global variables for var in gcc.get_variables(): variables[str(var.decl)] = init_variable(str(var.decl), var.decl.type) shared.append(str(var.decl)) # initialize formal parameters for decl in fun.decl.arguments: variables[str(decl)] = init_variable(str(decl), decl.type) shared.append(str(decl)) # initialize local variables for decl in fun.local_decls: variables[str(decl)] = init_variable(str(decl), decl.type) return variables, shared
def on_pass_execution(p, fn): if p.name == '*free_lang_data': super_ops = set() inode_ops = set() dentry_ops = set() file_ops = set() for var in gcc.get_variables(): if isinstance(var.decl.type, gcc.RecordType): ops = None if var.decl.type.name: if var.decl.type.name.name == 'super_operations': ops = super_ops elif var.decl.type.name.name == 'inode_operations': ops = inode_ops elif var.decl.type.name.name == 'file_operations': ops = file_ops elif var.decl.type.name.name == 'dentry_operations': ops = dentry_ops if ops != None and var.decl.initial: ops.update(['{}={}'.format(a.name, b.operand.name) for a,b in var.decl.initial.elements if ( isinstance(b, gcc.AddrExpr) and isinstance(b.operand, gcc.FunctionDecl))]) if super_ops or inode_ops or dentry_ops or file_ops: with open('%s-vfs_ops.sprute' % (gcc.get_dump_base_name()), 'w') as f: for i in [['super', super_ops], ['inode', inode_ops], ['dentry', dentry_ops], ['file', file_ops]]: if i[1]: f.write("\n".join(map(lambda x: i[0] + ';' + x, i[1])) + '\n' )
def get_all_PyMethodDef_initializers(): """ Locate all initializers for PyMethodDef, returning a list of StructInitializer instances """ log('get_all_PyMethodDef_initializers') result = [] vars = gcc.get_variables() for var in vars: if isinstance(var.decl, gcc.VarDecl): if isinstance(var.decl.type, gcc.ArrayType): if str(var.decl.type.type) == 'struct PyMethodDef': if var.decl.initial: table = [] for idx, ctor in var.decl.initial.elements: #print idx, ctor si = PyMethodDefInitializer(ctor) table.append(si) # Warn about missing sentinel entry with # ml->ml_name == NULL ml_name = table[-1].char_ptr_field('ml_name') if 0: print('final ml_name: %r' % ml_name) if ml_name is not None: gcc.warning( table[-1].get_location(), 'missing NULL sentinel value at end of PyMethodDef table' ) result += table return result
def get_all_PyTypeObject_initializers(): """ Locate all initializers for PyTypeObject, returning a list of PyTypeObjectInitializer instances """ log('get_all_PyTypeObject_initializers') result = [] vars = gcc.get_variables() for var in vars: if isinstance(var.decl, gcc.VarDecl): if str(var.decl.type) == 'struct PyTypeObject': ctor = var.decl.initial if ctor: si = PyTypeObjectInitializer(ctor) result.append(si) return result
def examine_globals(): global output_file vars = gcc.get_variables() for var in vars: if not isinstance(var.decl, gcc.VarDecl): continue output_file.write("################\n") output_file.write("# Analysis for %s\n" % var.decl.name) if not var.decl.initial: continue if not type_is_pythonic(var.decl.type): continue if isinstance(var.decl.type, gcc.ArrayType): for idx, value in var.decl.initial.elements: examine_struct_fields(value) else: gccutils.check_isinstance(var.decl.type, gcc.RecordType) examine_struct_fields(var.decl.initial)
def gccPassHook (): global TranslationUnit for i in gcc.get_variables (): TranslationUnit.append (i.decl) for i in gcc.get_translation_units (): if i.language == 'GNU C++': TranslationUnit = [] gns = gcc.get_global_namespace () for decl in gns.namespaces: if decl.is_builtin is False: TranslationUnit.append (decl) for decl in gns.declarations: if decl.is_builtin is False: TranslationUnit.append (decl) else: for y in i.block.vars: if type (y) is not gcc.VarDecl: TranslationUnit.append (y) pxdutil.pxdcompile (TranslationUnit)
def __init__(self): # Locate all declarations of variables holding "global" state: self.global_decls = set() for var in gcc.get_variables(): type_ = var.decl.type if DEBUG: print('var.decl: %r' % var.decl) print(type_) # Don't bother warning about const data: if is_const(type_): continue self.global_decls.add(var.decl) if DEBUG: print('self.global_decls: %r' % self.global_decls) self.state_users = set()
def get_variables_as_dict(): result = {} for var in gcc.get_variables(): result[var.decl.name] = var return result
def execute(self, fun): def init_shared_variable(decl): name = decl.name vtype = decl.type while isinstance(vtype, gcc.PointerType): # analyze each function independant from others so # add faked locations in order to emulate shared pointers # behaviour faked = 'fake{}'.format(random.randint(*self.FAKE_RANGE)) pts[name] = set([faked]) name, vtype = faked, vtype.type pts[name] = set() def eval_lhs(lhs): # x if isinstance(lhs, gcc.VarDecl): return set([lhs.name]) # *x if isinstance(lhs, gcc.MemRef): return eval_rhs(lhs.operand) raise Exception('Unknown lhs type: {}'.format(type(lhs))) def eval_rhs(rhs): # x if isinstance(rhs, gcc.VarDecl): return pts[rhs.name] # &x if isinstance(rhs, gcc.AddrExpr): return set([rhs.operand.name]) # *x if isinstance(rhs, gcc.MemRef): pt = set() for p in eval_rhs(rhs.operand): pt.update(pts[p]) return pt raise Exception('Unknown rhs type: {}'.format(type(rhs))) # initialize points-to sets # initialize points-to sets # initialize points-to sets for local variables variables = [decl.name for decl in fun.local_decls if decl.name] pts = {v: set() for v in variables} # initialize points-to sets for global variables for variable in gcc.get_variables(): init_shared_variable(variable.decl) # initialize points-to sets for function formal parameters for variable in fun.decl.arguments: init_shared_variable(variable) # iterate until fixed point reached changed = True; while changed: changed = False for block in fun.cfg.basic_blocks: for instr in block.gimple: # analyze only assignments operations if not isinstance(instr, gcc.GimpleAssign): continue # analyze only next types of expressions if instr.exprcode not in (gcc.VarDecl, gcc.AddrExpr, gcc.MemRef): continue # rhs must contain only 1 element if len(instr.rhs) > 1: continue lhs = eval_lhs(instr.lhs) rhs = eval_rhs(instr.rhs[0]) for var in lhs: if not rhs.issubset(pts[var]): pts[var].update(rhs) changed = True # dump result of function analysis to file fname = 'output/{}.pts'.format(fun.decl.name) pts = {k: list(v) for k, v in pts.items()} with open(fname, 'w') as fo: fo.write(json.dumps(pts))
def on_pass_execution(p, fn): if p.name == '*free_lang_data': for var in gcc.get_variables(): gcc.inform(var.decl.location, 'global state "%s %s" defined here' % (var.decl.type, var.decl))