Exemplo n.º 1
0
def make_params_reading(syscall):
    stmts = []
    for a in syscall.input_args:
        opt = opt_of_syscall(SYSCALLS, syscall, a)
        indent = (0 if opt is None else 4) * " "

        name = a.name
        if a.datatype == "void *":
            fmt = "{indent}{name} = mIn.read((int){size});"
            size = SYSCALLS[syscall.name][name].size
            stmts.append(fmt.format(**locals()))
            continue

        meth = read_method_of_c_datatype(a.datatype)
        if meth is None:
            # TODO: Remove here. This is temporary escaping from compile error.
            if (a.datatype[-1] == "*") or (a.datatype == "caddr_t"):
                initval = "null"
            else:
                initval = "0"
            stmts.append("{indent}{name} = {initval};".format(**locals()))
            continue

        if opt is not None:
            stmts.append("if ({opt}) {{".format(**locals()))
        stmts.append("{indent}{name} = mIn.{meth}();".format(**locals()))
        if opt is not None:
            stmts.append("}")

    return ("\n" + 12 * " ").join(stmts)
Exemplo n.º 2
0
def print_encoding(p, syscall):
    for a in syscall.input_args:
        if a.datatype == "void *":
            continue

        if data_of_argument(syscall, a).fd:
            fmt = "{name} = lfd"
        else:
            fmt = "{name} = uap->{name}"
        p("\t" + fmt.format(**vars(a)) + ";\n")
        if a.datatype == "struct iovec *":
            concrete_datatype = concrete_datatype_of_abstract_datatype("size_t")
            size = data_of_argument(syscall, a).size
            name = a.name
            p("""\
\t{name}_iov_len_buf = (char (*)[FSYSCALL_BUFSIZE_UINT64])malloc(
\t\tsizeof(char [FSYSCALL_BUFSIZE_UINT64]) * {size},
\t\tM_TEMP,
\t\tM_WAITOK);
\t{name}_iov_len_len = (int *)malloc(
\t\tsizeof(u_int) * iovcnt,
\t\tM_TEMP,
\t\tM_WAITOK);
\tfor (i = 0; i < iovcnt; i++) {{
\t\t{name}_iov_len_len[i] = fsyscall_encode_{concrete_datatype}(
\t\t\t{name}[i].iov_len,
\t\t\t{name}_iov_len_buf[i],
\t\t\tarray_sizeof({name}_iov_len_buf[i]));
\t\tif ({name}_iov_len_len[i] < 0)
\t\t\treturn (EMSGSIZE);
\t}}
""".format(**locals()))
            continue

        if a.datatype == "char *":
            p("""\
\t{name}_len = strlen({name});
""".format(name=a.name))
            name = "{name}_len".format(**vars(a))
        else:
            name = a.name
        concrete_datatype = concrete_datatype_of_abstract_datatype(a.datatype)
        opt = opt_of_syscall(FMASTER_SYSCALLS, syscall, a)
        if opt is not None:
            expr_head = "{opt} ? ".format(**locals())
            expr_tail = " : 0"
        else:
            expr_head = expr_tail = ""
        p("""\
\t{name}_len = {expr_head}fsyscall_encode_{concrete_datatype}(
\t\t{name},
\t\t{name}_buf,
\t\tarray_sizeof({name}_buf)){expr_tail};
\tif ({name}_len < 0)
\t\treturn (EMSGSIZE);
""".format(**locals()))
Exemplo n.º 3
0
def make_params_declarations(syscall):
    stmts = []
    for a in syscall.input_args:
        opt = opt_of_syscall(SYSCALLS, syscall, a)

        name = a.name
        datatype = java_datatype_of_c_datatype(a.datatype)
        initval = "" if opt is None else " = 0"
        stmts.append("{datatype} {name}{initval}".format(**locals()))

    return (";\n" + 12 * " ").join(stmts)
