Ejemplo n.º 1
0
    def _get_cf_struct(self, automaton, params):
        """
        Provides declaration of structure to pack all control function (or maybe other) parameters as a single argument
        with help of it.

        :param automaton: Automaton object.
        :param params: Declaration objects list.
        :return: Declaration object.
        """
        # todo: ensure proper ordering of structure parameters especially arrays, bit fields and so on.
        cache_identifier = ''
        for param in params:
            cache_identifier += param.identifier

        if cache_identifier not in self._structures:
            struct_name = 'ldv_struct_{}_{}'.format(automaton.process.name, automaton.identifier)
            if struct_name in self._structures:
                raise KeyError('Structure name is not unique')

            decl = import_declaration('struct {} a'.format(struct_name))
            for index in range(len(params)):
                decl.fields['arg{}'.format(index)] = params[index]
            decl.fields['signal_pending'] = import_declaration('int a')

            self._structures[cache_identifier] = decl
        else:
            decl = self._structures[cache_identifier]

        return decl
Ejemplo n.º 2
0
 def get_clean_declaration(c, desc, i):
     if "declaration" in desc:
         decl = import_declaration(desc["declaration"])
     else:
         raise ValueError(
             "Provide declaration at the interface specification of '{}.{}'".format(c, i))
     return decl
Ejemplo n.º 3
0
    def check_ast(given_ast, declarator, iint):
        try:
            probe_ast = copy.deepcopy(given_ast)
            cl = import_declaration(None, probe_ast)
            expr = cl.to_string(declarator)
            return expr, None
        except KeyError:
            if 'specifiers' in given_ast and 'category' in given_ast['specifiers'] and \
                    'identifier' in given_ast['specifiers']:
                n = given_ast['specifiers']['identifier']
                category = given_ast['specifiers']['category']
                i = collection.get_intf("{}.{}".format(category, n))
                if 'pointer' in given_ast['specifiers'] and given_ast['specifiers']['pointer']:
                    d = i.declaration.take_pointer.to_string(declarator)
                else:
                    d = i.declaration.to_string(declarator)
                return d, i
            else:
                if check_function(given_ast):
                    if 'specifiers' not in given_ast:
                        parameter_declarations = []
                        for index, p in enumerate(given_ast['declarator'][0]['function arguments']):
                            if isinstance(p, str):
                                parameter_declarations.append(p)
                            else:
                                expr, i = check_ast(p, 'a', None)
                                if iint and i:
                                    iint.set_param_interface(index, i)
                                parameter_declarations.append(expr)

                        if len(parameter_declarations) == 0:
                            declarator += '(void)'
                        else:
                            declarator += '(' + ', '.join(parameter_declarations) + ')'

                        declarator, i = check_ast(given_ast['return value type'], declarator, None)
                        if iint and i:
                            iint.rv_interface = i

                        return declarator, None

                elif check_array(given_ast):
                    array = given_ast['declarator'][-1]['arrays'].pop()
                    size = array['size']
                    given_ast = reduce_level(given_ast)
                    if not size:
                        size = ''
                    declarator += '[{}]'.format(size)
                    return check_ast(given_ast, declarator, iint)
                elif 'pointer' in given_ast['declarator'][-1] and given_ast['declarator'][-1]['pointer'] > 0:
                    given_ast['declarator'][-1]['pointer'] -= 1
                    given_ast = reduce_level(given_ast)
                    if check_array(given_ast) or check_function(given_ast):
                        declarator = '(*' + declarator + ')'
                    else:
                        declarator = '*' + declarator
                    return check_ast(given_ast, declarator, iint)
                else:
                    raise NotImplementedError
Ejemplo n.º 4
0
    def _import_label(self, name, dic):
        label = self.LABEL_CONSTRUCTOR(name)

        for att in self.LABEL_ATTRIBUTES:
            if att in dic:
                if self.LABEL_ATTRIBUTES[att]:
                    attname = self.LABEL_ATTRIBUTES[att]
                else:
                    attname = att
                setattr(label, attname, dic[att])

        if label.declaration:
            label.declaration = import_declaration(label.declaration)

        return label
