Exemplo n.º 1
0
def clang(
    bc_path,
    cpp_path,
    include_flags=None,
    define_flags=None,
    machine_flags=None,
    colors=True,
):
    cmd = [settings.clang()]
    cmd += clang_emit_llvm_flags()
    cmd += clang_ikos_flags()
    cmd += [cpp_path, '-o', bc_path]

    # For #include <ikos/analyzer/intrinsic.hpp>
    cmd += ['-isystem', settings.INCLUDE_DIR]

    if include_flags:
        cmd += ['-I%s' % i for i in include_flags]
    if define_flags:
        cmd += ['-D%s' % d for d in define_flags]
    if machine_flags:
        cmd += ['-m%s' % m for m in machine_flags]

    if colors:
        cmd.append('-fcolor-diagnostics')
    else:
        cmd.append('-fno-color-diagnostics')

    if cpp_path.endswith('.cpp'):
        cmd.append('-std=c++17')  # available because clang >= 7.0

    log.info('Compiling %s' % cpp_path)
    log.debug('Running %s' % command_string(cmd))
    subprocess.check_call(cmd)
Exemplo n.º 2
0
def compiler(mode):
    ''' Return the full path to the compiler for the given mode '''
    if mode == 'cc':
        return settings.clang()
    elif mode == 'c++':
        return settings.clangxx()
    else:
        assert False, 'unexpected mode'
Exemplo n.º 3
0
Arquivo: scan.py Projeto: uuhan/ikos
def build_bitcode(mode, parser, src_path, bc_path):
    ''' Compile the given source file to llvm bitcode '''
    cmd = [mode]
    cmd += analyzer.clang_emit_llvm_flags()
    cmd += parser.compile_args
    cmd += analyzer.clang_ikos_flags()
    cmd += [src_path, '-o', bc_path]
    run(cmd, executable=settings.clang())
Exemplo n.º 4
0
def clang(bc_path, cpp_path, colors=True):
    cmd = [
        settings.clang(), '-emit-llvm', '-c', '-g', '-D_FORTIFY_SOURCE=0',
        '-Wall', cpp_path, '-o', bc_path
    ]

    if colors:
        cmd.append('-fcolor-diagnostics')
    else:
        cmd.append('-fno-color-diagnostics')

    if cpp_path.endswith('.cpp'):
        cmd.append('-std=c++14')  # available because clang >= 4.0

    subprocess.check_call(cmd)
Exemplo n.º 5
0
def clang(bc_path, cpp_path, colors=True):
    cmd = [settings.clang(),
           '-c',
           '-emit-llvm',
           '-g',
           '-D_FORTIFY_SOURCE=0',
           '-Wall',
           cpp_path,
           '-o', bc_path]

    # For #include <ikos/analyzer/intrinsic.hpp>
    cmd += ['-isystem', settings.INCLUDE_DIR]

    if colors:
        cmd.append('-fcolor-diagnostics')
    else:
        cmd.append('-fno-color-diagnostics')

    if cpp_path.endswith('.cpp'):
        cmd.append('-std=c++14')  # available because clang >= 4.0

    log.info('Compiling %s' % cpp_path)
    log.debug('Running %s' % command_string(cmd))
    subprocess.check_call(cmd)
