Ejemplo n.º 1
0
def generate_patch_list(symtab, fw_wrapper, src_files, gen_dir):
    """
    generates a list of patches needed to be applied in order to patch the ELF file
    
    :param symtab: symbol table
    :param fw_wrapper: firmware wrapper header file
    :param src_files: list of patch source code files
    :param gen_dir: destination directory for generated (intermediate) files
    """
    patches = []
    for filename in src_files:
        text = preprocess_file(filename, 'hexagon-cpp',
                               '-DFW_WRAPPER="' + fw_wrapper + '"')

        try:  # pycparserext >= 2016.2
            parser = GnuCParser(taboutputdir=gen_dir)
        except TypeError:
            parser = GnuCParser()
        ast = parser.parse(text, filename)

        v = FuncDefVisitor()
        v.visit(ast)

        patches.extend(v.patches)
    return patches
Ejemplo n.º 2
0
def show_func(filename):

    use_cpp=True # 执行预处理 execute the C pre-processor  可以去除注释  和 宏定义等
    #use_cpp = False
    if use_cpp:
        from pycparser import preprocess_file
        cpp_path = 'cpp'                      # 预处理 器 路径
        cpp_args=r'-Iutils/fake_libc_include' # command line arguments 预处理选项
        text = preprocess_file(filename, cpp_path, cpp_args)
    else:
        import io
        with io.open(filename) as f:
            text = f.read()
            
    if not use_cpp:
        # 去除注释
        import decomment as dc
        rc = dc.rmcmnt("c")
        text, rm = rc.removecomment(text)
        
    parser = c_parser.CParser()
    global ast
    ast = parser.parse(text, filename)
    
    # 显示函数定义的信息
    show_func_def(ast)
    
    # 显示函数调用树
    print("func_call_tree:")
    call_tree_d = show_func_call_tree("main",ast)
    print_func_call_tree(call_tree_d)
Ejemplo n.º 3
0
def generate_org_fw_functions(src_files, org_functions_file,
                              org_functions_header, org_functions_lcs, symtab,
                              base_elf, gen_dir):
    """
    determines the helper functions required to generate and writes them
    
    :param src_files:               list of source code files
    :param org_functions_file:      destination file for generated c-code
    :param org_functions_header:    destination file for generated header code
    :param org_functions_lcs:       destination file for generated linker symbol definitions
    :param symtab:                  symbol table
    :param base_elf:                base firmware ELF file
    :param gen_dir:                 destination directory for generated (intermediate) files
    """
    # determine required original function helpers
    req_org_funcs = Set()
    for src_file in src_files:
        text = preprocess_file(src_file, 'hexagon-cpp',
                               r'-DFW_WRAPPER="/dev/null"')

        try:  # pycparserext >= 2016.2
            parser = GnuCParser(taboutputdir=gen_dir)
        except TypeError:
            parser = GnuCParser()
        ast = parser.parse(text, src_file)

        v = FuncCallVisitor()
        v.visit(ast)

        req_org_funcs = req_org_funcs.union(v.get_req_org_funcs())

    # generate and write the functions
    write_functions(req_org_funcs, org_functions_file, org_functions_header,
                    org_functions_lcs, symtab, base_elf)
Ejemplo n.º 4
0
def process_file(filename, incpath):
	cppargs = ["-Iutils/fake_libc_include", "-I%s" % incpath,
			"-DDECLSPEC=",
			"-D_SDL_platform_h=1",
			"-D_SDL_endian_h=1",
			"-DSDL_FORCE_INLINE=", "-D__attribute__(x)=",
	];
	ast = parse_file(filename, use_cpp=True, cpp_args=cppargs);
	v = visitor();
	v.visit(ast);

	del ast;

	cppargs.append("-dM");
	defines_text = preprocess_file(filename, cpp_args=cppargs);
	for s in defines_text.split("\n"):
		if s[:8] == "#define ":
			s = s[8:];
			m = re.search("(SDL_[A-Za-z0-9_]+)", s);
			if m != None:
				d = m.group(0);
				if isinstance(d, str) and len(d) > 4 and d == d.upper():
					v.defines.append(d);

	generate_output("sdl2.vim", v);
