コード例 #1
0
def setupTypes(ast, entryFunc, inputs, nondets, entry, typedefs):
    for fun in ast.ext:
        if isinstance(fun, c_ast.Decl) and isinstance(fun.type,
                                                      c_ast.FuncDecl):
            if fun.name.startswith('__VERIFIER_nondet_'):
                info = {}
                info['type'] = ext_c_generator.GnuCGenerator().visit(fun.type)
                info['line'] = fun.coord.line
                nondets[fun.name] = info
        if isinstance(fun, c_ast.Decl) and isinstance(
                fun.type, ext_c_parser.FuncDeclExt):
            if fun.name.startswith('__VERIFIER_nondet_'):
                info = {}
                info['type'] = ext_c_generator.GnuCGenerator().visit(fun)
                info['type'] = re.sub(r'^extern ', '', info['type'])
                info['line'] = fun.coord.line
                nondets[fun.name] = info
        elif isinstance(fun, c_ast.FuncDef):
            inputs[fun.decl.name] = {}
            if fun.body.block_items:
                for d in fun.body.block_items:
                    if isinstance(d, c_ast.Decl):
                        info = {}
                        typestr = ext_c_generator.GnuCGenerator().visit(d)
                        typestr = re.sub(r'\b%s\b' % d.name, '', typestr)
                        if typedefs.get(typestr):
                            typestr = typedefs[typestr]
                        info['type'] = typestr
                        info['line'] = d.coord.line
                        if d.init is None:
                            inputs[fun.decl.name][d.name] = info
            if fun.decl.name == entryFunc:
                entry['type'] = ext_c_generator.GnuCGenerator().visit(
                    fun.decl.type)
                entry['line'] = fun.coord.line
        elif isinstance(fun, c_ast.Typedef):
            name = fun.name
            if isinstance(fun.type, ext_c_parser.FuncDeclExt):
                typestr = ext_c_generator.GnuCGenerator().visit(
                    fun.type.type) + ('()' + '(' +
                                      ext_c_generator.GnuCGenerator().visit(
                                          fun.type.args) + ')')
                name = fun.name + ' (*)'
            elif isinstance(fun.type, c_ast.PtrDecl) and isinstance(
                    fun.type.type, ext_c_parser.FuncDeclExt):
                typestr = ext_c_generator.GnuCGenerator().visit(
                    fun.type.type.type) + (
                        '(*)' + '(' + ext_c_generator.GnuCGenerator().visit(
                            fun.type.type.args) + ')')
            else:
                typestr = ext_c_generator.GnuCGenerator().visit(fun.type)
            while typedefs.get(typestr):
                typestr = typedefs.get(typestr)
            typedefs[name] = typestr
コード例 #2
0
def preprocess(path):
    text = preprocess_file(path)
    cparser = GnuCParser()
    ast = cparser.parse(text, path)
    generator = ext_c_generator.GnuCGenerator()
    with open(path, "w") as o:
        o.write(generator.visit(ast))
    return ast
コード例 #3
0
def start_prediction(id, pred_dir, req_file):
    P, ast = run_clf_predict(pred_dir, req_file)

    F = to_func(ast)

    generator = ext_c_generator.GnuCGenerator()
    for name, ast in F.items():
        path = os.path.join(pred_dir, name+".c")
        with open(path, "w") as o:
            out = generator.visit(ast)
            o.write(out)
コード例 #4
0
def test_double_pointer():
    src = """
    typedef struct Error {
        int dummy;
    } Error;

    void func_with_p2pp(const char *, Error **);
    """
    import pycparserext.ext_c_parser as ext_c_parser
    import pycparserext.ext_c_generator as ext_c_generator

    parser = ext_c_parser.GnuCParser()
    ast = parser.parse(src)
    gen = ext_c_generator.GnuCGenerator()
    ast.show()
    assert gen.visit(ast).find("func_with_p2pp(const char *, Error **)") != -1