Exemplo n.º 6
0
def main(argv):
    progname = os.path.basename(argv[0])

    start_date = datetime.datetime.now()

    # parse arguments
    opt = parse_arguments(argv[1:])

    # setup colors and logging
    colors.setup(opt.color, file=log.out)
    log.setup(opt.log_level)

    if is_apron_domain(opt.domain) and not settings.HAS_APRON:
        printf(
            '%s: error: cannot use apron abstract domains.\n'
            'ikos was compiled without apron support, '
            'see analyzer/README.md\n',
            progname,
            file=sys.stderr)
        sys.exit(1)

    # create working directory
    wd = create_working_directory(opt.temp_dir, opt.save_temps)

    input_path = opt.file

    # compile c/c++ code
    if path_ext(input_path) in c_extensions + cpp_extensions:
        bc_path = namer(opt.file, '.bc', wd)

        try:
            with stats.timer('clang'):
                clang(bc_path, input_path, opt.compiler_include_flags,
                      opt.compiler_define_flags, opt.compiler_warning_flags,
                      opt.compiler_disable_warnings,
                      opt.compiler_machine_flags, colors.ENABLE)
        except subprocess.CalledProcessError as e:
            printf('%s: error while compiling %s, abort.\n',
                   progname,
                   input_path,
                   file=sys.stderr)
            sys.exit(e.returncode)

        input_path = bc_path

    if path_ext(input_path) not in llvm_extensions:
        printf('%s: error: unexpected file extension.\n',
               progname,
               file=sys.stderr)
        sys.exit(1)

    # ikos-pp: preprocess llvm bitcode
    pp_path = namer(opt.file, '.pp.bc', wd)
    try:
        with stats.timer('ikos-pp'):
            ikos_pp(pp_path, input_path, opt.entry_points, opt.opt_level,
                    opt.inline_all, not opt.no_bc_verify)
    except subprocess.CalledProcessError as e:
        printf('%s: error while preprocessing llvm bitcode, abort.\n',
               progname,
               file=sys.stderr)
        sys.exit(e.returncode)

    # display the llvm bitcode, if requested
    if opt.display_llvm:
        display_llvm(pp_path)

    # ikos-analyzer: analyze llvm bitcode
    try:
        with stats.timer('ikos-analyzer'):
            ikos_analyzer(opt.output_db, pp_path, opt)
    except AnalyzerError as e:
        printf('%s: error: %s\n', progname, e, file=sys.stderr)
        sys.exit(e.returncode)

    # open output database
    db = OutputDatabase(path=opt.output_db)

    # insert timing results in the database
    db.insert_timing_results(stats.rows())

    # insert settings in the database
    settings_rows = [
        ('version', settings.VERSION),
        ('start-date', start_date.isoformat(' ')),
        ('end-date', datetime.datetime.now().isoformat(' ')),
        ('working-directory', wd),
        ('input', opt.file),
        ('bc-file', input_path),
        ('pp-bc-file', pp_path),
        ('clang', settings.clang()),
        ('ikos-pp', settings.ikos_pp()),
        ('opt-level', opt.opt_level),
        ('inline-all', json.dumps(opt.inline_all)),
        ('use-libc-intrinsics', json.dumps(not opt.no_libc)),
        ('use-libcpp-intrinsics', json.dumps(not opt.no_libcpp)),
        ('use-libikos-intrinsics', json.dumps(not opt.no_libikos)),
        ('use-simplify-cfg', json.dumps(not opt.no_simplify_cfg)),
        ('use-simplify-upcast-comparison',
         json.dumps(not opt.no_simplify_upcast_comparison)),
    ]
    if opt.cpu:
        settings_rows.append(('cpu-limit', opt.cpu))
    if opt.mem:
        settings_rows.append(('mem-limit', opt.mem))
    db.insert_settings(settings_rows)

    first = (log.LEVEL >= log.ERROR)

    # display timing results
    if opt.display_times != 'no':
        if not first:
            printf('\n')
        report.print_timing_results(db, opt.display_times == 'full')
        first = False

    # display summary
    if opt.display_summary != 'no':
        if not first:
            printf('\n')
        report.print_summary(db, opt.display_summary == 'full')
        first = False

    # display raw checks
    if opt.display_raw_checks:
        if not first:
            printf('\n')
        report.print_raw_checks(db, opt.procedural == 'inter')
        first = False

    # start ikos-view
    if opt.format == 'web':
        ikos_view(opt, db)
        return

    # report
    if opt.format != 'no':
        if not first and opt.report_file is sys.stdout:
            printf('\n' + colors.bold('# Results') + '\n')
            first = False

        # setup colors again (in case opt.color = 'auto')
        colors.setup(opt.color, file=opt.report_file)

        # generate report
        rep = report.generate_report(db,
                                     status_filter=opt.status_filter,
                                     analyses_filter=None)

        # format report
        formatter_class = report.formats[opt.format]
        formatter = formatter_class(opt.report_file, opt.report_verbosity)
        formatter.format(rep)

    # close database
    db.close()

    if opt.remove_db:
        os.remove(opt.output_db)