Ejemplo n.º 5
0
def get_header_text(path, include_path=[], defines=[], strip_includes=False):
    if strip_includes:
        with open(path, 'r') as f:
            text = f.read()

        text = re.sub(r'#include.*', '', text)
        tfile, path = tempfile.mkstemp()
        try:
            os.write(tfile, text.encode('utf-8'))
        finally:
            os.close(tfile)

    else:
        tfile = None

    cpp_args = []

    if include_path:
        for ip in include_path:
            cpp_args.extend(['-I', ip])

    if defines:
        for d in defines:
            cpp_args.extend(['-D', d])

    try:
        text = pycparser.preprocess_file(path, cpp_args=cpp_args)
    finally:
        if tfile is not None:
            os.unlink(path)

    return text
Ejemplo n.º 6
0
def process_file(filename, incpath):
    cppargs = [
        "-Iutils/fake_libc_include",
        "-I%s" % incpath,
        "-DDECLSPEC=",
        "-D_SDL_platform_h=1",
        "-D_SDL_endian_h=1",
        "-DSDL_FORCE_INLINE=",
        "-D__attribute__(x)=",
    ]
    ast = parse_file(filename, use_cpp=True, cpp_args=cppargs)
    v = visitor()
    v.visit(ast)

    del ast

    cppargs.append("-dM")
    defines_text = preprocess_file(filename, cpp_args=cppargs)
    for s in defines_text.split("\n"):
        if s[:8] == "#define ":
            s = s[8:]
            m = re.search("(SDL_[A-Za-z0-9_]+)", s)
            if m != None:
                d = m.group(0)
                if isinstance(d, str) and len(d) > 4 and d == d.upper():
                    v.defines.append(d)

    generate_output("sdl2.vim", v)
Ejemplo n.º 7
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
Ejemplo n.º 8
0
def parse_file_text(filename, use_cpp=False, cpp_path='cpp', cpp_args=''):
    with open(filename) as f:
        raw_text = f.read()

    if use_cpp:
        text = preprocess_file(filename, cpp_path, cpp_args)
    else:
        text = raw_text

    return raw_text, CParser().parse(text, filename)
Ejemplo n.º 9
0
def parse_ast(file_path, clean=False):
    global cparser

    text = preprocess_file(file_path)

    text = prepare_code(text)

    if clean:
        text = clean_code(text)

    return cparser.parse(text, file_path)
Ejemplo n.º 10
0
def write_files(dir_list, header_include, out_dir, fn_names):
    header_file = header_include.split('/')[-1]

    is_valid_file = [
        os.path.isfile(dir_name + header_file) for dir_name in dir_list
    ]

    if not any(is_valid_file):
        print "Skipped all functions in %s because it could not be found in %s." % (
            header_file, dir_list)
        return
    else:
        header_file = dir_list[is_valid_file.index(True)] + header_file

    # pycparser utility function for preprocessing the file and
    # getting all of the file as a string
    text = preprocess_file(header_file)

    # use pycparserext to parse the GNU C header file
    p = GnuCParser()
    ast = p.parse(text)

    # loop over all functions requested
    for fn in fn_names:
        found = False

        # loop over the ast
        for node in ast.ext:
            if isinstance(node, c_ast.FuncDef) or not isinstance(
                    node.type, c_ast.FuncDecl):
                continue

            # skip over functions with __noreturn__
            if hasattr(node.type.type, 'attributes') and any([
                    e.name == "__noreturn__"
                    for e in node.type.type.attributes.exprs
            ]):
                continue

            if node.name != fn[0]:
                continue

            found = True

            write_file(out_dir, header_include, node, fn[1], fn[2])

        if not found:
            print "The header file %s does not contain a method signature for %s" % (
                header_file, fn[0])
Ejemplo n.º 11
0
    def __init__(self, file_name, entropy_subset_length=5):

        #preprocess the file
        # print("Make sure to remove all the library includes")
        # subprocess.call("gcc -E -std=c99 -I/my_pycparser/utils/fake_libc_include " +
        #                            file_name +  " -o preprocessed.c")

        #from pycparser import preprocess_file,c_parser
        cpp_path = 'cpp'  # 预处理 器 路径
        cpp_args = r'-Iutils/fake_libc_include'  # command line arguments 预处理选项
        text = preprocess_file(file_name, cpp_path, cpp_args)
        parser = c_parser.CParser()
        #self.ast = pycparser.parse_file(file_name, use_cpp=True)
        self.ast = parser.parse(text, file_name)
        self.entropy_subset_length = entropy_subset_length
        self.current_entropy_subset_length = 0
