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)
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()))
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)
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)))
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()))