Exemplo n.º 7
0
Arquivo: scan.py Projeto: uuhan/ikos
def compile(mode, argv):
    assert mode in ('clang', 'clang++')

    progname = os.path.basename(argv[0])

    if 'IKOS_SCAN_SERVER' not in os.environ:
        printf('error: %s: missing environment variable IKOS_SCAN_SERVER.\n',
               progname,
               file=sys.stderr)
        sys.exit(1)

    # setup colors and logging
    colors.setup(os.environ.get('IKOS_SCAN_COLOR', args.default_color),
                 file=log.out)
    log.setup(os.environ.get('IKOS_SCAN_LOG_LEVEL', args.default_log_level))

    # first step, run the actual command
    run([mode] + argv[1:], executable=settings.clang())

    # second step, parse the command line and compile to llvm bitcode
    parser = ClangArgumentParser(argv[1:])

    if parser.skip_bitcode_gen():
        return

    try:
        if (len(parser.source_files) == 1 and len(parser.object_files) == 0
                and not parser.is_link):
            # in this case, just compile to llvm bitcode and attach the llvm
            # bitcode path to the output object file
            src_path = parser.source_files[0]
            obj_path = parser.output_file
            bc_path = '%s.bc' % obj_path
            build_bitcode(mode, parser, src_path, bc_path)
            attach_bitcode_path(obj_path, bc_path)
            return

        # compile the source files one by one and attach the llvm bitcode path
        new_object_files = []
        for src_path in parser.source_files:
            # build the object file
            obj_path = '%s.o' % src_path
            build_object(mode, parser, src_path, obj_path)
            new_object_files.append(obj_path)

            # build the bitcode file
            if src_path.endswith('.bc'):
                bc_path = src_path
            else:
                bc_path = '%s.bc' % obj_path
                build_bitcode(mode, parser, src_path, bc_path)

            # attach the bitcode path to the object file, ready to be linked
            attach_bitcode_path(obj_path, bc_path)

        # re-link to merge the llvm bitcode paths section
        if new_object_files:
            if parser.is_link:
                link_objects(mode, parser,
                             new_object_files + parser.object_files,
                             parser.output_file)
            else:
                log.warning('New object files but nothing to link')

        if parser.is_link and u'executable' in filetype(parser.output_file):
            bc_path = '%s.bc' % parser.output_file
            extract_bitcode(parser.output_file, bc_path)
            notify_binary_built(parser.output_file, bc_path)
    except IOError as error:
        # ./configure sometimes removes the file while we are still running
        if error.filename == parser.output_file:
            pass
        else:
            raise error
Exemplo n.º 8
0
Arquivo: scan.py Projeto: uuhan/ikos
def link_objects(mode, parser, input_paths, output_path):
    cmd = [mode]
    cmd += input_paths
    cmd += parser.link_args
    cmd += ['-o', output_path]
    run(cmd, executable=settings.clang())
Exemplo n.º 9
0
Arquivo: scan.py Projeto: uuhan/ikos
def build_object(mode, parser, src_path, obj_path):
    ''' Compile the given source file to an object file '''
    cmd = [mode, '-c']
    cmd += parser.compile_args
    cmd += [src_path, '-o', obj_path]
    run(cmd, executable=settings.clang())
