#   Copyright 2011-2016 Free Software Foundation, 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/>.

# This is a GCC plugin that computes some exception-handling data for
# gdb.  This data can then be summarized and checked by the
# exsummary.py script.

# To use:
# * First, install the GCC Python plugin.  See
#   https://fedorahosted.org/gcc-python-plugin/
# * export PYTHON_PLUGIN=/full/path/to/plugin/directory
#   This should be the directory holding "python.so".
# * cd build/gdb; make mostlyclean
# * make CC=.../gcc-with-excheck
#   This will write a number of .py files in the build directory.
# * python .../exsummary.py
#   This will show the violations.

import gcc
import gccutils
import sys

# Where our output goes.
output_file = None

# Cleanup functions require special treatment, because they take a
# function argument, but in theory the function must be nothrow.
cleanup_functions = {
    'make_cleanup': 1,
    'make_cleanup_dtor': 1,
    'make_final_cleanup': 1,
    'make_my_cleanup2': 1,
    'make_my_cleanup': 1
}

# Functions which may throw but which we want to ignore.
ignore_functions = {
    # This one is super special.
    'exceptions_state_mc': 1,
    # gdb generally pretends that internal_error cannot throw, even
    # though it can.
    'internal_error': 1,
    # do_cleanups and friends are supposedly nothrow but we don't want
    # to run afoul of the indirect function call logic.
    'do_cleanups': 1,
    'do_final_cleanups': 1
}

# Functions which take a function argument, but which are not
# interesting, usually because the argument is not called in the
# current context.
non_passthrough_functions = {
    'signal': 1,
    'add_internal_function': 1
}

# Return True if the type is from Python.
def type_is_pythonic(t):
    if isinstance(t, gcc.ArrayType):
        t = t.type
    if not isinstance(t, gcc.RecordType):
        return False
    # Hack.
    return str(t).find('struct Py') == 0

# Examine all the fields of a struct.  We don't currently need any
# sort of recursion, so this is simple for now.
def examine_struct_fields(initializer):
    global output_file
    for idx2, value2 in initializer.elements:
        if isinstance(idx2, gcc.Declaration):
            if isinstance(value2, gcc.AddrExpr):
                value2 = value2.operand
                if isinstance(value2, gcc.FunctionDecl):
                    output_file.write("declare_nothrow(%s)\n"
                                      % repr(str(value2.name)))

# Examine all global variables looking for pointers to functions in
# structures whose types were defined by Python.
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)

# Called at the end of compilation to write out some data derived from
# globals and to close the output.
def close_output(*args):
    global output_file
    examine_globals()
    output_file.close()