コード例 #5
0
def test_no_added_attr():
    src = """
    char* foo() {
        return "";
    }

    int main() {
        return 0;
    }
    """
    import pycparserext.ext_c_parser as ext_c_parser
    import pycparserext.ext_c_generator as ext_c_generator

    parser = ext_c_parser.GnuCParser()
    ast = parser.parse(src)
    gen = ext_c_generator.GnuCGenerator()
    print(gen.visit(ast))
    assert "attr" not in gen.visit(ast)
コード例 #6
0
def test_pointer_reproduction():
    src = """
    struct foo {
        const char                      *bar;
        const char                      *baz;
    };

    int main () {
        return 0;
    }
    """
    import pycparserext.ext_c_parser as ext_c_parser
    import pycparserext.ext_c_generator as ext_c_generator

    parser = ext_c_parser.GnuCParser()
    ast = parser.parse(src)
    gen = ext_c_generator.GnuCGenerator()
    print(gen.visit(ast))
コード例 #7
0
def processWitness(witness, benchmark, bitwidth):
    try:
        root = ElementTree.parse(witness).getroot()
    except:
        eprint("INVALID WITNESS FILE: failed to parse XML")
        sys.exit(1)
    # print(ElementTree.tostring(root))
    ns = {'graphml': 'http://graphml.graphdrawing.org/xmlns'}
    graph = root.find('./graphml:graph', ns)
    if graph is None:
        eprint("INVALID WITNESS FILE: failed to parse XML - no graph node")
        sys.exit(1)

    entryFun = validateConfig(graph, ns, witness, benchmark, bitwidth)

    benchmarkString = ''
    with tempfile.NamedTemporaryFile() as fp:
        # preprocess and remove __attribute__
        subprocess.check_call([
            'gcc', '-D__attribute__(x)=', '-x', 'c', '-E', benchmark, '-o',
            fp.name
        ])
        with open(fp.name, 'r') as b:
            needStructBody = False
            skipAsm = False
            for line in b:
                # rewrite some GCC extensions
                """
        line = re.sub(r'__extension__\s*\(\{\s*if\s*\(0\)\s*;\s*else\s+(__assert_fail\s*\("0",\s*".*",\s*\d+,\s*__extension__\s+__PRETTY_FUNCTION__\s*\));\s*\}\)', r'\1', line)
        """
                line = re.sub(r'__extension__', '', line)
                """
        line = re.sub(r'__restrict', 'restrict', line)
        line = re.sub(r'__inline__', 'inline', line)
        line = re.sub(r'__inline', 'inline', line)
        line = re.sub(r'__const', 'const', line)
        """
                line = re.sub(r'__signed__', 'signed', line)
                """
        line = re.sub(r'__builtin_va_list', 'int', line)
        """
                # a hack for some C-standards violating code in LDV benchmarks
                if needStructBody and re.match(r'^\s*}\s*;\s*$', line):
                    line = 'int __dummy; ' + line
                    needStructBody = False
                elif needStructBody:
                    needStructBody = re.match(r'^\s*$', line) is not None
                elif re.match(r'^\s*struct\s+[a-zA-Z0-9_]+\s*{\s*$', line):
                    needStructBody = True
                # remove inline asm
                if re.match(
                        r'^\s*__asm__(\s+volatile)?\s*\("([^"]|\\")*"[^;]*$',
                        line):
                    skipAsm = True
                elif skipAsm and re.search(r'\)\s*;\s*$', line):
                    line = '\n'
                    skipAsm = False
                    line = '\n'
                if (skipAsm or re.match(
                        r'^\s*__asm__(\s+volatile)?\s*\("([^"]|\\")*"[^;]*\)\s*;\s*$',
                        line)):
                    line = '\n'
                # remove asm renaming
                line = re.sub(r'__asm__\s*\(""\s+"[a-zA-Z0-9_]+"\)', '', line)
                benchmarkString += line
    parser = ext_c_parser.GnuCParser()
    ast = parser.parse(benchmarkString, filename=benchmark)
    # ast.show(showcoord=True, buf=sys.stderr)

    inputs = {}
    nondets = {}
    entry = {}
    typedefs = {}
    setupTypes(ast, entryFun, inputs, nondets, entry, typedefs)
    assert entry
    watch = {}
    setupWatch(ast, watch)

    trace = {}
    entryNode = buildTrace(graph, ns, trace)

    values = []
    n = entryNode
    missing_nondets = set(nondets)
    while trace[n].get('target') is not None:
        if trace[n].get('assumption') is not None:
            # assumptions may use = or ==
            a = re.sub(r'==', '=', trace[n]['assumption'])
            a = re.sub(r'\\result', '__SV_COMP_result', a)
            # we may be missing typedefs used in type casts
            a_copy = a
            if re.search(r'\(\s*[a-zA-Z_][a-zA-Z0-9_]*.*\)', a):
                # do two rounds - strictly speaking, we'd need a fixed point here
                for t in typedefs:
                    if t.endswith(' (*)'):
                        a = re.sub(r'%s' % re.escape(t), typedefs[t], a)
                    else:
                        a = re.sub(r'\b%s\b' % re.escape(t), typedefs[t], a)
                for t in typedefs:
                    if t.endswith(' (*)'):
                        a = re.sub(r'%s' % re.escape(t), typedefs[t], a)
                    else:
                        a = re.sub(r'\b%s\b' % re.escape(t), typedefs[t], a)
            wrapped = 'void foo() { ' + a + ';}'
            try:
                block_items = parser.parse(wrapped).ext[0].body.block_items
            except:
                eprint('Failed to parse ' + wrapped + '(expanded from ' +
                       a_copy + ')')
                raise
            for a_ast in block_items:
                if isinstance(a_ast, c_ast.Assignment):
                    f = trace[n].get('assumption.scope')
                    v = ext_c_generator.GnuCGenerator().visit(a_ast.rvalue)
                    if (trace[n].get('startline') is not None and watch.get(
                            int(trace[n]['startline'])) is not None):
                        w = watch[int(trace[n]['startline'])]
                        values.append([w, v])
                        if w in missing_nondets:
                            missing_nondets.remove(w)
                    elif (f is not None and isinstance(a_ast.lvalue, c_ast.ID)
                          and inputs.get(f) is not None
                          and inputs[f].get(a_ast.lvalue.name) is not None):
                        values.append([f, a_ast.lvalue.name, v])
                    # else:
                    #   print(trace[n]['startline'])
                    #   a_ast.show()
                # else:
                #   print(trace[n]['startline'])
                #   a_ast.show()

        n = trace[n]['target']

    if watch and not values:
        eprint('inputs: ')
        eprint(inputs)
        eprint('nondets: ')
        eprint(nondets)
        eprint('watch: ')
        eprint(watch)
        eprint(
            "WARNING: no input values found in witness file, behaviour of harness may be undefined"
        )

    print('IN:')
    print('  ENTRY {n}()@[file {f} line {l}]'.format(n=entryFun,
                                                     f=benchmark,
                                                     l=entry['line']))

    for v in values:
        if len(v) == 3:
            info = inputs[v[0]][v[1]]
            print(
                '  {t} {n}@[file {f} line {l} function {fun}]={value}'.format(
                    t=info['type'],
                    n=v[1],
                    f=benchmark,
                    l=info['line'],
                    fun=v[0],
                    value=v[2]))
        else:
            info = nondets[v[0]]
            print('  {t}@[file {f} line {l}]={value}'.format(t=info['type'],
                                                             f=benchmark,
                                                             l=info['line'],
                                                             value=v[1]))

    for n in missing_nondets:
        info = nondets[n]
        print('  {t}@[file {f} line {l}]=0'.format(t=info['type'],
                                                   f=benchmark,
                                                   l=info['line']))