Ejemplo n.º 12
0
 def get_mappings(self):
     pk = pkgconfig.parse("tss2-esys")
     header_path = None
     for ip in pk["include_dirs"]:
         hp = os.path.join(ip, "tss2_tpm2_types.h")
         if os.path.isfile(hp):
             header_path = hp
             break
         hp = os.path.join(ip, "tss2", "tss2_tpm2_types.h")
         if os.path.isfile(hp):
             header_path = hp
             break
     if header_path is None:
         raise RuntimeError(
             f"unable to find tss2_tpm2_types.h in {pk['include_dirs']}")
     pdata = preprocess_file(
         header_path, cpp_args=["-D__extension__=", "-D__attribute__(x)="])
     parser = c_parser.CParser()
     ast = parser.parse(pdata, "tss2_tpm2_types.h")
     tm = self.get_types(ast)
     return self.generate_mappings(ast, tm)
def generate_wrapper_lcs(filename, lcs_file, symtab_json_file, gen_dir):
    """
    main linker script generation function
    
    :param filename: firmware wrapper header
    :param lcs_file: destination file
    :param symtab_json_file: destination file for symbol table in JSON format
    :param gen_dir: destination directory for generated (intermediate) files
    """
    text = preprocess_file(filename, 'hexagon-cpp')

    try:  # pycparserext >= 2016.2
        parser = GnuCParser(taboutputdir=gen_dir)
    except TypeError:
        parser = GnuCParser()
    ast = parser.parse(text, filename)

    v = DeclVisitor(lcs_file)
    v.visit(ast)

    json.dump(v.get_symtab(), open(symtab_json_file, 'w'))
def parse_prepro(filename):
    os.system("sed -i 's/asm volatile/asm/' '%s'" % filename)
    os.system("sed -i 's/asm __volatile__/asm/' '%s'" % filename)

    cpp_path = "arm-none-eabi-cpp"
    cpp_args = [
        '-Dasm(...)=',
        '-D__asm__(...)=',
        '-D__extension__=',
        '-D__attribute__(...)=',
        '-D__builtin_va_list=int',
        '-D__builtin_va_arg(a,b)=0',
    ]

    text = preprocess_file(filename, cpp_path, cpp_args)

    # pycparser doesn't like a C file to begin with ;
    # (happens after removing the first asm block from arm-mcr.h)
    text = "struct __dummy__;\n" + text
    #~ print(text)

    return c_parser.CParser().parse(text, lookup_c(filename))
Ejemplo n.º 15
0
    url = f"https://github.com/maxsei/bimax/releases/download/v0.0.1/{goos}_{goarch}.tar.gz"
    resp = requests.get(url)
    if not resp.ok:
        raise Exception(
            f"could not find release for os: {goos} arch: {goarch} at {url}")
    # Read in the content of the request and extract tar
    buf = io.BytesIO(resp.content)
    archive = tarfile.open(fileobj=buf)
    archive.extractall()

# Preprocess header file
pp = pycparser.preprocess_file(
    str(header_filename),
    cpp_path="gcc",
    cpp_args=[
        "-E",
        "-x",
        "c",
        "-std=c99",
    ],
)
# pycparser.c_ast.Compound
# ast = pycparser.c_parser.CParser().parse(pp)

# TODO: simply commenting out the void pointer compile time check that go
# does for now but the future would be cool to do static simplification of
# the ast in the header file i.e. replacing int[2 + 2] with int[4]<25-01-21, Max Schulte> #