Exemplo n.º 10
0
def main(argv):
    progname = os.path.basename(argv[0])

    start_date = datetime.datetime.now()

    # disable unix signals forwarding
    os.setpgrp()

    # parse arguments
    opt = parse_opt(argv[1:])

    # setup colors
    colors.setup(opt.colors)

    try:
        # create working directory
        wd = create_work_dir(opt.temp_dir, opt.save_temps)

        input_path = opt.file

        # compile c/c++ code
        if path_ext(input_path) in ('.c', '.cpp'):
            bc_path = namer(opt.file, '.bc', wd)

            try:
                with stats.timer('clang'):
                    clang(bc_path, input_path, colors.ENABLE)
            except subprocess.CalledProcessError as e:
                printf('%s: error while compiling %s, abort.\n',
                       progname,
                       input_path,
                       file=sys.stderr)
                sys.exit(e.returncode)

            input_path = bc_path

        if path_ext(input_path) != '.bc':
            printf('%s: error: unexpected file extension.\n',
                   progname,
                   file=sys.stderr)
            sys.exit(1)

        # preprocess bitcode
        pp_path = namer(opt.file, '.pp.bc', wd)
        try:
            with stats.timer('ikos-pp'):
                ikos_pp(pp_path, input_path, opt.entry_points, opt.ikos_pp,
                        opt.inline, opt.verify)
        except subprocess.CalledProcessError as e:
            printf('%s: error while preprocessing llvm bitcode, abort.\n',
                   progname,
                   file=sys.stderr)
            sys.exit(e.returncode)

        # translate bitcode to arbos ar
        ar_path = namer(opt.file, '.ar', wd)
        try:
            with stats.timer('llvm-to-ar'):
                llvm_to_ar(ar_path, pp_path, opt.gv_zero_initializers)
        except subprocess.CalledProcessError as e:
            printf('%s: error while running llvm-to-ar, abort.\n',
                   progname,
                   file=sys.stderr)
            sys.exit(e.returncode)

        # arbos (libanalyzer)
        try:
            with stats.timer('arbos'):
                passes = arbos(ar_path, opt.output_db, opt.analyses,
                               opt.entry_points, opt.entry_points_init_gv,
                               opt.arbos_optimize, opt.arbos_optimize_cfg,
                               opt.dot_cfg,
                               settings.ABSTRACT_DOMAIN.startswith('GAUGE'),
                               not opt.intraprocedural, opt.precision_level,
                               not opt.no_liveness, not opt.no_pointer,
                               opt.gv_init, opt.use_summaries,
                               opt.use_pointer_summaries,
                               opt.display_invariants, opt.display_checks,
                               opt.mem, opt.cpu, opt.print_command)
        except ArbosError as e:
            printf('%s: error: %s\n', progname, e, file=sys.stderr)
            sys.exit(e.returncode)

        if opt.print_command:
            return

        # open output database
        db = sqlite3.connect(opt.output_db)

        # insert timing results in the database
        stats.save_database(db)

        # insert settings in the database
        settings_rows = [
            ('version', settings.VERSION),
            ('start-date', start_date.isoformat(' ')),
            ('end-date', datetime.datetime.now().isoformat(' ')),
            ('entry-points-init-gv', json.dumps(opt.entry_points_init_gv)),
            ('working-directory', wd),
            ('input', opt.file),
            ('bc-file', input_path),
            ('pp-bc-file', pp_path),
            ('ar-file', ar_path),
            ('clang', settings.clang()),
            ('opt', settings.opt()),
            ('arbos', settings.arbos()),
            ('llvm-to-ar', settings.llvm_to_ar()),
            ('ikos-pp', settings.ikos_pp()),
            ('ikos-pp-level', 'full' if opt.ikos_pp else 'simple'),
            ('ikos-pp-inline-all', json.dumps(opt.inline)),
            ('global-variables-init', json.dumps(opt.gv_init)),
            ('arbos-passes', json.dumps(passes)),
        ]
        if opt.cpu > 0:
            settings_rows.append(('cpu-limit', opt.cpu))
        if opt.mem > 0:
            settings_rows.append(('mem-limit', opt.mem))
        save_settings(db, settings_rows)

        # display timing results
        if opt.display_timing_results != 'off':
            printf('\n')
            render.print_timing_results(db,
                                        opt.display_timing_results == 'full')

        # display summary
        if opt.display_summary != 'off':
            printf('\n')
            render.print_summary(db, opt.display_summary == 'full')

        # display raw checks
        if opt.show_raw_checks:
            printf('\n')
            render.print_raw_checks(db, not opt.intraprocedural)

        # export
        if opt.export:
            if opt.export_file is sys.stdout:
                printf('\n')
                printf(colors.bold('# Results') + '\n')

            # setup colors again (in case opt.colors = 'auto')
            colors.setup(opt.colors, file=opt.export_file)

            # export format
            formatter_class = render.formats[opt.export_format]
            formatter = formatter_class(opt.export_file, opt.export_verbosity,
                                        opt.export_demangle)

            render.export(db, formatter, opt.export_level,
                          not opt.export_no_unreachable)

        # close database
        db.close()

        # ikos view
        if opt.ikosview:
            ikos_view(opt.output_db, not opt.intraprocedural)

        if opt.remove_db:
            os.remove(opt.output_db)
    except KeyboardInterrupt:
        pass