Ejemplo n.º 5
0
 def _entry_point(self):
     self._logger.info(
         "Finally generate an entry point function {!r}".format(
             self._cmodel.entry_name))
     if get_conf_property(self._conf, "self parallel model"):
         self._control_function(
             self._entry_fsa).declaration = import_declaration(
                 "void *(*start_routine)(void *)")
         name = self._control_function(self._entry_fsa).name
         body = [
             "pthread_t **thread;",
             "pthread_create_N(thread, 0, {}, 0);".format(name),
             "pthread_join_N(thread, {});".format(name)
         ]
     else:
         body = [
             '{}(0);'.format(self._control_function(self._entry_fsa).name)
         ]
     return self._cmodel.compose_entry_point(body)
Ejemplo n.º 6
0
    def __init__(self, name, declaration):
        self.name = name
        self.static = False
        self.raw_declaration = None
        self.declaration = None
        self.value = None
        self.declaration_files = set()
        self.use = 0
        self.initialization_file = None

        if not declaration:
            declaration = 'void f(void)'
        if isinstance(declaration, str):
            self.declaration = import_declaration(declaration)
            self.raw_declaration = declaration
        elif issubclass(type(declaration), Declaration):
            self.declaration = declaration
        else:
            raise ValueError(
                "Attempt to add variable {!r} without signature".format(name))
Ejemplo n.º 7
0
    def __init__(self, name, declaration=None):
        self.name = name
        self.static = False
        self.raw_declaration = None
        self.declaration = None
        self.body = []
        self.calls = dict()
        self.called_at = dict()
        self.declaration_files = set()
        self.definition_file = None
        self.header_files = list()

        if not declaration:
            declaration = 'void f(void)'
        if isinstance(declaration, str):
            self.declaration = import_declaration(declaration)
            self.raw_declaration = declaration
        elif issubclass(type(declaration), Declaration):
            self.declaration = declaration
        else:
            raise ValueError(
                "Attempt to add function {!r} without signature".format(name))