pp = "\n".join(
    filter(
        lambda x: "_check_for_64_bit_pointer_matching_GoInt" not in x,
        pp.split("\n"),
Ejemplo n.º 16
0
    return "\n".join(v.assembly)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="GOLF C compiler.")
    parser.add_argument("file", help="source file")
    parser.add_argument("-o",
                        metavar="file",
                        dest="binary_out",
                        help="output file")
    parser.add_argument("-S",
                        metavar="file",
                        dest="assembly_out",
                        help="also produce assembly to the given file")

    args = parser.parse_args()

    source = preprocess_file(args.file)

    #with open(args.file) as in_file:
    #    source = in_file.read()

    assembly = compile(args.file, source)

    if args.assembly_out:
        with open(args.assembly_out, "wb") as out_file:
            out_file.write(assembly)
    else:
        print "Warning: binary output not implemented yet"
Ejemplo n.º 17
0
    v = CompilerVisitor(filename)
    v.visit(ast)

    if v.calls - v.labels:
        print "Warning: No labels for calls [%s]" % ", ".join(v.calls - v.labels)

    return "\n".join(v.assembly)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="GOLF C compiler.")
    parser.add_argument("file", help="source file")
    parser.add_argument("-o", metavar="file", dest="binary_out", help="output file")
    parser.add_argument("-S", metavar="file", dest="assembly_out",
                        help="also produce assembly to the given file")

    args = parser.parse_args()

    source = preprocess_file(args.file)

    #with open(args.file) as in_file:
    #    source = in_file.read()

    assembly = compile(args.file, source)

    if args.assembly_out:
        with open(args.assembly_out, "wb") as out_file:
            out_file.write(assembly)
    else:
        print "Warning: binary output not implemented yet"
Ejemplo n.º 18
0
def preprocess(file: str, cpp_args: List[str] = []) -> str:
    preprocessed = preprocess_file(file,
                                   cpp_args=cpp_args + ['-P', '-nostdinc'])
    return preprocessed
Ejemplo n.º 19
0
def preprocess_file(filename, jdi=True):
    if jdi:
        return pycparser.preprocess_file(
            filename, cpp_args=[r'-Iutils/fake_libc_include'])
    return open(filename, 'r').read()
Ejemplo n.º 20
0
parser = c_parser.CParser()

header_info = HeaderInfo()
for root, dir_, files in os.walk(u'.'):
    for file_ in files:
        # cut out the ./
        header = os.path.join(root, file_)[2:]
        if header in [
                'sys/signal.h', 'sys/fcntl.h', 'sys/errno.h', 'sys/termios.h',
                'sys/poll.h', 'wait.h'
        ]:
            # these are annoying files that just put up a warning telling you the correct header to use
            continue
        cfile = preprocess_file(header,
                                cpp_path='clang',
                                cpp_args=['-E'] + cpp_args)
        try:
            ast = parser.parse(cfile)
            header_info.visit(ast)
        except Exception as e:
            # This isn't necessarily a bad thing. Some of the header files are strictly meant to be included by other
            # files.
            if header not in [
                    'bits/sem.h', 'bits/ipc.h', 'bits/stat.h', 'bits/statfs.h',
                    'bits/msg.h', 'bits/shm.h', 'bits/user.h',
                    'bits/termios.h', 'bits/link.h', 'bits/socket.h',
                    'bits/stdint.h', 'atomic_arch.h'
            ]:

                print("Couldn\'t parse file.", header, e)
Ejemplo n.º 21
0
import cffi
import pycparser

# XXX CFFI cdef() does not allow inline functions, which is more or less all of
# capsicum_helpers.h.
# TODO: Casper.

cappp = pycparser.preprocess_file("/usr/include/sys/capsicum.h",
    cpp_args=[
        '-P',     # Don't generate line markers
        '-undef', # Don't include predefined macros (most of them, anyway)
        '-dD',    # Keep '#define' directives
        '-D_SYS_CDEFS_H_',
        '-D_SYS_TYPES_H_',
        '-D_SYS__TYPES_H_',
        '-D_SYS_PARAM_H_',
        '-D_SYS_FILE_H_',
        '-D_SYS_FCNTL_H_',
        '-D__BEGIN_DECLS=',
        '-D__END_DECLS=',
        '-Du_int=unsigned',
        '-Dcap_ioctl_t=unsigned long',
    ])

cdefs = []
trailing_trash = False
for line in cappp.splitlines():
    # Remove remnents of deleted multi-line macros.
    if trailing_trash:
        if not line.endswith('\\'):
            trailing_trash = False