diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-03-25 13:03:34 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-03-25 13:03:34 -0600 |
commit | 50fb8395526066d20e143b49a12c0f6aeddee1ac (patch) | |
tree | 23a2ecef774a66eca64ccac067b7d252bb0487d4 | |
parent | c275032964505d3ceecf3cc0ce21b059ede930dd (diff) | |
parent | 5478200c1560ebbb1ac6dcf8d96cf94c3fa3693e (diff) |
Merge branch 'lukeshu/9p-gen-cleanup'
-rw-r--r-- | lib9p/9p.c | 95 | ||||
-rw-r--r-- | lib9p/9p.generated.c | 5882 | ||||
-rw-r--r-- | lib9p/include/lib9p/9p.h | 10 | ||||
-rw-r--r-- | lib9p/internal.h | 45 | ||||
-rw-r--r-- | lib9p/protogen/c.py | 18 | ||||
-rw-r--r-- | lib9p/protogen/c9util.py | 8 | ||||
-rw-r--r-- | lib9p/protogen/c_marshal.py | 583 | ||||
-rw-r--r-- | lib9p/protogen/c_unmarshal.py | 169 | ||||
-rw-r--r-- | lib9p/protogen/c_validate.py | 394 | ||||
-rw-r--r-- | lib9p/protogen/cutil.py | 2 |
10 files changed, 3680 insertions, 3526 deletions
@@ -123,17 +123,8 @@ ssize_t _lib9p_validate(uint8_t xxx_low_typ_bit, const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0x80], struct lib9p_ctx *ctx, uint8_t *net_bytes) { /* Inspect the first 5 bytes ourselves. */ - struct _validate_ctx subctx = { - /* input */ - .ctx = ctx, - .net_size = uint32le_decode(net_bytes), - .net_bytes = net_bytes, - - /* output */ - .net_offset = 0, - .host_extra = 0, - }; - if (subctx.net_size < 5) + uint32_t net_size = uint32le_decode(net_bytes); + if (net_size < 5) return lib9p_error(ctx, LINUX_EBADMSG, "message is impossibly short"); uint8_t typ = net_bytes[4]; if (typ % 2 != xxx_low_typ_bit) @@ -145,18 +136,7 @@ ssize_t _lib9p_validate(uint8_t xxx_low_typ_bit, lib9p_msgtype_str(ctx->version, typ), lib9p_version_str(ctx->version)); /* Now use the message-type-specific tentry to process the whole thing. */ - if (tentry.validate(&subctx)) - return -1; - assert(subctx.net_offset <= subctx.net_size); - if (subctx.net_offset < subctx.net_size) - return lib9p_errorf(ctx, LINUX_EBADMSG, "message has %"PRIu32" extra bytes", - subctx.net_size - subctx.net_offset); - - /* Return. */ - ssize_t ret; - if (__builtin_add_overflow(tentry.basesize, subctx.host_extra, &ret)) - return lib9p_error(ctx, LINUX_EMSGSIZE, "unmarshalled payload overflows SSIZE_MAX"); - return ret; + return tentry.validate(ctx, net_size, net_bytes); } ssize_t lib9p_Tmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { @@ -177,16 +157,7 @@ void _lib9p_unmarshal(const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0 *ret_typ = typ; struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2]; - struct _unmarshal_ctx subctx = { - /* input */ - .ctx = ctx, - .net_bytes = net_bytes, - - /* output */ - .net_offset = 0, - .extra = ret_body + tentry.basesize, - }; - tentry.unmarshal(&subctx, ret_body); + tentry.unmarshal(ctx, net_bytes, ret_body); } void lib9p_Tmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, @@ -205,11 +176,7 @@ static bool _lib9p_marshal(const struct _lib9p_send_tentry xxx_table[LIB9P_VER_NUM][0x80], struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, size_t *ret_iov_cnt, struct iovec *ret_iov, uint8_t *ret_copied) { - struct _marshal_ctx subctx = { - /* input */ - .ctx = ctx, - - /* ouptut */ + struct _marshal_ret ret = { .net_iov_cnt = 1, .net_iov = ret_iov, .net_copied_size = 0, @@ -217,10 +184,10 @@ bool _lib9p_marshal(const struct _lib9p_send_tentry xxx_table[LIB9P_VER_NUM][0x8 }; struct _lib9p_send_tentry tentry = xxx_table[ctx->version][typ/2]; - bool ret_erred = tentry.marshal(&subctx, body); - if (ret_iov[subctx.net_iov_cnt-1].iov_len == 0) - subctx.net_iov_cnt--; - *ret_iov_cnt = subctx.net_iov_cnt; + bool ret_erred = tentry.marshal(ctx, body, &ret); + if (ret_iov[ret.net_iov_cnt-1].iov_len == 0) + ret.net_iov_cnt--; + *ret_iov_cnt = ret.net_iov_cnt; return ret_erred; } @@ -246,39 +213,17 @@ bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *bo bool lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size, ssize_t *ret_host_size) { - struct _validate_ctx subctx = { - /* input */ - .ctx = ctx, - .net_size = net_size, - .net_bytes = net_bytes, - - /* output */ - .net_offset = 0, - .host_extra = 0, - }; - if (_lib9p_stat_validate(&subctx)) + ssize_t host_size = _lib9p_stat_validate(ctx, net_size, net_bytes, ret_net_size); + if (host_size < 0) return true; - if (ret_net_size) - *ret_net_size = subctx.net_offset; if (ret_host_size) - if (__builtin_add_overflow(sizeof(struct lib9p_stat), subctx.host_extra, ret_host_size)) - return lib9p_error(ctx, LINUX_EMSGSIZE, "unmarshalled stat object overflows SSIZE_MAX"); + *ret_host_size = host_size; return false; } -uint32_t lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, - struct lib9p_stat *ret_obj, void *ret_extra) { - struct _unmarshal_ctx subctx = { - /* input */ - .ctx = ctx, - .net_bytes = net_bytes, - - /* output */ - .net_offset = 0, - .extra = ret_extra, - }; - _lib9p_stat_unmarshal(&subctx, ret_obj); - return subctx.net_offset; +void lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, + struct lib9p_stat *ret) { + _lib9p_stat_unmarshal(ctx, net_bytes, ret); } uint32_t lib9p_stat_marshal(struct lib9p_ctx *ctx, uint32_t max_net_size, struct lib9p_stat *obj, @@ -287,17 +232,13 @@ uint32_t lib9p_stat_marshal(struct lib9p_ctx *ctx, uint32_t max_net_size, struct _ctx.max_msg_size = max_net_size; struct iovec iov = {0}; - struct _marshal_ctx subctx = { - /* input */ - .ctx = &_ctx, - - /* output */ + struct _marshal_ret ret = { .net_iov_cnt = 1, .net_iov = &iov, .net_copied_size = 0, .net_copied = ret_bytes, }; - if (_lib9p_stat_marshal(&subctx, obj)) + if (_lib9p_stat_marshal(&_ctx, obj, &ret)) return 0; - return subctx.net_iov[0].iov_len; + return ret.net_iov[0].iov_len; } diff --git a/lib9p/9p.generated.c b/lib9p/9p.generated.c index af5200f..6726084 100644 --- a/lib9p/9p.generated.c +++ b/lib9p/9p.generated.c @@ -39,12 +39,12 @@ #endif /** - * is_ver(ctx, ver) is essentially `(ctx->ctx->version == LIB9P_VER_##ver)`, - * but compiles correctly (to `false`) even if `LIB9P_VER_##ver` isn't defined + * is_ver(ctx, ver) is essentially `(ctx->version == LIB9P_VER_##ver)`, but + * compiles correctly (to `false`) even if `LIB9P_VER_##ver` isn't defined * (because `!CONFIG_9P_ENABLE_##ver`). This is useful when `||`ing * several version checks together. */ -#define is_ver(CTX, ver) _is_ver_##ver(CTX->ctx->version) +#define is_ver(ctx, ver) _is_ver_##ver((ctx)->version) /* strings ********************************************************************/ @@ -416,2562 +416,2664 @@ static const lib9p_lock_flags_t lock_flags_masks[LIB9P_VER_NUM] = { /* validate_* *****************************************************************/ -LM_ALWAYS_INLINE static bool _validate_size_net(struct _validate_ctx *ctx, uint32_t n) { - if (__builtin_add_overflow(ctx->net_offset, n, &ctx->net_offset)) - /* If needed-net-size overflowed uint32_t, then - * there's no way that actual-net-size will live up to - * that. */ - return lib9p_error(ctx->ctx, LINUX_EBADMSG, "message is too short for content"); - if (ctx->net_offset > ctx->net_size) - return lib9p_error(ctx->ctx, LINUX_EBADMSG, "message is too short for content"); - return false; -} - -LM_ALWAYS_INLINE static bool _validate_size_host(struct _validate_ctx *ctx, size_t n) { - if (__builtin_add_overflow(ctx->host_extra, n, &ctx->host_extra)) - /* If needed-host-size overflowed size_t, then there's - * no way that actual-net-size will live up to - * that. */ - return lib9p_error(ctx->ctx, LINUX_EBADMSG, "message is too short for content"); - return false; -} - -LM_ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx, - size_t cnt, - _validate_fn_t item_fn, size_t item_host_size) { - for (size_t i = 0; i < cnt; i++) - if (_validate_size_host(ctx, item_host_size) || item_fn(ctx)) - return true; - return false; -} - -LM_ALWAYS_INLINE static bool validate_1(struct _validate_ctx *ctx) { return _validate_size_net(ctx, 1); } -LM_ALWAYS_INLINE static bool validate_2(struct _validate_ctx *ctx) { return _validate_size_net(ctx, 2); } -LM_ALWAYS_INLINE static bool validate_4(struct _validate_ctx *ctx) { return _validate_size_net(ctx, 4); } -LM_ALWAYS_INLINE static bool validate_8(struct _validate_ctx *ctx) { return _validate_size_net(ctx, 8); } - -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static bool validate_tag(struct _validate_ctx *ctx) { - return validate_2(ctx); -} - -LM_ALWAYS_INLINE static bool validate_fid(struct _validate_ctx *ctx) { - return validate_4(ctx); -} - -LM_ALWAYS_INLINE static bool validate_s(struct _validate_ctx *ctx) { - uint16_t len; - return false - || (validate_2(ctx) || ({ len = uint16le_decode(&ctx->net_bytes[ctx->net_offset-2]); false; })) - || _validate_size_net(ctx, len) - || ({ (!is_valid_utf8_without_nul(&ctx->net_bytes[ctx->net_offset-len], len)) && lib9p_error(ctx->ctx, LINUX_EBADMSG, "message contains invalid UTF-8"); }) - ; -} +#define VALIDATE_NET_BYTES(n) \ + if (__builtin_add_overflow(net_offset, n, &net_offset)) \ + /* If needed-net-size overflowed uint32_t, then \ + * there's no way that actual-net-size will live up to \ + * that. */ \ + return lib9p_error(ctx, LINUX_EBADMSG, "message is too short for content"); \ + if (net_offset > net_size) \ + return lib9p_errorf(ctx, LINUX_EBADMSG, "message is too short for content (%"PRIu32" > %"PRIu32") @ %d", net_offset, net_size, __LINE__); +#define VALIDATE_NET_UTF8(n) \ + { \ + size_t len = n; \ + VALIDATE_NET_BYTES(len); \ + if (!is_valid_utf8_without_nul(&net_bytes[net_offset-len], len)) \ + return lib9p_error(ctx, LINUX_EBADMSG, "message contains invalid UTF-8"); \ + } +#define RESERVE_HOST_BYTES(n) \ + if (__builtin_add_overflow(host_size, n, &host_size)) \ + /* If needed-host-size overflowed ssize_t, then there's \ + * no way that actual-net-size will live up to \ + * that. */ \ + return lib9p_error(ctx, LINUX_EBADMSG, "message is too short for content"); +#define GET_U8LE(off) (net_bytes[off]) +#define GET_U16LE(off) uint16le_decode(&net_bytes[off]) +#define GET_U32LE(off) uint32le_decode(&net_bytes[off]) +#define GET_U64LE(off) uint64le_decode(&net_bytes[off]) +#define LAST_U8LE() GET_U8LE(net_offset-1) +#define LAST_U16LE() GET_U16LE(net_offset-2) +#define LAST_U32LE() GET_U32LE(net_offset-4) +#define LAST_U64LE() GET_U64LE(net_offset-8) -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static bool validate_dm(struct _validate_ctx *ctx) { - if (validate_4(ctx)) - return true; - lib9p_dm_t mask = dm_masks[ctx->ctx->version]; - lib9p_dm_t val = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); - if (val & ~mask) - return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#04"PRIx32, val & ~mask); - return false; +static ssize_t validate_stat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_stat); + uint32_t offsetof_stat_size = net_offset + 0; + uint32_t offsetof_kern_type = net_offset + 2; + uint32_t offsetof_file_qid_type = net_offset + 8; + VALIDATE_NET_BYTES(21); + if (GET_U8LE(offsetof_file_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_file_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_file_mode = net_offset + 0; + VALIDATE_NET_BYTES(22); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); +#if CONFIG_9P_ENABLE_9P2000_u + if (is_ver(ctx, 9P2000_u)) { + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(12); + } +#endif /* CONFIG_9P_ENABLE_9P2000_u */ + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_stat_size) != (uint32_t)(offsetof_end - offsetof_kern_type)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "stat->stat_size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_stat_size), (uint32_t)(offsetof_end - offsetof_kern_type)); + if (GET_U32LE(offsetof_file_mode) & ~dm_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32, + GET_U32LE(offsetof_file_mode) & ~dm_masks[ctx->version]); + if (ret_net_size) + *ret_net_size = net_offset; + return (ssize_t)host_size; } #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static bool validate_qt(struct _validate_ctx *ctx) { - if (validate_1(ctx)) - return true; - lib9p_qt_t mask = qt_masks[ctx->ctx->version]; - lib9p_qt_t val = ctx->net_bytes[ctx->net_offset-1]; - if (val & ~mask) - return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#01"PRIx8, val & ~mask); - return false; -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ +static ssize_t validate_Tversion(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tversion); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tversion->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(100)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tversion->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(100)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rversion(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rversion); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rversion->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(101)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rversion->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(101)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tauth(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tauth); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); #if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static bool validate_nuid(struct _validate_ctx *ctx) { - return validate_4(ctx); -} - + if (( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) )) { + VALIDATE_NET_BYTES(4); + } #endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static bool validate_o(struct _validate_ctx *ctx) { - if (validate_1(ctx)) - return true; - lib9p_o_t mask = o_masks[ctx->ctx->version]; - lib9p_o_t val = ctx->net_bytes[ctx->net_offset-1]; - if (val & ~mask) - return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in o bitfield: %#01"PRIx8, val & ~mask); - return false; -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tauth->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(102)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tauth->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(102)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rauth(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rauth); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_aqid_type = net_offset + 7; + VALIDATE_NET_BYTES(20); + if (GET_U8LE(offsetof_aqid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_aqid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rauth->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(103)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rauth->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(103)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tattach(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tattach); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(17); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); #if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static bool validate_errno(struct _validate_ctx *ctx) { - return validate_4(ctx); -} - + if (( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) )) { + VALIDATE_NET_BYTES(4); + } #endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_ALWAYS_INLINE static bool validate_super_magic(struct _validate_ctx *ctx) { - return validate_4(ctx); -} - -LM_ALWAYS_INLINE static bool validate_lo(struct _validate_ctx *ctx) { - if (validate_4(ctx)) - return true; - lib9p_lo_t mask = lo_masks[ctx->ctx->version]; - lib9p_lo_t val = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); - if (val & ~mask) - return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in lo bitfield: %#04"PRIx32, val & ~mask); - return false; -} - -LM_ALWAYS_INLINE static bool validate_dt(struct _validate_ctx *ctx) { - return validate_1(ctx); -} - -LM_ALWAYS_INLINE static bool validate_mode(struct _validate_ctx *ctx) { - if (validate_4(ctx)) - return true; - lib9p_mode_t mask = mode_masks[ctx->ctx->version]; - lib9p_mode_t val = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); - if (val & ~mask) - return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in mode bitfield: %#04"PRIx32, val & ~mask); - return false; -} - -LM_ALWAYS_INLINE static bool validate_b4(struct _validate_ctx *ctx) { - return validate_4(ctx); -} - -LM_ALWAYS_INLINE static bool validate_getattr(struct _validate_ctx *ctx) { - if (validate_8(ctx)) - return true; - lib9p_getattr_t mask = getattr_masks[ctx->ctx->version]; - lib9p_getattr_t val = uint64le_decode(&ctx->net_bytes[ctx->net_offset-8]); - if (val & ~mask) - return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in getattr bitfield: %#08"PRIx64, val & ~mask); - return false; -} - -LM_ALWAYS_INLINE static bool validate_setattr(struct _validate_ctx *ctx) { - if (validate_4(ctx)) - return true; - lib9p_setattr_t mask = setattr_masks[ctx->ctx->version]; - lib9p_setattr_t val = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); - if (val & ~mask) - return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in setattr bitfield: %#04"PRIx32, val & ~mask); - return false; -} - -LM_ALWAYS_INLINE static bool validate_lock_type(struct _validate_ctx *ctx) { - return validate_1(ctx); -} - -LM_ALWAYS_INLINE static bool validate_lock_flags(struct _validate_ctx *ctx) { - if (validate_4(ctx)) - return true; - lib9p_lock_flags_t mask = lock_flags_masks[ctx->ctx->version]; - lib9p_lock_flags_t val = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); - if (val & ~mask) - return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in lock_flags bitfield: %#04"PRIx32, val & ~mask); - return false; -} - -LM_ALWAYS_INLINE static bool validate_lock_status(struct _validate_ctx *ctx) { - return validate_1(ctx); -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static bool validate_Tflush(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_2(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 108; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rflush(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 109; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rread(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t count; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || _validate_size_net(ctx, count) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 117; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - || ({ uint32_t max = INT32_MAX; (((uint32_t)count) > max) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "count value is too large (%"PRIu32" > %"PRIu32")", count, max); }) - ; -} - -LM_FLATTEN static bool validate_Rwrite(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t count; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 119; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - || ({ uint32_t max = INT32_MAX; (((uint32_t)count) > max) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "count value is too large (%"PRIu32" > %"PRIu32")", count, max); }) - ; -} - -LM_FLATTEN static bool validate_Rclunk(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 121; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rremove(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 123; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static bool validate_Rwstat(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 127; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static bool validate_Rrename(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 21; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rsetattr(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 27; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rxattrwalk(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_8(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 31; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rxattrcreate(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 33; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rreaddir(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t count; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || _validate_size_net(ctx, count) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 41; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rfsync(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 51; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rlink(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 71; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rrenameat(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 75; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Runlinkat(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 77; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ -#if CONFIG_9P_ENABLE_9P2000_e -LM_FLATTEN static bool validate_Tsession(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_8(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 150; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rsession(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 151; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rsread(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t count; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || _validate_size_net(ctx, count) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 153; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rswrite(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_4(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 155; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000_e */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static bool validate_Tread(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint64_t offset; - uint32_t count; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || (validate_8(ctx) || ({ offset = uint64le_decode(&ctx->net_bytes[ctx->net_offset-8]); false; })) - || (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 116; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - || ({ uint64_t max = INT64_MAX; (((uint64_t)offset) > max) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "offset value is too large (%"PRIu64" > %"PRIu64")", offset, max); }) - || ({ uint32_t max = INT32_MAX; (((uint32_t)count) > max) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "count value is too large (%"PRIu32" > %"PRIu32")", count, max); }) - ; -} - -LM_FLATTEN static bool validate_Twrite(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint64_t offset; - uint32_t count; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || (validate_8(ctx) || ({ offset = uint64le_decode(&ctx->net_bytes[ctx->net_offset-8]); false; })) - || (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || _validate_size_net(ctx, count) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 118; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - || ({ uint64_t max = INT64_MAX; (((uint64_t)offset) > max) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "offset value is too large (%"PRIu64" > %"PRIu64")", offset, max); }) - || ({ uint32_t max = INT32_MAX; (((uint32_t)count) > max) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "count value is too large (%"PRIu32" > %"PRIu32")", count, max); }) - ; -} - -LM_FLATTEN static bool validate_Tclunk(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 120; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tremove(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 122; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tattach->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(104)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tattach->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(104)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rattach(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rattach); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_qid_type = net_offset + 7; + VALIDATE_NET_BYTES(20); + if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rattach->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(105)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rattach->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(105)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rerror(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rerror); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(9); + VALIDATE_NET_UTF8(LAST_U16LE()); +#if CONFIG_9P_ENABLE_9P2000_u + if (is_ver(ctx, 9P2000_u)) { + VALIDATE_NET_BYTES(4); + } +#endif /* CONFIG_9P_ENABLE_9P2000_u */ + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rerror->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(107)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rerror->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(107)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tflush(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tflush); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 9; + VALIDATE_NET_BYTES(9); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tflush->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(108)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tflush->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(108)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rflush(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rflush); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rflush->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(109)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rflush->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(109)); + return (ssize_t)host_size; +} + +static ssize_t validate_Twalk(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Twalk); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_nwname = net_offset + 15; + VALIDATE_NET_BYTES(17); + for (uint16_t i = 0, cnt = LAST_U16LE(); i < cnt; i++) { + RESERVE_HOST_BYTES(sizeof(struct lib9p_s)); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + } + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Twalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(110)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Twalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(110)); + if ((uint16_t)GET_U16LE(offsetof_nwname) > (uint16_t)(16)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Twalk->nwname value is too large: %"PRIu16" > %"PRIu16, + (uint16_t)GET_U16LE(offsetof_nwname), (uint16_t)(16)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rwalk(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rwalk); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_nwqid = net_offset + 7; + VALIDATE_NET_BYTES(9); + for (uint16_t i = 0, cnt = LAST_U16LE(); i < cnt; i++) { + RESERVE_HOST_BYTES(sizeof(struct lib9p_qid)); + uint32_t offsetof_wqid_type = net_offset + 0; + VALIDATE_NET_BYTES(13); + if (GET_U8LE(offsetof_wqid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_wqid_type) & ~qt_masks[ctx->version]); + } + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(111)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(111)); + if ((uint16_t)GET_U16LE(offsetof_nwqid) > (uint16_t)(16)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwalk->nwqid value is too large: %"PRIu16" > %"PRIu16, + (uint16_t)GET_U16LE(offsetof_nwqid), (uint16_t)(16)); + return (ssize_t)host_size; } #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static bool validate_Tstat(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 124; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; +static ssize_t validate_Topen(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Topen); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_mode = net_offset + 11; + uint32_t offsetof_end = net_offset + 12; + VALIDATE_NET_BYTES(12); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Topen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(112)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Topen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(112)); + if (GET_U8LE(offsetof_mode) & ~o_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in o bitfield: %#02"PRIx8, + GET_U8LE(offsetof_mode) & ~o_masks[ctx->version]); + return (ssize_t)host_size; +} + +static ssize_t validate_Ropen(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Ropen); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_qid_type = net_offset + 7; + VALIDATE_NET_BYTES(20); + if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 4; + VALIDATE_NET_BYTES(4); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Ropen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(113)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Ropen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(113)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tcreate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tcreate); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_perm = net_offset + 0; + uint32_t offsetof_mode = net_offset + 4; + uint32_t offsetof_end = net_offset + 5; + VALIDATE_NET_BYTES(5); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(114)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(114)); + if (GET_U32LE(offsetof_perm) & ~dm_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32, + GET_U32LE(offsetof_perm) & ~dm_masks[ctx->version]); + if (GET_U8LE(offsetof_mode) & ~o_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in o bitfield: %#02"PRIx8, + GET_U8LE(offsetof_mode) & ~o_masks[ctx->version]); + return (ssize_t)host_size; +} + +static ssize_t validate_Rcreate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rcreate); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_qid_type = net_offset + 7; + VALIDATE_NET_BYTES(20); + if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 4; + VALIDATE_NET_BYTES(4); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(115)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(115)); + return (ssize_t)host_size; } #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static bool validate_Tstatfs(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 8; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Treadlink(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 22; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Treaddir(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_8(ctx) - || validate_4(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 40; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static bool validate_Tversion(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_4(ctx) - || validate_s(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 100; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rversion(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_4(ctx) - || validate_s(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 101; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Twalk(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint16_t nwname; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_fid(ctx) - || (validate_2(ctx) || ({ nwname = uint16le_decode(&ctx->net_bytes[ctx->net_offset-2]); false; })) - || _validate_list(ctx, nwname, validate_s, sizeof(struct lib9p_s)) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 110; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - || ({ uint16_t max = 16; (((uint16_t)nwname) > max) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nwname value is too large (%"PRIu16" > %"PRIu16")", nwname, max); }) - ; +static ssize_t validate_Tread(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tread); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_offset = net_offset + 11; + uint32_t offsetof_count = net_offset + 19; + uint32_t offsetof_end = net_offset + 23; + VALIDATE_NET_BYTES(23); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(116)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(116)); + if ((uint64_t)GET_U64LE(offsetof_offset) > (uint64_t)(INT64_MAX)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tread->offset value is too large: %"PRIu64" > %"PRIu64, + (uint64_t)GET_U64LE(offsetof_offset), (uint64_t)(INT64_MAX)); + if ((uint32_t)GET_U32LE(offsetof_count) > (uint32_t)(INT32_MAX)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tread->count value is too large: %"PRIu32" > %"PRIu32, + (uint32_t)GET_U32LE(offsetof_count), (uint32_t)(INT32_MAX)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rread(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rread); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_count = net_offset + 7; + VALIDATE_NET_BYTES(11); + VALIDATE_NET_BYTES(LAST_U32LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(117)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(117)); + if ((uint32_t)GET_U32LE(offsetof_count) > (uint32_t)(INT32_MAX)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rread->count value is too large: %"PRIu32" > %"PRIu32, + (uint32_t)GET_U32LE(offsetof_count), (uint32_t)(INT32_MAX)); + return (ssize_t)host_size; +} + +static ssize_t validate_Twrite(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Twrite); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_offset = net_offset + 11; + uint32_t offsetof_count = net_offset + 19; + VALIDATE_NET_BYTES(23); + VALIDATE_NET_BYTES(LAST_U32LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Twrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(118)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Twrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(118)); + if ((uint64_t)GET_U64LE(offsetof_offset) > (uint64_t)(INT64_MAX)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Twrite->offset value is too large: %"PRIu64" > %"PRIu64, + (uint64_t)GET_U64LE(offsetof_offset), (uint64_t)(INT64_MAX)); + if ((uint32_t)GET_U32LE(offsetof_count) > (uint32_t)(INT32_MAX)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Twrite->count value is too large: %"PRIu32" > %"PRIu32, + (uint32_t)GET_U32LE(offsetof_count), (uint32_t)(INT32_MAX)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rwrite(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rwrite); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_count = net_offset + 7; + uint32_t offsetof_end = net_offset + 11; + VALIDATE_NET_BYTES(11); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(119)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(119)); + if ((uint32_t)GET_U32LE(offsetof_count) > (uint32_t)(INT32_MAX)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwrite->count value is too large: %"PRIu32" > %"PRIu32, + (uint32_t)GET_U32LE(offsetof_count), (uint32_t)(INT32_MAX)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tclunk(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tclunk); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 11; + VALIDATE_NET_BYTES(11); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tclunk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(120)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tclunk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(120)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rclunk(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rclunk); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rclunk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(121)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rclunk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(121)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tremove(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tremove); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 11; + VALIDATE_NET_BYTES(11); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tremove->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(122)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tremove->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(122)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rremove(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rremove); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rremove->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(123)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rremove->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(123)); + return (ssize_t)host_size; } #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static bool validate_Trename(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 20; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rreadlink(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_s(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 23; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Txattrwalk(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 30; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Txattrcreate(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || validate_8(ctx) - || validate_4(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 32; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tlink(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 70; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Trenameat(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 74; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tunlinkat(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || validate_4(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 76; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ -#if CONFIG_9P_ENABLE_9P2000_e -LM_FLATTEN static bool validate_Tsread(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint16_t nwname; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_4(ctx) - || (validate_2(ctx) || ({ nwname = uint16le_decode(&ctx->net_bytes[ctx->net_offset-2]); false; })) - || _validate_list(ctx, nwname, validate_s, sizeof(struct lib9p_s)) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 152; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tswrite(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint16_t nwname; - uint32_t count; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_4(ctx) - || (validate_2(ctx) || ({ nwname = uint16le_decode(&ctx->net_bytes[ctx->net_offset-2]); false; })) - || _validate_list(ctx, nwname, validate_s, sizeof(struct lib9p_s)) - || (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || _validate_size_net(ctx, count) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 154; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000_e */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static bool validate_qid(struct _validate_ctx *ctx) { - return false - || validate_qt(ctx) - || validate_4(ctx) - || validate_8(ctx) - ; -} - -LM_FLATTEN static bool validate_Tauth(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || validate_s(ctx) -#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u - || ( ( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) ) && validate_nuid(ctx) ) -#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */ - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 102; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tattach(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || validate_s(ctx) -#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u - || ( ( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) ) && validate_nuid(ctx) ) -#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */ - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 104; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static bool validate_Tsymlink(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || validate_s(ctx) - || validate_nuid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 16; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static bool validate_Topen(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_o(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 112; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tcreate(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || validate_dm(ctx) - || validate_o(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 114; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_p9p -LM_FLATTEN static bool validate_Topenfd(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_o(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 98; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000_p9p */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static bool validate_Rerror(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_s(ctx) +static ssize_t validate_Tstat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tstat); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 11; + VALIDATE_NET_BYTES(11); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(124)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(124)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rstat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rstat); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_nstat = net_offset + 7; + uint32_t offsetof_stat = net_offset + 9; + uint32_t offsetof_stat_stat_size = net_offset + 9; + uint32_t offsetof_stat_kern_type = net_offset + 11; + uint32_t offsetof_stat_file_qid_type = net_offset + 17; + VALIDATE_NET_BYTES(30); + if (GET_U8LE(offsetof_stat_file_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_stat_file_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_stat_file_mode = net_offset + 0; + VALIDATE_NET_BYTES(22); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); #if CONFIG_9P_ENABLE_9P2000_u - || ( is_ver(ctx, 9P2000_u) && validate_errno(ctx) ) + if (is_ver(ctx, 9P2000_u)) { + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(12); + } #endif /* CONFIG_9P_ENABLE_9P2000_u */ - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 107; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static bool validate_Rlerror(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_errno(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 7; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rstatfs(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_super_magic(ctx) - || validate_4(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_4(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 9; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tlopen(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_lo(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 12; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tlcreate(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || validate_lo(ctx) - || validate_mode(ctx) - || validate_nuid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 14; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tmknod(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || validate_mode(ctx) - || validate_4(ctx) - || validate_4(ctx) - || validate_nuid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 18; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tmkdir(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_s(ctx) - || validate_mode(ctx) - || validate_nuid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 72; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tfsync(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_b4(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 50; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tgetattr(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_getattr(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 24; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tsetattr(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_setattr(ctx) - || validate_mode(ctx) - || validate_nuid(ctx) - || validate_nuid(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 26; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tgetlock(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_lock_type(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_4(ctx) - || validate_s(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 54; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rgetlock(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_lock_type(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_4(ctx) - || validate_s(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 55; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Tlock(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || validate_lock_type(ctx) - || validate_lock_flags(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_4(ctx) - || validate_s(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 52; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rlock(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_lock_status(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 53; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static bool validate_stat(struct _validate_ctx *ctx) { - uint16_t stat_size; - uint32_t _kern_type_offset; - return false - || (validate_2(ctx) || ({ stat_size = uint16le_decode(&ctx->net_bytes[ctx->net_offset-2]); false; })) - || ({ _kern_type_offset = ctx->net_offset; validate_2(ctx); }) - || validate_4(ctx) - || validate_qid(ctx) - || validate_dm(ctx) - || validate_4(ctx) - || validate_4(ctx) - || validate_8(ctx) - || validate_s(ctx) - || validate_s(ctx) - || validate_s(ctx) - || validate_s(ctx) + uint32_t offsetof_stat_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_stat_stat_size) != (uint32_t)(offsetof_stat_end - offsetof_stat_kern_type)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstat->stat.stat_size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_stat_stat_size), (uint32_t)(offsetof_stat_end - offsetof_stat_kern_type)); + if (GET_U32LE(offsetof_stat_file_mode) & ~dm_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32, + GET_U32LE(offsetof_stat_file_mode) & ~dm_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(125)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(125)); + if ((uint32_t)GET_U32LE(offsetof_nstat) != (uint32_t)(offsetof_end - offsetof_stat)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstat->nstat value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_nstat), (uint32_t)(offsetof_end - offsetof_stat)); + return (ssize_t)host_size; +} + +static ssize_t validate_Twstat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Twstat); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_nstat = net_offset + 11; + uint32_t offsetof_stat = net_offset + 13; + uint32_t offsetof_stat_stat_size = net_offset + 13; + uint32_t offsetof_stat_kern_type = net_offset + 15; + uint32_t offsetof_stat_file_qid_type = net_offset + 21; + VALIDATE_NET_BYTES(34); + if (GET_U8LE(offsetof_stat_file_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_stat_file_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_stat_file_mode = net_offset + 0; + VALIDATE_NET_BYTES(22); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); #if CONFIG_9P_ENABLE_9P2000_u - || ( is_ver(ctx, 9P2000_u) && validate_s(ctx) ) - || ( is_ver(ctx, 9P2000_u) && validate_nuid(ctx) ) - || ( is_ver(ctx, 9P2000_u) && validate_nuid(ctx) ) - || ( is_ver(ctx, 9P2000_u) && validate_nuid(ctx) ) + if (is_ver(ctx, 9P2000_u)) { + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(12); + } #endif /* CONFIG_9P_ENABLE_9P2000_u */ - || ({ uint16_t exp = ctx->net_offset - _kern_type_offset; (((uint16_t)stat_size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "stat_size value is wrong (actual:%"PRIu16" != correct:%"PRIu16")", (uint16_t)stat_size, exp); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static bool validate_Rauth(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_qid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 103; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rattach(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_qid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 105; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rwalk(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint16_t nwqid; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || (validate_2(ctx) || ({ nwqid = uint16le_decode(&ctx->net_bytes[ctx->net_offset-2]); false; })) - || _validate_list(ctx, nwqid, validate_qid, sizeof(struct lib9p_qid)) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 111; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - || ({ uint16_t max = 16; (((uint16_t)nwqid) > max) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nwqid value is too large (%"PRIu16" > %"PRIu16")", nwqid, max); }) - ; -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static bool validate_Ropen(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_qid(ctx) - || validate_4(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 113; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rcreate(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_qid(ctx) - || validate_4(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 115; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; + uint32_t offsetof_stat_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_stat_stat_size) != (uint32_t)(offsetof_stat_end - offsetof_stat_kern_type)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Twstat->stat.stat_size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_stat_stat_size), (uint32_t)(offsetof_stat_end - offsetof_stat_kern_type)); + if (GET_U32LE(offsetof_stat_file_mode) & ~dm_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32, + GET_U32LE(offsetof_stat_file_mode) & ~dm_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Twstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(126)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Twstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(126)); + if ((uint32_t)GET_U32LE(offsetof_nstat) != (uint32_t)(offsetof_end - offsetof_stat)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Twstat->nstat value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_nstat), (uint32_t)(offsetof_end - offsetof_stat)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rwstat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rwstat); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(127)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(127)); + return (ssize_t)host_size; } #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000_p9p -LM_FLATTEN static bool validate_Ropenfd(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_qid(ctx) - || validate_4(ctx) - || validate_4(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 99; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; +static ssize_t validate_Topenfd(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Topenfd); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_mode = net_offset + 11; + uint32_t offsetof_end = net_offset + 12; + VALIDATE_NET_BYTES(12); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Topenfd->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(98)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Topenfd->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(98)); + if (GET_U8LE(offsetof_mode) & ~o_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in o bitfield: %#02"PRIx8, + GET_U8LE(offsetof_mode) & ~o_masks[ctx->version]); + return (ssize_t)host_size; +} + +static ssize_t validate_Ropenfd(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Ropenfd); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_qid_type = net_offset + 7; + VALIDATE_NET_BYTES(20); + if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 8; + VALIDATE_NET_BYTES(8); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Ropenfd->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(99)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Ropenfd->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(99)); + return (ssize_t)host_size; } #endif /* CONFIG_9P_ENABLE_9P2000_p9p */ #if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static bool validate_Rlopen(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_qid(ctx) - || validate_4(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 13; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rlcreate(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_qid(ctx) - || validate_4(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 15; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rsymlink(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_qid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 17; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rmknod(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_qid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 19; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rgetattr(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_getattr(ctx) - || validate_qid(ctx) - || validate_mode(ctx) - || validate_nuid(ctx) - || validate_nuid(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || validate_8(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 25; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; -} - -LM_FLATTEN static bool validate_Rmkdir(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint32_t _size_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_qid(ctx) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 73; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - ; +static ssize_t validate_Rlerror(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rlerror); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 11; + VALIDATE_NET_BYTES(11); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlerror->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(7)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlerror->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(7)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tstatfs(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tstatfs); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 11; + VALIDATE_NET_BYTES(11); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tstatfs->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(8)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tstatfs->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(8)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rstatfs(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rstatfs); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 67; + VALIDATE_NET_BYTES(67); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstatfs->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(9)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstatfs->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(9)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tlopen(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tlopen); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_flags = net_offset + 11; + uint32_t offsetof_end = net_offset + 15; + VALIDATE_NET_BYTES(15); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlopen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(12)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlopen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(12)); + if (GET_U32LE(offsetof_flags) & ~lo_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in lo bitfield: %#08"PRIx32, + GET_U32LE(offsetof_flags) & ~lo_masks[ctx->version]); + return (ssize_t)host_size; +} + +static ssize_t validate_Rlopen(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rlopen); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_qid_type = net_offset + 7; + VALIDATE_NET_BYTES(20); + if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 4; + VALIDATE_NET_BYTES(4); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlopen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(13)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlopen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(13)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tlcreate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tlcreate); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_flags = net_offset + 0; + uint32_t offsetof_mode = net_offset + 4; + uint32_t offsetof_end = net_offset + 12; + VALIDATE_NET_BYTES(12); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(14)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(14)); + if (GET_U32LE(offsetof_flags) & ~lo_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in lo bitfield: %#08"PRIx32, + GET_U32LE(offsetof_flags) & ~lo_masks[ctx->version]); + if (GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32, + GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]); + return (ssize_t)host_size; +} + +static ssize_t validate_Rlcreate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rlcreate); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_qid_type = net_offset + 7; + VALIDATE_NET_BYTES(20); + if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 4; + VALIDATE_NET_BYTES(4); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(15)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(15)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tsymlink(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tsymlink); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 4; + VALIDATE_NET_BYTES(4); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsymlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(16)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsymlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(16)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rsymlink(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rsymlink); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_qid_type = net_offset + 7; + VALIDATE_NET_BYTES(20); + if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsymlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(17)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsymlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(17)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tmknod(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tmknod); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_mode = net_offset + 0; + uint32_t offsetof_end = net_offset + 16; + VALIDATE_NET_BYTES(16); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tmknod->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(18)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tmknod->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(18)); + if (GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32, + GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]); + return (ssize_t)host_size; +} + +static ssize_t validate_Rmknod(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rmknod); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_qid_type = net_offset + 7; + VALIDATE_NET_BYTES(20); + if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rmknod->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(19)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rmknod->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(19)); + return (ssize_t)host_size; +} + +static ssize_t validate_Trename(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Trename); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(17); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Trename->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(20)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Trename->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(20)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rrename(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rrename); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rrename->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(21)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rrename->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(21)); + return (ssize_t)host_size; +} + +static ssize_t validate_Treadlink(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Treadlink); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 11; + VALIDATE_NET_BYTES(11); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Treadlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(22)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Treadlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(22)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rreadlink(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rreadlink); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(9); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rreadlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(23)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rreadlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(23)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tgetattr(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tgetattr); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_request_mask = net_offset + 11; + uint32_t offsetof_end = net_offset + 19; + VALIDATE_NET_BYTES(19); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tgetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(24)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tgetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(24)); + if (GET_U64LE(offsetof_request_mask) & ~getattr_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in getattr bitfield: %#016"PRIx64, + GET_U64LE(offsetof_request_mask) & ~getattr_masks[ctx->version]); + return (ssize_t)host_size; +} + +static ssize_t validate_Rgetattr(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rgetattr); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_valid = net_offset + 7; + uint32_t offsetof_qid_type = net_offset + 15; + VALIDATE_NET_BYTES(28); + if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_mode = net_offset + 0; + uint32_t offsetof_end = net_offset + 132; + VALIDATE_NET_BYTES(132); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rgetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(25)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rgetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(25)); + if (GET_U64LE(offsetof_valid) & ~getattr_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in getattr bitfield: %#016"PRIx64, + GET_U64LE(offsetof_valid) & ~getattr_masks[ctx->version]); + if (GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32, + GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]); + return (ssize_t)host_size; +} + +static ssize_t validate_Tsetattr(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tsetattr); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_valid = net_offset + 11; + uint32_t offsetof_mode = net_offset + 15; + uint32_t offsetof_end = net_offset + 67; + VALIDATE_NET_BYTES(67); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(26)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(26)); + if (GET_U32LE(offsetof_valid) & ~setattr_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in setattr bitfield: %#08"PRIx32, + GET_U32LE(offsetof_valid) & ~setattr_masks[ctx->version]); + if (GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32, + GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]); + return (ssize_t)host_size; +} + +static ssize_t validate_Rsetattr(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rsetattr); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(27)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(27)); + return (ssize_t)host_size; +} + +static ssize_t validate_Txattrwalk(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Txattrwalk); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(17); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Txattrwalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(30)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Txattrwalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(30)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rxattrwalk(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rxattrwalk); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 15; + VALIDATE_NET_BYTES(15); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rxattrwalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(31)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rxattrwalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(31)); + return (ssize_t)host_size; +} + +static ssize_t validate_Txattrcreate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Txattrcreate); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 12; + VALIDATE_NET_BYTES(12); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Txattrcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(32)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Txattrcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(32)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rxattrcreate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rxattrcreate); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rxattrcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(33)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rxattrcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(33)); + return (ssize_t)host_size; +} + +static ssize_t validate_Treaddir(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Treaddir); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 23; + VALIDATE_NET_BYTES(23); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Treaddir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(40)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Treaddir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(40)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rreaddir(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rreaddir); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(11); + VALIDATE_NET_BYTES(LAST_U32LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rreaddir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(41)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rreaddir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(41)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tfsync(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tfsync); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 15; + VALIDATE_NET_BYTES(15); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tfsync->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(50)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tfsync->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(50)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rfsync(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rfsync); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rfsync->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(51)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rfsync->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(51)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tlock(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tlock); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_flags = net_offset + 12; + VALIDATE_NET_BYTES(38); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(52)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(52)); + if (GET_U32LE(offsetof_flags) & ~lock_flags_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in lock_flags bitfield: %#08"PRIx32, + GET_U32LE(offsetof_flags) & ~lock_flags_masks[ctx->version]); + return (ssize_t)host_size; +} + +static ssize_t validate_Rlock(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rlock); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 8; + VALIDATE_NET_BYTES(8); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(53)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(53)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tgetlock(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tgetlock); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(34); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tgetlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(54)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tgetlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(54)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rgetlock(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rgetlock); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(30); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rgetlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(55)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rgetlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(55)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tlink(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tlink); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(17); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(70)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(70)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rlink(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rlink); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(71)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(71)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tmkdir(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tmkdir); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_mode = net_offset + 0; + uint32_t offsetof_end = net_offset + 8; + VALIDATE_NET_BYTES(8); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tmkdir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(72)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tmkdir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(72)); + if (GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32, + GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]); + return (ssize_t)host_size; +} + +static ssize_t validate_Rmkdir(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rmkdir); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_qid_type = net_offset + 7; + VALIDATE_NET_BYTES(20); + if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]) + return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8, + GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rmkdir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(73)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rmkdir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(73)); + return (ssize_t)host_size; +} + +static ssize_t validate_Trenameat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Trenameat); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + VALIDATE_NET_UTF8(LAST_U16LE()); + VALIDATE_NET_BYTES(6); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Trenameat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(74)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Trenameat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(74)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rrenameat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rrenameat); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rrenameat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(75)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rrenameat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(75)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tunlinkat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tunlinkat); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + VALIDATE_NET_UTF8(LAST_U16LE()); + uint32_t offsetof_end = net_offset + 4; + VALIDATE_NET_BYTES(4); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tunlinkat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(76)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tunlinkat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(76)); + return (ssize_t)host_size; +} + +static ssize_t validate_Runlinkat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Runlinkat); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Runlinkat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(77)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Runlinkat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(77)); + return (ssize_t)host_size; } #endif /* CONFIG_9P_ENABLE_9P2000_L */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static bool validate_Rstat(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint16_t nstat; - uint32_t _size_offset; - uint32_t _stat_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || (validate_2(ctx) || ({ nstat = uint16le_decode(&ctx->net_bytes[ctx->net_offset-2]); false; })) - || ({ _stat_offset = ctx->net_offset; validate_stat(ctx); }) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 125; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - || ({ uint16_t exp = ctx->net_offset - _stat_offset; (((uint16_t)nstat) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nstat value is wrong (actual:%"PRIu16" != correct:%"PRIu16")", (uint16_t)nstat, exp); }) - ; -} - -LM_FLATTEN static bool validate_Twstat(struct _validate_ctx *ctx) { - uint32_t size; - uint8_t typ; - uint16_t nstat; - uint32_t _size_offset; - uint32_t _stat_offset; - return false - || (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; })) - || (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; })) - || validate_tag(ctx) - || validate_fid(ctx) - || (validate_2(ctx) || ({ nstat = uint16le_decode(&ctx->net_bytes[ctx->net_offset-2]); false; })) - || ({ _stat_offset = ctx->net_offset; validate_stat(ctx); }) - || ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); }) - || ({ uint8_t exp = 126; (((uint8_t)typ) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu8" != correct:%"PRIu8")", (uint8_t)typ, exp); }) - || ({ uint16_t exp = ctx->net_offset - _stat_offset; (((uint16_t)nstat) != exp) && - lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nstat value is wrong (actual:%"PRIu16" != correct:%"PRIu16")", (uint16_t)nstat, exp); }) - ; +#if CONFIG_9P_ENABLE_9P2000_e +static ssize_t validate_Tsession(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tsession); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 15; + VALIDATE_NET_BYTES(15); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsession->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(150)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsession->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(150)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rsession(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rsession); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 7; + VALIDATE_NET_BYTES(7); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsession->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(151)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsession->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(151)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tsread(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tsread); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + for (uint16_t i = 0, cnt = LAST_U16LE(); i < cnt; i++) { + RESERVE_HOST_BYTES(sizeof(struct lib9p_s)); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + } + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(152)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(152)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rsread(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rsread); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(11); + VALIDATE_NET_BYTES(LAST_U32LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(153)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(153)); + return (ssize_t)host_size; +} + +static ssize_t validate_Tswrite(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Tswrite); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + VALIDATE_NET_BYTES(13); + for (uint16_t i = 0, cnt = LAST_U16LE(); i < cnt; i++) { + RESERVE_HOST_BYTES(sizeof(struct lib9p_s)); + VALIDATE_NET_BYTES(2); + VALIDATE_NET_UTF8(LAST_U16LE()); + } + VALIDATE_NET_BYTES(4); + VALIDATE_NET_BYTES(LAST_U32LE()); + uint32_t offsetof_end = net_offset + 0; + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tswrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(154)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Tswrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(154)); + return (ssize_t)host_size; +} + +static ssize_t validate_Rswrite(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) { + uint32_t net_offset = 0; + ssize_t host_size = sizeof(struct lib9p_msg_Rswrite); + uint32_t offsetof_size = net_offset + 0; + uint32_t offsetof_typ = net_offset + 4; + uint32_t offsetof_end = net_offset + 11; + VALIDATE_NET_BYTES(11); + if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rswrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32, + (uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size)); + if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(155)) + return lib9p_errorf(ctx, LINUX_EBADMSG, "Rswrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8, + (uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(155)); + return (ssize_t)host_size; } -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ +#endif /* CONFIG_9P_ENABLE_9P2000_e */ /* unmarshal_* ****************************************************************/ -LM_ALWAYS_INLINE static void unmarshal_1(struct _unmarshal_ctx *ctx, uint8_t *out) { - *out = ctx->net_bytes[ctx->net_offset]; - ctx->net_offset += 1; -} - -LM_ALWAYS_INLINE static void unmarshal_2(struct _unmarshal_ctx *ctx, uint16_t *out) { - *out = uint16le_decode(&ctx->net_bytes[ctx->net_offset]); - ctx->net_offset += 2; -} +#define UNMARSHAL_BYTES(ctx, data_lvalue, len) \ + data_lvalue = (char *)&net_bytes[net_offset]; \ + net_offset += len; +#define UNMARSHAL_U8LE(ctx, val_lvalue) \ + val_lvalue = net_bytes[net_offset]; \ + net_offset += 1; +#define UNMARSHAL_U16LE(ctx, val_lvalue) \ + val_lvalue = uint16le_decode(&net_bytes[net_offset]); \ + net_offset += 2; +#define UNMARSHAL_U32LE(ctx, val_lvalue) \ + val_lvalue = uint32le_decode(&net_bytes[net_offset]); \ + net_offset += 4; +#define UNMARSHAL_U64LE(ctx, val_lvalue) \ + val_lvalue = uint64le_decode(&net_bytes[net_offset]); \ + net_offset += 8; -LM_ALWAYS_INLINE static void unmarshal_4(struct _unmarshal_ctx *ctx, uint32_t *out) { - *out = uint32le_decode(&ctx->net_bytes[ctx->net_offset]); - ctx->net_offset += 4; -} - -LM_ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *out) { - *out = uint64le_decode(&ctx->net_bytes[ctx->net_offset]); - ctx->net_offset += 8; -} - -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static void unmarshal_tag(struct _unmarshal_ctx *ctx, lib9p_tag_t *out) { - unmarshal_2(ctx, (uint16_t *)out); -} - -LM_ALWAYS_INLINE static void unmarshal_fid(struct _unmarshal_ctx *ctx, lib9p_fid_t *out) { - unmarshal_4(ctx, (uint32_t *)out); -} - -LM_ALWAYS_INLINE static void unmarshal_s(struct _unmarshal_ctx *ctx, struct lib9p_s *out) { - memset(out, 0, sizeof(*out)); - unmarshal_2(ctx, &out->len); - out->utf8 = (char *)&ctx->net_bytes[ctx->net_offset]; - ctx->net_offset += out->len; -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static void unmarshal_dm(struct _unmarshal_ctx *ctx, lib9p_dm_t *out) { - unmarshal_4(ctx, (uint32_t *)out); +static void unmarshal_stat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_stat *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 2; + UNMARSHAL_U16LE(ctx, out->kern_type); + UNMARSHAL_U32LE(ctx, out->kern_dev); + UNMARSHAL_U8LE(ctx, out->file_qid.type); + UNMARSHAL_U32LE(ctx, out->file_qid.vers); + UNMARSHAL_U64LE(ctx, out->file_qid.path); + UNMARSHAL_U32LE(ctx, out->file_mode); + UNMARSHAL_U32LE(ctx, out->file_atime); + UNMARSHAL_U32LE(ctx, out->file_mtime); + UNMARSHAL_U64LE(ctx, out->file_size); + UNMARSHAL_U16LE(ctx, out->file_name.len); + UNMARSHAL_BYTES(ctx, out->file_name.utf8, out->file_name.len); + UNMARSHAL_U16LE(ctx, out->file_owner_uid.len); + UNMARSHAL_BYTES(ctx, out->file_owner_uid.utf8, out->file_owner_uid.len); + UNMARSHAL_U16LE(ctx, out->file_owner_gid.len); + UNMARSHAL_BYTES(ctx, out->file_owner_gid.utf8, out->file_owner_gid.len); + UNMARSHAL_U16LE(ctx, out->file_last_modified_uid.len); + UNMARSHAL_BYTES(ctx, out->file_last_modified_uid.utf8, out->file_last_modified_uid.len); +#if CONFIG_9P_ENABLE_9P2000_u + if (is_ver(ctx, 9P2000_u)) { + UNMARSHAL_U16LE(ctx, out->file_extension.len); + UNMARSHAL_BYTES(ctx, out->file_extension.utf8, out->file_extension.len); + UNMARSHAL_U32LE(ctx, out->file_owner_n_uid); + UNMARSHAL_U32LE(ctx, out->file_owner_n_gid); + UNMARSHAL_U32LE(ctx, out->file_last_modified_n_uid); + } +#endif /* CONFIG_9P_ENABLE_9P2000_u */ } #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static void unmarshal_qt(struct _unmarshal_ctx *ctx, lib9p_qt_t *out) { - unmarshal_1(ctx, (uint8_t *)out); -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ +static void unmarshal_Tversion([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tversion *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->max_msg_size); + UNMARSHAL_U16LE(ctx, out->version.len); + UNMARSHAL_BYTES(ctx, out->version.utf8, out->version.len); +} + +static void unmarshal_Rversion([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rversion *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->max_msg_size); + UNMARSHAL_U16LE(ctx, out->version.len); + UNMARSHAL_BYTES(ctx, out->version.utf8, out->version.len); +} + +static void unmarshal_Tauth([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tauth *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->afid); + UNMARSHAL_U16LE(ctx, out->uname.len); + UNMARSHAL_BYTES(ctx, out->uname.utf8, out->uname.len); + UNMARSHAL_U16LE(ctx, out->aname.len); + UNMARSHAL_BYTES(ctx, out->aname.utf8, out->aname.len); #if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static void unmarshal_nuid(struct _unmarshal_ctx *ctx, lib9p_nuid_t *out) { - unmarshal_4(ctx, (uint32_t *)out); -} - + if (( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) )) { + UNMARSHAL_U32LE(ctx, out->n_uid); + } #endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static void unmarshal_o(struct _unmarshal_ctx *ctx, lib9p_o_t *out) { - unmarshal_1(ctx, (uint8_t *)out); } -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ +static void unmarshal_Rauth([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rauth *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->aqid.type); + UNMARSHAL_U32LE(ctx, out->aqid.vers); + UNMARSHAL_U64LE(ctx, out->aqid.path); +} + +static void unmarshal_Tattach([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tattach *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U32LE(ctx, out->afid); + UNMARSHAL_U16LE(ctx, out->uname.len); + UNMARSHAL_BYTES(ctx, out->uname.utf8, out->uname.len); + UNMARSHAL_U16LE(ctx, out->aname.len); + UNMARSHAL_BYTES(ctx, out->aname.utf8, out->aname.len); #if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static void unmarshal_errno(struct _unmarshal_ctx *ctx, lib9p_errno_t *out) { - unmarshal_4(ctx, (uint32_t *)out); -} - + if (( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) )) { + UNMARSHAL_U32LE(ctx, out->n_uid); + } #endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_ALWAYS_INLINE static void unmarshal_super_magic(struct _unmarshal_ctx *ctx, lib9p_super_magic_t *out) { - unmarshal_4(ctx, (uint32_t *)out); -} - -LM_ALWAYS_INLINE static void unmarshal_lo(struct _unmarshal_ctx *ctx, lib9p_lo_t *out) { - unmarshal_4(ctx, (uint32_t *)out); -} - -LM_ALWAYS_INLINE static void unmarshal_dt(struct _unmarshal_ctx *ctx, lib9p_dt_t *out) { - unmarshal_1(ctx, (uint8_t *)out); -} - -LM_ALWAYS_INLINE static void unmarshal_mode(struct _unmarshal_ctx *ctx, lib9p_mode_t *out) { - unmarshal_4(ctx, (uint32_t *)out); -} - -LM_ALWAYS_INLINE static void unmarshal_b4(struct _unmarshal_ctx *ctx, lib9p_b4_t *out) { - unmarshal_4(ctx, (uint32_t *)out); -} - -LM_ALWAYS_INLINE static void unmarshal_getattr(struct _unmarshal_ctx *ctx, lib9p_getattr_t *out) { - unmarshal_8(ctx, (uint64_t *)out); -} - -LM_ALWAYS_INLINE static void unmarshal_setattr(struct _unmarshal_ctx *ctx, lib9p_setattr_t *out) { - unmarshal_4(ctx, (uint32_t *)out); -} - -LM_ALWAYS_INLINE static void unmarshal_lock_type(struct _unmarshal_ctx *ctx, lib9p_lock_type_t *out) { - unmarshal_1(ctx, (uint8_t *)out); -} - -LM_ALWAYS_INLINE static void unmarshal_lock_flags(struct _unmarshal_ctx *ctx, lib9p_lock_flags_t *out) { - unmarshal_4(ctx, (uint32_t *)out); -} - -LM_ALWAYS_INLINE static void unmarshal_lock_status(struct _unmarshal_ctx *ctx, lib9p_lock_status_t *out) { - unmarshal_1(ctx, (uint8_t *)out); -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static void unmarshal_Tflush(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tflush *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_2(ctx, &out->oldtag); -} - -LM_FLATTEN static void unmarshal_Rflush(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rflush *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -LM_FLATTEN static void unmarshal_Rread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rread *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_4(ctx, &out->count); - out->data = (char *)&ctx->net_bytes[ctx->net_offset]; - ctx->net_offset += out->count; -} - -LM_FLATTEN static void unmarshal_Rwrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwrite *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_4(ctx, &out->count); -} - -LM_FLATTEN static void unmarshal_Rclunk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rclunk *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -LM_FLATTEN static void unmarshal_Rremove(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rremove *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static void unmarshal_Rwstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwstat *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static void unmarshal_Rrename(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rrename *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -LM_FLATTEN static void unmarshal_Rsetattr(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rsetattr *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -LM_FLATTEN static void unmarshal_Rxattrwalk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rxattrwalk *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_8(ctx, &out->attr_size); -} - -LM_FLATTEN static void unmarshal_Rxattrcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rxattrcreate *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -LM_FLATTEN static void unmarshal_Rreaddir(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rreaddir *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_4(ctx, &out->count); - out->data = (char *)&ctx->net_bytes[ctx->net_offset]; - ctx->net_offset += out->count; -} - -LM_FLATTEN static void unmarshal_Rfsync(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rfsync *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -LM_FLATTEN static void unmarshal_Rlink(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rlink *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -LM_FLATTEN static void unmarshal_Rrenameat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rrenameat *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -LM_FLATTEN static void unmarshal_Runlinkat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Runlinkat *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ -#if CONFIG_9P_ENABLE_9P2000_e -LM_FLATTEN static void unmarshal_Tsession(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tsession *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_8(ctx, &out->key); } -LM_FLATTEN static void unmarshal_Rsession(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rsession *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); -} - -LM_FLATTEN static void unmarshal_Rsread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rsread *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_4(ctx, &out->count); - out->data = (char *)&ctx->net_bytes[ctx->net_offset]; - ctx->net_offset += out->count; +static void unmarshal_Rattach([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rattach *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->qid.type); + UNMARSHAL_U32LE(ctx, out->qid.vers); + UNMARSHAL_U64LE(ctx, out->qid.path); +} + +static void unmarshal_Rerror([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rerror *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U16LE(ctx, out->ename.len); + UNMARSHAL_BYTES(ctx, out->ename.utf8, out->ename.len); +#if CONFIG_9P_ENABLE_9P2000_u + if (is_ver(ctx, 9P2000_u)) { + UNMARSHAL_U32LE(ctx, out->errno); + } +#endif /* CONFIG_9P_ENABLE_9P2000_u */ } -LM_FLATTEN static void unmarshal_Rswrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rswrite *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_4(ctx, &out->count); +static void unmarshal_Tflush([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tflush *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U16LE(ctx, out->oldtag); +} + +static void unmarshal_Rflush([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rflush *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); +} + +static void unmarshal_Twalk([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Twalk *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U32LE(ctx, out->newfid); + UNMARSHAL_U16LE(ctx, out->nwname); + out->wname = extra; + extra += sizeof(out->wname[0]) * out->nwname; + for (uint16_t i = 0; i < out->nwname; i++) { + UNMARSHAL_U16LE(ctx, out->wname[i].len); + UNMARSHAL_BYTES(ctx, out->wname[i].utf8, out->wname[i].len); + } } -#endif /* CONFIG_9P_ENABLE_9P2000_e */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static void unmarshal_Tread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tread *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_8(ctx, &out->offset); - unmarshal_4(ctx, &out->count); -} - -LM_FLATTEN static void unmarshal_Twrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twrite *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_8(ctx, &out->offset); - unmarshal_4(ctx, &out->count); - out->data = (char *)&ctx->net_bytes[ctx->net_offset]; - ctx->net_offset += out->count; -} - -LM_FLATTEN static void unmarshal_Tclunk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tclunk *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); -} - -LM_FLATTEN static void unmarshal_Tremove(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tremove *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); +static void unmarshal_Rwalk([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rwalk *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U16LE(ctx, out->nwqid); + out->wqid = extra; + extra += sizeof(out->wqid[0]) * out->nwqid; + for (uint16_t i = 0; i < out->nwqid; i++) { + UNMARSHAL_U8LE(ctx, out->wqid[i].type); + UNMARSHAL_U32LE(ctx, out->wqid[i].vers); + UNMARSHAL_U64LE(ctx, out->wqid[i].path); + } } #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static void unmarshal_Tstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tstat *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); +static void unmarshal_Topen([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Topen *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U8LE(ctx, out->mode); +} + +static void unmarshal_Ropen([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Ropen *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->qid.type); + UNMARSHAL_U32LE(ctx, out->qid.vers); + UNMARSHAL_U64LE(ctx, out->qid.path); + UNMARSHAL_U32LE(ctx, out->iounit); +} + +static void unmarshal_Tcreate([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tcreate *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U16LE(ctx, out->name.len); + UNMARSHAL_BYTES(ctx, out->name.utf8, out->name.len); + UNMARSHAL_U32LE(ctx, out->perm); + UNMARSHAL_U8LE(ctx, out->mode); +} + +static void unmarshal_Rcreate([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rcreate *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->qid.type); + UNMARSHAL_U32LE(ctx, out->qid.vers); + UNMARSHAL_U64LE(ctx, out->qid.path); + UNMARSHAL_U32LE(ctx, out->iounit); } #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static void unmarshal_Tstatfs(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tstatfs *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); -} - -LM_FLATTEN static void unmarshal_Treadlink(struct _unmarshal_ctx *ctx, struct lib9p_msg_Treadlink *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); -} - -LM_FLATTEN static void unmarshal_Treaddir(struct _unmarshal_ctx *ctx, struct lib9p_msg_Treaddir *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_8(ctx, &out->offset); - unmarshal_4(ctx, &out->count); -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static void unmarshal_Tversion(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tversion *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_4(ctx, &out->max_msg_size); - unmarshal_s(ctx, &out->version); -} - -LM_FLATTEN static void unmarshal_Rversion(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rversion *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_4(ctx, &out->max_msg_size); - unmarshal_s(ctx, &out->version); -} - -LM_FLATTEN static void unmarshal_Twalk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twalk *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_fid(ctx, &out->newfid); - unmarshal_2(ctx, &out->nwname); - out->wname = ctx->extra; - ctx->extra += sizeof(out->wname[0]) * out->nwname; - for (typeof(out->nwname) i = 0; i < out->nwname; i++) - unmarshal_s(ctx, &out->wname[i]); -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static void unmarshal_Trename(struct _unmarshal_ctx *ctx, struct lib9p_msg_Trename *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_fid(ctx, &out->dfid); - unmarshal_s(ctx, &out->name); -} - -LM_FLATTEN static void unmarshal_Rreadlink(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rreadlink *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_s(ctx, &out->target); -} - -LM_FLATTEN static void unmarshal_Txattrwalk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Txattrwalk *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_fid(ctx, &out->newfid); - unmarshal_s(ctx, &out->name); -} - -LM_FLATTEN static void unmarshal_Txattrcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Txattrcreate *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_s(ctx, &out->name); - unmarshal_8(ctx, &out->attr_size); - unmarshal_4(ctx, &out->flags); -} - -LM_FLATTEN static void unmarshal_Tlink(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tlink *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->dfid); - unmarshal_fid(ctx, &out->fid); - unmarshal_s(ctx, &out->name); -} - -LM_FLATTEN static void unmarshal_Trenameat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Trenameat *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->olddirfid); - unmarshal_s(ctx, &out->oldname); - unmarshal_fid(ctx, &out->newdirfid); - unmarshal_s(ctx, &out->newname); -} - -LM_FLATTEN static void unmarshal_Tunlinkat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tunlinkat *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->dirfd); - unmarshal_s(ctx, &out->name); - unmarshal_4(ctx, &out->flags); -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ -#if CONFIG_9P_ENABLE_9P2000_e -LM_FLATTEN static void unmarshal_Tsread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tsread *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_4(ctx, &out->fid); - unmarshal_2(ctx, &out->nwname); - out->wname = ctx->extra; - ctx->extra += sizeof(out->wname[0]) * out->nwname; - for (typeof(out->nwname) i = 0; i < out->nwname; i++) - unmarshal_s(ctx, &out->wname[i]); -} - -LM_FLATTEN static void unmarshal_Tswrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tswrite *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_4(ctx, &out->fid); - unmarshal_2(ctx, &out->nwname); - out->wname = ctx->extra; - ctx->extra += sizeof(out->wname[0]) * out->nwname; - for (typeof(out->nwname) i = 0; i < out->nwname; i++) - unmarshal_s(ctx, &out->wname[i]); - unmarshal_4(ctx, &out->count); - out->data = (char *)&ctx->net_bytes[ctx->net_offset]; - ctx->net_offset += out->count; -} - -#endif /* CONFIG_9P_ENABLE_9P2000_e */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static void unmarshal_qid(struct _unmarshal_ctx *ctx, struct lib9p_qid *out) { - memset(out, 0, sizeof(*out)); - unmarshal_qt(ctx, &out->type); - unmarshal_4(ctx, &out->vers); - unmarshal_8(ctx, &out->path); -} - -LM_FLATTEN static void unmarshal_Tauth(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tauth *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->afid); - unmarshal_s(ctx, &out->uname); - unmarshal_s(ctx, &out->aname); -#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u - if ( ( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) ) ) unmarshal_nuid(ctx, &out->n_uid); -#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */ -} - -LM_FLATTEN static void unmarshal_Tattach(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tattach *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_fid(ctx, &out->afid); - unmarshal_s(ctx, &out->uname); - unmarshal_s(ctx, &out->aname); -#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u - if ( ( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) ) ) unmarshal_nuid(ctx, &out->n_uid); -#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */ +static void unmarshal_Tread([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tread *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U64LE(ctx, out->offset); + UNMARSHAL_U32LE(ctx, out->count); +} + +static void unmarshal_Rread([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rread *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->count); + UNMARSHAL_BYTES(ctx, out->data, out->count); +} + +static void unmarshal_Twrite([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Twrite *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U64LE(ctx, out->offset); + UNMARSHAL_U32LE(ctx, out->count); + UNMARSHAL_BYTES(ctx, out->data, out->count); +} + +static void unmarshal_Rwrite([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rwrite *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->count); +} + +static void unmarshal_Tclunk([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tclunk *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); +} + +static void unmarshal_Rclunk([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rclunk *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); +} + +static void unmarshal_Tremove([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tremove *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); +} + +static void unmarshal_Rremove([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rremove *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); } #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static void unmarshal_Tsymlink(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tsymlink *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_s(ctx, &out->name); - unmarshal_s(ctx, &out->symtgt); - unmarshal_nuid(ctx, &out->gid); -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static void unmarshal_Topen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Topen *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_o(ctx, &out->mode); -} - -LM_FLATTEN static void unmarshal_Tcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tcreate *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_s(ctx, &out->name); - unmarshal_dm(ctx, &out->perm); - unmarshal_o(ctx, &out->mode); -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_p9p -LM_FLATTEN static void unmarshal_Topenfd(struct _unmarshal_ctx *ctx, struct lib9p_msg_Topenfd *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_o(ctx, &out->mode); -} - -#endif /* CONFIG_9P_ENABLE_9P2000_p9p */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static void unmarshal_Rerror(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rerror *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_s(ctx, &out->ename); +static void unmarshal_Tstat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tstat *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); +} + +static void unmarshal_Rstat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rstat *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + net_offset += 2; + net_offset += 2; + UNMARSHAL_U16LE(ctx, out->stat.kern_type); + UNMARSHAL_U32LE(ctx, out->stat.kern_dev); + UNMARSHAL_U8LE(ctx, out->stat.file_qid.type); + UNMARSHAL_U32LE(ctx, out->stat.file_qid.vers); + UNMARSHAL_U64LE(ctx, out->stat.file_qid.path); + UNMARSHAL_U32LE(ctx, out->stat.file_mode); + UNMARSHAL_U32LE(ctx, out->stat.file_atime); + UNMARSHAL_U32LE(ctx, out->stat.file_mtime); + UNMARSHAL_U64LE(ctx, out->stat.file_size); + UNMARSHAL_U16LE(ctx, out->stat.file_name.len); + UNMARSHAL_BYTES(ctx, out->stat.file_name.utf8, out->stat.file_name.len); + UNMARSHAL_U16LE(ctx, out->stat.file_owner_uid.len); + UNMARSHAL_BYTES(ctx, out->stat.file_owner_uid.utf8, out->stat.file_owner_uid.len); + UNMARSHAL_U16LE(ctx, out->stat.file_owner_gid.len); + UNMARSHAL_BYTES(ctx, out->stat.file_owner_gid.utf8, out->stat.file_owner_gid.len); + UNMARSHAL_U16LE(ctx, out->stat.file_last_modified_uid.len); + UNMARSHAL_BYTES(ctx, out->stat.file_last_modified_uid.utf8, out->stat.file_last_modified_uid.len); #if CONFIG_9P_ENABLE_9P2000_u - if ( is_ver(ctx, 9P2000_u) ) unmarshal_errno(ctx, &out->errno); + if (is_ver(ctx, 9P2000_u)) { + UNMARSHAL_U16LE(ctx, out->stat.file_extension.len); + UNMARSHAL_BYTES(ctx, out->stat.file_extension.utf8, out->stat.file_extension.len); + UNMARSHAL_U32LE(ctx, out->stat.file_owner_n_uid); + UNMARSHAL_U32LE(ctx, out->stat.file_owner_n_gid); + UNMARSHAL_U32LE(ctx, out->stat.file_last_modified_n_uid); + } #endif /* CONFIG_9P_ENABLE_9P2000_u */ } -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static void unmarshal_Rlerror(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rlerror *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_errno(ctx, &out->ecode); -} - -LM_FLATTEN static void unmarshal_Rstatfs(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rstatfs *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_super_magic(ctx, &out->type); - unmarshal_4(ctx, &out->bsize); - unmarshal_8(ctx, &out->blocks); - unmarshal_8(ctx, &out->bfree); - unmarshal_8(ctx, &out->bavail); - unmarshal_8(ctx, &out->files); - unmarshal_8(ctx, &out->ffree); - unmarshal_8(ctx, &out->fsid); - unmarshal_4(ctx, &out->namelen); -} - -LM_FLATTEN static void unmarshal_Tlopen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tlopen *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_lo(ctx, &out->flags); -} - -LM_FLATTEN static void unmarshal_Tlcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tlcreate *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_s(ctx, &out->name); - unmarshal_lo(ctx, &out->flags); - unmarshal_mode(ctx, &out->mode); - unmarshal_nuid(ctx, &out->gid); -} - -LM_FLATTEN static void unmarshal_Tmknod(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tmknod *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->dfid); - unmarshal_s(ctx, &out->name); - unmarshal_mode(ctx, &out->mode); - unmarshal_4(ctx, &out->major); - unmarshal_4(ctx, &out->minor); - unmarshal_nuid(ctx, &out->gid); -} - -LM_FLATTEN static void unmarshal_Tmkdir(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tmkdir *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->dfid); - unmarshal_s(ctx, &out->name); - unmarshal_mode(ctx, &out->mode); - unmarshal_nuid(ctx, &out->gid); -} - -LM_FLATTEN static void unmarshal_Tfsync(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tfsync *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_b4(ctx, &out->datasync); -} - -LM_FLATTEN static void unmarshal_Tgetattr(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tgetattr *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_getattr(ctx, &out->request_mask); -} - -LM_FLATTEN static void unmarshal_Tsetattr(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tsetattr *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_setattr(ctx, &out->valid); - unmarshal_mode(ctx, &out->mode); - unmarshal_nuid(ctx, &out->uid); - unmarshal_nuid(ctx, &out->gid); - unmarshal_8(ctx, &out->filesize); - unmarshal_8(ctx, &out->atime_sec); - unmarshal_8(ctx, &out->atime_nsec); - unmarshal_8(ctx, &out->mtime_sec); - unmarshal_8(ctx, &out->mtime_nsec); -} - -LM_FLATTEN static void unmarshal_Tgetlock(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tgetlock *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_lock_type(ctx, &out->type); - unmarshal_8(ctx, &out->start); - unmarshal_8(ctx, &out->length); - unmarshal_4(ctx, &out->proc_id); - unmarshal_s(ctx, &out->client_id); -} - -LM_FLATTEN static void unmarshal_Rgetlock(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rgetlock *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_lock_type(ctx, &out->type); - unmarshal_8(ctx, &out->start); - unmarshal_8(ctx, &out->length); - unmarshal_4(ctx, &out->proc_id); - unmarshal_s(ctx, &out->client_id); -} - -LM_FLATTEN static void unmarshal_Tlock(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tlock *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - unmarshal_lock_type(ctx, &out->type); - unmarshal_lock_flags(ctx, &out->flags); - unmarshal_8(ctx, &out->start); - unmarshal_8(ctx, &out->length); - unmarshal_4(ctx, &out->proc_id); - unmarshal_s(ctx, &out->client_id); -} - -LM_FLATTEN static void unmarshal_Rlock(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rlock *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_lock_status(ctx, &out->status); -} - -#endif /* CONFIG_9P_ENABLE_9P2000_L */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_ALWAYS_INLINE static void unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9p_stat *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 2; - unmarshal_2(ctx, &out->kern_type); - unmarshal_4(ctx, &out->kern_dev); - unmarshal_qid(ctx, &out->file_qid); - unmarshal_dm(ctx, &out->file_mode); - unmarshal_4(ctx, &out->file_atime); - unmarshal_4(ctx, &out->file_mtime); - unmarshal_8(ctx, &out->file_size); - unmarshal_s(ctx, &out->file_name); - unmarshal_s(ctx, &out->file_owner_uid); - unmarshal_s(ctx, &out->file_owner_gid); - unmarshal_s(ctx, &out->file_last_modified_uid); +static void unmarshal_Twstat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Twstat *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + net_offset += 2; + net_offset += 2; + UNMARSHAL_U16LE(ctx, out->stat.kern_type); + UNMARSHAL_U32LE(ctx, out->stat.kern_dev); + UNMARSHAL_U8LE(ctx, out->stat.file_qid.type); + UNMARSHAL_U32LE(ctx, out->stat.file_qid.vers); + UNMARSHAL_U64LE(ctx, out->stat.file_qid.path); + UNMARSHAL_U32LE(ctx, out->stat.file_mode); + UNMARSHAL_U32LE(ctx, out->stat.file_atime); + UNMARSHAL_U32LE(ctx, out->stat.file_mtime); + UNMARSHAL_U64LE(ctx, out->stat.file_size); + UNMARSHAL_U16LE(ctx, out->stat.file_name.len); + UNMARSHAL_BYTES(ctx, out->stat.file_name.utf8, out->stat.file_name.len); + UNMARSHAL_U16LE(ctx, out->stat.file_owner_uid.len); + UNMARSHAL_BYTES(ctx, out->stat.file_owner_uid.utf8, out->stat.file_owner_uid.len); + UNMARSHAL_U16LE(ctx, out->stat.file_owner_gid.len); + UNMARSHAL_BYTES(ctx, out->stat.file_owner_gid.utf8, out->stat.file_owner_gid.len); + UNMARSHAL_U16LE(ctx, out->stat.file_last_modified_uid.len); + UNMARSHAL_BYTES(ctx, out->stat.file_last_modified_uid.utf8, out->stat.file_last_modified_uid.len); #if CONFIG_9P_ENABLE_9P2000_u - if ( is_ver(ctx, 9P2000_u) ) unmarshal_s(ctx, &out->file_extension); - if ( is_ver(ctx, 9P2000_u) ) unmarshal_nuid(ctx, &out->file_owner_n_uid); - if ( is_ver(ctx, 9P2000_u) ) unmarshal_nuid(ctx, &out->file_owner_n_gid); - if ( is_ver(ctx, 9P2000_u) ) unmarshal_nuid(ctx, &out->file_last_modified_n_uid); + if (is_ver(ctx, 9P2000_u)) { + UNMARSHAL_U16LE(ctx, out->stat.file_extension.len); + UNMARSHAL_BYTES(ctx, out->stat.file_extension.utf8, out->stat.file_extension.len); + UNMARSHAL_U32LE(ctx, out->stat.file_owner_n_uid); + UNMARSHAL_U32LE(ctx, out->stat.file_owner_n_gid); + UNMARSHAL_U32LE(ctx, out->stat.file_last_modified_n_uid); + } #endif /* CONFIG_9P_ENABLE_9P2000_u */ } -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static void unmarshal_Rauth(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rauth *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_qid(ctx, &out->aqid); -} - -LM_FLATTEN static void unmarshal_Rattach(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rattach *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_qid(ctx, &out->qid); -} - -LM_FLATTEN static void unmarshal_Rwalk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwalk *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_2(ctx, &out->nwqid); - out->wqid = ctx->extra; - ctx->extra += sizeof(out->wqid[0]) * out->nwqid; - for (typeof(out->nwqid) i = 0; i < out->nwqid; i++) - unmarshal_qid(ctx, &out->wqid[i]); -} - -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static void unmarshal_Ropen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Ropen *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_qid(ctx, &out->qid); - unmarshal_4(ctx, &out->iounit); -} - -LM_FLATTEN static void unmarshal_Rcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rcreate *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_qid(ctx, &out->qid); - unmarshal_4(ctx, &out->iounit); +static void unmarshal_Rwstat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rwstat *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); } #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000_p9p -LM_FLATTEN static void unmarshal_Ropenfd(struct _unmarshal_ctx *ctx, struct lib9p_msg_Ropenfd *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_qid(ctx, &out->qid); - unmarshal_4(ctx, &out->iounit); - unmarshal_4(ctx, &out->unixfd); +static void unmarshal_Topenfd([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Topenfd *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U8LE(ctx, out->mode); +} + +static void unmarshal_Ropenfd([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Ropenfd *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->qid.type); + UNMARSHAL_U32LE(ctx, out->qid.vers); + UNMARSHAL_U64LE(ctx, out->qid.path); + UNMARSHAL_U32LE(ctx, out->iounit); + UNMARSHAL_U32LE(ctx, out->unixfd); } #endif /* CONFIG_9P_ENABLE_9P2000_p9p */ #if CONFIG_9P_ENABLE_9P2000_L -LM_FLATTEN static void unmarshal_Rlopen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rlopen *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_qid(ctx, &out->qid); - unmarshal_4(ctx, &out->iounit); -} - -LM_FLATTEN static void unmarshal_Rlcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rlcreate *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_qid(ctx, &out->qid); - unmarshal_4(ctx, &out->iounit); -} - -LM_FLATTEN static void unmarshal_Rsymlink(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rsymlink *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_qid(ctx, &out->qid); -} - -LM_FLATTEN static void unmarshal_Rmknod(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rmknod *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_qid(ctx, &out->qid); -} - -LM_FLATTEN static void unmarshal_Rgetattr(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rgetattr *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_getattr(ctx, &out->valid); - unmarshal_qid(ctx, &out->qid); - unmarshal_mode(ctx, &out->mode); - unmarshal_nuid(ctx, &out->uid); - unmarshal_nuid(ctx, &out->gid); - unmarshal_8(ctx, &out->nlink); - unmarshal_8(ctx, &out->rdev); - unmarshal_8(ctx, &out->filesize); - unmarshal_8(ctx, &out->blksize); - unmarshal_8(ctx, &out->blocks); - unmarshal_8(ctx, &out->atime_sec); - unmarshal_8(ctx, &out->atime_nsec); - unmarshal_8(ctx, &out->mtime_sec); - unmarshal_8(ctx, &out->mtime_nsec); - unmarshal_8(ctx, &out->ctime_sec); - unmarshal_8(ctx, &out->ctime_nsec); - unmarshal_8(ctx, &out->btime_sec); - unmarshal_8(ctx, &out->btime_nsec); - unmarshal_8(ctx, &out->gen); - unmarshal_8(ctx, &out->data_version); -} - -LM_FLATTEN static void unmarshal_Rmkdir(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rmkdir *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_qid(ctx, &out->qid); +static void unmarshal_Rlerror([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rlerror *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->ecode); +} + +static void unmarshal_Tstatfs([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tstatfs *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); +} + +static void unmarshal_Rstatfs([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rstatfs *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->type); + UNMARSHAL_U32LE(ctx, out->bsize); + UNMARSHAL_U64LE(ctx, out->blocks); + UNMARSHAL_U64LE(ctx, out->bfree); + UNMARSHAL_U64LE(ctx, out->bavail); + UNMARSHAL_U64LE(ctx, out->files); + UNMARSHAL_U64LE(ctx, out->ffree); + UNMARSHAL_U64LE(ctx, out->fsid); + UNMARSHAL_U32LE(ctx, out->namelen); +} + +static void unmarshal_Tlopen([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tlopen *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U32LE(ctx, out->flags); +} + +static void unmarshal_Rlopen([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rlopen *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->qid.type); + UNMARSHAL_U32LE(ctx, out->qid.vers); + UNMARSHAL_U64LE(ctx, out->qid.path); + UNMARSHAL_U32LE(ctx, out->iounit); +} + +static void unmarshal_Tlcreate([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tlcreate *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U16LE(ctx, out->name.len); + UNMARSHAL_BYTES(ctx, out->name.utf8, out->name.len); + UNMARSHAL_U32LE(ctx, out->flags); + UNMARSHAL_U32LE(ctx, out->mode); + UNMARSHAL_U32LE(ctx, out->gid); +} + +static void unmarshal_Rlcreate([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rlcreate *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->qid.type); + UNMARSHAL_U32LE(ctx, out->qid.vers); + UNMARSHAL_U64LE(ctx, out->qid.path); + UNMARSHAL_U32LE(ctx, out->iounit); +} + +static void unmarshal_Tsymlink([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tsymlink *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U16LE(ctx, out->name.len); + UNMARSHAL_BYTES(ctx, out->name.utf8, out->name.len); + UNMARSHAL_U16LE(ctx, out->symtgt.len); + UNMARSHAL_BYTES(ctx, out->symtgt.utf8, out->symtgt.len); + UNMARSHAL_U32LE(ctx, out->gid); +} + +static void unmarshal_Rsymlink([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rsymlink *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->qid.type); + UNMARSHAL_U32LE(ctx, out->qid.vers); + UNMARSHAL_U64LE(ctx, out->qid.path); +} + +static void unmarshal_Tmknod([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tmknod *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->dfid); + UNMARSHAL_U16LE(ctx, out->name.len); + UNMARSHAL_BYTES(ctx, out->name.utf8, out->name.len); + UNMARSHAL_U32LE(ctx, out->mode); + UNMARSHAL_U32LE(ctx, out->major); + UNMARSHAL_U32LE(ctx, out->minor); + UNMARSHAL_U32LE(ctx, out->gid); +} + +static void unmarshal_Rmknod([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rmknod *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->qid.type); + UNMARSHAL_U32LE(ctx, out->qid.vers); + UNMARSHAL_U64LE(ctx, out->qid.path); +} + +static void unmarshal_Trename([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Trename *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U32LE(ctx, out->dfid); + UNMARSHAL_U16LE(ctx, out->name.len); + UNMARSHAL_BYTES(ctx, out->name.utf8, out->name.len); +} + +static void unmarshal_Rrename([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rrename *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); +} + +static void unmarshal_Treadlink([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Treadlink *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); +} + +static void unmarshal_Rreadlink([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rreadlink *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U16LE(ctx, out->target.len); + UNMARSHAL_BYTES(ctx, out->target.utf8, out->target.len); +} + +static void unmarshal_Tgetattr([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tgetattr *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U64LE(ctx, out->request_mask); +} + +static void unmarshal_Rgetattr([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rgetattr *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U64LE(ctx, out->valid); + UNMARSHAL_U8LE(ctx, out->qid.type); + UNMARSHAL_U32LE(ctx, out->qid.vers); + UNMARSHAL_U64LE(ctx, out->qid.path); + UNMARSHAL_U32LE(ctx, out->mode); + UNMARSHAL_U32LE(ctx, out->uid); + UNMARSHAL_U32LE(ctx, out->gid); + UNMARSHAL_U64LE(ctx, out->nlink); + UNMARSHAL_U64LE(ctx, out->rdev); + UNMARSHAL_U64LE(ctx, out->filesize); + UNMARSHAL_U64LE(ctx, out->blksize); + UNMARSHAL_U64LE(ctx, out->blocks); + UNMARSHAL_U64LE(ctx, out->atime_sec); + UNMARSHAL_U64LE(ctx, out->atime_nsec); + UNMARSHAL_U64LE(ctx, out->mtime_sec); + UNMARSHAL_U64LE(ctx, out->mtime_nsec); + UNMARSHAL_U64LE(ctx, out->ctime_sec); + UNMARSHAL_U64LE(ctx, out->ctime_nsec); + UNMARSHAL_U64LE(ctx, out->btime_sec); + UNMARSHAL_U64LE(ctx, out->btime_nsec); + UNMARSHAL_U64LE(ctx, out->gen); + UNMARSHAL_U64LE(ctx, out->data_version); +} + +static void unmarshal_Tsetattr([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tsetattr *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U32LE(ctx, out->valid); + UNMARSHAL_U32LE(ctx, out->mode); + UNMARSHAL_U32LE(ctx, out->uid); + UNMARSHAL_U32LE(ctx, out->gid); + UNMARSHAL_U64LE(ctx, out->filesize); + UNMARSHAL_U64LE(ctx, out->atime_sec); + UNMARSHAL_U64LE(ctx, out->atime_nsec); + UNMARSHAL_U64LE(ctx, out->mtime_sec); + UNMARSHAL_U64LE(ctx, out->mtime_nsec); +} + +static void unmarshal_Rsetattr([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rsetattr *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); +} + +static void unmarshal_Txattrwalk([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Txattrwalk *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U32LE(ctx, out->newfid); + UNMARSHAL_U16LE(ctx, out->name.len); + UNMARSHAL_BYTES(ctx, out->name.utf8, out->name.len); +} + +static void unmarshal_Rxattrwalk([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rxattrwalk *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U64LE(ctx, out->attr_size); +} + +static void unmarshal_Txattrcreate([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Txattrcreate *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U16LE(ctx, out->name.len); + UNMARSHAL_BYTES(ctx, out->name.utf8, out->name.len); + UNMARSHAL_U64LE(ctx, out->attr_size); + UNMARSHAL_U32LE(ctx, out->flags); +} + +static void unmarshal_Rxattrcreate([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rxattrcreate *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); +} + +static void unmarshal_Treaddir([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Treaddir *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U64LE(ctx, out->offset); + UNMARSHAL_U32LE(ctx, out->count); +} + +static void unmarshal_Rreaddir([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rreaddir *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->count); + UNMARSHAL_BYTES(ctx, out->data, out->count); +} + +static void unmarshal_Tfsync([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tfsync *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U32LE(ctx, out->datasync); +} + +static void unmarshal_Rfsync([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rfsync *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); +} + +static void unmarshal_Tlock([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tlock *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U8LE(ctx, out->type); + UNMARSHAL_U32LE(ctx, out->flags); + UNMARSHAL_U64LE(ctx, out->start); + UNMARSHAL_U64LE(ctx, out->length); + UNMARSHAL_U32LE(ctx, out->proc_id); + UNMARSHAL_U16LE(ctx, out->client_id.len); + UNMARSHAL_BYTES(ctx, out->client_id.utf8, out->client_id.len); +} + +static void unmarshal_Rlock([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rlock *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->status); +} + +static void unmarshal_Tgetlock([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tgetlock *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U8LE(ctx, out->type); + UNMARSHAL_U64LE(ctx, out->start); + UNMARSHAL_U64LE(ctx, out->length); + UNMARSHAL_U32LE(ctx, out->proc_id); + UNMARSHAL_U16LE(ctx, out->client_id.len); + UNMARSHAL_BYTES(ctx, out->client_id.utf8, out->client_id.len); +} + +static void unmarshal_Rgetlock([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rgetlock *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->type); + UNMARSHAL_U64LE(ctx, out->start); + UNMARSHAL_U64LE(ctx, out->length); + UNMARSHAL_U32LE(ctx, out->proc_id); + UNMARSHAL_U16LE(ctx, out->client_id.len); + UNMARSHAL_BYTES(ctx, out->client_id.utf8, out->client_id.len); +} + +static void unmarshal_Tlink([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tlink *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->dfid); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U16LE(ctx, out->name.len); + UNMARSHAL_BYTES(ctx, out->name.utf8, out->name.len); +} + +static void unmarshal_Rlink([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rlink *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); +} + +static void unmarshal_Tmkdir([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tmkdir *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->dfid); + UNMARSHAL_U16LE(ctx, out->name.len); + UNMARSHAL_BYTES(ctx, out->name.utf8, out->name.len); + UNMARSHAL_U32LE(ctx, out->mode); + UNMARSHAL_U32LE(ctx, out->gid); +} + +static void unmarshal_Rmkdir([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rmkdir *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U8LE(ctx, out->qid.type); + UNMARSHAL_U32LE(ctx, out->qid.vers); + UNMARSHAL_U64LE(ctx, out->qid.path); +} + +static void unmarshal_Trenameat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Trenameat *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->olddirfid); + UNMARSHAL_U16LE(ctx, out->oldname.len); + UNMARSHAL_BYTES(ctx, out->oldname.utf8, out->oldname.len); + UNMARSHAL_U32LE(ctx, out->newdirfid); + UNMARSHAL_U16LE(ctx, out->newname.len); + UNMARSHAL_BYTES(ctx, out->newname.utf8, out->newname.len); +} + +static void unmarshal_Rrenameat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rrenameat *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); +} + +static void unmarshal_Tunlinkat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tunlinkat *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->dirfd); + UNMARSHAL_U16LE(ctx, out->name.len); + UNMARSHAL_BYTES(ctx, out->name.utf8, out->name.len); + UNMARSHAL_U32LE(ctx, out->flags); +} + +static void unmarshal_Runlinkat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Runlinkat *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); } #endif /* CONFIG_9P_ENABLE_9P2000_L */ -#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -LM_FLATTEN static void unmarshal_Rstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rstat *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - ctx->net_offset += 2; - unmarshal_stat(ctx, &out->stat); -} - -LM_FLATTEN static void unmarshal_Twstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twstat *out) { - memset(out, 0, sizeof(*out)); - ctx->net_offset += 4; - ctx->net_offset += 1; - unmarshal_tag(ctx, &out->tag); - unmarshal_fid(ctx, &out->fid); - ctx->net_offset += 2; - unmarshal_stat(ctx, &out->stat); +#if CONFIG_9P_ENABLE_9P2000_e +static void unmarshal_Tsession([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tsession *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U64LE(ctx, out->key); +} + +static void unmarshal_Rsession([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rsession *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); +} + +static void unmarshal_Tsread([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tsread *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U16LE(ctx, out->nwname); + out->wname = extra; + extra += sizeof(out->wname[0]) * out->nwname; + for (uint16_t i = 0; i < out->nwname; i++) { + UNMARSHAL_U16LE(ctx, out->wname[i].len); + UNMARSHAL_BYTES(ctx, out->wname[i].utf8, out->wname[i].len); + } +} + +static void unmarshal_Rsread([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rsread *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->count); + UNMARSHAL_BYTES(ctx, out->data, out->count); +} + +static void unmarshal_Tswrite([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Tswrite *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->fid); + UNMARSHAL_U16LE(ctx, out->nwname); + out->wname = extra; + extra += sizeof(out->wname[0]) * out->nwname; + for (uint16_t i = 0; i < out->nwname; i++) { + UNMARSHAL_U16LE(ctx, out->wname[i].len); + UNMARSHAL_BYTES(ctx, out->wname[i].utf8, out->wname[i].len); + } + UNMARSHAL_U32LE(ctx, out->count); + UNMARSHAL_BYTES(ctx, out->data, out->count); } -#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ + +static void unmarshal_Rswrite([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) { + struct lib9p_msg_Rswrite *out = out_buf; + [[gnu::unused]] void *extra = &out[1]; + uint32_t net_offset = 0; + net_offset += 4; + net_offset += 1; + UNMARSHAL_U16LE(ctx, out->tag); + UNMARSHAL_U32LE(ctx, out->count); +} +#endif /* CONFIG_9P_ENABLE_9P2000_e */ /* marshal_* ******************************************************************/ -#define MARSHAL_BYTES_ZEROCOPY(ctx, data, len) \ - if (ctx->net_iov[ctx->net_iov_cnt-1].iov_len) \ - ctx->net_iov_cnt++; \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_base = data; \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_len = len; \ - ctx->net_iov_cnt++; -#define MARSHAL_BYTES(ctx, data, len) \ - if (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base) \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size]; \ - memcpy(&ctx->net_copied[ctx->net_copied_size], data, len); \ - ctx->net_copied_size += len; \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_len += len; -#define MARSHAL_U8LE(ctx, val) \ - if (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base) \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size]; \ - ctx->net_copied[ctx->net_copied_size] = val; \ - ctx->net_copied_size += 1; \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_len += 1; -#define MARSHAL_U16LE(ctx, val) \ - if (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base) \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size]; \ - uint16le_encode(&ctx->net_copied[ctx->net_copied_size], val); \ - ctx->net_copied_size += 2; \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_len += 2; -#define MARSHAL_U32LE(ctx, val) \ - if (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base) \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size]; \ - uint32le_encode(&ctx->net_copied[ctx->net_copied_size], val); \ - ctx->net_copied_size += 4; \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_len += 4; -#define MARSHAL_U64LE(ctx, val) \ - if (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base) \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size]; \ - uint64le_encode(&ctx->net_copied[ctx->net_copied_size], val); \ - ctx->net_copied_size += 8; \ - ctx->net_iov[ctx->net_iov_cnt-1].iov_len += 8; +#define MARSHAL_BYTES_ZEROCOPY(ctx, data, len) \ + if (ret->net_iov[ret->net_iov_cnt-1].iov_len) \ + ret->net_iov_cnt++; \ + ret->net_iov[ret->net_iov_cnt-1].iov_base = data; \ + ret->net_iov[ret->net_iov_cnt-1].iov_len = len; \ + ret->net_iov_cnt++; +#define MARSHAL_BYTES(ctx, data, len) \ + if (!ret->net_iov[ret->net_iov_cnt-1].iov_base) \ + ret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size]; \ + memcpy(&ret->net_copied[ret->net_copied_size], data, len); \ + ret->net_copied_size += len; \ + ret->net_iov[ret->net_iov_cnt-1].iov_len += len; +#define MARSHAL_U8LE(ctx, val) \ + if (!ret->net_iov[ret->net_iov_cnt-1].iov_base) \ + ret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size]; \ + ret->net_copied[ret->net_copied_size] = val; \ + ret->net_copied_size += 1; \ + ret->net_iov[ret->net_iov_cnt-1].iov_len += 1; +#define MARSHAL_U16LE(ctx, val) \ + if (!ret->net_iov[ret->net_iov_cnt-1].iov_base) \ + ret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size]; \ + uint16le_encode(&ret->net_copied[ret->net_copied_size], val); \ + ret->net_copied_size += 2; \ + ret->net_iov[ret->net_iov_cnt-1].iov_len += 2; +#define MARSHAL_U32LE(ctx, val) \ + if (!ret->net_iov[ret->net_iov_cnt-1].iov_base) \ + ret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size]; \ + uint32le_encode(&ret->net_copied[ret->net_copied_size], val); \ + ret->net_copied_size += 4; \ + ret->net_iov[ret->net_iov_cnt-1].iov_len += 4; +#define MARSHAL_U64LE(ctx, val) \ + if (!ret->net_iov[ret->net_iov_cnt-1].iov_base) \ + ret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size]; \ + uint64le_encode(&ret->net_copied[ret->net_copied_size], val); \ + ret->net_copied_size += 8; \ + ret->net_iov[ret->net_iov_cnt-1].iov_len += 8; #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -static bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) { +static bool marshal_stat(struct lib9p_ctx *ctx, struct lib9p_stat *val, struct _marshal_ret *ret) { uint32_t needed_size = 49 + val->file_name.len + val->file_owner_uid.len + val->file_owner_gid.len + val->file_last_modified_uid.len; #if CONFIG_9P_ENABLE_9P2000_u if is_ver(ctx, 9P2000_u) { needed_size += 14 + val->file_extension.len; } #endif /* CONFIG_9P_ENABLE_9P2000_u */ - if (needed_size > ctx->ctx->max_msg_size) { + if (needed_size > ctx->max_msg_size) { return true; } uint32_t offsetof_end = needed_size; @@ -2979,10 +3081,10 @@ static bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) { MARSHAL_U16LE(ctx, offsetof_end - offsetof_kern_type); MARSHAL_U16LE(ctx, val->kern_type); MARSHAL_U32LE(ctx, val->kern_dev); - MARSHAL_U8LE(ctx, val->file_qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->file_qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->file_qid.vers); MARSHAL_U64LE(ctx, val->file_qid.path); - MARSHAL_U32LE(ctx, val->file_mode & dm_masks[ctx->ctx->version]); + MARSHAL_U32LE(ctx, val->file_mode & dm_masks[ctx->version]); MARSHAL_U32LE(ctx, val->file_atime); MARSHAL_U32LE(ctx, val->file_mtime); MARSHAL_U64LE(ctx, val->file_size); @@ -2998,20 +3100,8 @@ static bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) { if (is_ver(ctx, 9P2000_u)) { MARSHAL_U16LE(ctx, val->file_extension.len); MARSHAL_BYTES(ctx, val->file_extension.utf8, val->file_extension.len); - } -#endif /* CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_u - if (is_ver(ctx, 9P2000_u)) { MARSHAL_U32LE(ctx, val->file_owner_n_uid); - } -#endif /* CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_u - if (is_ver(ctx, 9P2000_u)) { MARSHAL_U32LE(ctx, val->file_owner_n_gid); - } -#endif /* CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_u - if (is_ver(ctx, 9P2000_u)) { MARSHAL_U32LE(ctx, val->file_last_modified_n_uid); } #endif /* CONFIG_9P_ENABLE_9P2000_u */ @@ -3020,13 +3110,13 @@ static bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) { #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -static bool marshal_Tversion(struct _marshal_ctx *ctx, struct lib9p_msg_Tversion *val) { +static bool marshal_Tversion(struct lib9p_ctx *ctx, struct lib9p_msg_Tversion *val, struct _marshal_ret *ret) { uint32_t needed_size = 13 + val->version.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tversion", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3040,13 +3130,13 @@ static bool marshal_Tversion(struct _marshal_ctx *ctx, struct lib9p_msg_Tversion return false; } -static bool marshal_Rversion(struct _marshal_ctx *ctx, struct lib9p_msg_Rversion *val) { +static bool marshal_Rversion(struct lib9p_ctx *ctx, struct lib9p_msg_Rversion *val, struct _marshal_ret *ret) { uint32_t needed_size = 13 + val->version.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rversion", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3060,18 +3150,18 @@ static bool marshal_Rversion(struct _marshal_ctx *ctx, struct lib9p_msg_Rversion return false; } -static bool marshal_Tauth(struct _marshal_ctx *ctx, struct lib9p_msg_Tauth *val) { +static bool marshal_Tauth(struct lib9p_ctx *ctx, struct lib9p_msg_Tauth *val, struct _marshal_ret *ret) { uint32_t needed_size = 15 + val->uname.len + val->aname.len; #if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u if ( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) ) { needed_size += 4; } #endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */ - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tauth", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3092,13 +3182,13 @@ static bool marshal_Tauth(struct _marshal_ctx *ctx, struct lib9p_msg_Tauth *val) return false; } -static bool marshal_Rauth(struct _marshal_ctx *ctx, struct lib9p_msg_Rauth *val) { +static bool marshal_Rauth(struct lib9p_ctx *ctx, struct lib9p_msg_Rauth *val, struct _marshal_ret *ret) { uint32_t needed_size = 20; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rauth", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3106,24 +3196,24 @@ static bool marshal_Rauth(struct _marshal_ctx *ctx, struct lib9p_msg_Rauth *val) MARSHAL_U32LE(ctx, offsetof_end - offsetof_size); MARSHAL_U8LE(ctx, 103); MARSHAL_U16LE(ctx, val->tag); - MARSHAL_U8LE(ctx, val->aqid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->aqid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->aqid.vers); MARSHAL_U64LE(ctx, val->aqid.path); return false; } -static bool marshal_Tattach(struct _marshal_ctx *ctx, struct lib9p_msg_Tattach *val) { +static bool marshal_Tattach(struct lib9p_ctx *ctx, struct lib9p_msg_Tattach *val, struct _marshal_ret *ret) { uint32_t needed_size = 19 + val->uname.len + val->aname.len; #if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u if ( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) ) { needed_size += 4; } #endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */ - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tattach", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3145,13 +3235,13 @@ static bool marshal_Tattach(struct _marshal_ctx *ctx, struct lib9p_msg_Tattach * return false; } -static bool marshal_Rattach(struct _marshal_ctx *ctx, struct lib9p_msg_Rattach *val) { +static bool marshal_Rattach(struct lib9p_ctx *ctx, struct lib9p_msg_Rattach *val, struct _marshal_ret *ret) { uint32_t needed_size = 20; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rattach", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3159,24 +3249,24 @@ static bool marshal_Rattach(struct _marshal_ctx *ctx, struct lib9p_msg_Rattach * MARSHAL_U32LE(ctx, offsetof_end - offsetof_size); MARSHAL_U8LE(ctx, 105); MARSHAL_U16LE(ctx, val->tag); - MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->qid.vers); MARSHAL_U64LE(ctx, val->qid.path); return false; } -static bool marshal_Rerror(struct _marshal_ctx *ctx, struct lib9p_msg_Rerror *val) { +static bool marshal_Rerror(struct lib9p_ctx *ctx, struct lib9p_msg_Rerror *val, struct _marshal_ret *ret) { uint32_t needed_size = 9 + val->ename.len; #if CONFIG_9P_ENABLE_9P2000_u if is_ver(ctx, 9P2000_u) { needed_size += 4; } #endif /* CONFIG_9P_ENABLE_9P2000_u */ - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rerror", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3194,13 +3284,13 @@ static bool marshal_Rerror(struct _marshal_ctx *ctx, struct lib9p_msg_Rerror *va return false; } -static bool marshal_Tflush(struct _marshal_ctx *ctx, struct lib9p_msg_Tflush *val) { +static bool marshal_Tflush(struct lib9p_ctx *ctx, struct lib9p_msg_Tflush *val, struct _marshal_ret *ret) { uint32_t needed_size = 9; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tflush", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3212,13 +3302,13 @@ static bool marshal_Tflush(struct _marshal_ctx *ctx, struct lib9p_msg_Tflush *va return false; } -static bool marshal_Rflush(struct _marshal_ctx *ctx, struct lib9p_msg_Rflush *val) { +static bool marshal_Rflush(struct lib9p_ctx *ctx, struct lib9p_msg_Rflush *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rflush", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3229,16 +3319,16 @@ static bool marshal_Rflush(struct _marshal_ctx *ctx, struct lib9p_msg_Rflush *va return false; } -static bool marshal_Twalk(struct _marshal_ctx *ctx, struct lib9p_msg_Twalk *val) { +static bool marshal_Twalk(struct lib9p_ctx *ctx, struct lib9p_msg_Twalk *val, struct _marshal_ret *ret) { uint32_t needed_size = 17; for (uint16_t i = 0; i < val->nwname; i++) { needed_size += 2 + val->wname[i].len; } - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Twalk", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3256,13 +3346,13 @@ static bool marshal_Twalk(struct _marshal_ctx *ctx, struct lib9p_msg_Twalk *val) return false; } -static bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwalk *val) { +static bool marshal_Rwalk(struct lib9p_ctx *ctx, struct lib9p_msg_Rwalk *val, struct _marshal_ret *ret) { uint32_t needed_size = 9 + (val->nwqid)*13; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rwalk", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3272,7 +3362,7 @@ static bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwalk *val) MARSHAL_U16LE(ctx, val->tag); MARSHAL_U16LE(ctx, val->nwqid); for (uint16_t i = 0; i < val->nwqid; i++) { - MARSHAL_U8LE(ctx, val->wqid[i].type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->wqid[i].type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->wqid[i].vers); MARSHAL_U64LE(ctx, val->wqid[i].path); } @@ -3281,13 +3371,13 @@ static bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwalk *val) #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -static bool marshal_Topen(struct _marshal_ctx *ctx, struct lib9p_msg_Topen *val) { +static bool marshal_Topen(struct lib9p_ctx *ctx, struct lib9p_msg_Topen *val, struct _marshal_ret *ret) { uint32_t needed_size = 12; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Topen", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3296,17 +3386,17 @@ static bool marshal_Topen(struct _marshal_ctx *ctx, struct lib9p_msg_Topen *val) MARSHAL_U8LE(ctx, 112); MARSHAL_U16LE(ctx, val->tag); MARSHAL_U32LE(ctx, val->fid); - MARSHAL_U8LE(ctx, val->mode & o_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->mode & o_masks[ctx->version]); return false; } -static bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Ropen *val) { +static bool marshal_Ropen(struct lib9p_ctx *ctx, struct lib9p_msg_Ropen *val, struct _marshal_ret *ret) { uint32_t needed_size = 24; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Ropen", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3314,20 +3404,20 @@ static bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Ropen *val) MARSHAL_U32LE(ctx, offsetof_end - offsetof_size); MARSHAL_U8LE(ctx, 113); MARSHAL_U16LE(ctx, val->tag); - MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->qid.vers); MARSHAL_U64LE(ctx, val->qid.path); MARSHAL_U32LE(ctx, val->iounit); return false; } -static bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tcreate *val) { +static bool marshal_Tcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Tcreate *val, struct _marshal_ret *ret) { uint32_t needed_size = 18 + val->name.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tcreate", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3338,18 +3428,18 @@ static bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tcreate * MARSHAL_U32LE(ctx, val->fid); MARSHAL_U16LE(ctx, val->name.len); MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len); - MARSHAL_U32LE(ctx, val->perm & dm_masks[ctx->ctx->version]); - MARSHAL_U8LE(ctx, val->mode & o_masks[ctx->ctx->version]); + MARSHAL_U32LE(ctx, val->perm & dm_masks[ctx->version]); + MARSHAL_U8LE(ctx, val->mode & o_masks[ctx->version]); return false; } -static bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rcreate *val) { +static bool marshal_Rcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Rcreate *val, struct _marshal_ret *ret) { uint32_t needed_size = 24; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rcreate", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3357,7 +3447,7 @@ static bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rcreate * MARSHAL_U32LE(ctx, offsetof_end - offsetof_size); MARSHAL_U8LE(ctx, 115); MARSHAL_U16LE(ctx, val->tag); - MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->qid.vers); MARSHAL_U64LE(ctx, val->qid.path); MARSHAL_U32LE(ctx, val->iounit); @@ -3366,13 +3456,13 @@ static bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rcreate * #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -static bool marshal_Tread(struct _marshal_ctx *ctx, struct lib9p_msg_Tread *val) { +static bool marshal_Tread(struct lib9p_ctx *ctx, struct lib9p_msg_Tread *val, struct _marshal_ret *ret) { uint32_t needed_size = 23; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tread", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3386,13 +3476,13 @@ static bool marshal_Tread(struct _marshal_ctx *ctx, struct lib9p_msg_Tread *val) return false; } -static bool marshal_Rread(struct _marshal_ctx *ctx, struct lib9p_msg_Rread *val) { +static bool marshal_Rread(struct lib9p_ctx *ctx, struct lib9p_msg_Rread *val, struct _marshal_ret *ret) { uint32_t needed_size = 11 + val->count; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rread", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3405,13 +3495,13 @@ static bool marshal_Rread(struct _marshal_ctx *ctx, struct lib9p_msg_Rread *val) return false; } -static bool marshal_Twrite(struct _marshal_ctx *ctx, struct lib9p_msg_Twrite *val) { +static bool marshal_Twrite(struct lib9p_ctx *ctx, struct lib9p_msg_Twrite *val, struct _marshal_ret *ret) { uint32_t needed_size = 23 + val->count; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Twrite", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3426,13 +3516,13 @@ static bool marshal_Twrite(struct _marshal_ctx *ctx, struct lib9p_msg_Twrite *va return false; } -static bool marshal_Rwrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rwrite *val) { +static bool marshal_Rwrite(struct lib9p_ctx *ctx, struct lib9p_msg_Rwrite *val, struct _marshal_ret *ret) { uint32_t needed_size = 11; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rwrite", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3444,13 +3534,13 @@ static bool marshal_Rwrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rwrite *va return false; } -static bool marshal_Tclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Tclunk *val) { +static bool marshal_Tclunk(struct lib9p_ctx *ctx, struct lib9p_msg_Tclunk *val, struct _marshal_ret *ret) { uint32_t needed_size = 11; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tclunk", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3462,13 +3552,13 @@ static bool marshal_Tclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Tclunk *va return false; } -static bool marshal_Rclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Rclunk *val) { +static bool marshal_Rclunk(struct lib9p_ctx *ctx, struct lib9p_msg_Rclunk *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rclunk", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3479,13 +3569,13 @@ static bool marshal_Rclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Rclunk *va return false; } -static bool marshal_Tremove(struct _marshal_ctx *ctx, struct lib9p_msg_Tremove *val) { +static bool marshal_Tremove(struct lib9p_ctx *ctx, struct lib9p_msg_Tremove *val, struct _marshal_ret *ret) { uint32_t needed_size = 11; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tremove", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3497,13 +3587,13 @@ static bool marshal_Tremove(struct _marshal_ctx *ctx, struct lib9p_msg_Tremove * return false; } -static bool marshal_Rremove(struct _marshal_ctx *ctx, struct lib9p_msg_Rremove *val) { +static bool marshal_Rremove(struct lib9p_ctx *ctx, struct lib9p_msg_Rremove *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rremove", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3516,13 +3606,13 @@ static bool marshal_Rremove(struct _marshal_ctx *ctx, struct lib9p_msg_Rremove * #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u -static bool marshal_Tstat(struct _marshal_ctx *ctx, struct lib9p_msg_Tstat *val) { +static bool marshal_Tstat(struct lib9p_ctx *ctx, struct lib9p_msg_Tstat *val, struct _marshal_ret *ret) { uint32_t needed_size = 11; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tstat", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3534,18 +3624,18 @@ static bool marshal_Tstat(struct _marshal_ctx *ctx, struct lib9p_msg_Tstat *val) return false; } -static bool marshal_Rstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rstat *val) { +static bool marshal_Rstat(struct lib9p_ctx *ctx, struct lib9p_msg_Rstat *val, struct _marshal_ret *ret) { uint32_t needed_size = 58 + val->stat.file_name.len + val->stat.file_owner_uid.len + val->stat.file_owner_gid.len + val->stat.file_last_modified_uid.len; #if CONFIG_9P_ENABLE_9P2000_u if is_ver(ctx, 9P2000_u) { needed_size += 14 + val->stat.file_extension.len; } #endif /* CONFIG_9P_ENABLE_9P2000_u */ - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rstat", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3565,10 +3655,10 @@ static bool marshal_Rstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rstat *val) MARSHAL_U16LE(ctx, offsetof_stat_end - offsetof_stat_kern_type); MARSHAL_U16LE(ctx, val->stat.kern_type); MARSHAL_U32LE(ctx, val->stat.kern_dev); - MARSHAL_U8LE(ctx, val->stat.file_qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->stat.file_qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->stat.file_qid.vers); MARSHAL_U64LE(ctx, val->stat.file_qid.path); - MARSHAL_U32LE(ctx, val->stat.file_mode & dm_masks[ctx->ctx->version]); + MARSHAL_U32LE(ctx, val->stat.file_mode & dm_masks[ctx->version]); MARSHAL_U32LE(ctx, val->stat.file_atime); MARSHAL_U32LE(ctx, val->stat.file_mtime); MARSHAL_U64LE(ctx, val->stat.file_size); @@ -3584,38 +3674,26 @@ static bool marshal_Rstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rstat *val) if (is_ver(ctx, 9P2000_u)) { MARSHAL_U16LE(ctx, val->stat.file_extension.len); MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_extension.utf8, val->stat.file_extension.len); - } -#endif /* CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_u - if (is_ver(ctx, 9P2000_u)) { MARSHAL_U32LE(ctx, val->stat.file_owner_n_uid); - } -#endif /* CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_u - if (is_ver(ctx, 9P2000_u)) { MARSHAL_U32LE(ctx, val->stat.file_owner_n_gid); - } -#endif /* CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_u - if (is_ver(ctx, 9P2000_u)) { MARSHAL_U32LE(ctx, val->stat.file_last_modified_n_uid); } #endif /* CONFIG_9P_ENABLE_9P2000_u */ return false; } -static bool marshal_Twstat(struct _marshal_ctx *ctx, struct lib9p_msg_Twstat *val) { +static bool marshal_Twstat(struct lib9p_ctx *ctx, struct lib9p_msg_Twstat *val, struct _marshal_ret *ret) { uint32_t needed_size = 62 + val->stat.file_name.len + val->stat.file_owner_uid.len + val->stat.file_owner_gid.len + val->stat.file_last_modified_uid.len; #if CONFIG_9P_ENABLE_9P2000_u if is_ver(ctx, 9P2000_u) { needed_size += 14 + val->stat.file_extension.len; } #endif /* CONFIG_9P_ENABLE_9P2000_u */ - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Twstat", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3636,10 +3714,10 @@ static bool marshal_Twstat(struct _marshal_ctx *ctx, struct lib9p_msg_Twstat *va MARSHAL_U16LE(ctx, offsetof_stat_end - offsetof_stat_kern_type); MARSHAL_U16LE(ctx, val->stat.kern_type); MARSHAL_U32LE(ctx, val->stat.kern_dev); - MARSHAL_U8LE(ctx, val->stat.file_qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->stat.file_qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->stat.file_qid.vers); MARSHAL_U64LE(ctx, val->stat.file_qid.path); - MARSHAL_U32LE(ctx, val->stat.file_mode & dm_masks[ctx->ctx->version]); + MARSHAL_U32LE(ctx, val->stat.file_mode & dm_masks[ctx->version]); MARSHAL_U32LE(ctx, val->stat.file_atime); MARSHAL_U32LE(ctx, val->stat.file_mtime); MARSHAL_U64LE(ctx, val->stat.file_size); @@ -3655,33 +3733,21 @@ static bool marshal_Twstat(struct _marshal_ctx *ctx, struct lib9p_msg_Twstat *va if (is_ver(ctx, 9P2000_u)) { MARSHAL_U16LE(ctx, val->stat.file_extension.len); MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_extension.utf8, val->stat.file_extension.len); - } -#endif /* CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_u - if (is_ver(ctx, 9P2000_u)) { MARSHAL_U32LE(ctx, val->stat.file_owner_n_uid); - } -#endif /* CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_u - if (is_ver(ctx, 9P2000_u)) { MARSHAL_U32LE(ctx, val->stat.file_owner_n_gid); - } -#endif /* CONFIG_9P_ENABLE_9P2000_u */ -#if CONFIG_9P_ENABLE_9P2000_u - if (is_ver(ctx, 9P2000_u)) { MARSHAL_U32LE(ctx, val->stat.file_last_modified_n_uid); } #endif /* CONFIG_9P_ENABLE_9P2000_u */ return false; } -static bool marshal_Rwstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rwstat *val) { +static bool marshal_Rwstat(struct lib9p_ctx *ctx, struct lib9p_msg_Rwstat *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rwstat", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3694,13 +3760,13 @@ static bool marshal_Rwstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rwstat *va #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000_p9p -static bool marshal_Topenfd(struct _marshal_ctx *ctx, struct lib9p_msg_Topenfd *val) { +static bool marshal_Topenfd(struct lib9p_ctx *ctx, struct lib9p_msg_Topenfd *val, struct _marshal_ret *ret) { uint32_t needed_size = 12; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Topenfd", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3709,17 +3775,17 @@ static bool marshal_Topenfd(struct _marshal_ctx *ctx, struct lib9p_msg_Topenfd * MARSHAL_U8LE(ctx, 98); MARSHAL_U16LE(ctx, val->tag); MARSHAL_U32LE(ctx, val->fid); - MARSHAL_U8LE(ctx, val->mode & o_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->mode & o_masks[ctx->version]); return false; } -static bool marshal_Ropenfd(struct _marshal_ctx *ctx, struct lib9p_msg_Ropenfd *val) { +static bool marshal_Ropenfd(struct lib9p_ctx *ctx, struct lib9p_msg_Ropenfd *val, struct _marshal_ret *ret) { uint32_t needed_size = 28; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Ropenfd", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3727,7 +3793,7 @@ static bool marshal_Ropenfd(struct _marshal_ctx *ctx, struct lib9p_msg_Ropenfd * MARSHAL_U32LE(ctx, offsetof_end - offsetof_size); MARSHAL_U8LE(ctx, 99); MARSHAL_U16LE(ctx, val->tag); - MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->qid.vers); MARSHAL_U64LE(ctx, val->qid.path); MARSHAL_U32LE(ctx, val->iounit); @@ -3737,13 +3803,13 @@ static bool marshal_Ropenfd(struct _marshal_ctx *ctx, struct lib9p_msg_Ropenfd * #endif /* CONFIG_9P_ENABLE_9P2000_p9p */ #if CONFIG_9P_ENABLE_9P2000_L -static bool marshal_Rlerror(struct _marshal_ctx *ctx, struct lib9p_msg_Rlerror *val) { +static bool marshal_Rlerror(struct lib9p_ctx *ctx, struct lib9p_msg_Rlerror *val, struct _marshal_ret *ret) { uint32_t needed_size = 11; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rlerror", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3755,13 +3821,13 @@ static bool marshal_Rlerror(struct _marshal_ctx *ctx, struct lib9p_msg_Rlerror * return false; } -static bool marshal_Tstatfs(struct _marshal_ctx *ctx, struct lib9p_msg_Tstatfs *val) { +static bool marshal_Tstatfs(struct lib9p_ctx *ctx, struct lib9p_msg_Tstatfs *val, struct _marshal_ret *ret) { uint32_t needed_size = 11; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tstatfs", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3773,13 +3839,13 @@ static bool marshal_Tstatfs(struct _marshal_ctx *ctx, struct lib9p_msg_Tstatfs * return false; } -static bool marshal_Rstatfs(struct _marshal_ctx *ctx, struct lib9p_msg_Rstatfs *val) { +static bool marshal_Rstatfs(struct lib9p_ctx *ctx, struct lib9p_msg_Rstatfs *val, struct _marshal_ret *ret) { uint32_t needed_size = 67; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rstatfs", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3799,13 +3865,13 @@ static bool marshal_Rstatfs(struct _marshal_ctx *ctx, struct lib9p_msg_Rstatfs * return false; } -static bool marshal_Tlopen(struct _marshal_ctx *ctx, struct lib9p_msg_Tlopen *val) { +static bool marshal_Tlopen(struct lib9p_ctx *ctx, struct lib9p_msg_Tlopen *val, struct _marshal_ret *ret) { uint32_t needed_size = 15; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tlopen", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3814,17 +3880,17 @@ static bool marshal_Tlopen(struct _marshal_ctx *ctx, struct lib9p_msg_Tlopen *va MARSHAL_U8LE(ctx, 12); MARSHAL_U16LE(ctx, val->tag); MARSHAL_U32LE(ctx, val->fid); - MARSHAL_U32LE(ctx, val->flags & lo_masks[ctx->ctx->version]); + MARSHAL_U32LE(ctx, val->flags & lo_masks[ctx->version]); return false; } -static bool marshal_Rlopen(struct _marshal_ctx *ctx, struct lib9p_msg_Rlopen *val) { +static bool marshal_Rlopen(struct lib9p_ctx *ctx, struct lib9p_msg_Rlopen *val, struct _marshal_ret *ret) { uint32_t needed_size = 24; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rlopen", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3832,20 +3898,20 @@ static bool marshal_Rlopen(struct _marshal_ctx *ctx, struct lib9p_msg_Rlopen *va MARSHAL_U32LE(ctx, offsetof_end - offsetof_size); MARSHAL_U8LE(ctx, 13); MARSHAL_U16LE(ctx, val->tag); - MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->qid.vers); MARSHAL_U64LE(ctx, val->qid.path); MARSHAL_U32LE(ctx, val->iounit); return false; } -static bool marshal_Tlcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tlcreate *val) { +static bool marshal_Tlcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Tlcreate *val, struct _marshal_ret *ret) { uint32_t needed_size = 25 + val->name.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tlcreate", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3856,19 +3922,19 @@ static bool marshal_Tlcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tlcreate MARSHAL_U32LE(ctx, val->fid); MARSHAL_U16LE(ctx, val->name.len); MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len); - MARSHAL_U32LE(ctx, val->flags & lo_masks[ctx->ctx->version]); - MARSHAL_U32LE(ctx, val->mode & mode_masks[ctx->ctx->version]); + MARSHAL_U32LE(ctx, val->flags & lo_masks[ctx->version]); + MARSHAL_U32LE(ctx, val->mode & mode_masks[ctx->version]); MARSHAL_U32LE(ctx, val->gid); return false; } -static bool marshal_Rlcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rlcreate *val) { +static bool marshal_Rlcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Rlcreate *val, struct _marshal_ret *ret) { uint32_t needed_size = 24; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rlcreate", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3876,20 +3942,20 @@ static bool marshal_Rlcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rlcreate MARSHAL_U32LE(ctx, offsetof_end - offsetof_size); MARSHAL_U8LE(ctx, 15); MARSHAL_U16LE(ctx, val->tag); - MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->qid.vers); MARSHAL_U64LE(ctx, val->qid.path); MARSHAL_U32LE(ctx, val->iounit); return false; } -static bool marshal_Tsymlink(struct _marshal_ctx *ctx, struct lib9p_msg_Tsymlink *val) { +static bool marshal_Tsymlink(struct lib9p_ctx *ctx, struct lib9p_msg_Tsymlink *val, struct _marshal_ret *ret) { uint32_t needed_size = 19 + val->name.len + val->symtgt.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tsymlink", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3906,13 +3972,13 @@ static bool marshal_Tsymlink(struct _marshal_ctx *ctx, struct lib9p_msg_Tsymlink return false; } -static bool marshal_Rsymlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rsymlink *val) { +static bool marshal_Rsymlink(struct lib9p_ctx *ctx, struct lib9p_msg_Rsymlink *val, struct _marshal_ret *ret) { uint32_t needed_size = 20; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rsymlink", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3920,19 +3986,19 @@ static bool marshal_Rsymlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rsymlink MARSHAL_U32LE(ctx, offsetof_end - offsetof_size); MARSHAL_U8LE(ctx, 17); MARSHAL_U16LE(ctx, val->tag); - MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->qid.vers); MARSHAL_U64LE(ctx, val->qid.path); return false; } -static bool marshal_Tmknod(struct _marshal_ctx *ctx, struct lib9p_msg_Tmknod *val) { +static bool marshal_Tmknod(struct lib9p_ctx *ctx, struct lib9p_msg_Tmknod *val, struct _marshal_ret *ret) { uint32_t needed_size = 29 + val->name.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tmknod", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3943,20 +4009,20 @@ static bool marshal_Tmknod(struct _marshal_ctx *ctx, struct lib9p_msg_Tmknod *va MARSHAL_U32LE(ctx, val->dfid); MARSHAL_U16LE(ctx, val->name.len); MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len); - MARSHAL_U32LE(ctx, val->mode & mode_masks[ctx->ctx->version]); + MARSHAL_U32LE(ctx, val->mode & mode_masks[ctx->version]); MARSHAL_U32LE(ctx, val->major); MARSHAL_U32LE(ctx, val->minor); MARSHAL_U32LE(ctx, val->gid); return false; } -static bool marshal_Rmknod(struct _marshal_ctx *ctx, struct lib9p_msg_Rmknod *val) { +static bool marshal_Rmknod(struct lib9p_ctx *ctx, struct lib9p_msg_Rmknod *val, struct _marshal_ret *ret) { uint32_t needed_size = 20; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rmknod", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3964,19 +4030,19 @@ static bool marshal_Rmknod(struct _marshal_ctx *ctx, struct lib9p_msg_Rmknod *va MARSHAL_U32LE(ctx, offsetof_end - offsetof_size); MARSHAL_U8LE(ctx, 19); MARSHAL_U16LE(ctx, val->tag); - MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->qid.vers); MARSHAL_U64LE(ctx, val->qid.path); return false; } -static bool marshal_Trename(struct _marshal_ctx *ctx, struct lib9p_msg_Trename *val) { +static bool marshal_Trename(struct lib9p_ctx *ctx, struct lib9p_msg_Trename *val, struct _marshal_ret *ret) { uint32_t needed_size = 17 + val->name.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Trename", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -3991,13 +4057,13 @@ static bool marshal_Trename(struct _marshal_ctx *ctx, struct lib9p_msg_Trename * return false; } -static bool marshal_Rrename(struct _marshal_ctx *ctx, struct lib9p_msg_Rrename *val) { +static bool marshal_Rrename(struct lib9p_ctx *ctx, struct lib9p_msg_Rrename *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rrename", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4008,13 +4074,13 @@ static bool marshal_Rrename(struct _marshal_ctx *ctx, struct lib9p_msg_Rrename * return false; } -static bool marshal_Treadlink(struct _marshal_ctx *ctx, struct lib9p_msg_Treadlink *val) { +static bool marshal_Treadlink(struct lib9p_ctx *ctx, struct lib9p_msg_Treadlink *val, struct _marshal_ret *ret) { uint32_t needed_size = 11; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Treadlink", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4026,13 +4092,13 @@ static bool marshal_Treadlink(struct _marshal_ctx *ctx, struct lib9p_msg_Treadli return false; } -static bool marshal_Rreadlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rreadlink *val) { +static bool marshal_Rreadlink(struct lib9p_ctx *ctx, struct lib9p_msg_Rreadlink *val, struct _marshal_ret *ret) { uint32_t needed_size = 9 + val->target.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rreadlink", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4045,13 +4111,13 @@ static bool marshal_Rreadlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rreadli return false; } -static bool marshal_Tgetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Tgetattr *val) { +static bool marshal_Tgetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Tgetattr *val, struct _marshal_ret *ret) { uint32_t needed_size = 19; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tgetattr", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4060,17 +4126,17 @@ static bool marshal_Tgetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Tgetattr MARSHAL_U8LE(ctx, 24); MARSHAL_U16LE(ctx, val->tag); MARSHAL_U32LE(ctx, val->fid); - MARSHAL_U64LE(ctx, val->request_mask & getattr_masks[ctx->ctx->version]); + MARSHAL_U64LE(ctx, val->request_mask & getattr_masks[ctx->version]); return false; } -static bool marshal_Rgetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Rgetattr *val) { +static bool marshal_Rgetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Rgetattr *val, struct _marshal_ret *ret) { uint32_t needed_size = 160; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rgetattr", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4078,11 +4144,11 @@ static bool marshal_Rgetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Rgetattr MARSHAL_U32LE(ctx, offsetof_end - offsetof_size); MARSHAL_U8LE(ctx, 25); MARSHAL_U16LE(ctx, val->tag); - MARSHAL_U64LE(ctx, val->valid & getattr_masks[ctx->ctx->version]); - MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U64LE(ctx, val->valid & getattr_masks[ctx->version]); + MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->qid.vers); MARSHAL_U64LE(ctx, val->qid.path); - MARSHAL_U32LE(ctx, val->mode & mode_masks[ctx->ctx->version]); + MARSHAL_U32LE(ctx, val->mode & mode_masks[ctx->version]); MARSHAL_U32LE(ctx, val->uid); MARSHAL_U32LE(ctx, val->gid); MARSHAL_U64LE(ctx, val->nlink); @@ -4103,13 +4169,13 @@ static bool marshal_Rgetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Rgetattr return false; } -static bool marshal_Tsetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Tsetattr *val) { +static bool marshal_Tsetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Tsetattr *val, struct _marshal_ret *ret) { uint32_t needed_size = 67; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tsetattr", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4118,8 +4184,8 @@ static bool marshal_Tsetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Tsetattr MARSHAL_U8LE(ctx, 26); MARSHAL_U16LE(ctx, val->tag); MARSHAL_U32LE(ctx, val->fid); - MARSHAL_U32LE(ctx, val->valid & setattr_masks[ctx->ctx->version]); - MARSHAL_U32LE(ctx, val->mode & mode_masks[ctx->ctx->version]); + MARSHAL_U32LE(ctx, val->valid & setattr_masks[ctx->version]); + MARSHAL_U32LE(ctx, val->mode & mode_masks[ctx->version]); MARSHAL_U32LE(ctx, val->uid); MARSHAL_U32LE(ctx, val->gid); MARSHAL_U64LE(ctx, val->filesize); @@ -4130,13 +4196,13 @@ static bool marshal_Tsetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Tsetattr return false; } -static bool marshal_Rsetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Rsetattr *val) { +static bool marshal_Rsetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Rsetattr *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rsetattr", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4147,13 +4213,13 @@ static bool marshal_Rsetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Rsetattr return false; } -static bool marshal_Txattrwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Txattrwalk *val) { +static bool marshal_Txattrwalk(struct lib9p_ctx *ctx, struct lib9p_msg_Txattrwalk *val, struct _marshal_ret *ret) { uint32_t needed_size = 17 + val->name.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Txattrwalk", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4168,13 +4234,13 @@ static bool marshal_Txattrwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Txattr return false; } -static bool marshal_Rxattrwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rxattrwalk *val) { +static bool marshal_Rxattrwalk(struct lib9p_ctx *ctx, struct lib9p_msg_Rxattrwalk *val, struct _marshal_ret *ret) { uint32_t needed_size = 15; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rxattrwalk", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4186,13 +4252,13 @@ static bool marshal_Rxattrwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rxattr return false; } -static bool marshal_Txattrcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Txattrcreate *val) { +static bool marshal_Txattrcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Txattrcreate *val, struct _marshal_ret *ret) { uint32_t needed_size = 25 + val->name.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Txattrcreate", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4208,13 +4274,13 @@ static bool marshal_Txattrcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Txat return false; } -static bool marshal_Rxattrcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rxattrcreate *val) { +static bool marshal_Rxattrcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Rxattrcreate *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rxattrcreate", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4225,13 +4291,13 @@ static bool marshal_Rxattrcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rxat return false; } -static bool marshal_Treaddir(struct _marshal_ctx *ctx, struct lib9p_msg_Treaddir *val) { +static bool marshal_Treaddir(struct lib9p_ctx *ctx, struct lib9p_msg_Treaddir *val, struct _marshal_ret *ret) { uint32_t needed_size = 23; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Treaddir", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4245,13 +4311,13 @@ static bool marshal_Treaddir(struct _marshal_ctx *ctx, struct lib9p_msg_Treaddir return false; } -static bool marshal_Rreaddir(struct _marshal_ctx *ctx, struct lib9p_msg_Rreaddir *val) { +static bool marshal_Rreaddir(struct lib9p_ctx *ctx, struct lib9p_msg_Rreaddir *val, struct _marshal_ret *ret) { uint64_t needed_size = 11 + val->count; - if (needed_size > (uint64_t)(ctx->ctx->max_msg_size)) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > (uint64_t)(ctx->max_msg_size)) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rreaddir", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = (uint32_t)needed_size; @@ -4264,13 +4330,13 @@ static bool marshal_Rreaddir(struct _marshal_ctx *ctx, struct lib9p_msg_Rreaddir return false; } -static bool marshal_Tfsync(struct _marshal_ctx *ctx, struct lib9p_msg_Tfsync *val) { +static bool marshal_Tfsync(struct lib9p_ctx *ctx, struct lib9p_msg_Tfsync *val, struct _marshal_ret *ret) { uint32_t needed_size = 15; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tfsync", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4283,13 +4349,13 @@ static bool marshal_Tfsync(struct _marshal_ctx *ctx, struct lib9p_msg_Tfsync *va return false; } -static bool marshal_Rfsync(struct _marshal_ctx *ctx, struct lib9p_msg_Rfsync *val) { +static bool marshal_Rfsync(struct lib9p_ctx *ctx, struct lib9p_msg_Rfsync *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rfsync", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4300,13 +4366,13 @@ static bool marshal_Rfsync(struct _marshal_ctx *ctx, struct lib9p_msg_Rfsync *va return false; } -static bool marshal_Tlock(struct _marshal_ctx *ctx, struct lib9p_msg_Tlock *val) { +static bool marshal_Tlock(struct lib9p_ctx *ctx, struct lib9p_msg_Tlock *val, struct _marshal_ret *ret) { uint32_t needed_size = 38 + val->client_id.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tlock", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4316,7 +4382,7 @@ static bool marshal_Tlock(struct _marshal_ctx *ctx, struct lib9p_msg_Tlock *val) MARSHAL_U16LE(ctx, val->tag); MARSHAL_U32LE(ctx, val->fid); MARSHAL_U8LE(ctx, val->type); - MARSHAL_U32LE(ctx, val->flags & lock_flags_masks[ctx->ctx->version]); + MARSHAL_U32LE(ctx, val->flags & lock_flags_masks[ctx->version]); MARSHAL_U64LE(ctx, val->start); MARSHAL_U64LE(ctx, val->length); MARSHAL_U32LE(ctx, val->proc_id); @@ -4325,13 +4391,13 @@ static bool marshal_Tlock(struct _marshal_ctx *ctx, struct lib9p_msg_Tlock *val) return false; } -static bool marshal_Rlock(struct _marshal_ctx *ctx, struct lib9p_msg_Rlock *val) { +static bool marshal_Rlock(struct lib9p_ctx *ctx, struct lib9p_msg_Rlock *val, struct _marshal_ret *ret) { uint32_t needed_size = 8; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rlock", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4343,13 +4409,13 @@ static bool marshal_Rlock(struct _marshal_ctx *ctx, struct lib9p_msg_Rlock *val) return false; } -static bool marshal_Tgetlock(struct _marshal_ctx *ctx, struct lib9p_msg_Tgetlock *val) { +static bool marshal_Tgetlock(struct lib9p_ctx *ctx, struct lib9p_msg_Tgetlock *val, struct _marshal_ret *ret) { uint32_t needed_size = 34 + val->client_id.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tgetlock", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4367,13 +4433,13 @@ static bool marshal_Tgetlock(struct _marshal_ctx *ctx, struct lib9p_msg_Tgetlock return false; } -static bool marshal_Rgetlock(struct _marshal_ctx *ctx, struct lib9p_msg_Rgetlock *val) { +static bool marshal_Rgetlock(struct lib9p_ctx *ctx, struct lib9p_msg_Rgetlock *val, struct _marshal_ret *ret) { uint32_t needed_size = 30 + val->client_id.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rgetlock", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4390,13 +4456,13 @@ static bool marshal_Rgetlock(struct _marshal_ctx *ctx, struct lib9p_msg_Rgetlock return false; } -static bool marshal_Tlink(struct _marshal_ctx *ctx, struct lib9p_msg_Tlink *val) { +static bool marshal_Tlink(struct lib9p_ctx *ctx, struct lib9p_msg_Tlink *val, struct _marshal_ret *ret) { uint32_t needed_size = 17 + val->name.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tlink", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4411,13 +4477,13 @@ static bool marshal_Tlink(struct _marshal_ctx *ctx, struct lib9p_msg_Tlink *val) return false; } -static bool marshal_Rlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rlink *val) { +static bool marshal_Rlink(struct lib9p_ctx *ctx, struct lib9p_msg_Rlink *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rlink", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4428,13 +4494,13 @@ static bool marshal_Rlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rlink *val) return false; } -static bool marshal_Tmkdir(struct _marshal_ctx *ctx, struct lib9p_msg_Tmkdir *val) { +static bool marshal_Tmkdir(struct lib9p_ctx *ctx, struct lib9p_msg_Tmkdir *val, struct _marshal_ret *ret) { uint32_t needed_size = 21 + val->name.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tmkdir", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4445,18 +4511,18 @@ static bool marshal_Tmkdir(struct _marshal_ctx *ctx, struct lib9p_msg_Tmkdir *va MARSHAL_U32LE(ctx, val->dfid); MARSHAL_U16LE(ctx, val->name.len); MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len); - MARSHAL_U32LE(ctx, val->mode & mode_masks[ctx->ctx->version]); + MARSHAL_U32LE(ctx, val->mode & mode_masks[ctx->version]); MARSHAL_U32LE(ctx, val->gid); return false; } -static bool marshal_Rmkdir(struct _marshal_ctx *ctx, struct lib9p_msg_Rmkdir *val) { +static bool marshal_Rmkdir(struct lib9p_ctx *ctx, struct lib9p_msg_Rmkdir *val, struct _marshal_ret *ret) { uint32_t needed_size = 20; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rmkdir", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4464,19 +4530,19 @@ static bool marshal_Rmkdir(struct _marshal_ctx *ctx, struct lib9p_msg_Rmkdir *va MARSHAL_U32LE(ctx, offsetof_end - offsetof_size); MARSHAL_U8LE(ctx, 73); MARSHAL_U16LE(ctx, val->tag); - MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]); + MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->version]); MARSHAL_U32LE(ctx, val->qid.vers); MARSHAL_U64LE(ctx, val->qid.path); return false; } -static bool marshal_Trenameat(struct _marshal_ctx *ctx, struct lib9p_msg_Trenameat *val) { +static bool marshal_Trenameat(struct lib9p_ctx *ctx, struct lib9p_msg_Trenameat *val, struct _marshal_ret *ret) { uint32_t needed_size = 19 + val->oldname.len + val->newname.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Trenameat", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4493,13 +4559,13 @@ static bool marshal_Trenameat(struct _marshal_ctx *ctx, struct lib9p_msg_Trename return false; } -static bool marshal_Rrenameat(struct _marshal_ctx *ctx, struct lib9p_msg_Rrenameat *val) { +static bool marshal_Rrenameat(struct lib9p_ctx *ctx, struct lib9p_msg_Rrenameat *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rrenameat", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4510,13 +4576,13 @@ static bool marshal_Rrenameat(struct _marshal_ctx *ctx, struct lib9p_msg_Rrename return false; } -static bool marshal_Tunlinkat(struct _marshal_ctx *ctx, struct lib9p_msg_Tunlinkat *val) { +static bool marshal_Tunlinkat(struct lib9p_ctx *ctx, struct lib9p_msg_Tunlinkat *val, struct _marshal_ret *ret) { uint32_t needed_size = 17 + val->name.len; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tunlinkat", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4531,13 +4597,13 @@ static bool marshal_Tunlinkat(struct _marshal_ctx *ctx, struct lib9p_msg_Tunlink return false; } -static bool marshal_Runlinkat(struct _marshal_ctx *ctx, struct lib9p_msg_Runlinkat *val) { +static bool marshal_Runlinkat(struct lib9p_ctx *ctx, struct lib9p_msg_Runlinkat *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Runlinkat", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4550,13 +4616,13 @@ static bool marshal_Runlinkat(struct _marshal_ctx *ctx, struct lib9p_msg_Runlink #endif /* CONFIG_9P_ENABLE_9P2000_L */ #if CONFIG_9P_ENABLE_9P2000_e -static bool marshal_Tsession(struct _marshal_ctx *ctx, struct lib9p_msg_Tsession *val) { +static bool marshal_Tsession(struct lib9p_ctx *ctx, struct lib9p_msg_Tsession *val, struct _marshal_ret *ret) { uint32_t needed_size = 15; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tsession", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4568,13 +4634,13 @@ static bool marshal_Tsession(struct _marshal_ctx *ctx, struct lib9p_msg_Tsession return false; } -static bool marshal_Rsession(struct _marshal_ctx *ctx, struct lib9p_msg_Rsession *val) { +static bool marshal_Rsession(struct lib9p_ctx *ctx, struct lib9p_msg_Rsession *val, struct _marshal_ret *ret) { uint32_t needed_size = 7; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rsession", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4585,16 +4651,16 @@ static bool marshal_Rsession(struct _marshal_ctx *ctx, struct lib9p_msg_Rsession return false; } -static bool marshal_Tsread(struct _marshal_ctx *ctx, struct lib9p_msg_Tsread *val) { +static bool marshal_Tsread(struct lib9p_ctx *ctx, struct lib9p_msg_Tsread *val, struct _marshal_ret *ret) { uint64_t needed_size = 13; for (uint16_t i = 0; i < val->nwname; i++) { needed_size += 2 + val->wname[i].len; } - if (needed_size > (uint64_t)(ctx->ctx->max_msg_size)) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > (uint64_t)(ctx->max_msg_size)) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tsread", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = (uint32_t)needed_size; @@ -4611,13 +4677,13 @@ static bool marshal_Tsread(struct _marshal_ctx *ctx, struct lib9p_msg_Tsread *va return false; } -static bool marshal_Rsread(struct _marshal_ctx *ctx, struct lib9p_msg_Rsread *val) { +static bool marshal_Rsread(struct lib9p_ctx *ctx, struct lib9p_msg_Rsread *val, struct _marshal_ret *ret) { uint64_t needed_size = 11 + val->count; - if (needed_size > (uint64_t)(ctx->ctx->max_msg_size)) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > (uint64_t)(ctx->max_msg_size)) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rsread", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = (uint32_t)needed_size; @@ -4630,16 +4696,16 @@ static bool marshal_Rsread(struct _marshal_ctx *ctx, struct lib9p_msg_Rsread *va return false; } -static bool marshal_Tswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Tswrite *val) { +static bool marshal_Tswrite(struct lib9p_ctx *ctx, struct lib9p_msg_Tswrite *val, struct _marshal_ret *ret) { uint64_t needed_size = 17 + val->count; for (uint16_t i = 0; i < val->nwname; i++) { needed_size += 2 + val->wname[i].len; } - if (needed_size > (uint64_t)(ctx->ctx->max_msg_size)) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > (uint64_t)(ctx->max_msg_size)) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Tswrite", - ctx->ctx->version ? "negotiated" : "client", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "client", + ctx->max_msg_size); return true; } uint32_t offsetof_end = (uint32_t)needed_size; @@ -4658,13 +4724,13 @@ static bool marshal_Tswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Tswrite * return false; } -static bool marshal_Rswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rswrite *val) { +static bool marshal_Rswrite(struct lib9p_ctx *ctx, struct lib9p_msg_Rswrite *val, struct _marshal_ret *ret) { uint32_t needed_size = 11; - if (needed_size > ctx->ctx->max_msg_size) { - lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", + if (needed_size > ctx->max_msg_size) { + lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")", "Rswrite", - ctx->ctx->version ? "negotiated" : "server", - ctx->ctx->max_msg_size); + ctx->version ? "negotiated" : "server", + ctx->max_msg_size); return true; } uint32_t offsetof_end = needed_size; @@ -4698,13 +4764,13 @@ const uint32_t _lib9p_table_msg_min_size[LIB9P_VER_NUM] = { #endif /* CONFIG_9P_ENABLE_9P2000_u */ }; -#define _MSG_RECV(typ) [LIB9P_TYP_##typ/2] = { \ - .basesize = sizeof(struct lib9p_msg_##typ), \ - .validate = validate_##typ, \ - .unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \ +#define _MSG_RECV(typ) [LIB9P_TYP_##typ/2] = { \ + .basesize = sizeof(struct lib9p_msg_##typ), \ + .validate = validate_##typ, \ + .unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \ } -#define _MSG_SEND(typ) [LIB9P_TYP_##typ/2] = { \ - .marshal = (_marshal_fn_t)marshal_##typ, \ +#define _MSG_SEND(typ) [LIB9P_TYP_##typ/2] = { \ + .marshal = (_marshal_fn_t)marshal_##typ, \ } const struct _lib9p_recv_tentry _lib9p_table_Tmsg_recv[LIB9P_VER_NUM][0x80] = { @@ -5161,12 +5227,12 @@ const struct _lib9p_send_tentry _lib9p_table_Rmsg_send[LIB9P_VER_NUM][0x80] = { #endif /* CONFIG_9P_ENABLE_9P2000_u */ }; -LM_FLATTEN bool _lib9p_stat_validate(struct _validate_ctx *ctx) { - return validate_stat(ctx); +LM_FLATTEN ssize_t _lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size) { + return validate_stat(ctx, net_size, net_bytes, ret_net_size); } -LM_FLATTEN void _lib9p_stat_unmarshal(struct _unmarshal_ctx *ctx, struct lib9p_stat *out) { - unmarshal_stat(ctx, out); +LM_FLATTEN void _lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out) { + unmarshal_stat(ctx, net_bytes, out); } -LM_FLATTEN bool _lib9p_stat_marshal(struct _marshal_ctx *ctx, struct lib9p_stat *val) { - return marshal_stat(ctx, val); +LM_FLATTEN bool _lib9p_stat_marshal(struct lib9p_ctx *ctx, struct lib9p_stat *val, struct _marshal_ret *ret) { + return marshal_stat(ctx, val, ret); } diff --git a/lib9p/include/lib9p/9p.h b/lib9p/include/lib9p/9p.h index 35b7ef2..ffac453 100644 --- a/lib9p/include/lib9p/9p.h +++ b/lib9p/include/lib9p/9p.h @@ -159,7 +159,7 @@ static inline void lib9p_stat_assert(struct lib9p_stat stat) { * @return whether there was an error */ bool lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, - uint32_t *ret_net_size, ssize_t *ret_host_size); + uint32_t *ret_net_size, ssize_t *ret_host_size); /** * Unmarshal the 9P `net_bytes` into the C struct `ret_obj`. @@ -170,12 +170,10 @@ bool lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_ * @param ctx : negotiated protocol parameters * @param net_bytes : network-encoded stat structure * - * @return ret_obj : where to put the stat object itself - * @return ret_extra : where to put strings for the stat object - * @return consumed net_bytes + * @return ret : the stat object, must be at least lib9p_stat_validate()->ret_net_size bytes */ -uint32_t lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, - struct lib9p_stat *ret_obj, void *ret_extra); +void lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, + struct lib9p_stat *ret); /** * Marhsal a `struct lib9p_stat` structure into a byte-array. diff --git a/lib9p/internal.h b/lib9p/internal.h index 801dc4c..92340a5 100644 --- a/lib9p/internal.h +++ b/lib9p/internal.h @@ -36,47 +36,18 @@ static_assert(CONFIG_9P_MAX_ERR_SIZE <= UINT16_MAX); static_assert(CONFIG_9P_MAX_MSG_SIZE <= CONFIG_9P_MAX_HOSTMSG_SIZE); static_assert(CONFIG_9P_MAX_HOSTMSG_SIZE <= SSIZE_MAX); -/* specialized contexts *******************************************************/ - -struct _validate_ctx { - /* input */ - struct lib9p_ctx *ctx; - uint32_t net_size; - uint8_t *net_bytes; - - /* output */ - uint32_t net_offset; - /* Increment `host_extra` to pre-allocate space that is - * "extra" beyond sizeof(). */ - size_t host_extra; -}; -typedef bool (*_validate_fn_t)(struct _validate_ctx *ctx); - -struct _unmarshal_ctx { - /* input */ - struct lib9p_ctx *ctx; - uint8_t *net_bytes; - - /* output */ - uint32_t net_offset; - /* `extra` points to the beginning of unallocated space. */ - void *extra; -}; -typedef void (*_unmarshal_fn_t)(struct _unmarshal_ctx *ctx, void *out); +/* tables / exports ***********************************************************/ -struct _marshal_ctx { - /* input */ - struct lib9p_ctx *ctx; +typedef ssize_t (*_validate_fn_t)(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes); +typedef void (*_unmarshal_fn_t)(struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out); - /* output */ +struct _marshal_ret { size_t net_iov_cnt; struct iovec *net_iov; size_t net_copied_size; uint8_t *net_copied; }; -typedef bool (*_marshal_fn_t)(struct _marshal_ctx *ctx, void *host_val); - -/* tables / exports ***********************************************************/ +typedef bool (*_marshal_fn_t)(struct lib9p_ctx *ctx, void *host_val, struct _marshal_ret *ret); struct _lib9p_recv_tentry { size_t basesize; @@ -96,9 +67,9 @@ extern const struct _lib9p_recv_tentry _lib9p_table_Rmsg_recv[LIB9P_VER_NUM][0x8 extern const struct _lib9p_send_tentry _lib9p_table_Tmsg_send[LIB9P_VER_NUM][0x80]; extern const struct _lib9p_send_tentry _lib9p_table_Rmsg_send[LIB9P_VER_NUM][0x80]; -bool _lib9p_stat_validate(struct _validate_ctx *ctx); -void _lib9p_stat_unmarshal(struct _unmarshal_ctx *ctx, struct lib9p_stat *out); -bool _lib9p_stat_marshal(struct _marshal_ctx *ctx, struct lib9p_stat *val); +ssize_t _lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size); +void _lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out); +bool _lib9p_stat_marshal(struct lib9p_ctx *ctx, struct lib9p_stat *val, struct _marshal_ret *ret); /* unmarshal utilities ********************************************************/ diff --git a/lib9p/protogen/c.py b/lib9p/protogen/c.py index a7e1773..5e67939 100644 --- a/lib9p/protogen/c.py +++ b/lib9p/protogen/c.py @@ -76,12 +76,12 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str: ret += "#endif\n" ret += "\n" ret += "/**\n" - ret += f" * is_ver(ctx, ver) is essentially `(ctx->ctx->version == {c9util.Ident('VER_')}##ver)`,\n" - ret += f" * but compiles correctly (to `false`) even if `{c9util.Ident('VER_')}##ver` isn't defined\n" + ret += f" * is_ver(ctx, ver) is essentially `(ctx->version == {c9util.Ident('VER_')}##ver)`, but\n" + ret += f" * compiles correctly (to `false`) even if `{c9util.Ident('VER_')}##ver` isn't defined\n" ret += " * (because `!CONFIG_9P_ENABLE_##ver`). This is useful when `||`ing\n" ret += " * several version checks together.\n" ret += " */\n" - ret += "#define is_ver(CTX, ver) _is_ver_##ver(CTX->ctx->version)\n" + ret += "#define is_ver(ctx, ver) _is_ver_##ver((ctx)->version)\n" # strings ################################################################## ret += f""" @@ -185,14 +185,14 @@ const char *const {c9util.ident('_table_ver_name')}[{c9util.ver_enum('NUM')}] = ) ret += f""" -LM_FLATTEN bool {c9util.ident('_stat_validate')}(struct _validate_ctx *ctx) {{ -\treturn validate_stat(ctx); +LM_FLATTEN ssize_t {c9util.ident('_stat_validate')}(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size) {{ +\treturn validate_stat(ctx, net_size, net_bytes, ret_net_size); }} -LM_FLATTEN void {c9util.ident('_stat_unmarshal')}(struct _unmarshal_ctx *ctx, struct {c9util.ident('stat')} *out) {{ -\tunmarshal_stat(ctx, out); +LM_FLATTEN void {c9util.ident('_stat_unmarshal')}(struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out) {{ +\tunmarshal_stat(ctx, net_bytes, out); }} -LM_FLATTEN bool {c9util.ident('_stat_marshal')}(struct _marshal_ctx *ctx, struct {c9util.ident('stat')} *val) {{ -\treturn marshal_stat(ctx, val); +LM_FLATTEN bool {c9util.ident('_stat_marshal')}(struct lib9p_ctx *ctx, struct {c9util.ident('stat')} *val, struct _marshal_ret *ret) {{ +\treturn marshal_stat(ctx, val, ret); }} """ diff --git a/lib9p/protogen/c9util.py b/lib9p/protogen/c9util.py index f9c49fc..e7ad999 100644 --- a/lib9p/protogen/c9util.py +++ b/lib9p/protogen/c9util.py @@ -107,11 +107,3 @@ def idl_expr(expr: idl.Expr, lookup_sym: typing.Callable[[str], str]) -> str: case _: assert False return " ".join(ret) - - -def arg_used(arg: str) -> str: - return arg - - -def arg_unused(arg: str) -> str: - return f"LM_UNUSED({arg})" diff --git a/lib9p/protogen/c_marshal.py b/lib9p/protogen/c_marshal.py index 152206d..74b64f5 100644 --- a/lib9p/protogen/c_marshal.py +++ b/lib9p/protogen/c_marshal.py @@ -17,6 +17,162 @@ from . import c9util, cutil, idlutil # pylint: disable=unused-variable __all__ = ["gen_c_marshal"] +# get_offset_expr() ############################################################ + + +class OffsetExpr: + static: int + cond: dict[frozenset[str], "OffsetExpr"] + rep: list[tuple[idlutil.Path, "OffsetExpr"]] + + def __init__(self) -> None: + self.static = 0 + self.rep = [] + self.cond = {} + + def add(self, other: "OffsetExpr") -> None: + self.static += other.static + self.rep += other.rep + for k, v in other.cond.items(): + if k in self.cond: + self.cond[k].add(v) + else: + self.cond[k] = v + + def gen_c( + self, + dsttyp: str, + dstvar: str, + root: str, + indent_depth: int, + loop_depth: int, + ) -> str: + oneline: list[str] = [] + multiline = "" + if self.static: + oneline.append(str(self.static)) + for cnt, sub in self.rep: + if not sub.cond and not sub.rep: + if sub.static == 1: + oneline.append(cnt.c_str(root)) + else: + oneline.append(f"({cnt.c_str(root)})*{sub.static}") + continue + loopvar = chr(ord("i") + loop_depth) + multiline += f"{'\t'*indent_depth}for ({c9util.typename(cnt.elems[-1].typ)} {loopvar} = 0; {loopvar} < {cnt.c_str(root)}; {loopvar}++) {{\n" + multiline += sub.gen_c("", dstvar, root, indent_depth + 1, loop_depth + 1) + multiline += f"{'\t'*indent_depth}}}\n" + for vers, sub in self.cond.items(): + multiline += cutil.ifdef_push(indent_depth + 1, c9util.ver_ifdef(vers)) + multiline += f"{'\t'*indent_depth}if {c9util.ver_cond(vers)} {{\n" + multiline += sub.gen_c("", dstvar, root, indent_depth + 1, loop_depth) + multiline += f"{'\t'*indent_depth}}}\n" + multiline += cutil.ifdef_pop(indent_depth) + ret = "" + if dsttyp: + if not oneline: + oneline.append("0") + ret += f"{'\t'*indent_depth}{dsttyp} {dstvar} = {' + '.join(oneline)};\n" + elif oneline: + ret += f"{'\t'*indent_depth}{dstvar} += {' + '.join(oneline)};\n" + ret += multiline + return ret + + +type OffsetExprRecursion = typing.Callable[[idlutil.Path], idlutil.WalkCmd] + + +def get_offset_expr(typ: idl.UserType, recurse: OffsetExprRecursion) -> OffsetExpr: + if not isinstance(typ, idl.Struct): + assert typ.static_size + ret = OffsetExpr() + ret.static = typ.static_size + return ret + + class ExprStackItem(typing.NamedTuple): + path: idlutil.Path + expr: OffsetExpr + pop: typing.Callable[[], None] + + expr_stack: list[ExprStackItem] + + def pop_root() -> None: + assert False + + def pop_cond() -> None: + nonlocal expr_stack + key = frozenset(expr_stack[-1].path.elems[-1].in_versions) + if key in expr_stack[-2].expr.cond: + expr_stack[-2].expr.cond[key].add(expr_stack[-1].expr) + else: + expr_stack[-2].expr.cond[key] = expr_stack[-1].expr + expr_stack = expr_stack[:-1] + + def pop_rep() -> None: + nonlocal expr_stack + member_path = expr_stack[-1].path + member = member_path.elems[-1] + assert member.cnt + cnt_path = member_path.parent().add(member.cnt) + expr_stack[-2].expr.rep.append((cnt_path, expr_stack[-1].expr)) + expr_stack = expr_stack[:-1] + + def handle( + path: idlutil.Path, + ) -> tuple[idlutil.WalkCmd, typing.Callable[[], None] | None]: + nonlocal recurse + + ret = recurse(path) + if ret != idlutil.WalkCmd.KEEP_GOING: + return ret, None + + nonlocal expr_stack + expr_stack_len = len(expr_stack) + + def pop() -> None: + nonlocal expr_stack + nonlocal expr_stack_len + while len(expr_stack) > expr_stack_len: + expr_stack[-1].pop() + + if path.elems: + child = path.elems[-1] + parent = path.elems[-2].typ if len(path.elems) > 1 else path.root + if child.in_versions < parent.in_versions: + expr_stack.append( + ExprStackItem(path=path, expr=OffsetExpr(), pop=pop_cond) + ) + if child.cnt: + expr_stack.append( + ExprStackItem(path=path, expr=OffsetExpr(), pop=pop_rep) + ) + if not isinstance(child.typ, idl.Struct): + assert child.typ.static_size + expr_stack[-1].expr.static += child.typ.static_size + return ret, pop + + expr_stack = [ + ExprStackItem(path=idlutil.Path(typ), expr=OffsetExpr(), pop=pop_root) + ] + idlutil.walk(typ, handle) + return expr_stack[0].expr + + +def go_to_end(path: idlutil.Path) -> idlutil.WalkCmd: + return idlutil.WalkCmd.KEEP_GOING + + +def go_to_tok(name: str) -> typing.Callable[[idlutil.Path], idlutil.WalkCmd]: + def ret(path: idlutil.Path) -> idlutil.WalkCmd: + if len(path.elems) == 1 and path.elems[0].membname == name: + return idlutil.WalkCmd.ABORT + return idlutil.WalkCmd.KEEP_GOING + + return ret + + +# Generate .c ################################################################## + def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str: ret = """ @@ -25,188 +181,164 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str: """ ret += cutil.macro( "#define MARSHAL_BYTES_ZEROCOPY(ctx, data, len)\n" - "\tif (ctx->net_iov[ctx->net_iov_cnt-1].iov_len)\n" - "\t\tctx->net_iov_cnt++;\n" - "\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = data;\n" - "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len = len;\n" - "\tctx->net_iov_cnt++;\n" + "\tif (ret->net_iov[ret->net_iov_cnt-1].iov_len)\n" + "\t\tret->net_iov_cnt++;\n" + "\tret->net_iov[ret->net_iov_cnt-1].iov_base = data;\n" + "\tret->net_iov[ret->net_iov_cnt-1].iov_len = len;\n" + "\tret->net_iov_cnt++;\n" ) ret += cutil.macro( "#define MARSHAL_BYTES(ctx, data, len)\n" - "\tif (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base)\n" - "\t\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size];\n" - "\tmemcpy(&ctx->net_copied[ctx->net_copied_size], data, len);\n" - "\tctx->net_copied_size += len;\n" - "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len += len;\n" + "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_base)\n" + "\t\tret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size];\n" + "\tmemcpy(&ret->net_copied[ret->net_copied_size], data, len);\n" + "\tret->net_copied_size += len;\n" + "\tret->net_iov[ret->net_iov_cnt-1].iov_len += len;\n" ) ret += cutil.macro( "#define MARSHAL_U8LE(ctx, val)\n" - "\tif (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base)\n" - "\t\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size];\n" - "\tctx->net_copied[ctx->net_copied_size] = val;\n" - "\tctx->net_copied_size += 1;\n" - "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len += 1;\n" + "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_base)\n" + "\t\tret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size];\n" + "\tret->net_copied[ret->net_copied_size] = val;\n" + "\tret->net_copied_size += 1;\n" + "\tret->net_iov[ret->net_iov_cnt-1].iov_len += 1;\n" ) ret += cutil.macro( "#define MARSHAL_U16LE(ctx, val)\n" - "\tif (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base)\n" - "\t\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size];\n" - "\tuint16le_encode(&ctx->net_copied[ctx->net_copied_size], val);\n" - "\tctx->net_copied_size += 2;\n" - "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len += 2;\n" + "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_base)\n" + "\t\tret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size];\n" + "\tuint16le_encode(&ret->net_copied[ret->net_copied_size], val);\n" + "\tret->net_copied_size += 2;\n" + "\tret->net_iov[ret->net_iov_cnt-1].iov_len += 2;\n" ) ret += cutil.macro( "#define MARSHAL_U32LE(ctx, val)\n" - "\tif (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base)\n" - "\t\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size];\n" - "\tuint32le_encode(&ctx->net_copied[ctx->net_copied_size], val);\n" - "\tctx->net_copied_size += 4;\n" - "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len += 4;\n" + "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_base)\n" + "\t\tret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size];\n" + "\tuint32le_encode(&ret->net_copied[ret->net_copied_size], val);\n" + "\tret->net_copied_size += 4;\n" + "\tret->net_iov[ret->net_iov_cnt-1].iov_len += 4;\n" ) ret += cutil.macro( "#define MARSHAL_U64LE(ctx, val)\n" - "\tif (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base)\n" - "\t\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size];\n" - "\tuint64le_encode(&ctx->net_copied[ctx->net_copied_size], val);\n" - "\tctx->net_copied_size += 8;\n" - "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len += 8;\n" + "\tif (!ret->net_iov[ret->net_iov_cnt-1].iov_base)\n" + "\t\tret->net_iov[ret->net_iov_cnt-1].iov_base = &ret->net_copied[ret->net_copied_size];\n" + "\tuint64le_encode(&ret->net_copied[ret->net_copied_size], val);\n" + "\tret->net_copied_size += 8;\n" + "\tret->net_iov[ret->net_iov_cnt-1].iov_len += 8;\n" ) - class OffsetExpr: - static: int - cond: dict[frozenset[str], "OffsetExpr"] - rep: list[tuple[idlutil.Path, "OffsetExpr"]] - - def __init__(self) -> None: - self.static = 0 - self.rep = [] - self.cond = {} - - def add(self, other: "OffsetExpr") -> None: - self.static += other.static - self.rep += other.rep - for k, v in other.cond.items(): - if k in self.cond: - self.cond[k].add(v) - else: - self.cond[k] = v - - def gen_c( - self, - dsttyp: str, - dstvar: str, - root: str, - indent_depth: int, - loop_depth: int, - ) -> str: - oneline: list[str] = [] - multiline = "" - if self.static: - oneline.append(str(self.static)) - for cnt, sub in self.rep: - if not sub.cond and not sub.rep: - if sub.static == 1: - oneline.append(cnt.c_str(root)) - else: - oneline.append(f"({cnt.c_str(root)})*{sub.static}") - continue - loopvar = chr(ord("i") + loop_depth) - multiline += f"{'\t'*indent_depth}for ({c9util.typename(cnt.elems[-1].typ)} {loopvar} = 0; {loopvar} < {cnt.c_str(root)}; {loopvar}++) {{\n" - multiline += sub.gen_c( - "", dstvar, root, indent_depth + 1, loop_depth + 1 - ) - multiline += f"{'\t'*indent_depth}}}\n" - for vers, sub in self.cond.items(): - multiline += cutil.ifdef_push(indent_depth + 1, c9util.ver_ifdef(vers)) - multiline += f"{'\t'*indent_depth}if {c9util.ver_cond(vers)} {{\n" - multiline += sub.gen_c("", dstvar, root, indent_depth + 1, loop_depth) - multiline += f"{'\t'*indent_depth}}}\n" - multiline += cutil.ifdef_pop(indent_depth) - if dsttyp: - if not oneline: - oneline.append("0") - ret = f"{'\t'*indent_depth}{dsttyp} {dstvar} = {' + '.join(oneline)};\n" - elif oneline: - ret = f"{'\t'*indent_depth}{dstvar} += {' + '.join(oneline)};\n" - ret += multiline - return ret - - type OffsetExprRecursion = typing.Callable[[idlutil.Path], idlutil.WalkCmd] - - def get_offset_expr(typ: idl.UserType, recurse: OffsetExprRecursion) -> OffsetExpr: - if not isinstance(typ, idl.Struct): - assert typ.static_size - ret = OffsetExpr() - ret.static = typ.static_size - return ret - - stack: list[tuple[idlutil.Path, OffsetExpr, typing.Callable[[], None]]] - - def pop_root() -> None: - assert False - - def pop_cond() -> None: - nonlocal stack - key = frozenset(stack[-1][0].elems[-1].in_versions) - if key in stack[-2][1].cond: - stack[-2][1].cond[key].add(stack[-1][1]) - else: - stack[-2][1].cond[key] = stack[-1][1] - stack = stack[:-1] - - def pop_rep() -> None: - nonlocal stack - member_path = stack[-1][0] - member = member_path.elems[-1] - assert member.cnt - cnt_path = member_path.parent().add(member.cnt) - stack[-2][1].rep.append((cnt_path, stack[-1][1])) - stack = stack[:-1] - - def handle( - path: idlutil.Path, - ) -> tuple[idlutil.WalkCmd, typing.Callable[[], None] | None]: - nonlocal recurse - - ret = recurse(path) - if ret != idlutil.WalkCmd.KEEP_GOING: - return ret, None - - nonlocal stack - stack_len = len(stack) - - def pop() -> None: - nonlocal stack - nonlocal stack_len - while len(stack) > stack_len: - stack[-1][2]() - - if path.elems: - child = path.elems[-1] - parent = path.elems[-2].typ if len(path.elems) > 1 else path.root - if child.in_versions < parent.in_versions: - stack.append((path, OffsetExpr(), pop_cond)) - if child.cnt: - stack.append((path, OffsetExpr(), pop_rep)) - if not isinstance(child.typ, idl.Struct): - assert child.typ.static_size - stack[-1][1].static += child.typ.static_size - return ret, pop - - stack = [(idlutil.Path(typ), OffsetExpr(), pop_root)] - idlutil.walk(typ, handle) - return stack[0][1] + class IndentLevel(typing.NamedTuple): + ifdef: bool # whether this is both `{` and `#if`, or just `{` - def go_to_end(path: idlutil.Path) -> idlutil.WalkCmd: - return idlutil.WalkCmd.KEEP_GOING + indent_stack: list[IndentLevel] - def go_to_tok(name: str) -> typing.Callable[[idlutil.Path], idlutil.WalkCmd]: - def ret(path: idlutil.Path) -> idlutil.WalkCmd: - if len(path.elems) == 1 and path.elems[0].membname == name: - return idlutil.WalkCmd.ABORT - return idlutil.WalkCmd.KEEP_GOING + def ifdef_lvl() -> int: + return sum(1 if lvl.ifdef else 0 for lvl in indent_stack) - return ret + def indent_lvl() -> int: + return len(indent_stack) + + max_size: int + + def handle( + path: idlutil.Path, + ) -> tuple[idlutil.WalkCmd, typing.Callable[[], None]]: + nonlocal ret + nonlocal indent_stack + nonlocal max_size + indent_stack_len = len(indent_stack) + + def pop() -> None: + nonlocal ret + nonlocal indent_stack + nonlocal indent_stack_len + while len(indent_stack) > indent_stack_len: + if len(indent_stack) == indent_stack_len + 1 and indent_stack[-1].ifdef: + break + ret += f"{'\t'*(indent_lvl()-1)}}}\n" + if indent_stack.pop().ifdef: + ret += cutil.ifdef_pop(ifdef_lvl()) + + loopdepth = sum(1 for elem in path.elems if elem.cnt) + struct = path.elems[-1].typ if path.elems else path.root + if isinstance(struct, idl.Struct): + offsets: list[str] = [] + for member in struct.members: + if not member.val: + continue + for tok in member.val.tokens: + if not isinstance(tok, idl.ExprSym): + continue + if tok.symname == "end" or tok.symname.startswith("&"): + if tok.symname not in offsets: + offsets.append(tok.symname) + for name in offsets: + name_prefix = f"offsetof{''.join('_'+m.membname for m in path.elems)}_" + if name == "end": + if not path.elems: + if max_size > cutil.UINT32_MAX: + ret += f"{'\t'*indent_lvl()}uint32_t {name_prefix}end = (uint32_t)needed_size;\n" + else: + ret += f"{'\t'*indent_lvl()}uint32_t {name_prefix}end = needed_size;\n" + continue + recurse: OffsetExprRecursion = go_to_end + else: + assert name.startswith("&") + name = name[1:] + recurse = go_to_tok(name) + expr = get_offset_expr(struct, recurse) + expr_prefix = path.c_str("val->", loopdepth) + if not expr_prefix.endswith(">"): + expr_prefix += "." + ret += expr.gen_c( + "uint32_t", + name_prefix + name, + expr_prefix, + indent_lvl(), + loopdepth, + ) + if not path.elems: + return idlutil.WalkCmd.KEEP_GOING, pop + + child = path.elems[-1] + parent = path.elems[-2].typ if len(path.elems) > 1 else path.root + if child.in_versions < parent.in_versions: + if line := cutil.ifdef_push( + ifdef_lvl() + 1, c9util.ver_ifdef(child.in_versions) + ): + ret += line + ret += ( + f"{'\t'*indent_lvl()}if ({c9util.ver_cond(child.in_versions)}) {{\n" + ) + indent_stack.append(IndentLevel(ifdef=True)) + if child.cnt: + cnt_path = path.parent().add(child.cnt) + if child.typ.static_size == 1: # SPECIAL (zerocopy) + if path.root.typname == "stat": # SPECIAL (stat) + ret += f"{'\t'*indent_lvl()}MARSHAL_BYTES(ctx, {path.c_str('val->')[:-3]}, {cnt_path.c_str('val->')});\n" + else: + ret += f"{'\t'*indent_lvl()}MARSHAL_BYTES_ZEROCOPY(ctx, {path.c_str('val->')[:-3]}, {cnt_path.c_str('val->')});\n" + return idlutil.WalkCmd.KEEP_GOING, pop + loopvar = chr(ord("i") + loopdepth - 1) + ret += f"{'\t'*indent_lvl()}for ({c9util.typename(child.cnt.typ)} {loopvar} = 0; {loopvar} < {cnt_path.c_str('val->')}; {loopvar}++) {{\n" + indent_stack.append(IndentLevel(ifdef=False)) + if not isinstance(child.typ, idl.Struct): + if child.val: + + def lookup_sym(sym: str) -> str: + nonlocal path + if sym.startswith("&"): + sym = sym[1:] + return f"offsetof{''.join('_'+m.membname for m in path.elems[:-1])}_{sym}" + + val = c9util.idl_expr(child.val, lookup_sym) + else: + val = path.c_str("val->") + if isinstance(child.typ, idl.Bitfield): + val += f" & {child.typ.typname}_masks[ctx->version]" + ret += f"{'\t'*indent_lvl()}MARSHAL_U{child.typ.static_size*8}LE(ctx, {val});\n" + return idlutil.WalkCmd.KEEP_GOING, pop for typ in typs: if not ( @@ -216,7 +348,7 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str: assert isinstance(typ, idl.Struct) ret += "\n" ret += cutil.ifdef_push(1, c9util.ver_ifdef(typ.in_versions)) - ret += f"static bool marshal_{typ.typname}(struct _marshal_ctx *ctx, {c9util.typename(typ)} *val) {{\n" + ret += f"static bool marshal_{typ.typname}(struct lib9p_ctx *ctx, {c9util.typename(typ)} *val, struct _marshal_ret *ret) {{\n" # Pass 1 - check size max_size = max(typ.max_size(v) for v in typ.in_versions) @@ -225,132 +357,29 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str: ret += get_offset_expr(typ, go_to_end).gen_c( "uint64_t", "needed_size", "val->", 1, 0 ) - ret += "\tif (needed_size > (uint64_t)(ctx->ctx->max_msg_size)) {\n" + ret += "\tif (needed_size > (uint64_t)(ctx->max_msg_size)) {\n" else: ret += get_offset_expr(typ, go_to_end).gen_c( "uint32_t", "needed_size", "val->", 1, 0 ) - ret += "\tif (needed_size > ctx->ctx->max_msg_size) {\n" + ret += "\tif (needed_size > ctx->max_msg_size) {\n" if isinstance(typ, idl.Message): # SPECIAL (disable for stat) - ret += '\t\tlib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",\n' + ret += '\t\tlib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",\n' ret += f'\t\t\t"{typ.typname}",\n' - ret += f'\t\t\tctx->ctx->version ? "negotiated" : "{'client' if typ.msgid % 2 == 0 else 'server'}",\n' - ret += "\t\t\tctx->ctx->max_msg_size);\n" + ret += f'\t\t\tctx->version ? "negotiated" : "{'client' if typ.msgid % 2 == 0 else 'server'}",\n' + ret += "\t\t\tctx->max_msg_size);\n" ret += "\t\treturn true;\n" ret += "\t}\n" # Pass 2 - write data - ifdef_depth = 1 - stack: list[tuple[idlutil.Path, bool]] = [(idlutil.Path(typ), False)] - - def handle( - path: idlutil.Path, - ) -> tuple[idlutil.WalkCmd, typing.Callable[[], None]]: - nonlocal ret - nonlocal ifdef_depth - nonlocal stack - stack_len = len(stack) - - def pop() -> None: - nonlocal ret - nonlocal ifdef_depth - nonlocal stack - nonlocal stack_len - while len(stack) > stack_len: - ret += f"{'\t'*(len(stack)-1)}}}\n" - if stack[-1][1]: - ifdef_depth -= 1 - ret += cutil.ifdef_pop(ifdef_depth) - stack = stack[:-1] - - loopdepth = sum(1 for elem in path.elems if elem.cnt) - struct = path.elems[-1].typ if path.elems else path.root - if isinstance(struct, idl.Struct): - offsets: list[str] = [] - for member in struct.members: - if not member.val: - continue - for tok in member.val.tokens: - if not isinstance(tok, idl.ExprSym): - continue - if tok.symname == "end" or tok.symname.startswith("&"): - if tok.symname not in offsets: - offsets.append(tok.symname) - for name in offsets: - name_prefix = "offsetof_" + "".join( - m.membname + "_" for m in path.elems - ) - if name == "end": - if not path.elems: - nonlocal max_size - if max_size > cutil.UINT32_MAX: - ret += f"{'\t'*len(stack)}uint32_t {name_prefix}end = (uint32_t)needed_size;\n" - else: - ret += f"{'\t'*len(stack)}uint32_t {name_prefix}end = needed_size;\n" - continue - recurse: OffsetExprRecursion = go_to_end - else: - assert name.startswith("&") - name = name[1:] - recurse = go_to_tok(name) - expr = get_offset_expr(struct, recurse) - expr_prefix = path.c_str("val->", loopdepth) - if not expr_prefix.endswith(">"): - expr_prefix += "." - ret += expr.gen_c( - "uint32_t", - name_prefix + name, - expr_prefix, - len(stack), - loopdepth, - ) - if path.elems: - child = path.elems[-1] - parent = path.elems[-2].typ if len(path.elems) > 1 else path.root - if child.in_versions < parent.in_versions: - ret += cutil.ifdef_push( - ifdef_depth + 1, c9util.ver_ifdef(child.in_versions) - ) - ifdef_depth += 1 - ret += f"{'\t'*len(stack)}if ({c9util.ver_cond(child.in_versions)}) {{\n" - stack.append((path, True)) - if child.cnt: - cnt_path = path.parent().add(child.cnt) - if child.typ.static_size == 1: # SPECIAL (zerocopy) - if path.root.typname == "stat": # SPECIAL (stat) - ret += f"{'\t'*len(stack)}MARSHAL_BYTES(ctx, {path.c_str('val->')[:-3]}, {cnt_path.c_str('val->')});\n" - else: - ret += f"{'\t'*len(stack)}MARSHAL_BYTES_ZEROCOPY(ctx, {path.c_str('val->')[:-3]}, {cnt_path.c_str('val->')});\n" - return idlutil.WalkCmd.KEEP_GOING, pop - loopvar = chr(ord("i") + loopdepth - 1) - ret += f"{'\t'*len(stack)}for ({c9util.typename(child.cnt.typ)} {loopvar} = 0; {loopvar} < {cnt_path.c_str('val->')}; {loopvar}++) {{\n" - stack.append((path, False)) - if not isinstance(child.typ, idl.Struct): - if child.val: - - def lookup_sym(sym: str) -> str: - nonlocal path - if sym.startswith("&"): - sym = sym[1:] - return ( - "offsetof_" - + "".join(m.membname + "_" for m in path.elems[:-1]) - + sym - ) - - val = c9util.idl_expr(child.val, lookup_sym) - else: - val = path.c_str("val->") - if isinstance(child.typ, idl.Bitfield): - val += f" & {child.typ.typname}_masks[ctx->ctx->version]" - ret += f"{'\t'*len(stack)}MARSHAL_U{child.typ.static_size*8}LE(ctx, {val});\n" - return idlutil.WalkCmd.KEEP_GOING, pop - + indent_stack = [IndentLevel(ifdef=True)] idlutil.walk(typ, handle) - del handle - del stack - del max_size + while len(indent_stack) > 1: + ret += f"{'\t'*(indent_lvl()-1)}}}\n" + if indent_stack.pop().ifdef: + ret += cutil.ifdef_pop(ifdef_lvl()) + # Return ret += "\treturn false;\n" ret += "}\n" ret += cutil.ifdef_pop(0) diff --git a/lib9p/protogen/c_unmarshal.py b/lib9p/protogen/c_unmarshal.py index e17f456..018d750 100644 --- a/lib9p/protogen/c_unmarshal.py +++ b/lib9p/protogen/c_unmarshal.py @@ -3,6 +3,7 @@ # Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> # SPDX-License-Identifier: AGPL-3.0-or-later +import typing import idl @@ -21,72 +22,112 @@ def gen_c_unmarshal(versions: set[str], typs: list[idl.UserType]) -> str: ret = """ /* unmarshal_* ****************************************************************/ -LM_ALWAYS_INLINE static void unmarshal_1(struct _unmarshal_ctx *ctx, uint8_t *out) { -\t*out = ctx->net_bytes[ctx->net_offset]; -\tctx->net_offset += 1; -} - -LM_ALWAYS_INLINE static void unmarshal_2(struct _unmarshal_ctx *ctx, uint16_t *out) { -\t*out = uint16le_decode(&ctx->net_bytes[ctx->net_offset]); -\tctx->net_offset += 2; -} - -LM_ALWAYS_INLINE static void unmarshal_4(struct _unmarshal_ctx *ctx, uint32_t *out) { -\t*out = uint32le_decode(&ctx->net_bytes[ctx->net_offset]); -\tctx->net_offset += 4; -} - -LM_ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *out) { -\t*out = uint64le_decode(&ctx->net_bytes[ctx->net_offset]); -\tctx->net_offset += 8; -} """ - for typ in idlutil.topo_sorted(typs): - inline = "LM_FLATTEN" if isinstance(typ, idl.Message) else "LM_ALWAYS_INLINE" - argfn = ( - c9util.arg_unused - if (isinstance(typ, idl.Struct) and not typ.members) - else c9util.arg_used - ) + ret += cutil.macro( + "#define UNMARSHAL_BYTES(ctx, data_lvalue, len)\n" + "\tdata_lvalue = (char *)&net_bytes[net_offset];\n" + "\tnet_offset += len;\n" + ) + ret += cutil.macro( + "#define UNMARSHAL_U8LE(ctx, val_lvalue)\n" + "\tval_lvalue = net_bytes[net_offset];\n" + "\tnet_offset += 1;\n" + ) + ret += cutil.macro( + "#define UNMARSHAL_U16LE(ctx, val_lvalue)\n" + "\tval_lvalue = uint16le_decode(&net_bytes[net_offset]);\n" + "\tnet_offset += 2;\n" + ) + ret += cutil.macro( + "#define UNMARSHAL_U32LE(ctx, val_lvalue)\n" + "\tval_lvalue = uint32le_decode(&net_bytes[net_offset]);\n" + "\tnet_offset += 4;\n" + ) + ret += cutil.macro( + "#define UNMARSHAL_U64LE(ctx, val_lvalue)\n" + "\tval_lvalue = uint64le_decode(&net_bytes[net_offset]);\n" + "\tnet_offset += 8;\n" + ) + + class IndentLevel(typing.NamedTuple): + ifdef: bool # whether this is both `{` and `#if`, or just `{` + + indent_stack: list[IndentLevel] + + def ifdef_lvl() -> int: + return sum(1 if lvl.ifdef else 0 for lvl in indent_stack) + + def indent_lvl() -> int: + return len(indent_stack) + + def handle( + path: idlutil.Path, + ) -> tuple[idlutil.WalkCmd, typing.Callable[[], None]]: + nonlocal ret + nonlocal indent_stack + indent_stack_len = len(indent_stack) + + def pop() -> None: + nonlocal ret + nonlocal indent_stack + nonlocal indent_stack_len + while len(indent_stack) > indent_stack_len: + if len(indent_stack) == indent_stack_len + 1 and indent_stack[-1].ifdef: + break + ret += f"{'\t'*(indent_lvl()-1)}}}\n" + if indent_stack.pop().ifdef: + ret += cutil.ifdef_pop(ifdef_lvl()) + + if not path.elems: + return idlutil.WalkCmd.KEEP_GOING, pop + + child = path.elems[-1] + parent = path.elems[-2].typ if len(path.elems) > 1 else path.root + if child.in_versions < parent.in_versions: + if line := cutil.ifdef_push( + ifdef_lvl() + 1, c9util.ver_ifdef(child.in_versions) + ): + ret += line + ret += ( + f"{'\t'*indent_lvl()}if ({c9util.ver_cond(child.in_versions)}) {{\n" + ) + indent_stack.append(IndentLevel(ifdef=True)) + if child.cnt: + cnt_path = path.parent().add(child.cnt) + if child.typ.static_size == 1: # SPECIAL (zerocopy) + ret += f"{'\t'*indent_lvl()}UNMARSHAL_BYTES(ctx, {path.c_str('out->')[:-3]}, {cnt_path.c_str('out->')});\n" + return idlutil.WalkCmd.KEEP_GOING, pop + ret += f"{'\t'*indent_lvl()}{path.c_str('out->')[:-3]} = extra;\n" + ret += f"{'\t'*indent_lvl()}extra += sizeof({path.c_str('out->')[:-3]}[0]) * {cnt_path.c_str('out->')};\n" + loopdepth = sum(1 for elem in path.elems if elem.cnt) + loopvar = chr(ord("i") + loopdepth - 1) + ret += f"{'\t'*indent_lvl()}for ({c9util.typename(child.cnt.typ)} {loopvar} = 0; {loopvar} < {cnt_path.c_str('out->')}; {loopvar}++) {{\n" + indent_stack.append(IndentLevel(ifdef=False)) + if not isinstance(child.typ, idl.Struct): + if child.val: + ret += f"{'\t'*indent_lvl()}net_offset += {child.typ.static_size};\n" + else: + ret += f"{'\t'*indent_lvl()}UNMARSHAL_U{child.typ.static_size*8}LE(ctx, {path.c_str('out->')});\n" + return idlutil.WalkCmd.KEEP_GOING, pop + + for typ in typs: + if not ( + isinstance(typ, idl.Message) or typ.typname == "stat" + ): # SPECIAL (include stat) + continue + assert isinstance(typ, idl.Struct) ret += "\n" ret += cutil.ifdef_push(1, c9util.ver_ifdef(typ.in_versions)) - ret += f"{inline} static void unmarshal_{typ.typname}(struct _unmarshal_ctx *{argfn('ctx')}, {c9util.typename(typ)} *out) {{\n" - match typ: - case idl.Number(): - ret += f"\tunmarshal_{typ.prim.typname}(ctx, ({c9util.typename(typ.prim)} *)out);\n" - case idl.Bitfield(): - ret += f"\tunmarshal_{typ.prim.typname}(ctx, ({c9util.typename(typ.prim)} *)out);\n" - case idl.Struct(): - ret += "\tmemset(out, 0, sizeof(*out));\n" - - for member in typ.members: - ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions)) - if member.val: - ret += f"\tctx->net_offset += {member.static_size};\n" - continue - ret += "\t" - - prefix = "\t" - if member.in_versions != typ.in_versions: - ret += "if ( " + c9util.ver_cond(member.in_versions) + " ) " - prefix = "\t\t" - if member.cnt: - if member.in_versions != typ.in_versions: - ret += "{\n" - ret += prefix - if member.typ.static_size == 1: # SPECIAL (string, zerocopy) - ret += f"out->{member.membname} = (char *)&ctx->net_bytes[ctx->net_offset];\n" - ret += f"{prefix}ctx->net_offset += out->{member.cnt.membname};\n" - else: - ret += f"out->{member.membname} = ctx->extra;\n" - ret += f"{prefix}ctx->extra += sizeof(out->{member.membname}[0]) * out->{member.cnt.membname};\n" - ret += f"{prefix}for (typeof(out->{member.cnt.membname}) i = 0; i < out->{member.cnt.membname}; i++)\n" - ret += f"{prefix}\tunmarshal_{member.typ.typname}(ctx, &out->{member.membname}[i]);\n" - if member.in_versions != typ.in_versions: - ret += "\t}\n" - else: - ret += f"unmarshal_{member.typ.typname}(ctx, &out->{member.membname});\n" - ret += cutil.ifdef_pop(1) - ret += "}\n" + ret += f"static void unmarshal_{typ.typname}([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) {{\n" + ret += f"\t{c9util.typename(typ)} *out = out_buf;\n" + ret += "\t[[gnu::unused]] void *extra = &out[1];\n" + ret += "\tuint32_t net_offset = 0;\n" + + indent_stack = [IndentLevel(ifdef=True)] + idlutil.walk(typ, handle) + while len(indent_stack) > 0: + ret += f"{'\t'*(indent_lvl()-1)}}}\n" + if indent_stack.pop().ifdef and indent_stack: + ret += cutil.ifdef_pop(ifdef_lvl()) ret += cutil.ifdef_pop(0) return ret diff --git a/lib9p/protogen/c_validate.py b/lib9p/protogen/c_validate.py index a3f4348..e315b60 100644 --- a/lib9p/protogen/c_validate.py +++ b/lib9p/protogen/c_validate.py @@ -3,6 +3,7 @@ # Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> # SPDX-License-Identifier: AGPL-3.0-or-later +import typing import idl @@ -17,155 +18,270 @@ from . import c9util, cutil, idlutil __all__ = ["gen_c_validate"] -def should_save_value(typ: idl.Struct, member: idl.StructMember) -> bool: - return bool(member.max or member.val or any(m.cnt == member for m in typ.members)) +def should_save_offset(parent: idl.Struct, child: idl.StructMember) -> bool: + if child.val or child.max or isinstance(child.typ, idl.Bitfield): + return True + for sibling in parent.members: + if sibling.val: + for tok in sibling.val.tokens: + if isinstance(tok, idl.ExprSym) and tok.symname == f"&{child.membname}": + return True + if sibling.max: + for tok in sibling.max.tokens: + if isinstance(tok, idl.ExprSym) and tok.symname == f"&{child.membname}": + return True + return False + + +def should_save_end_offset(struct: idl.Struct) -> bool: + for memb in struct.members: + if memb.val: + for tok in memb.val.tokens: + if isinstance(tok, idl.ExprSym) and tok.symname == "end": + return True + if memb.max: + for tok in memb.max.tokens: + if isinstance(tok, idl.ExprSym) and tok.symname == "end": + return True + return False def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str: ret = """ /* validate_* *****************************************************************/ -LM_ALWAYS_INLINE static bool _validate_size_net(struct _validate_ctx *ctx, uint32_t n) { -\tif (__builtin_add_overflow(ctx->net_offset, n, &ctx->net_offset)) -\t\t/* If needed-net-size overflowed uint32_t, then -\t\t * there's no way that actual-net-size will live up to -\t\t * that. */ -\t\treturn lib9p_error(ctx->ctx, LINUX_EBADMSG, "message is too short for content"); -\tif (ctx->net_offset > ctx->net_size) -\t\treturn lib9p_error(ctx->ctx, LINUX_EBADMSG, "message is too short for content"); -\treturn false; -} - -LM_ALWAYS_INLINE static bool _validate_size_host(struct _validate_ctx *ctx, size_t n) { -\tif (__builtin_add_overflow(ctx->host_extra, n, &ctx->host_extra)) -\t\t/* If needed-host-size overflowed size_t, then there's -\t\t * no way that actual-net-size will live up to -\t\t * that. */ -\t\treturn lib9p_error(ctx->ctx, LINUX_EBADMSG, "message is too short for content"); -\treturn false; -} - -LM_ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx, - size_t cnt, - _validate_fn_t item_fn, size_t item_host_size) { -\tfor (size_t i = 0; i < cnt; i++) -\t\tif (_validate_size_host(ctx, item_host_size) || item_fn(ctx)) -\t\t\treturn true; -\treturn false; -} - -LM_ALWAYS_INLINE static bool validate_1(struct _validate_ctx *ctx) { return _validate_size_net(ctx, 1); } -LM_ALWAYS_INLINE static bool validate_2(struct _validate_ctx *ctx) { return _validate_size_net(ctx, 2); } -LM_ALWAYS_INLINE static bool validate_4(struct _validate_ctx *ctx) { return _validate_size_net(ctx, 4); } -LM_ALWAYS_INLINE static bool validate_8(struct _validate_ctx *ctx) { return _validate_size_net(ctx, 8); } """ + ret += cutil.macro( + "#define VALIDATE_NET_BYTES(n)\n" + "\tif (__builtin_add_overflow(net_offset, n, &net_offset))\n" + "\t\t/* If needed-net-size overflowed uint32_t, then\n" + "\t\t * there's no way that actual-net-size will live up to\n" + "\t\t * that. */\n" + '\t\treturn lib9p_error(ctx, LINUX_EBADMSG, "message is too short for content");\n' + "\tif (net_offset > net_size)\n" + '\t\treturn lib9p_errorf(ctx, LINUX_EBADMSG, "message is too short for content (%"PRIu32" > %"PRIu32") @ %d", net_offset, net_size, __LINE__);\n' + ) + ret += cutil.macro( + "#define VALIDATE_NET_UTF8(n)\n" + "\t{\n" + "\t\tsize_t len = n;\n" + "\t\tVALIDATE_NET_BYTES(len);\n" + "\t\tif (!is_valid_utf8_without_nul(&net_bytes[net_offset-len], len))\n" + '\t\t\treturn lib9p_error(ctx, LINUX_EBADMSG, "message contains invalid UTF-8");\n' + "\t}\n" + ) + ret += cutil.macro( + "#define RESERVE_HOST_BYTES(n)\n" + "\tif (__builtin_add_overflow(host_size, n, &host_size))\n" + "\t\t/* If needed-host-size overflowed ssize_t, then there's\n" + "\t\t * no way that actual-net-size will live up to\n" + "\t\t * that. */\n" + '\t\treturn lib9p_error(ctx, LINUX_EBADMSG, "message is too short for content");\n' + ) + + ret += "#define GET_U8LE(off) (net_bytes[off])\n" + ret += "#define GET_U16LE(off) uint16le_decode(&net_bytes[off])\n" + ret += "#define GET_U32LE(off) uint32le_decode(&net_bytes[off])\n" + ret += "#define GET_U64LE(off) uint64le_decode(&net_bytes[off])\n" + + ret += "#define LAST_U8LE() GET_U8LE(net_offset-1)\n" + ret += "#define LAST_U16LE() GET_U16LE(net_offset-2)\n" + ret += "#define LAST_U32LE() GET_U32LE(net_offset-4)\n" + ret += "#define LAST_U64LE() GET_U64LE(net_offset-8)\n" + + class IndentLevel(typing.NamedTuple): + ifdef: bool # whether this is both `{` and `#if`, or just `{` + + indent_stack: list[IndentLevel] + + def ifdef_lvl() -> int: + return sum(1 if lvl.ifdef else 0 for lvl in indent_stack) + + def indent_lvl() -> int: + return len(indent_stack) + + incr_buf: int + + def incr_flush() -> None: + nonlocal ret + nonlocal incr_buf + if incr_buf: + ret += f"{'\t'*indent_lvl()}VALIDATE_NET_BYTES({incr_buf});\n" + incr_buf = 0 + + def gen_validate_size(path: idlutil.Path) -> None: + nonlocal ret + nonlocal incr_buf + nonlocal indent_stack + + assert path.elems + child = path.elems[-1] + parent = path.elems[-2].typ if len(path.elems) > 1 else path.root + assert isinstance(parent, idl.Struct) + + if child.in_versions < parent.in_versions: + if line := cutil.ifdef_push( + ifdef_lvl() + 1, c9util.ver_ifdef(child.in_versions) + ): + incr_flush() + ret += line + ret += ( + f"{'\t'*indent_lvl()}if ({c9util.ver_cond(child.in_versions)}) {{\n" + ) + indent_stack.append(IndentLevel(ifdef=True)) + if should_save_offset(parent, child): + ret += f"{'\t'*indent_lvl()}uint32_t offsetof{''.join('_'+m.membname for m in path.elems)} = net_offset + {incr_buf};\n" + if child.cnt: + assert child.cnt.typ.static_size + cnt_path = path.parent().add(child.cnt) + incr_flush() + if child.membname == "utf8": # SPECIAL (string) + # Yes, this is content-validation and "belongs" in + # gen_validate_content(), not here. But it's just + # easier this way. + ret += f"{'\t'*indent_lvl()}VALIDATE_NET_UTF8(LAST_U{child.cnt.typ.static_size*8}LE());\n" + return + if child.typ.static_size == 1: # SPECIAL (zerocopy) + ret += f"{'\t'*indent_lvl()}VALIDATE_NET_BYTES(LAST_U{child.cnt.typ.static_size*8}LE());\n" + return + loopdepth = sum(1 for elem in path.elems if elem.cnt) + loopvar = chr(ord("i") + loopdepth - 1) + ret += f"{'\t'*indent_lvl()}for ({c9util.typename(child.cnt.typ)} {loopvar} = 0, cnt = LAST_U{child.cnt.typ.static_size*8}LE(); {loopvar} < cnt; {loopvar}++) {{\n" + indent_stack.append(IndentLevel(ifdef=False)) + ret += f"{'\t'*indent_lvl()}RESERVE_HOST_BYTES(sizeof({c9util.typename(child.typ)}));\n" + if not isinstance(child.typ, idl.Struct): + incr_buf += child.typ.static_size - for typ in idlutil.topo_sorted(typs): - inline = "LM_FLATTEN" if isinstance(typ, idl.Message) else "LM_ALWAYS_INLINE" - argfn = ( - c9util.arg_unused - if (isinstance(typ, idl.Struct) and not typ.members) - else c9util.arg_used - ) + def gen_validate_content(path: idlutil.Path) -> None: + nonlocal ret + nonlocal incr_buf + nonlocal indent_stack + + assert path.elems + child = path.elems[-1] + parent = path.elems[-2].typ if len(path.elems) > 1 else path.root + assert isinstance(parent, idl.Struct) + + def lookup_sym(sym: str) -> str: + if sym.startswith("&"): + sym = sym[1:] + return f"offsetof{''.join('_'+m.membname for m in path.elems[:-1])}_{sym}" + + if child.val: + incr_flush() + assert child.typ.static_size + nbits = child.typ.static_size * 8 + nbits = child.typ.static_size * 8 + if nbits < 32 and any( + isinstance(tok, idl.ExprSym) + and (tok.symname == "end" or tok.symname.startswith("&")) + for tok in child.val.tokens + ): + nbits = 32 + act = f"(uint{nbits}_t)GET_U{nbits}LE({lookup_sym(f'&{child.membname}')})" + exp = f"(uint{nbits}_t)({c9util.idl_expr(child.val, lookup_sym)})" + ret += f"{'\t'*indent_lvl()}if ({act} != {exp})\n" + ret += f'{"\t"*(indent_lvl()+1)}return lib9p_errorf(ctx, LINUX_EBADMSG, "{path} value is wrong: actual: %"PRIu{nbits}" != correct:%"PRIu{nbits},\n' + ret += f"{'\t'*(indent_lvl()+2)}{act}, {exp});\n" + if child.max: + incr_flush() + assert child.typ.static_size + nbits = child.typ.static_size * 8 + if nbits < 32 and any( + isinstance(tok, idl.ExprSym) + and (tok.symname == "end" or tok.symname.startswith("&")) + for tok in child.max.tokens + ): + nbits = 32 + act = f"(uint{nbits}_t)GET_U{nbits}LE({lookup_sym(f'&{child.membname}')})" + exp = f"(uint{nbits}_t)({c9util.idl_expr(child.max, lookup_sym)})" + ret += f"{'\t'*indent_lvl()}if ({act} > {exp})\n" + ret += f'{"\t"*(indent_lvl()+1)}return lib9p_errorf(ctx, LINUX_EBADMSG, "{path} value is too large: %"PRIu{nbits}" > %"PRIu{nbits},\n' + ret += f"{'\t'*(indent_lvl()+2)}{act}, {exp});\n" + if isinstance(child.typ, idl.Bitfield): + incr_flush() + nbytes = child.typ.static_size + nbits = nbytes * 8 + act = f"GET_U{nbits}LE({lookup_sym(f'&{child.membname}')})" + ret += f"{'\t'*indent_lvl()}if ({act} & ~{child.typ.typname}_masks[ctx->version])\n" + ret += f'{"\t"*(indent_lvl()+1)}return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in {child.typ.typname} bitfield: %#0{nbytes*2}"PRIx{nbits},\n' + ret += f"{'\t'*(indent_lvl()+2)}{act} & ~{child.typ.typname}_masks[ctx->version]);\n" + + def handle( + path: idlutil.Path, + ) -> tuple[idlutil.WalkCmd, typing.Callable[[], None]]: + nonlocal ret + nonlocal incr_buf + nonlocal indent_stack + indent_stack_len = len(indent_stack) + pop_struct = path.elems[-1].typ if path.elems else path.root + pop_path = path + pop_indent_stack_len: int + + def pop() -> None: + nonlocal ret + nonlocal indent_stack + nonlocal indent_stack_len + nonlocal pop_struct + nonlocal pop_path + nonlocal pop_indent_stack_len + if isinstance(pop_struct, idl.Struct): + while len(indent_stack) > pop_indent_stack_len: + incr_flush() + ret += f"{'\t'*(indent_lvl()-1)}}}\n" + if indent_stack.pop().ifdef: + ret += cutil.ifdef_pop(ifdef_lvl()) + parent = pop_struct + path = pop_path + if should_save_end_offset(parent): + ret += f"{'\t'*indent_lvl()}uint32_t offsetof{''.join('_'+m.membname for m in path.elems)}_end = net_offset + {incr_buf};\n" + for child in parent.members: + gen_validate_content(pop_path.add(child)) + while len(indent_stack) > indent_stack_len: + if len(indent_stack) == indent_stack_len + 1 and indent_stack[-1].ifdef: + break + incr_flush() + ret += f"{'\t'*(indent_lvl()-1)}}}\n" + if indent_stack.pop().ifdef: + ret += cutil.ifdef_pop(ifdef_lvl()) + + if path.elems: + gen_validate_size(path) + + pop_indent_stack_len = len(indent_stack) + + return idlutil.WalkCmd.KEEP_GOING, pop + + for typ in typs: + if not ( + isinstance(typ, idl.Message) or typ.typname == "stat" + ): # SPECIAL (include stat) + continue + assert isinstance(typ, idl.Struct) ret += "\n" ret += cutil.ifdef_push(1, c9util.ver_ifdef(typ.in_versions)) - ret += f"{inline} static bool validate_{typ.typname}(struct _validate_ctx *{argfn('ctx')}) {{\n" - - match typ: - case idl.Number(): - ret += f"\treturn validate_{typ.prim.typname}(ctx);\n" - case idl.Bitfield(): - ret += f"\t if (validate_{typ.static_size}(ctx))\n" - ret += "\t\treturn true;\n" - ret += f"\t{c9util.typename(typ)} mask = {typ.typname}_masks[ctx->ctx->version];\n" - if typ.static_size == 1: - ret += f"\t{c9util.typename(typ)} val = ctx->net_bytes[ctx->net_offset-1];\n" - else: - ret += f"\t{c9util.typename(typ)} val = uint{typ.static_size*8}le_decode(&ctx->net_bytes[ctx->net_offset-{typ.static_size}]);\n" - ret += "\tif (val & ~mask)\n" - ret += f'\t\treturn lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in {typ.typname} bitfield: %#0{typ.static_size}"PRIx{typ.static_size*8}, val & ~mask);\n' - ret += "\treturn false;\n" - case idl.Struct(): # and idl.Message() - if len(typ.members) == 0: - ret += "\treturn false;\n" - ret += "}\n" - continue - - # Pass 1 - declare value variables - for member in typ.members: - if should_save_value(typ, member): - ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions)) - ret += f"\t{c9util.typename(member.typ)} {member.membname};\n" - ret += cutil.ifdef_pop(1) - - # Pass 2 - declare offset variables - mark_offset: set[str] = set() - for member in typ.members: - for tok in [*member.max.tokens, *member.val.tokens]: - if isinstance(tok, idl.ExprSym) and tok.symname.startswith("&"): - if tok.symname[1:] not in mark_offset: - ret += f"\tuint32_t _{tok.symname[1:]}_offset;\n" - mark_offset.add(tok.symname[1:]) - - # Pass 3 - main pass - ret += "\treturn false\n" - for member in typ.members: - ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions)) - ret += "\t || " - if member.in_versions != typ.in_versions: - ret += "( " + c9util.ver_cond(member.in_versions) + " && " - if member.cnt is not None: - if member.typ.static_size == 1: # SPECIAL (zerocopy) - ret += f"_validate_size_net(ctx, {member.cnt.membname})" - else: - ret += f"_validate_list(ctx, {member.cnt.membname}, validate_{member.typ.typname}, sizeof({c9util.typename(member.typ)}))" - if typ.typname == "s": # SPECIAL (string) - ret += '\n\t || ({ (!is_valid_utf8_without_nul(&ctx->net_bytes[ctx->net_offset-len], len)) && lib9p_error(ctx->ctx, LINUX_EBADMSG, "message contains invalid UTF-8"); })' - else: - if should_save_value(typ, member): - ret += "(" - if member.membname in mark_offset: - ret += f"({{ _{member.membname}_offset = ctx->net_offset; " - ret += f"validate_{member.typ.typname}(ctx)" - if member.membname in mark_offset: - ret += "; })" - if should_save_value(typ, member): - nbytes = member.static_size - assert nbytes - if nbytes == 1: - ret += f" || ({{ {member.membname} = ctx->net_bytes[ctx->net_offset-1]; false; }}))" - else: - ret += f" || ({{ {member.membname} = uint{nbytes*8}le_decode(&ctx->net_bytes[ctx->net_offset-{nbytes}]); false; }}))" - if member.in_versions != typ.in_versions: - ret += " )" - ret += "\n" - - # Pass 4 - validate ,max= and ,val= constraints - for member in typ.members: - - def lookup_sym(sym: str) -> str: - match sym: - case "end": - return "ctx->net_offset" - case _: - assert sym.startswith("&") - return f"_{sym[1:]}_offset" - - if member.max: - assert member.static_size - nbits = member.static_size * 8 - ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions)) - ret += f"\t || ({{ uint{nbits}_t max = {c9util.idl_expr(member.max, lookup_sym)}; (((uint{nbits}_t){member.membname}) > max) &&\n" - ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.membname} value is too large (%"PRIu{nbits}" > %"PRIu{nbits}")", {member.membname}, max); }})\n' - if member.val: - assert member.static_size - nbits = member.static_size * 8 - ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions)) - ret += f"\t || ({{ uint{nbits}_t exp = {c9util.idl_expr(member.val, lookup_sym)}; (((uint{nbits}_t){member.membname}) != exp) &&\n" - ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.membname} value is wrong (actual:%"PRIu{nbits}" != correct:%"PRIu{nbits}")", (uint{nbits}_t){member.membname}, exp); }})\n' - - ret += cutil.ifdef_pop(1) - ret += "\t ;\n" + if typ.typname == "stat": # SPECIAL (stat) + ret += f"static ssize_t validate_{typ.typname}(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size) {{\n" + else: + ret += f"static ssize_t validate_{typ.typname}(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) {{\n" + + ret += "\tuint32_t net_offset = 0;\n" + ret += f"\tssize_t host_size = sizeof({c9util.typename(typ)});\n" + + incr_buf = 0 + indent_stack = [IndentLevel(ifdef=True)] + idlutil.walk(typ, handle) + while len(indent_stack) > 1: + incr_flush() + ret += f"{'\t'*(indent_lvl()-1)}}}\n" + if indent_stack.pop().ifdef: + ret += cutil.ifdef_pop(ifdef_lvl()) + + incr_flush() + if typ.typname == "stat": # SPECIAL (stat) + ret += "\tif (ret_net_size)\n" + ret += "\t\t*ret_net_size = net_offset;\n" + ret += "\treturn (ssize_t)host_size;\n" ret += "}\n" ret += cutil.ifdef_pop(0) return ret diff --git a/lib9p/protogen/cutil.py b/lib9p/protogen/cutil.py index a78cd17..8df6db9 100644 --- a/lib9p/protogen/cutil.py +++ b/lib9p/protogen/cutil.py @@ -31,7 +31,7 @@ def macro(full: str) -> str: lines = [l.rstrip() for l in full.split("\n")] width = max(len(l.expandtabs(tabsize=8)) for l in lines[:-1]) lines = [tab_ljust(l, width) for l in lines] - return " \\\n".join(lines).rstrip() + "\n" + return " \\\n".join(lines).rstrip() + "\n" _ifdef_stack: list[str | None] = [] |