def main(**kwargs): global output_file output_file = open(gcc.get_dump_base_name() + '.gdb_exc.py', 'w') # We used to use attributes here, but there didn't seem to be a # big benefit over hard-coding. output_file.write('declare_throw("throw_exception")\n') output_file.write('declare_throw("throw_verror")\n') output_file.write('declare_throw("throw_vfatal")\n') output_file.write('declare_throw("throw_error")\n') gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, close_output) ps = GdbExceptionChecker(output_file) ps.register_after('ssa')
def main(**kwargs): # Register our custom attributes: gcc.register_callback(gcc.PLUGIN_ATTRIBUTES, register_our_attributes) # Hook for GCC 4.7 and later: if hasattr(gcc, 'PLUGIN_FINISH_DECL'): gcc.register_callback(gcc.PLUGIN_FINISH_DECL, on_finish_decl) # Register our GCC passes: gimple_ps = CpyCheckerGimplePass(**kwargs) if 1: # non-SSA version: gimple_ps.register_before('*warn_function_return') else: # SSA version: gimple_ps.register_after('ssa') ipa_ps = CpyCheckerIpaPass() ipa_ps.register_before('*free_lang_data')
# # This is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. import gcc def on_decl(v, *args, **kwargs): if v.name != 'variable': return t = v.type print(t.name) print('length = %d' % len(t.values)) for (name, value) in t.values: print('%s = %s' % (name, value)) gcc.register_callback(gcc.PLUGIN_FINISH_DECL, on_decl)
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 gccDeclHook (decl, _): if decl.is_builtin is False: if type (decl) not in [gcc.VarDecl, gcc.FieldDecl, gcc.ParmDecl]: TranslationUnit.append (decl) if __name__ == '__main__': cmod = imp.load_source ('cygcc.config', gcc.argument_dict ['config']) pxdutil.Config = pxdutil.pxdconfig (cmod) gcc.register_callback (gcc.PLUGIN_FINISH_DECL, gccDeclHook) gcc.register_callback (gcc.PLUGIN_PASS_EXECUTION, gccPassHook)
# # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. import gcc def attribute_callback_for_claims_mutex(*args): print('attribute_callback_for_claims_mutex called: args: %s' % (args, )) def attribute_callback_for_releases_mutex(*args): print('attribute_callback_for_releases_mutex called: args: %s' % (args, )) def register_our_attributes(): gcc.register_attribute('claims_mutex', 1, 1, False, False, False, attribute_callback_for_claims_mutex) gcc.define_macro('WITH_ATTRIBUTE_CLAIMS_MUTEX') gcc.register_attribute('releases_mutex', 1, 1, False, False, False, attribute_callback_for_releases_mutex) gcc.define_macro('WITH_ATTRIBUTE_RELEASES_MUTEX') # Wire up our callback: gcc.register_callback(gcc.PLUGIN_ATTRIBUTES, register_our_attributes)
indent_print(depth, (method_name, e)) print('') def dump_namespaces(ns, depth): # ignore builtin's they would just make stdout.txt painful. if ns.is_builtin == False: print_namespace(ns, depth) # aliases of namespaces in particular will occur # within declarations, but we don't want to call # declarations on them (here). if ns.alias_of == None: for decl in ns.declarations: if type(decl) == gcc.NamespaceDecl: dump_namespaces(decl, depth + 1) # nested namespaces.. for namespace in ns.namespaces: dump_namespaces(namespace, depth + 1) def finish_unit_cb(*args, **kwargs): # depth of -1 to ignore the global namespace itself (because its a builtin). dump_namespaces(gcc.get_global_namespace(), -1) gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, finish_unit_cb)
elif t is gcc.Type.long(): return ":long" elif t is gcc.Type.unsigned_long(): return ":ulong" elif t is gcc.Type.uint32(): return ":uint32" elif t is gcc.Type.uint64(): return ":uint64" elif isinstance(t, gcc.PointerType): return note_special_type(t) elif isinstance(t, gcc.EnumeralType): return note_special_type(t) raise ValueError("Unhandled type", t) def note_declaration(decl, *args, **kwargs): if from_jit_h(decl.location.file) and isinstance(decl, gcc.FunctionDecl): c_name = decl.name lisp_name = c_name.replace('_', '-') rtype = convert_type(decl.type.type) argtypes = [convert_type(t) for t in decl.type.argument_types] print '(define-ffi-function %s\n "%s"\n %s\n (%s)\n libgccjit.so)' % (lisp_name, c_name, rtype, " ".join(argtypes)) print "(require 'ffi)" print '(define-ffi-library libgccjit.so "libgccjit")' def done(*arg, **kwargs): print "(provide 'gcc-jit)" gcc.register_callback(gcc.PLUGIN_FINISH_DECL, note_declaration) gcc.register_callback(gcc.PLUGIN_FINISH, done)
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. import gcc # Callback without any args: def my_callback(*args, **kwargs): print('my_callback:') print(' args: %r' % (args,)) print(' kwargs: %r' % (kwargs,)) gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, my_callback) gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, my_callback, (1, 2, 3)) gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, my_callback, foo='bar', baz='qux') gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, my_callback, (1, 2, 3), foo='bar', baz='qux')
# # This is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. import gcc import pprint def gccPassHook(passname, _): if passname.name == '*free_lang_data': for i in gcc.get_translation_units (): gns = gcc.get_global_namespace () for decl in gns.declarations: if decl.is_builtin is False: pp = pprint.PrettyPrinter(indent=4) pp.pprint (str (decl.type)) pp.pprint (decl.type.fields) pp.pprint (decl.type.methods) gcc.register_callback (gcc.PLUGIN_PASS_EXECUTION, gccPassHook)
# Copyright 2011 David Malcolm <*****@*****.**> # Copyright 2011 Red Hat, Inc. # # This is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. import gcc # Verify that we can register custom preprocessor macros: def register_our_macros(): gcc.define_macro('FOO') gcc.define_macro('BAR=42') # Wire up our callback: gcc.register_callback(gcc.PLUGIN_ATTRIBUTES, register_our_macros)
def verify_traces(optpass, fun): # Only run in one pass # FIXME: should we be adding our own pass for this? if optpass.name == '*warn_function_return': if fun: traces = get_traces(fun) # We should have two traces # print('traces: %r' % traces) assert len(traces) == 2 # Verify the "success" trace: state = traces[0].states[-1] print('Trace 0:') r = state.return_rvalue print(' returned: %r' %r) print(' r->ob_refcnt: %r' % state.get_value_of_field_by_region(r.region, 'ob_refcnt')) # Verify the "fail" trace: state = traces[1].states[-1] print('Trace 1:') print(' returned: %r' % state.return_rvalue) gcc.register_callback(gcc.PLUGIN_PASS_EXECUTION, verify_traces) #main(verify_refcounting=True) #main(verify_refcounting=True, # show_traces=False)
# Copyright 2012 David Malcolm <*****@*****.**> # Copyright 2012 Red Hat, Inc. # # This is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. # Invoke C-based selftest of integration with GCC's garbage collector import gcc def on_finish(): gcc._gc_selftest() gcc.register_callback(gcc.PLUGIN_FINISH, on_finish)
Takes module, class, list, dictionary, or string.""" methodList = [e for e in dir(object) if e != 'fullname' and callable(getattr(object, e))] nonmethodList = [e for e in dir(object) if e != 'fullname' and not callable(getattr(object, e))] processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList]) print nonmethodList def showMethods(a): methodList = [method for method in dir(a) if hasattr(a,method) and callable(getattr(a, method))] print methodList nonMethodList = [method for method in dir(a) if hasattr(a,method) and not callable(getattr(a, method))] for atr in nonMethodList: print atr,"=>",getattr(a,atr) def my_pass_execution_callback(decl,*args, **kwargs): print decl.__class__ #decl.debug() info(decl) if isinstance(decl,gcc.FunctionDecl): print "func ",decl.name,":", re.match(r'(.*)<T',str(decl.type)).group(1) args=decl.arguments for a in args: print "\t",a.name, ":", a.type gcc.register_callback(gcc.PLUGIN_PRE_GENERICIZE, my_pass_execution_callback) gcc.register_callback(gcc.PLUGIN_FINISH_DECL, my_pass_execution_callback)
# Copyright 2011 David Malcolm <*****@*****.**> # Copyright 2011 Red Hat, Inc. # # This is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. import gcc # A callback that raises an exception: def my_callback(*args, **kwargs): raise RuntimeError("This is a test of raising an exception") gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, my_callback)
# is described within the JSON: none_refcnt = vars['_Py_NoneStruct.ob_refcnt'] assertEqual(none_refcnt['gcctype'], "Py_ssize_t") assertEqual(none_refcnt['kind'], "RefcountValue") assertEqual(none_refcnt['actual_ob_refcnt']['refs_we_own'], 0) assertEqual(none_refcnt['expected_ob_refcnt']['pointers_to_this'], ['return value']) # Verify "self": selfjs = vars['self'] assertEqual(selfjs['gcctype'], 'struct PyObject *') assertEqual(selfjs['kind'], 'PointerToRegion') assertEqual(selfjs['value_comes_from'][0]['line'], 23) ob_refcnt = vars['self->ob_refcnt'] assertEqual(ob_refcnt['gcctype'], 'Py_ssize_t') assertEqual(ob_refcnt['kind'], 'RefcountValue') assertEqual(ob_refcnt['value_comes_from'][0]['line'], 23) ob_type = vars['self->ob_type'] assertEqual(ob_type['gcctype'], 'struct PyTypeObject *') assertEqual(ob_type['kind'], 'PointerToRegion') assertEqual(ob_type['value_comes_from'][0]['line'], 23) # Ensure that this testing code actually got run (stdout is # checked): print('GOT HERE') gcc.register_callback(gcc.PLUGIN_PASS_EXECUTION, verify_json)
# Copyright 2012 Red Hat, Inc. # # This is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. import gcc # Callback without any args: def my_callback(*args, **kwargs): print('my_callback:') print(' args: %r' % (args,)) print(' kwargs: %r' % (kwargs,)) for i in range(3): gcc.register_callback(gcc.PLUGIN_FINISH, my_callback, order=i) # (They seem to get invoked in reverse order)
def dump_integer_type(t): print('gcc.Type: %r' % str(t)) print(' t.const: %r' % t.const) print(' t.unsigned: %r' % t.unsigned) print(' t.precision: %r' % t.precision) assert isinstance(t.min_value, gcc.IntegerCst) assert isinstance(t.max_value, gcc.IntegerCst) print(' t.min_value.constant: %r' % t.min_value.constant) print(' t.max_value.constant: %r' % t.max_value.constant) assert isinstance(t.sizeof, int) print(' t.sizeof: %r' % t.sizeof) # gccutils.pprint(t) # Pick some types that ought to be arch-independent and thus suitable # for a unit test dump_integer_type(gcc.Type.unsigned_char()) dump_integer_type(gcc.Type.signed_char()) def dump_real_type(t): print('gcc.Type: %r' % str(t)) print(' t.const: %r' % t.const) print(' t.precision: %r' % t.precision) assert isinstance(t.sizeof, int) print(' t.sizeof: %r' % t.sizeof) dump_real_type(gcc.Type.float()) dump_real_type(gcc.Type.double()) gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, on_finish_unit)
# General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. import gcc from gccutils import sorted_dict_repr # Callback without any args: def my_callback(*args, **kwargs): print('my_callback:') print(' args: %r' % (args,)) print(' kwargs: %s' % (sorted_dict_repr(kwargs),)) gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, my_callback) gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, my_callback, (1, 2, 3)) gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, my_callback, foo='bar', baz='qux') gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, my_callback, (1, 2, 3), foo='bar', baz='qux')
def main(**kwargs): w = Whatever() gcc.register_callback(gcc.PLUGIN_PASS_EXECUTION, w.doit)
print(gcc.Type.char().const_equivalent.volatile_equivalent. unqualified_equivalent.const) def dump_real_type(t): print('gcc.Type: %r' % str(t)) print(' t.const: %r' % t.const) print(' t.precision: %r' % t.precision) assert isinstance(t.sizeof, int) print(' t.sizeof: %r' % t.sizeof) dump_real_type(gcc.Type.float()) dump_real_type(gcc.Type.double()) def dump_typedef(td): t = td.type print('gcc.TypeDecl: %r' % str(td)) print(' td.original_type: %r' % td.original_type) print(' td.original_type is gcc.Type.int(): %r' % (td.original_type is gcc.Type.int())) mytype = gccutils.get_global_typedef('mytype') print(' td.original_type.name: %r' % td.original_type.name) print(' td.original_type.name is mytype: %r' % (td.original_type.name is mytype)) dump_integer_type(t) dump_typedef(gccutils.get_global_typedef('mytype')) dump_typedef(gccutils.get_global_typedef('nestedtype')) gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, on_finish_unit)
# Copyright 2012 David Malcolm <*****@*****.**> # Copyright 2012 Red Hat, Inc. # # This is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. # Test case for gcc.PLUGIN_FINISH_DECL (only present in gcc 4.7 onwards) import gcc def finish_decl_cb(*args, **kwargs): print('finish_decl_cb(*args=%r, **kwargs=%r)' % (args, kwargs)) gcc.register_callback(gcc.PLUGIN_FINISH_DECL, finish_decl_cb, ('foo', ), bar='baz')
# Verify that we can forcibly invoke GCC's garbage collector, # (for selftest purposes) import gcc # Count the number of garbage collections: num_ggc_collections = 0 def on_ggc_start(): global num_ggc_collections num_ggc_collections += 1 gcc.register_callback(gcc.PLUGIN_GGC_START, on_ggc_start) def on_finish(): # Now traverse all of the data seen at every previous pass print('on_finish') if 0: print('num_ggc_collections: %i ' % num_ggc_collections) # Call gcc._force_garbage_collection(), and verify that on_ggc_start # gets called: old_collections = num_ggc_collections gcc._force_garbage_collection() # num_ggc_collections should have increased by 1:
ptr_type = decl.type.pointer print(' ptr_type: %s' % ptr_type) print(' is PyObject* subclass?: %s\n' % type_is_pyobjptr_subclass(ptr_type)) def check_struct(typename): print('typename: %r' % typename) struct_type = get_struct(typename) print(' struct_type: %s' % struct_type) ptr_type = struct_type.pointer print(' ptr_type: %s' % ptr_type) print(' is PyObject* subclass?: %s\n' % type_is_pyobjptr_subclass(ptr_type)) def on_pass_execution(p, fn): if p.name == '*free_lang_data': # The '*free_lang_data' pass is called once, rather than per-function, # and occurs immediately after "*build_cgraph_edges", which is the # pass that initially builds the callgraph # # So at this point we're likely to get a good view of the types: check_type(gcc.Type.int()) check_type(gcc.Type.char().pointer) check_typedef('PyObject') check_typedef('PyTypeObject') check_struct('FooObject') check_struct('BarObject') check_struct('BazObject') check_struct('NotAnObject') gcc.register_callback(gcc.PLUGIN_PASS_EXECUTION, on_pass_execution)
# -*- coding: utf-8 -*- # Copyright 2015 Tom Tromey <*****@*****.**> # # This is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. import gcc def on_decl(v, *args, **kwargs): if v.name != 'variable': return t = v.type print(t.name) print('length = %d' % len(t.values)) for (name, value) in t.values: print('%s = %s' % (name, value)) gcc.register_callback(gcc.PLUGIN_FINISH_DECL, on_decl)
# You should have received a copy of the GNU General Public License # along with this program. If not, see # <http://www.gnu.org/licenses/>. # Verify that we can forcibly invoke GCC's garbage collector, # (for selftest purposes) import gcc # Count the number of garbage collections: num_ggc_collections = 0 def on_ggc_start(): global num_ggc_collections num_ggc_collections += 1 gcc.register_callback(gcc.PLUGIN_GGC_START, on_ggc_start) def on_finish(): # Now traverse all of the data seen at every previous pass print('on_finish') if 0: print('num_ggc_collections: %i ' % num_ggc_collections) # Call gcc._force_garbage_collection(), and verify that on_ggc_start # gets called: old_collections = num_ggc_collections gcc._force_garbage_collection() # num_ggc_collections should have increased by 1: assert num_ggc_collections > 0
indent_print(depth, (method_name, method(ns, t[1]))) except Exception as e: indent_print(depth, (method_name, e)) print('') def dump_namespaces(ns, depth): # ignore builtin's they would just make stdout.txt painful. if ns.is_builtin == False: print_namespace(ns, depth) # aliases of namespaces in particular will occur # within declarations, but we don't want to call # declarations on them (here). if ns.alias_of == None: for decl in ns.declarations: if type(decl) == gcc.NamespaceDecl: dump_namespaces(decl, depth + 1) # nested namespaces.. for namespace in ns.namespaces: dump_namespaces(namespace, depth + 1) def finish_unit_cb(*args, **kwargs): # depth of -1 to ignore the global namespace itself (because its a builtin). dump_namespaces(gcc.get_global_namespace(), -1) gcc.register_callback(gcc.PLUGIN_FINISH_UNIT, finish_unit_cb)
import gcc from gccutils import pprint def on_pass_execution(p, fn): if p.name in '*warn_function_return': assert isinstance(fn, gcc.Function) print('fn: %r' % fn) assert isinstance(fn.decl, gcc.FunctionDecl) print('fn.decl.name: %r' % fn.decl.name) if fn.cfg: # None for some early passes print('CFG:') for bb in fn.cfg.basic_blocks: print(' BLOCK %i' % bb.index) if bb.gimple: for i,stmt in enumerate(bb.gimple): print(' gimple[%i]:' % i) print(' str(stmt): %r' % str(stmt)) print(' repr(stmt): %r' % repr(stmt)) if isinstance(stmt, gcc.GimpleCond): print(' stmt.lhs: %r' % stmt.lhs) print(' stmt.exprcode: %r' % stmt.exprcode) print(' stmt.rhs: %r' % stmt.rhs) print(' stmt.true_label: %r' % stmt.true_label) print(' stmt.false_label: %r' % stmt.false_label) gcc.register_callback(gcc.PLUGIN_PASS_EXECUTION, on_pass_execution)
gcc.inform(stmt.loc, "Cannot figure out message name") continue else: # This is a call to the message function that uses a string literal # for the message name. That's easy. messageName = str(stmt.args[1]).replace('"', '') if messageName not in registeredMessages: gcc.error(stmt.loc, "Unknown format message: %s" % messageName) continue # Check that enough arguments were provided. The expected length does # not include the first two arguments, which are not for the message. if not check_arg_count(stmt, messageName): continue # Check that the types are as expected. check_arg_types(stmt, messageName) if "messages" not in gcc.argument_dict: print("-fplugin-arg-python-messages= argument is missing") sys.exit(1) try: with open(gcc.argument_dict["messages"], "rb") as f: registeredMessages = pickle.load(f) except FileNotFoundError: registeredMessages = {} gcc.register_callback(gcc.PLUGIN_PASS_EXECUTION, find_function_calls)