Ejemplo n.º 8
0
def __generate_insmod_process(logger, conf, source, inits, exits,
                              kernel_initializations):
    logger.info(
        "Generate artificial process description to call Init and Exit module functions 'insmod'"
    )
    ep = Process("insmod")
    ep.category = 'linux'
    ep.comment = "Initialize or exit module."
    ep.self_parallelism = False
    ep.identifier = 0
    ep.process = ''
    ep.pretty_id = 'linux/initialization'

    if len(kernel_initializations) > 0:
        body = ["int ret;"]
        label_name = 'ldv_kernel_initialization_exit'

        # Generate kernel initializations
        for name, calls in kernel_initializations:
            for filename, func_name in calls:
                func = source.get_source_function(func_name, filename)
                if func:
                    retval = False if func.declaration.return_value.identifier == 'void' else True
                else:
                    raise RuntimeError(
                        "Cannot resolve function {!r} in file {!r}".format(
                            name, filename))
                new_name = __generate_alias(ep, func_name, filename, retval)
                statements = [
                    model_comment('callback', func_name,
                                  {'call': "{}();".format(func_name)}),
                ]
                if retval:
                    statements.extend([
                        "ret = {}();".format(new_name),
                        "ret = ldv_post_init(ret);", "if (ret)",
                        "\tgoto {};".format(label_name)
                    ])
                else:
                    statements.append("{}();".format(new_name))

                body.extend(statements)
        body.extend(["{}:".format(label_name), "return ret;"])
        func = Function('ldv_kernel_init', 'int ldv_kernel_init(void)')
        func.body = body
        addon = func.define()
        ep.add_definition('environment model', 'ldv_kernel_init', addon)
        ki_subprocess = ep.add_condition('kernel_initialization', [],
                                         ["%ret% = ldv_kernel_init();"],
                                         'Kernel initialization stage.')
        ki_subprocess.trace_relevant = True
        ki_success = ep.add_condition('kerninit_success', ["%ret% == 0"], [],
                                      "Kernel initialization is successful.")
        ki_failed = ep.add_condition('kerninit_failed', ["%ret% != 0"], [],
                                     "Kernel initialization is unsuccessful.")
    if len(inits) > 0:
        # Generate init subprocess
        for filename, init_name in inits:
            new_name = __generate_alias(ep, init_name, filename, True)
            init_subprocess = Condition(init_name)
            init_subprocess.comment = 'Initialize the module after insmod with {!r} function.'.format(
                init_name)
            init_subprocess.statements = [
                model_comment('callback', init_name,
                              {'call': "{}();".format(init_name)}),
                "%ret% = {}();".format(new_name),
                "%ret% = ldv_post_init(%ret%);"
            ]
            init_subprocess.trace_relevant = True
            logger.debug("Found init function {}".format(init_name))
            ep.actions[init_subprocess.name] = init_subprocess

    # Add ret label
    ep.add_label('ret', import_declaration("int label"))

    # Generate exit subprocess
    if len(exits) == 0:
        logger.debug("There is no exit function found")
    else:
        for filename, exit_name in exits:
            new_name = __generate_alias(ep, exit_name, filename, False)
            exit_subprocess = Condition(exit_name)
            exit_subprocess.comment = 'Exit the module before its unloading with {!r} function.'.format(
                exit_name)
            exit_subprocess.statements = [
                model_comment('callback', exit_name,
                              {'call': "{}();".format(exit_name)}),
                "{}();".format(new_name)
            ]
            exit_subprocess.trace_relevant = True
            logger.debug("Found exit function {}".format(exit_name))
            ep.actions[exit_subprocess.name] = exit_subprocess

    # Generate conditions
    success = ep.add_condition('init_success', ["%ret% == 0"], [],
                               "Module has been initialized.")
    ep.actions[success.name] = success
    # Generate else branch
    failed = ep.add_condition('init_failed', ["%ret% != 0"], [],
                              "Failed to initialize the module.")
    ep.actions[failed.name] = failed

    # Add subprocesses finally
    process = ''
    for i, pair in enumerate(inits):
        process += "<{0}>.(<init_failed>".format(pair[1])
        for j, pair2 in enumerate(exits[::-1]):
            if pair2[0] == pair[0]:
                break
        j = 1
        for _, exit_name in exits[:j - 1:-1]:
            process += ".<{}>".format(exit_name)
        process += "|<init_success>."

    for _, exit_name in exits:
        process += "<{}>.".format(exit_name)
    # Remove the last dot
    process = process[:-1]

    process += ")" * len(inits)

    if len(kernel_initializations) > 0 and len(inits) > 0:
        ep.process += "<{}>.(<{}> | <{}>.({}))".format(ki_subprocess.name,
                                                       ki_failed.name,
                                                       ki_success.name,
                                                       process)
    elif len(kernel_initializations) == 0 and len(inits) > 0:
        ep.process += process
    elif len(kernel_initializations) > 0 and len(inits) == 0:
        ep.process += "<{}>.(<{}> | <{}>)".format(ki_subprocess.name,
                                                  ki_failed.name,
                                                  ki_success.name, process)
    else:
        raise NotImplementedError(
            "There is no both kernel initilization functions and module initialization functions"
        )
    return ep
Ejemplo n.º 9
0
    'void a(void)', 'void a(int, ...)', 'void (*a) (int, ...)',
    "int func(int, void (*)(void))", "int func(void (*)(void), int)",
    "int func(int, int (*)(int))", "int func(int, void (*)(void *))",
    "int func(int *, void (*)(void))", "int func(int, int (*)(int))",
    "int func(int *, int (*)(int, int))",
    "int func(int *, int (*)(int, int), ...)", "int (*f)(int *)",
    "int (*f)(int *, int *)", "int func(struct nvme_dev *, void *)",
    "int (*f)(struct nvme_dev *, void *)",
    "void (**a)(struct nvme_dev *, void *)", "void (**a)",
    "void func(struct nvme_dev *, void *, struct nvme_completion *)",
    "void (**a)(void)", "void (**a)(struct nvme_dev * a)",
    "void (**a)(struct nvme_dev * a, int)",
    "void (**a)(struct nvme_dev * a, void * a)",
    "void (**a)(struct nvme_dev *, void *)",
    "void (**a)(struct nvme_dev *, void *, struct nvme_completion *)",
    "void (**a)(struct nvme_dev *, void *, int (*)(void))",
    "int func(int (*)(int))", "int func(int (*)(int *), ...)",
    "int func(int (*)(int, ...))", "int func(int (*)(int, ...), ...)",
    "int (*a)(int (*)(int, ...), ...)",
    'void (*((*a)(int, ...)) []) (void) []', '%usb.driver%',
    '$ my_function($, %usb.driver%, int)',
    '%usb.driver% function(int, void *)',
    '%usb.driver% function(int, $, %usb.driver%)'
]