Exemplo n.º 4
0
def print_write(p, print_newline, syscall):
    cmd_name = make_cmd_name(syscall.name)
    p("""\
\terror = fmaster_write_command(td, {cmd_name}_CALL);
\tif (error != 0)
\t\treturn (error);
""".format(**locals()))

    input_arguments = syscall.input_args
    for a in [a for a in input_arguments if a.datatype == "struct iovec *"]:
        name = a.name
        size = data_of_argument(syscall, a).size
        p("""\
\t{name}_payload_size = 0;
\tfor (i = 0; i < {size}; i++)
\t\t{name}_payload_size += {name}_iov_len_len[i] + {name}[i].iov_len;
""".format(**locals()))

    payload_size_expr = make_payload_size_expr(syscall, input_arguments)
    p("""\
\tpayload_size = {payload_size_expr};
\terror = fmaster_write_payload_size(td, payload_size);
\tif (error != 0)
\t\treturn (error);
""".format(**locals()))
    if len(input_arguments) == 0:
        return

    p("""\
\twfd = fmaster_wfd_of_thread(td);
""".format(**locals()))
    for a in syscall.input_args:
        if a.datatype == "char *":
            buf = "{name}_len_buf".format(**vars(a))
            size = "{name}_len_len".format(**vars(a))
            print_fmaster_write(p, buf, size)
            print_fmaster_write(p, a.name, "{name}_len".format(**vars(a)))
            continue

        if a.datatype == "void *":
            name = a.name
            size = SYSCALLS[syscall.name][name].size
            p("""\
\terror = fmaster_write_from_userspace(td, wfd, uap->{name}, {size});
\tif (error != 0)
\t\treturn (error);
""".format(**locals()))
            continue

        if a.datatype == "struct iovec *":
            p("""\
\tfor (i = 0; i < iovcnt; i++) {{
""".format(**locals()))

            buf = "{name}_iov_len_buf[i]".format(**vars(a))
            size = "{name}_iov_len_len[i]".format(**vars(a))
            print_fmaster_write(p, buf, size, 2)

            buf = "{name}[i].iov_base".format(**vars(a))
            size = "{name}[i].iov_len".format(**vars(a))
            print_fmaster_write(p, buf, size, 2)

            p("""\
\t}}
""".format(**locals()))
            continue

        opt = opt_of_syscall(FMASTER_SYSCALLS, syscall, a)
        if opt is not None:
            p("""\
\tif (!({opt}))
\t\treturn (0);
""".format(**locals()))
        buf = "{name}_buf".format(**vars(a))
        size = "{name}_len".format(**vars(a))
        print_fmaster_write(p, buf, size)

    cleanup_args = [
            a
            for a in syscall.sending_order_args
            if a.datatype == "struct iovec *"]
    if len(cleanup_args) == 0:
        return
    print_newline()
    for a in cleanup_args:
        p("""\
\tfree({name}_iov_len_len, M_TEMP);
\tfree({name}_iov_len_buf, M_TEMP);
""".format(**vars(a)))
Exemplo n.º 5
0
def print_fslave_call(p, print_newline, syscall):
    local_vars = []
    for datatype, name in (
            ("sigset_t", "oset"),
            ("payload_size_t", "payload_size"),
            ("payload_size_t", "actual_payload_size"),
            ("int", "rfd")):
        local_vars.append(Variable(datatype, name))
    input_arguments = syscall.input_args
    for a in input_arguments:
        if a.datatype == "void *":
            local_vars.append(Variable(a.datatype, a.name))
            continue

        if a.datatype == "struct iovec *":
            for datatype, name in (
                    (a.datatype, a.name),
                    ("payload_size_t *", "{name}_iov_len_len"),
                    ("int", "i"),
                    ("payload_size_t", "{name}_payload_size")):
                local_vars.append(Variable(datatype, name.format(**vars(a))))
            continue

        for datatype, name in (
                ("payload_size_t", "{name}_len"),
                ("{datatype}", "{name}")):
            d = vars(a)
            v = Variable(datatype.format(**d), name.format(**d))
            local_vars.append(v)

    print_locals(p, local_vars)
    print_newline()
    p("""\
\trfd = slave_thread->fsth_rfd;
\tpayload_size = read_payload_size(rfd);
""")
    print_newline()
    for a in syscall.input_args:
        name = a.name
        if a.datatype == "void *":
            size = SYSCALLS[syscall.name][name].size
            p("""\
\t{name} = alloca({size});
\tread_or_die(rfd, {name}, {size});
""".format(**locals()))
            continue

        if a.datatype == "struct iovec *":
            name = a.name
            size = data_of_argument(syscall, a).size
            p("""\
\t{name} = (struct iovec *)alloca(sizeof(*{name}) * {size});
\t{name}_iov_len_len = (payload_size_t *)alloca(sizeof(int) * {size});
\tfor (i = 0; i < {size}; i++) {{
\t\t{name}[i].iov_len = read_uint64(rfd, &{name}_iov_len_len[i]);
\t\t{name}[i].iov_base = alloca({name}[i].iov_len);
\t\tread_or_die(rfd, {name}[i].iov_base, {name}[i].iov_len);
\t}}
""".format(**locals()))
            continue

        f = {
                "char *": "read_string",
                "long": "read_int64",
                "int": "read_int32",
                "u_int": "read_uint32",
                "off_t": "read_int64",
                "size_t": "read_uint64" }[a.datatype]
        assignment = "{name} = {f}(rfd, &{name}_len)".format(**locals())
        opt = opt_of_syscall(FSLAVE_SYSCALLS, syscall, a)
        if opt is not None:
            p("""\
\tif ({opt})
\t\t{assignment};
\telse
\t\t{name} = {name}_len = 0;
""".format(**locals()))
        else:
            p("""\
\t{assignment};
""".format(**locals()))
    if 0 < len(syscall.args):
        print_newline()

    for a in [a for a in input_arguments if a.datatype == "struct iovec *"]:
        name = a.name
        size = data_of_argument(syscall, a).size
        p("""\
\t{name}_payload_size = 0;
\tfor (i = 0; i < {size}; i++)
\t\t{name}_payload_size += {name}_iov_len_len[i] + {name}[i].iov_len;
""".format(**locals()))
        continue

    payload_size = make_fslave_payload_size_expr(syscall)
    p("""\
\tactual_payload_size = {payload_size};
\tdie_if_payload_size_mismatched(payload_size, actual_payload_size);
""".format(**locals()))
    print_newline()

    malloced = False
    out_arguments = syscall.output_args
    for a in out_arguments:
        data = data_of_argument(syscall, a)
        if not data.is_array:
            continue
        name = a.name
        datatype = a.datatype
        size = data.size
        p("""\
\t*{name} = ({datatype})malloc({size});
""".format(**locals()))
        malloced = True
    if malloced:
        print_newline()

    args = []
    for a in syscall.args:
        data = data_of_argument(syscall, a)
        ast = (1 if data.out and data.is_array else 0) * "*"
        args.append("{ast}{name}".format(ast=ast, name=a.name))
    p("""\
\tsuspend_signal(slave_thread, &oset);
\t*retval = {name}({args});
\t*errnum = errno;
\tresume_signal(slave_thread, &oset);
""".format(name=drop_prefix(syscall.name), args=", ".join(args)))

    for a in syscall.args:
        if (a.datatype != "char *") or data_of_argument(syscall, a).out:
            continue
        p("""\
\tfree({name});
""".format(**vars(a)))
    p("""\
}}
""".format(**locals()))