# The pass which derives some exception-checking information.  We take
# a two-step approach: first we get a call graph from the compiler.
# This is emitted by the plugin as Python code.  Then, we run a second
# program that reads all the generated Python and uses it to get a
# global view of exception routes in gdb.
class GdbExceptionChecker(gcc.GimplePass):
    def __init__(self, output_file):
        gcc.GimplePass.__init__(self, 'gdb_exception_checker')
        self.output_file = output_file

    def log(self, obj):
        self.output_file.write("# %s\n" % str(obj))

    # Return true if FN is a call to a method on a Python object.
    # We know these cannot throw in the gdb sense.
    def fn_is_python_ignorable(self, fn):
        if not isinstance(fn, gcc.SsaName):
            return False
        stmt = fn.def_stmt
        if not isinstance(stmt, gcc.GimpleAssign):
            return False
        if stmt.exprcode is not gcc.ComponentRef:
            return False
        rhs = stmt.rhs[0]
        if not isinstance(rhs, gcc.ComponentRef):
            return False
        if not isinstance(rhs.field, gcc.FieldDecl):
            return False
        return rhs.field.name == 'tp_dealloc' or rhs.field.name == 'tp_free'

    # Decode a function call and write something to the output.
    # THIS_FUN is the enclosing function that we are processing.
    # FNDECL is the call to process; it might not actually be a DECL
    # node.
    # LOC is the location of the call.
    def handle_one_fndecl(self, this_fun, fndecl, loc):
        callee_name = ''
        if isinstance(fndecl, gcc.AddrExpr):
            fndecl = fndecl.operand
        if isinstance(fndecl, gcc.FunctionDecl):
            # Ordinary call to a named function.
            callee_name = str(fndecl.name)
            self.output_file.write("function_call(%s, %s, %s)\n"
                                   % (repr(callee_name),
                                      repr(this_fun.decl.name),
                                      repr(str(loc))))
        elif self.fn_is_python_ignorable(fndecl):
            # Call to tp_dealloc.
            pass
        elif (isinstance(fndecl, gcc.SsaName)
              and isinstance(fndecl.var, gcc.ParmDecl)):
            # We can ignore an indirect call via a parameter to the
            # current function, because this is handled via the rule
            # for passthrough functions.
            pass
        else:
            # Any other indirect call.
            self.output_file.write("has_indirect_call(%s, %s)\n"
                                   % (repr(this_fun.decl.name),
                                      repr(str(loc))))
        return callee_name

    # This does most of the work for examine_one_bb.
    # THIS_FUN is the enclosing function.
    # BB is the basic block to process.
    # Returns True if this block is the header of a TRY_CATCH, False
    # otherwise.
    def examine_one_bb_inner(self, this_fun, bb):
        if not bb.gimple:
            return False
        try_catch = False
        for stmt in bb.gimple:
            loc = stmt.loc
            if not loc:
                loc = this_fun.decl.location
            if not isinstance(stmt, gcc.GimpleCall):
                continue
            callee_name = self.handle_one_fndecl(this_fun, stmt.fn, loc)

            if callee_name == 'exceptions_state_mc_action_iter':
                try_catch = True

            global non_passthrough_functions
            if callee_name in non_passthrough_functions:
                continue

            # We have to specially handle calls where an argument to
            # the call is itself a function, e.g., qsort.  In general
            # we model these as "passthrough" -- we assume that in
            # addition to the call the qsort there is also a call to
            # the argument function.
            for arg in stmt.args:
                # We are only interested in arguments which are functions.
                t = arg.type
                if isinstance(t, gcc.PointerType):
                    t = t.dereference
                if not isinstance(t, gcc.FunctionType):
                    continue

                if isinstance(arg, gcc.AddrExpr):
                    arg = arg.operand

                global cleanup_functions
                if callee_name in cleanup_functions:
                    if not isinstance(arg, gcc.FunctionDecl):
                        gcc.inform(loc, 'cleanup argument not a DECL: %s' % repr(arg))
                    else:
                        # Cleanups must be nothrow.
                        self.output_file.write("declare_cleanup(%s)\n"
                                               % repr(str(arg.name)))
                else:
                    # Assume we have a passthrough function, like
                    # qsort or an iterator.  We model this by
                    # pretending there is an ordinary call at this
                    # point.
                    self.handle_one_fndecl(this_fun, arg, loc)
        return try_catch

    # Examine all the calls in a basic block and generate output for
    # them.
    # THIS_FUN is the enclosing function.
    # BB is the basic block to examine.
    # BB_WORKLIST is a list of basic blocks to work on; we add the
    # appropriate successor blocks to this.
    # SEEN_BBS is a map whose keys are basic blocks we have already
    # processed.  We use this to ensure that we only visit a given
    # block once.
    def examine_one_bb(self, this_fun, bb, bb_worklist, seen_bbs):
        try_catch = self.examine_one_bb_inner(this_fun, bb)
        for edge in bb.succs:
            if edge.dest in seen_bbs:
                continue
            seen_bbs[edge.dest] = 1
            if try_catch:
                # This is bogus, but we magically know the right
                # answer.
                if edge.false_value:
                    bb_worklist.append(edge.dest)
            else:
                bb_worklist.append(edge.dest)

    # Iterate over all basic blocks in THIS_FUN.
    def iterate_bbs(self, this_fun):
        # Iteration must be in control-flow order, because if we see a
        # TRY_CATCH construct we need to drop all the contained blocks.
        bb_worklist = [this_fun.cfg.entry]
        seen_bbs = {}
        seen_bbs[this_fun.cfg.entry] = 1
        for bb in bb_worklist:
            self.examine_one_bb(this_fun, bb, bb_worklist, seen_bbs)

    def execute(self, fun):
        if fun and fun.cfg and fun.decl:
            self.output_file.write("################\n")
            self.output_file.write("# Analysis for %s\n" % fun.decl.name)
            self.output_file.write("define_function(%s, %s)\n"
                                   % (repr(fun.decl.name),
                                      repr(str(fun.decl.location))))

            global ignore_functions
            if fun.decl.name not in ignore_functions:
                self.iterate_bbs(fun)

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')

main()