for test in __grammar_tests:
    print(test)
    object = import_declaration(test)
    #print(object.pretty_name)
    print(object.identifier)
    print(object.to_string('a'))
Ejemplo n.º 10
0
def __import_entities(collection, sa, entities):
    def determine_category(e, decl):
        c = None
        if 'category' in e:
            c = e['category']
        else:
            resolved = collection.resolve_interface_weakly(decl)
            if len(resolved) == 1:
                c = resolved[0].category
        return c

    while len(entities) > 0:
        entity = entities.pop()
        bt = entity["type"]

        if "value" in entity["description"] and isinstance(
                entity["description"]['value'], str):
            if is_not_null_function(bt, entity["description"]["value"]):
                category = entity["category"] if "category" in entity else None
                intfs = list(
                    check_relevant_interface(collection, entity["type"],
                                             category,
                                             entity["root sequence"][-1]))
                if len(intfs) == 0 and isinstance(entity["type"], Pointer) and \
                        isinstance(entity["type"].points, Function):
                    containers = collection.resolve_interface_weakly(
                        entity['parent type'], category)
                    for container in (c for c in containers
                                      if isinstance(c, StructureContainer)):
                        if "{}.{}".format(container.category,
                                          entity["root sequence"]
                                          [-1]) not in collection.interfaces:
                            identifier = entity["root sequence"][-1]
                        elif "{}.{}".format(container.category, entity["type"].pretty_name) \
                                not in collection.interfaces:
                            identifier = entity["type"].pretty_name
                        else:
                            raise RuntimeError(
                                "Cannot yield identifier for callback {!r} of category {!r}"
                                .format(entity["type"].identifier,
                                        container.category))
                        interface = Callback(container.category, identifier)
                        interface.declaration = entity["type"]
                        collection.set_intf(interface)
                        container.field_interfaces[entity["root sequence"]
                                                   [-1]] = interface
                        intfs.append(interface)
                        break

                for intf in intfs:
                    impl = intf.add_implementation(
                        entity["description"]["value"], entity['type'],
                        entity['path'], entity["root type"],
                        entity["root value"], entity["root sequence"])
                    impl.static = __check_static(
                        entity["description"]["value"], entity['path'], sa)

        elif "value" in entity["description"] and isinstance(
                entity["description"]['value'], list):
            if isinstance(bt, Array):
                for entry in entity["description"]['value']:
                    if not entity["root type"]:
                        new_root_type = bt
                    else:
                        new_root_type = entity["root type"]

                    e_bt = bt.element
                    new_sequence = list(entity["root sequence"])
                    new_sequence.append(entry['index'])
                    new_desc = {
                        "type": e_bt,
                        "description": entry,
                        "path": entity["path"],
                        "parent type": bt,
                        "root type": new_root_type,
                        "root value": entity["root value"],
                        "root sequence": new_sequence
                    }

                    category = determine_category(entity, e_bt)
                    if category:
                        new_desc["category"] = category

                    entities.append(new_desc)
            elif isinstance(bt, Structure) or isinstance(bt, Union):
                for entry in entity["description"]['value']:
                    if not entity["root type"] and not entity["root value"]:
                        new_root_type = bt
                        new_root_value = entity["description"]["value"]
                    else:
                        new_root_type = entity["root type"]
                        new_root_value = entity["root value"]

                    field = extract_name(entry['field'])
                    # Ignore actually unions and structures without a name
                    if field:
                        e_bt = import_declaration(entry['field'], None)
                        e_bt.add_parent(bt)
                        new_sequence = list(entity["root sequence"])
                        new_sequence.append(field)

                        new_desc = {
                            "type": e_bt,
                            "description": entry,
                            "path": entity["path"],
                            "parent type": bt,
                            "root type": new_root_type,
                            "root value": new_root_value,
                            "root sequence": new_sequence
                        }
                        category = determine_category(entity, e_bt)
                        if category:
                            new_desc["category"] = category

                        bt.fields[field] = e_bt
                        entities.append(new_desc)
            else:
                raise NotImplementedError
        else:
            raise TypeError('Expect list or string')