summaryrefslogtreecommitdiff
path: root/lib9p
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p')
-rw-r--r--lib9p/9p.c99
-rw-r--r--lib9p/9p.generated.c5852
-rw-r--r--lib9p/CMakeLists.txt4
-rwxr-xr-xlib9p/idl.gen1381
-rw-r--r--lib9p/idl/0000-README.md5
-rw-r--r--lib9p/idl/0000-TODO.md2
-rw-r--r--lib9p/idl/2002-9P2000.9p10
-rw-r--r--lib9p/idl/2005-9P2000.u.9p5
-rw-r--r--lib9p/idl/2010-9P2000.L.9p222
-rw-r--r--lib9p/idl/__init__.py305
-rw-r--r--lib9p/include/lib9p/9p.generated.h440
-rw-r--r--lib9p/include/lib9p/9p.h27
-rwxr-xr-xlib9p/include/lib9p/linux-errno.h.gen12
-rw-r--r--lib9p/internal.h45
-rwxr-xr-xlib9p/proto.gen15
-rw-r--r--lib9p/protogen/__init__.py57
-rw-r--r--lib9p/protogen/c.py200
-rw-r--r--lib9p/protogen/c9util.py109
-rw-r--r--lib9p/protogen/c_marshal.py386
-rw-r--r--lib9p/protogen/c_unmarshal.py133
-rw-r--r--lib9p/protogen/c_validate.py287
-rw-r--r--lib9p/protogen/cutil.py84
-rw-r--r--lib9p/protogen/h.py447
-rw-r--r--lib9p/protogen/idlutil.py112
-rw-r--r--lib9p/srv.c6
-rwxr-xr-xlib9p/tests/runtest11
-rw-r--r--lib9p/tests/test_compile.c157
-rwxr-xr-xlib9p/tests/test_compile.c.gen19
-rw-r--r--lib9p/tests/test_compile_config/config.h38
-rw-r--r--lib9p/tests/test_server/CMakeLists.txt3
-rw-r--r--lib9p/tests/test_server/config/config.h3
-rw-r--r--lib9p/tests/test_server/main.c11
-rw-r--r--lib9p/tests/test_server/static/Documentation/x.txt (renamed from lib9p/tests/test_server/static/Documentation/x)2
33 files changed, 5759 insertions, 4730 deletions
diff --git a/lib9p/9p.c b/lib9p/9p.c
index 1caa01a..c11bcd6 100644
--- a/lib9p/9p.c
+++ b/lib9p/9p.c
@@ -79,7 +79,7 @@ bool lib9p_ctx_has_error(struct lib9p_ctx *ctx) {
return ctx->err_msg[0];
}
-int lib9p_error(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *msg) {
+int lib9p_error(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *msg) {
if (lib9p_ctx_has_error(ctx))
return -1;
strncpy(ctx->err_msg, msg, sizeof(ctx->err_msg));
@@ -94,7 +94,7 @@ int lib9p_error(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *msg) {
return -1;
}
-int lib9p_errorf(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *fmt, ...) {
+int lib9p_errorf(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *fmt, ...) {
int n;
va_list args;
@@ -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 fe042e6..6726084 100644
--- a/lib9p/9p.generated.c
+++ b/lib9p/9p.generated.c
@@ -1,4 +1,4 @@
-/* Generated by `lib9p/idl.gen lib9p/idl/2002-9P2000.9p lib9p/idl/2003-9P2000.p9p.9p lib9p/idl/2005-9P2000.u.9p lib9p/idl/2010-9P2000.L.9p lib9p/idl/2012-9P2000.e.9p`. DO NOT EDIT! */
+/* Generated by `lib9p/proto.gen lib9p/idl/2002-9P2000.9p lib9p/idl/2003-9P2000.p9p.9p lib9p/idl/2005-9P2000.u.9p lib9p/idl/2010-9P2000.L.9p lib9p/idl/2012-9P2000.e.9p`. DO NOT EDIT! */
#include <stdbool.h>
#include <stddef.h> /* for size_t */
@@ -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 ********************************************************************/
@@ -333,6 +333,38 @@ static const lib9p_o_t o_masks[LIB9P_VER_NUM] = {
#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
+static const lib9p_lo_t lo_masks[LIB9P_VER_NUM] = {
+#if CONFIG_9P_ENABLE_9P2000
+ [LIB9P_VER_9P2000] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_9P2000 */
+ [LIB9P_VER_9P2000_L] = 0b00000000000111111111111111000011,
+#if CONFIG_9P_ENABLE_9P2000_e
+ [LIB9P_VER_9P2000_e] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_9P2000_e */
+#if CONFIG_9P_ENABLE_9P2000_p9p
+ [LIB9P_VER_9P2000_p9p] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
+#if CONFIG_9P_ENABLE_9P2000_u
+ [LIB9P_VER_9P2000_u] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+};
+
+static const lib9p_mode_t mode_masks[LIB9P_VER_NUM] = {
+#if CONFIG_9P_ENABLE_9P2000
+ [LIB9P_VER_9P2000] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_9P2000 */
+ [LIB9P_VER_9P2000_L] = 0b00000000000000001111111111111111,
+#if CONFIG_9P_ENABLE_9P2000_e
+ [LIB9P_VER_9P2000_e] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_9P2000_e */
+#if CONFIG_9P_ENABLE_9P2000_p9p
+ [LIB9P_VER_9P2000_p9p] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
+#if CONFIG_9P_ENABLE_9P2000_u
+ [LIB9P_VER_9P2000_u] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+};
+
static const lib9p_getattr_t getattr_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000
[LIB9P_VER_9P2000] = 0b0000000000000000000000000000000000000000000000000000000000000000,
@@ -384,2494 +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 */
-#if CONFIG_9P_ENABLE_9P2000_L
-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); })
- ;
+ 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
+ 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 */
+ 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_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); })
- ;
+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_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_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 = 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_4(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_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); })
- ;
+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 || 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); })
- ;
-}
-
-#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_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_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 = 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_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); })
- ;
-}
-
-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_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 = 50; (((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_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_4(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); })
- ;
-}
-
-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); })
- ;
-}
-
-#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_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_1(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_1(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_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_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_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 = 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_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); })
- ;
-}
-
-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_4(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_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 = 72; (((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_L
-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_4(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_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_8(ctx)
- || validate_qid(ctx)
- || validate_4(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;
-}
-
-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;
-}
+#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_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 */
-#if CONFIG_9P_ENABLE_9P2000_L
-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;
+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
+ 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 */
}
-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);
+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_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);
+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);
+ }
}
-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);
+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_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);
+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_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_4(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_4(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_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;
-}
-
-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);
-}
-
-#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_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 || 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);
-}
-
-#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_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_4(ctx, &out->flags);
-}
-
-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);
-}
-
-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_4(ctx, &out->datasync);
-}
-
-#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_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_4(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 */
}
-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_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_1(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_1(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_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_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_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_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_4(ctx, &out->flags);
- unmarshal_4(ctx, &out->mode);
- unmarshal_nuid(ctx, &out->gid);
-}
-
-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);
-}
-
-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_4(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_4(ctx, &out->mode);
- 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);
+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_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);
+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_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_4(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_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);
+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_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);
-#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);
-#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);
-}
-
-#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);
+#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);
+ }
}
-#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_8(ctx, &out->valid);
- unmarshal_qid(ctx, &out->qid);
- unmarshal_4(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_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_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);
+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 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#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;
@@ -2879,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);
@@ -2898,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 */
@@ -2920,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;
@@ -2940,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;
@@ -2960,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;
@@ -2992,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;
@@ -3006,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;
@@ -3045,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;
@@ -3059,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;
@@ -3094,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;
@@ -3112,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;
@@ -3129,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;
@@ -3156,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;
@@ -3172,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);
}
@@ -3181,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;
@@ -3196,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;
@@ -3214,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;
@@ -3238,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;
@@ -3257,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);
@@ -3266,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;
@@ -3286,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;
@@ -3305,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;
@@ -3326,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;
@@ -3344,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;
@@ -3362,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;
@@ -3379,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;
@@ -3397,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;
@@ -3416,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;
@@ -3434,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;
@@ -3465,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);
@@ -3484,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;
@@ -3536,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);
@@ -3555,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;
@@ -3594,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;
@@ -3609,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;
@@ -3627,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);
@@ -3637,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;
@@ -3655,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;
@@ -3673,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;
@@ -3699,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;
@@ -3714,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);
+ 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;
@@ -3732,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;
@@ -3756,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);
- MARSHAL_U32LE(ctx, val->mode);
+ 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;
@@ -3776,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;
@@ -3806,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;
@@ -3820,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;
@@ -3843,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);
+ 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;
@@ -3864,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;
@@ -3891,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;
@@ -3908,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;
@@ -3926,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;
@@ -3945,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;
@@ -3960,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;
@@ -3978,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);
- 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);
+ MARSHAL_U32LE(ctx, val->mode & mode_masks[ctx->version]);
MARSHAL_U32LE(ctx, val->uid);
MARSHAL_U32LE(ctx, val->gid);
MARSHAL_U64LE(ctx, val->nlink);
@@ -4003,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;
@@ -4018,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);
+ 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);
@@ -4030,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;
@@ -4047,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;
@@ -4068,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;
@@ -4086,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;
@@ -4108,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;
@@ -4125,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;
@@ -4145,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;
@@ -4164,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;
@@ -4183,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;
@@ -4200,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;
@@ -4216,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);
@@ -4225,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;
@@ -4243,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;
@@ -4267,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;
@@ -4290,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;
@@ -4311,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;
@@ -4328,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;
@@ -4345,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);
+ 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;
@@ -4364,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;
@@ -4393,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;
@@ -4410,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;
@@ -4431,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;
@@ -4450,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;
@@ -4468,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;
@@ -4485,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;
@@ -4511,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;
@@ -4530,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;
@@ -4558,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;
@@ -4598,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] = {
@@ -5061,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/CMakeLists.txt b/lib9p/CMakeLists.txt
index b356288..707308e 100644
--- a/lib9p/CMakeLists.txt
+++ b/lib9p/CMakeLists.txt
@@ -13,7 +13,7 @@ target_sources(lib9p INTERFACE
target_link_libraries(lib9p INTERFACE
libcr_ipc
libmisc
- libhw
+ libhw_generic
)
if (ENABLE_TESTS)
@@ -22,4 +22,6 @@ if (ENABLE_TESTS)
NAME "lib9p/runtest"
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/runtest"
)
+ add_lib_test(lib9p test_compile)
+ target_include_directories(test_compile PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_compile_config)
endif()
diff --git a/lib9p/idl.gen b/lib9p/idl.gen
deleted file mode 100755
index db5f37d..0000000
--- a/lib9p/idl.gen
+++ /dev/null
@@ -1,1381 +0,0 @@
-#!/usr/bin/env python
-# lib9p/idl.gen - Generate C marshalers/unmarshalers for .9p files
-# defining 9P protocol variants.
-#
-# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
-# SPDX-License-Identifier: AGPL-3.0-or-later
-
-import enum
-import graphlib
-import os.path
-import sys
-import typing
-
-sys.path.insert(0, os.path.normpath(os.path.join(__file__, "..")))
-
-import idl
-
-# This strives to be "general-purpose" in that it just acts on the
-# *.9p inputs; but (unfortunately?) there are a few special-cases in
-# this script, marked with "SPECIAL".
-
-
-# Utilities ####################################################################
-
-idprefix = "lib9p_"
-
-u32max = (1 << 32) - 1
-u64max = (1 << 64) - 1
-
-
-def tab_ljust(s: str, width: int) -> str:
- cur = len(s.expandtabs(tabsize=8))
- if cur >= width:
- return s
- return s + " " * (width - cur)
-
-
-def add_prefix(p: str, s: str) -> str:
- if s.startswith("_"):
- return "_" + p + s[1:]
- return p + s
-
-
-def c_macro(full: str) -> str:
- full = full.rstrip()
- assert "\n" in full
- 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"
-
-
-def c_ver_enum(ver: str) -> str:
- return f"{idprefix.upper()}VER_{ver.replace('.', '_')}"
-
-
-def c_ver_ifdef(versions: typing.Collection[str]) -> str:
- return " || ".join(
- f"CONFIG_9P_ENABLE_{v.replace('.', '_')}" for v in sorted(versions)
- )
-
-
-def c_ver_cond(versions: typing.Collection[str]) -> str:
- if len(versions) == 1:
- v = next(v for v in versions)
- return f"is_ver(ctx, {v.replace('.', '_')})"
- return "( " + (" || ".join(c_ver_cond({v}) for v in sorted(versions))) + " )"
-
-
-def c_typename(typ: idl.Type, parent: idl.StructMember | None = None) -> str:
- match typ:
- case idl.Primitive():
- if typ.value == 1 and parent and parent.cnt: # SPECIAL (string)
- return "[[gnu::nonstring]] char"
- return f"uint{typ.value*8}_t"
- case idl.Number():
- return f"{idprefix}{typ.name}_t"
- case idl.Bitfield():
- return f"{idprefix}{typ.name}_t"
- case idl.Message():
- return f"struct {idprefix}msg_{typ.name}"
- case idl.Struct():
- return f"struct {idprefix}{typ.name}"
- case _:
- raise ValueError(f"not a type: {typ.__class__.__name__}")
-
-
-def c_expr(expr: idl.Expr, lookup_sym: typing.Callable[[str], str]) -> str:
- ret: list[str] = []
- for tok in expr.tokens:
- match tok:
- case idl.ExprOp():
- ret.append(tok.op)
- case idl.ExprLit():
- ret.append(str(tok.val))
- case idl.ExprSym(name="s32_max"):
- ret.append("INT32_MAX")
- case idl.ExprSym(name="s64_max"):
- ret.append("INT64_MAX")
- case idl.ExprSym():
- ret.append(lookup_sym(tok.name))
- case _:
- assert False
- return " ".join(ret)
-
-
-_ifdef_stack: list[str | None] = []
-
-
-def ifdef_push(n: int, _newval: str) -> str:
- # Grow the stack as needed
- global _ifdef_stack
- while len(_ifdef_stack) < n:
- _ifdef_stack.append(None)
-
- # Set some variables
- parentval: str | None = None
- for x in _ifdef_stack[:-1]:
- if x is not None:
- parentval = x
- oldval = _ifdef_stack[-1]
- newval: str | None = _newval
- if newval == parentval:
- newval = None
-
- # Put newval on the stack.
- _ifdef_stack[-1] = newval
-
- # Build output.
- ret = ""
- if newval != oldval:
- if oldval is not None:
- ret += f"#endif /* {oldval} */\n"
- if newval is not None:
- ret += f"#if {newval}\n"
- return ret
-
-
-def ifdef_pop(n: int) -> str:
- global _ifdef_stack
- ret = ""
- while len(_ifdef_stack) > n:
- if _ifdef_stack[-1] is not None:
- ret += f"#endif /* {_ifdef_stack[-1]} */\n"
- _ifdef_stack = _ifdef_stack[:-1]
- return ret
-
-
-# topo_sorted() ################################################################
-
-
-def topo_sorted(typs: list[idl.Type]) -> typing.Iterable[idl.Type]:
- ts: graphlib.TopologicalSorter[idl.Type] = graphlib.TopologicalSorter()
- for typ in typs:
- match typ:
- case idl.Number():
- ts.add(typ)
- case idl.Bitfield():
- ts.add(typ)
- case idl.Struct(): # and idl.Message():
- deps = [
- member.typ
- for member in typ.members
- if not isinstance(member.typ, idl.Primitive)
- ]
- ts.add(typ, *deps)
- return ts.static_order()
-
-
-# walk() #######################################################################
-
-
-class Path:
- root: idl.Type
- elems: list[idl.StructMember]
-
- def __init__(
- self, root: idl.Type, elems: list[idl.StructMember] | None = None
- ) -> None:
- self.root = root
- self.elems = elems if elems is not None else []
-
- def add(self, elem: idl.StructMember) -> "Path":
- return Path(self.root, self.elems + [elem])
-
- def parent(self) -> "Path":
- return Path(self.root, self.elems[:-1])
-
- def c_str(self, base: str, loopdepth: int = 0) -> str:
- ret = base
- for i, elem in enumerate(self.elems):
- if i > 0:
- ret += "."
- ret += elem.name
- if elem.cnt:
- ret += f"[{chr(ord('i')+loopdepth)}]"
- loopdepth += 1
- return ret
-
- def __str__(self) -> str:
- return self.c_str(self.root.name + "->")
-
-
-class WalkCmd(enum.Enum):
- KEEP_GOING = 1
- DONT_RECURSE = 2
- ABORT = 3
-
-
-type WalkHandler = typing.Callable[
- [Path], tuple[WalkCmd, typing.Callable[[], None] | None]
-]
-
-
-def _walk(path: Path, handle: WalkHandler) -> WalkCmd:
- typ = path.elems[-1].typ if path.elems else path.root
-
- ret, atexit = handle(path)
-
- if isinstance(typ, idl.Struct):
- match ret:
- case WalkCmd.KEEP_GOING:
- for member in typ.members:
- if _walk(path.add(member), handle) == WalkCmd.ABORT:
- ret = WalkCmd.ABORT
- break
- case WalkCmd.DONT_RECURSE:
- ret = WalkCmd.KEEP_GOING
- case WalkCmd.ABORT:
- ret = WalkCmd.ABORT
- case _:
- assert False, f"invalid cmd: {ret}"
-
- if atexit:
- atexit()
- return ret
-
-
-def walk(typ: idl.Type, handle: WalkHandler) -> None:
- _walk(Path(typ), handle)
-
-
-# get_buffer_size() ############################################################
-
-
-class BufferSize:
- min_size: int # really just here to sanity-check against typ.min_size(version)
- exp_size: int # "expected" or max-reasonable size
- max_size: int # really just here to sanity-check against typ.max_size(version)
- max_copy: int
- max_copy_extra: str
- max_iov: int
- max_iov_extra: str
- _starts_with_copy: bool
- _ends_with_copy: bool
-
- def __init__(self) -> None:
- self.min_size = 0
- self.exp_size = 0
- self.max_size = 0
- self.max_copy = 0
- self.max_copy_extra = ""
- self.max_iov = 0
- self.max_iov_extra = ""
- self._starts_with_copy = False
- self._ends_with_copy = False
-
-
-def get_buffer_size(typ: idl.Type, version: str) -> BufferSize:
- assert isinstance(typ, idl.Primitive) or (version in typ.in_versions)
-
- ret = BufferSize()
-
- if not isinstance(typ, idl.Struct):
- assert typ.static_size
- ret.min_size = typ.static_size
- ret.exp_size = typ.static_size
- ret.max_size = typ.static_size
- ret.max_copy = typ.static_size
- ret.max_iov = 1
- ret._starts_with_copy = True
- ret._ends_with_copy = True
- return ret
-
- def handle(path: Path) -> tuple[WalkCmd, None]:
- nonlocal ret
- if path.elems:
- child = path.elems[-1]
- if version not in child.in_versions:
- return WalkCmd.DONT_RECURSE, None
- if child.cnt:
- if child.typ.static_size == 1: # SPECIAL (zerocopy)
- ret.max_iov += 1
- # HEURISTIC: 27 for strings (max-strlen from 9P1), 8KiB for other data
- ret.exp_size += 27 if child.name == "utf8" else 8192
- ret.max_size += child.max_cnt
- ret._ends_with_copy = False
- return WalkCmd.DONT_RECURSE, None
- sub = get_buffer_size(child.typ, version)
- ret.exp_size += sub.exp_size * 16 # HEURISTIC: MAXWELEM
- ret.max_size += sub.max_size * child.max_cnt
- if child.name == "wname" and path.root.name in (
- "Tsread",
- "Tswrite",
- ): # SPECIAL (9P2000.e)
- assert ret._ends_with_copy
- assert sub._starts_with_copy
- assert not sub._ends_with_copy
- ret.max_copy_extra = (
- f" + (CONFIG_9P_MAX_9P2000_e_WELEM * {sub.max_copy})"
- )
- ret.max_iov_extra = (
- f" + (CONFIG_9P_MAX_9P2000_e_WELEM * {sub.max_iov})"
- )
- ret.max_iov -= 1
- else:
- ret.max_copy += sub.max_copy * child.max_cnt
- if sub.max_iov == 1 and sub._starts_with_copy: # is purely copy
- ret.max_iov += 1
- else: # contains zero-copy segments
- ret.max_iov += sub.max_iov * child.max_cnt
- if ret._ends_with_copy and sub._starts_with_copy:
- # we can merge this one
- ret.max_iov -= 1
- if (
- sub._ends_with_copy
- and sub._starts_with_copy
- and sub.max_iov > 1
- ):
- # we can merge these
- ret.max_iov -= child.max_cnt - 1
- ret._ends_with_copy = sub._ends_with_copy
- return WalkCmd.DONT_RECURSE, None
- elif not isinstance(child.typ, idl.Struct):
- assert child.typ.static_size
- if not ret._ends_with_copy:
- if ret.max_size == 0:
- ret._starts_with_copy = True
- ret.max_iov += 1
- ret._ends_with_copy = True
- ret.min_size += child.typ.static_size
- ret.exp_size += child.typ.static_size
- ret.max_size += child.typ.static_size
- ret.max_copy += child.typ.static_size
- return WalkCmd.KEEP_GOING, None
-
- walk(typ, handle)
- assert ret.min_size == typ.min_size(version)
- assert ret.max_size == typ.max_size(version)
- return ret
-
-
-# Generate .h ##################################################################
-
-
-def gen_h(versions: set[str], typs: list[idl.Type]) -> str:
- global _ifdef_stack
- _ifdef_stack = []
-
- ret = f"""/* Generated by `{' '.join(sys.argv)}`. DO NOT EDIT! */
-
-#ifndef _LIB9P_9P_H_
-\t#error Do not include <lib9p/9p.generated.h> directly; include <lib9p/9p.h> instead
-#endif
-
-#include <stdint.h> /* for uint{{n}}_t types */
-
-#include <libhw/generic/net.h> /* for struct iovec */
-"""
-
- id2typ: dict[int, idl.Message] = {}
- for msg in [msg for msg in typs if isinstance(msg, idl.Message)]:
- id2typ[msg.msgid] = msg
-
- ret += f"""
-/* config *********************************************************************/
-
-#include "config.h"
-"""
- for ver in sorted(versions):
- ret += "\n"
- ret += f"#ifndef {c_ver_ifdef({ver})}\n"
- ret += f"\t#error config.h must define {c_ver_ifdef({ver})}\n"
- if ver == "9P2000.e": # SPECIAL (9P2000.e)
- ret += "#else\n"
- ret += f"\t#if {c_ver_ifdef({ver})}\n"
- ret += "\t\t#ifndef(CONFIG_9P_MAX_9P2000_e_WELEM)\n"
- ret += f"\t\t\t#error if {c_ver_ifdef({ver})} then config.h must define CONFIG_9P_MAX_9P2000_e_WELEM\n"
- ret += "\t\t#endif\n"
- ret += "\t\tstatic_assert(CONFIG_9P_MAX_9P2000_e_WELEM > 0);\n"
- ret += "\t#endif\n"
- ret += "#endif\n"
-
- ret += f"""
-/* enum version ***************************************************************/
-
-enum {idprefix}version {{
-"""
- fullversions = ["unknown = 0", *sorted(versions)]
- verwidth = max(len(v) for v in fullversions)
- for ver in fullversions:
- if ver in versions:
- ret += ifdef_push(1, c_ver_ifdef({ver}))
- ret += f"\t{c_ver_enum(ver)},"
- ret += (" " * (verwidth - len(ver))) + ' /* "' + ver.split()[0] + '" */\n'
- ret += ifdef_pop(0)
- ret += f"\t{c_ver_enum('NUM')},\n"
- ret += "};\n"
-
- ret += """
-/* enum msg_type **************************************************************/
-
-"""
- ret += f"enum {idprefix}msg_type {{ /* uint8_t */\n"
- namewidth = max(len(msg.name) for msg in typs if isinstance(msg, idl.Message))
- for n in range(0x100):
- if n not in id2typ:
- continue
- msg = id2typ[n]
- ret += ifdef_push(1, c_ver_ifdef(msg.in_versions))
- ret += f"\t{idprefix.upper()}TYP_{msg.name.ljust(namewidth)} = {msg.msgid},\n"
- ret += ifdef_pop(0)
- ret += "};\n"
-
- ret += """
-/* payload types **************************************************************/
-"""
-
- def per_version_comment(
- typ: idl.Type, fn: typing.Callable[[idl.Type, str], str]
- ) -> str:
- lines: dict[str, str] = {}
- for version in sorted(typ.in_versions):
- lines[version] = fn(typ, version)
- if len(set(lines.values())) == 1:
- for _, line in lines.items():
- return f"/* {line} */\n"
- assert False
- else:
- ret = ""
- v_width = max(len(c_ver_enum(v)) for v in typ.in_versions)
- for version, line in lines.items():
- ret += f"/* {c_ver_enum(version).ljust(v_width)}: {line} */\n"
- return ret
-
- for typ in topo_sorted(typs):
- ret += "\n"
- ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
-
- def sum_size(typ: idl.Type, version: str) -> str:
- sz = get_buffer_size(typ, version)
- assert (
- sz.min_size <= sz.exp_size
- and sz.exp_size <= sz.max_size
- and sz.max_size < u64max
- )
- ret = ""
- if sz.min_size == sz.max_size:
- ret += f"size = {sz.min_size:,}"
- else:
- ret += f"min_size = {sz.min_size:,} ; exp_size = {sz.exp_size:,} ; max_size = {sz.max_size:,}"
- if sz.max_size > u32max:
- ret += " (warning: >UINT32_MAX)"
- ret += f" ; max_iov = {sz.max_iov:,}{sz.max_iov_extra} ; max_copy = {sz.max_copy:,}{sz.max_copy_extra}"
- return ret
-
- ret += per_version_comment(typ, sum_size)
-
- match typ:
- case idl.Number():
- ret += f"typedef {c_typename(typ.prim)} {c_typename(typ)};\n"
- prefix = f"{idprefix.upper()}{typ.name.upper()}_"
- namewidth = max(len(name) for name in typ.vals)
- for name, val in typ.vals.items():
- ret += f"#define {prefix}{name.ljust(namewidth)} (({c_typename(typ)})UINT{typ.static_size*8}_C({val}))\n"
- case idl.Bitfield():
- ret += f"typedef {c_typename(typ.prim)} {c_typename(typ)};\n"
- names = [
- typ.bits[n] or f" {n}" for n in reversed(range(0, len(typ.bits)))
- ]
- if aliases := [k for k in typ.names if k not in typ.bits]:
- names.append("")
- names.extend(aliases)
- prefix = f"{idprefix.upper()}{typ.name.upper()}_"
- namewidth = max(len(add_prefix(prefix, name)) for name in names)
-
- ret += "\n"
- for name in names:
- if name == "":
- ret += "\n"
- continue
-
- if name.startswith(" "):
- vers = typ.in_versions
- c_name = ""
- c_val = f"1<<{name[1:]}"
- else:
- vers = typ.names[name].in_versions
- c_name = add_prefix(prefix, name)
- c_val = f"{typ.names[name].val}"
-
- ret += ifdef_push(2, c_ver_ifdef(vers))
-
- # It is important all of the `beg` strings have
- # the same length.
- end = ""
- if name.startswith(" "):
- beg = "/* unused"
- end = " */"
- elif _ifdef_stack[-1]:
- beg = "# define"
- else:
- beg = "#define "
-
- ret += f"{beg} {c_name.ljust(namewidth)} (({c_typename(typ)})({c_val})){end}\n"
- ret += ifdef_pop(1)
- case idl.Struct(): # and idl.Message():
- ret += c_typename(typ) + " {"
- if not typ.members:
- ret += "};\n"
- continue
- ret += "\n"
-
- typewidth = max(len(c_typename(m.typ, m)) for m in typ.members)
-
- for member in typ.members:
- if member.val:
- continue
- ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
- ret += f"\t{c_typename(member.typ, member).ljust(typewidth)} {'*' if member.cnt else ' '}{member.name};\n"
- ret += ifdef_pop(1)
- ret += "};\n"
- ret += ifdef_pop(0)
-
- ret += """
-/* containers *****************************************************************/
-"""
- ret += "\n"
- ret += f"#define _{idprefix.upper()}MAX(a, b) ((a) > (b)) ? (a) : (b)\n"
-
- tmsg_max_iov: dict[str, int] = {}
- tmsg_max_copy: dict[str, int] = {}
- rmsg_max_iov: dict[str, int] = {}
- rmsg_max_copy: dict[str, int] = {}
- for typ in typs:
- if not isinstance(typ, idl.Message):
- continue
- if typ.name in ("Tsread", "Tswrite"): # SPECIAL (9P2000.e)
- continue
- max_iov = tmsg_max_iov if typ.msgid % 2 == 0 else rmsg_max_iov
- max_copy = tmsg_max_copy if typ.msgid % 2 == 0 else rmsg_max_copy
- for version in typ.in_versions:
- if version not in max_iov:
- max_iov[version] = 0
- max_copy[version] = 0
- sz = get_buffer_size(typ, version)
- if sz.max_iov > max_iov[version]:
- max_iov[version] = sz.max_iov
- if sz.max_copy > max_copy[version]:
- max_copy[version] = sz.max_copy
-
- for name, table in [
- ("tmsg_max_iov", tmsg_max_iov),
- ("tmsg_max_copy", tmsg_max_copy),
- ("rmsg_max_iov", rmsg_max_iov),
- ("rmsg_max_copy", rmsg_max_copy),
- ]:
- inv: dict[int, set[str]] = {}
- for version, maxval in table.items():
- if maxval not in inv:
- inv[maxval] = set()
- inv[maxval].add(version)
-
- ret += "\n"
- directive = "if"
- seen_e = False # SPECIAL (9P2000.e)
- for maxval in sorted(inv, reverse=True):
- ret += f"#{directive} {c_ver_ifdef(inv[maxval])}\n"
- indent = 1
- if name.startswith("tmsg") and not seen_e: # SPECIAL (9P2000.e)
- typ = next(typ for typ in typs if typ.name == "Tswrite")
- sz = get_buffer_size(typ, "9P2000.e")
- match name:
- case "tmsg_max_iov":
- maxexpr = f"{sz.max_iov}{sz.max_iov_extra}"
- case "tmsg_max_copy":
- maxexpr = f"{sz.max_copy}{sz.max_copy_extra}"
- case _:
- assert False
- ret += f"\t#if {c_ver_ifdef({"9P2000.e"})}\n"
- ret += f"\t\t#define {idprefix.upper()}{name.upper()} _{idprefix.upper()}MAX({maxval}, {maxexpr})\n"
- ret += f"\t#else\n"
- indent += 1
- ret += f"{'\t'*indent}#define {idprefix.upper()}{name.upper()} {maxval}\n"
- if name.startswith("tmsg") and not seen_e: # SPECIAL (9P2000.e)
- ret += "\t#endif\n"
- if "9P2000.e" in inv[maxval]:
- seen_e = True
- directive = "elif"
- ret += "#endif\n"
-
- ret += "\n"
- ret += f"struct {idprefix}Tmsg_send_buf {{\n"
- ret += f"\tsize_t iov_cnt;\n"
- ret += f"\tstruct iovec iov[{idprefix.upper()}TMSG_MAX_IOV];\n"
- ret += f"\tuint8_t copied[{idprefix.upper()}TMSG_MAX_COPY];\n"
- ret += "};\n"
-
- ret += "\n"
- ret += f"struct {idprefix}Rmsg_send_buf {{\n"
- ret += f"\tsize_t iov_cnt;\n"
- ret += f"\tstruct iovec iov[{idprefix.upper()}RMSG_MAX_IOV];\n"
- ret += f"\tuint8_t copied[{idprefix.upper()}RMSG_MAX_COPY];\n"
- ret += "};\n"
-
- return ret
-
-
-# Generate .c ##################################################################
-
-
-def gen_c(versions: set[str], typs: list[idl.Type]) -> str:
- global _ifdef_stack
- _ifdef_stack = []
-
- ret = f"""/* Generated by `{' '.join(sys.argv)}`. DO NOT EDIT! */
-
-#include <stdbool.h>
-#include <stddef.h> /* for size_t */
-#include <inttypes.h> /* for PRI* macros */
-#include <string.h> /* for memset() */
-
-#include <libmisc/assert.h>
-
-#include <lib9p/9p.h>
-
-#include "internal.h"
-"""
-
- # utilities ################################################################
- ret += f"""
-/* utilities ******************************************************************/
-"""
-
- def used(arg: str) -> str:
- return arg
-
- def unused(arg: str) -> str:
- return f"LM_UNUSED({arg})"
-
- id2typ: dict[int, idl.Message] = {}
- for msg in [msg for msg in typs if isinstance(msg, idl.Message)]:
- id2typ[msg.msgid] = msg
-
- def msg_table(grp: str, meth: str, tentry: str, rng: tuple[int, int, int]) -> str:
- ret = f"const {tentry} _{idprefix}table_{grp}_{meth}[{c_ver_enum('NUM')}][{hex(len(range(*rng)))}] = {{\n"
- for ver in ["unknown", *sorted(versions)]:
- if ver != "unknown":
- ret += ifdef_push(1, c_ver_ifdef({ver}))
- ret += f"\t[{c_ver_enum(ver)}] = {{\n"
- for n in range(*rng):
- xmsg: idl.Message | None = id2typ.get(n, None)
- if xmsg:
- if ver == "unknown": # SPECIAL (initialization)
- if xmsg.name not in ["Tversion", "Rversion", "Rerror"]:
- xmsg = None
- else:
- if ver not in xmsg.in_versions:
- xmsg = None
- if xmsg:
- ret += f"\t\t_MSG_{meth.upper()}({xmsg.name}),\n"
- ret += "\t},\n"
- ret += ifdef_pop(0)
- ret += "};\n"
- return ret
-
- for v in sorted(versions):
- ret += f"#if CONFIG_9P_ENABLE_{v.replace('.', '_')}\n"
- ret += f"\t#define _is_ver_{v.replace('.', '_')}(v) (v == {c_ver_enum(v)})\n"
- ret += "#else\n"
- ret += f"\t#define _is_ver_{v.replace('.', '_')}(v) false\n"
- ret += "#endif\n"
- ret += "\n"
- ret += "/**\n"
- ret += f" * is_ver(ctx, ver) is essentially `(ctx->ctx->version == {idprefix.upper()}VER_##ver)`,\n"
- ret += f" * but compiles correctly (to `false`) even if `{idprefix.upper()}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"
-
- # strings ##################################################################
- ret += f"""
-/* strings ********************************************************************/
-
-const char *const _{idprefix}table_ver_name[{c_ver_enum('NUM')}] = {{
-"""
- for ver in ["unknown", *sorted(versions)]:
- if ver in versions:
- ret += ifdef_push(1, c_ver_ifdef({ver}))
- ret += f'\t[{c_ver_enum(ver)}] = "{ver}",\n'
- ret += ifdef_pop(0)
- ret += "};\n"
-
- ret += "\n"
- ret += f"#define _MSG_NAME(typ) [{idprefix.upper()}TYP_##typ] = #typ\n"
- ret += msg_table("msg", "name", "char *const", (0, 0x100, 1))
-
- # bitmasks #################################################################
- ret += f"""
-/* bitmasks *******************************************************************/
-"""
- for typ in typs:
- if not isinstance(typ, idl.Bitfield):
- continue
- ret += "\n"
- ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
- ret += f"static const {c_typename(typ)} {typ.name}_masks[{c_ver_enum('NUM')}] = {{\n"
- verwidth = max(len(ver) for ver in versions)
- for ver in sorted(versions):
- ret += ifdef_push(2, c_ver_ifdef({ver}))
- ret += (
- f"\t[{c_ver_enum(ver)}]{' '*(verwidth-len(ver))} = 0b"
- + "".join(
- "1" if typ.bit_is_valid(bitname, ver) else "0"
- for bitname in reversed(typ.bits)
- )
- + ",\n"
- )
- ret += ifdef_pop(1)
- ret += "};\n"
- ret += ifdef_pop(0)
-
- # validate_* ###############################################################
- 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); }
-"""
- for typ in topo_sorted(typs):
- inline = "LM_FLATTEN" if isinstance(typ, idl.Message) else "LM_ALWAYS_INLINE"
- argfn = unused if (isinstance(typ, idl.Struct) and not typ.members) else used
- ret += "\n"
- ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
- ret += f"{inline} static bool validate_{typ.name}(struct _validate_ctx *{argfn('ctx')}) {{\n"
-
- match typ:
- case idl.Number():
- ret += f"\treturn validate_{typ.prim.name}(ctx);\n"
- case idl.Bitfield():
- ret += f"\t if (validate_{typ.static_size}(ctx))\n"
- ret += "\t\treturn true;\n"
- ret += (
- f"\t{c_typename(typ)} mask = {typ.name}_masks[ctx->ctx->version];\n"
- )
- if typ.static_size == 1:
- ret += f"\t{c_typename(typ)} val = ctx->net_bytes[ctx->net_offset-1];\n"
- else:
- ret += f"\t{c_typename(typ)} val = uint{typ.static_size*8}le_decode(&ctx->net_bytes[ctx->net_offset-{typ.static_size}]);\n"
- ret += f"\tif (val & ~mask)\n"
- ret += f'\t\treturn lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in {typ.name} 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
-
- def should_save_value(member: idl.StructMember) -> bool:
- nonlocal typ
- assert isinstance(typ, idl.Struct)
- return bool(
- member.max
- or member.val
- or any(m.cnt == member for m in typ.members)
- )
-
- # Pass 1 - declare value variables
- for member in typ.members:
- if should_save_value(member):
- ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
- ret += f"\t{c_typename(member.typ)} {member.name};\n"
- ret += 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.name.startswith("&"):
- if tok.name[1:] not in mark_offset:
- ret += f"\tuint32_t _{tok.name[1:]}_offset;\n"
- mark_offset.add(tok.name[1:])
-
- # Pass 3 - main pass
- ret += "\treturn false\n"
- for member in typ.members:
- ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
- ret += f"\t || "
- if member.in_versions != typ.in_versions:
- ret += "( " + c_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.name})"
- else:
- ret += f"_validate_list(ctx, {member.cnt.name}, validate_{member.typ.name}, sizeof({c_typename(member.typ)}))"
- if typ.name == "s": # SPECIAL (string)
- ret += f'\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(member):
- ret += "("
- if member.name in mark_offset:
- ret += f"({{ _{member.name}_offset = ctx->net_offset; "
- ret += f"validate_{member.typ.name}(ctx)"
- if member.name in mark_offset:
- ret += "; })"
- if should_save_value(member):
- nbytes = member.static_size
- assert nbytes
- if nbytes == 1:
- ret += f" || ({{ {member.name} = ctx->net_bytes[ctx->net_offset-1]; false; }}))"
- else:
- ret += f" || ({{ {member.name} = 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 += ifdef_push(2, c_ver_ifdef(member.in_versions))
- ret += f"\t || ({{ uint{nbits}_t max = {c_expr(member.max, lookup_sym)}; (((uint{nbits}_t){member.name}) > max) &&\n"
- ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value is too large (%"PRIu{nbits}" > %"PRIu{nbits}")", {member.name}, max); }})\n'
- if member.val:
- assert member.static_size
- nbits = member.static_size * 8
- ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
- ret += f"\t || ({{ uint{nbits}_t exp = {c_expr(member.val, lookup_sym)}; (((uint{nbits}_t){member.name}) != exp) &&\n"
- ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value is wrong (actual:%"PRIu{nbits}" != correct:%"PRIu{nbits}")", (uint{nbits}_t){member.name}, exp); }})\n'
-
- ret += ifdef_pop(1)
- ret += "\t ;\n"
- ret += "}\n"
- ret += ifdef_pop(0)
-
- # unmarshal_* ##############################################################
- 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 topo_sorted(typs):
- inline = "LM_FLATTEN" if isinstance(typ, idl.Message) else "LM_ALWAYS_INLINE"
- argfn = unused if (isinstance(typ, idl.Struct) and not typ.members) else used
- ret += "\n"
- ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
- ret += f"{inline} static void unmarshal_{typ.name}(struct _unmarshal_ctx *{argfn('ctx')}, {c_typename(typ)} *out) {{\n"
- match typ:
- case idl.Number():
- ret += f"\tunmarshal_{typ.prim.name}(ctx, ({c_typename(typ.prim)} *)out);\n"
- case idl.Bitfield():
- ret += f"\tunmarshal_{typ.prim.name}(ctx, ({c_typename(typ.prim)} *)out);\n"
- case idl.Struct():
- ret += "\tmemset(out, 0, sizeof(*out));\n"
-
- for member in typ.members:
- ret += ifdef_push(2, c_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 ( " + c_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.name} = (char *)&ctx->net_bytes[ctx->net_offset];\n"
- ret += (
- f"{prefix}ctx->net_offset += out->{member.cnt.name};\n"
- )
- else:
- ret += f"out->{member.name} = ctx->extra;\n"
- ret += f"{prefix}ctx->extra += sizeof(out->{member.name}[0]) * out->{member.cnt.name};\n"
- ret += f"{prefix}for (typeof(out->{member.cnt.name}) i = 0; i < out->{member.cnt.name}; i++)\n"
- ret += f"{prefix}\tunmarshal_{member.typ.name}(ctx, &out->{member.name}[i]);\n"
- if member.in_versions != typ.in_versions:
- ret += "\t}\n"
- else:
- ret += (
- f"unmarshal_{member.typ.name}(ctx, &out->{member.name});\n"
- )
- ret += ifdef_pop(1)
- ret += "}\n"
- ret += ifdef_pop(0)
-
- # marshal_* ################################################################
- ret += """
-/* marshal_* ******************************************************************/
-
-"""
- ret += c_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"
- )
- ret += c_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"
- )
- ret += c_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"
- )
- ret += c_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"
- )
- ret += c_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"
- )
- ret += c_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"
- )
-
- class OffsetExpr:
- static: int
- cond: dict[frozenset[str], "OffsetExpr"]
- rep: list[tuple[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 ({c_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 += ifdef_push(indent_depth + 1, c_ver_ifdef(vers))
- multiline += f"{'\t'*indent_depth}if {c_ver_cond(vers)} {{\n"
- multiline += sub.gen_c("", dstvar, root, indent_depth + 1, loop_depth)
- multiline += f"{'\t'*indent_depth}}}\n"
- multiline += 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[[Path], WalkCmd]
-
- def get_offset_expr(typ: idl.Type, 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[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: Path) -> tuple[WalkCmd, typing.Callable[[], None] | None]:
- nonlocal recurse
-
- ret = recurse(path)
- if ret != 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 = [(Path(typ), OffsetExpr(), pop_root)]
- walk(typ, handle)
- return stack[0][1]
-
- def go_to_end(path: Path) -> WalkCmd:
- return WalkCmd.KEEP_GOING
-
- def go_to_tok(name: str) -> typing.Callable[[Path], WalkCmd]:
- def ret(path: Path) -> WalkCmd:
- if len(path.elems) == 1 and path.elems[0].name == name:
- return WalkCmd.ABORT
- return WalkCmd.KEEP_GOING
-
- return ret
-
- for typ in typs:
- if not (
- isinstance(typ, idl.Message) or typ.name == "stat"
- ): # SPECIAL (include stat)
- continue
- assert isinstance(typ, idl.Struct)
- ret += "\n"
- ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
- ret += f"static bool marshal_{typ.name}(struct _marshal_ctx *ctx, {c_typename(typ)} *val) {{\n"
-
- # Pass 1 - check size
- max_size = max(typ.max_size(v) for v in typ.in_versions)
-
- if max_size > u32max: # SPECIAL (9P2000.e)
- 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"
- 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"
- if isinstance(typ, idl.Message): # SPECIAL (disable for stat)
- ret += f'\t\tlib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",\n'
- ret += f'\t\t\t"{typ.name}",\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 += "\t\treturn true;\n"
- ret += "\t}\n"
-
- # Pass 2 - write data
- ifdef_depth = 1
- stack: list[tuple[Path, bool]] = [(Path(typ), False)]
-
- def handle(path: Path) -> tuple[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 += 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.name == "end" or tok.name.startswith("&"):
- if tok.name not in offsets:
- offsets.append(tok.name)
- for name in offsets:
- name_prefix = "offsetof_" + "".join(
- m.name + "_" for m in path.elems
- )
- if name == "end":
- if not path.elems:
- nonlocal max_size
- if max_size > u32max:
- 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 += ifdef_push(ifdef_depth + 1, c_ver_ifdef(child.in_versions))
- ifdef_depth += 1
- ret += f"{'\t'*len(stack)}if ({c_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.name == "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 WalkCmd.KEEP_GOING, pop
- loopvar = chr(ord("i") + loopdepth - 1)
- ret += f"{'\t'*len(stack)}for ({c_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.name + "_" for m in path.elems[:-1])
- + sym
- )
-
- val = c_expr(child.val, lookup_sym)
- else:
- val = path.c_str("val->")
- if isinstance(child.typ, idl.Bitfield):
- val += f" & {child.typ.name}_masks[ctx->ctx->version]"
- ret += f"{'\t'*len(stack)}MARSHAL_U{child.typ.static_size*8}LE(ctx, {val});\n"
- return WalkCmd.KEEP_GOING, pop
-
- walk(typ, handle)
-
- ret += "\treturn false;\n"
- ret += "}\n"
- ret += ifdef_pop(0)
-
- # function tables ##########################################################
- ret += """
-/* function tables ************************************************************/
-"""
-
- ret += "\n"
- ret += f"const uint32_t _{idprefix}table_msg_min_size[{c_ver_enum('NUM')}] = {{\n"
- rerror = next(typ for typ in typs if typ.name == "Rerror")
- ret += f"\t[{c_ver_enum('unknown')}] = {rerror.min_size('9P2000')},\n" # SPECIAL (initialization)
- for ver in sorted(versions):
- ret += ifdef_push(1, c_ver_ifdef({ver}))
- ret += f"\t[{c_ver_enum(ver)}] = {rerror.min_size(ver)},\n"
- ret += ifdef_pop(0)
- ret += "};\n"
-
- ret += "\n"
- ret += c_macro(
- f"#define _MSG_RECV(typ) [{idprefix.upper()}TYP_##typ/2] = {{\n"
- f"\t\t.basesize = sizeof(struct {idprefix}msg_##typ),\n"
- f"\t\t.validate = validate_##typ,\n"
- f"\t\t.unmarshal = (_unmarshal_fn_t)unmarshal_##typ,\n"
- f"\t}}\n"
- )
- ret += c_macro(
- f"#define _MSG_SEND(typ) [{idprefix.upper()}TYP_##typ/2] = {{\n"
- f"\t\t.marshal = (_marshal_fn_t)marshal_##typ,\n"
- f"\t}}\n"
- )
- ret += "\n"
- ret += msg_table("Tmsg", "recv", f"struct _{idprefix}recv_tentry", (0, 0x100, 2))
- ret += "\n"
- ret += msg_table("Rmsg", "recv", f"struct _{idprefix}recv_tentry", (1, 0x100, 2))
- ret += "\n"
- ret += msg_table("Tmsg", "send", f"struct _{idprefix}send_tentry", (0, 0x100, 2))
- ret += "\n"
- ret += msg_table("Rmsg", "send", f"struct _{idprefix}send_tentry", (1, 0x100, 2))
-
- ret += f"""
-LM_FLATTEN bool _{idprefix}stat_validate(struct _validate_ctx *ctx) {{
-\treturn validate_stat(ctx);
-}}
-LM_FLATTEN void _{idprefix}stat_unmarshal(struct _unmarshal_ctx *ctx, struct {idprefix}stat *out) {{
-\tunmarshal_stat(ctx, out);
-}}
-LM_FLATTEN bool _{idprefix}stat_marshal(struct _marshal_ctx *ctx, struct {idprefix}stat *val) {{
-\treturn marshal_stat(ctx, val);
-}}
-"""
-
- ############################################################################
- return ret
-
-
-# Main #########################################################################
-
-
-if __name__ == "__main__":
- import sys
-
- if typing.TYPE_CHECKING:
-
- class ANSIColors:
- MAGENTA = "\x1b[35m"
- RED = "\x1b[31m"
- RESET = "\x1b[0m"
-
- else:
- from _colorize import ANSIColors # Present in Python 3.13+
-
- if len(sys.argv) < 2:
- raise ValueError("requires at least 1 .9p filename")
- parser = idl.Parser()
- for txtname in sys.argv[1:]:
- try:
- parser.parse_file(txtname)
- except SyntaxError as e:
- print(
- f"{ANSIColors.RED}{e.filename}{ANSIColors.RESET}:{ANSIColors.MAGENTA}{e.lineno}{ANSIColors.RESET}: {e.msg}",
- file=sys.stderr,
- )
- assert e.text
- print(f"\t{e.text}", file=sys.stderr)
- print(
- f"\t{ANSIColors.RED}{'~'*len(e.text)}{ANSIColors.RESET}",
- file=sys.stderr,
- )
- sys.exit(2)
- versions, typs = parser.all()
- outdir = os.path.normpath(os.path.join(sys.argv[0], ".."))
- with open(os.path.join(outdir, "include/lib9p/9p.generated.h"), "w") as fh:
- fh.write(gen_h(versions, typs))
- with open(os.path.join(outdir, "9p.generated.c"), "w") as fh:
- fh.write(gen_c(versions, typs))
diff --git a/lib9p/idl/0000-README.md b/lib9p/idl/0000-README.md
index 036de22..e19a1e8 100644
--- a/lib9p/idl/0000-README.md
+++ b/lib9p/idl/0000-README.md
@@ -41,6 +41,11 @@ and messages (which are a special-case of structures).
msg Tname = "size[4,val=end-&size] typ[1,val=TYP] tag[tag] REST..."
+Bitfield bit names may be wrapped in `reserved(...)` or
+`subfield(...)`; reserved indicates that the bit is named but is not
+allowed to be used, and subfield indicates that the bit is part of a
+num/enum that is handled by an alias.
+
Struct fields that have numeric types (either primitives or `num`
types) can add to their type `,val=` and/or `,max=` to specify what
the exact value must be and/or what the maximum (inclusive) value is.
diff --git a/lib9p/idl/0000-TODO.md b/lib9p/idl/0000-TODO.md
index d196ac9..81cafe5 100644
--- a/lib9p/idl/0000-TODO.md
+++ b/lib9p/idl/0000-TODO.md
@@ -1,6 +1,6 @@
<!--
lib9p/idl/0000-TODO.md - Changes I intend to make to idl/__init__.py
- and idl.gen
+ and proto.gen
Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib9p/idl/2002-9P2000.9p b/lib9p/idl/2002-9P2000.9p
index 438e02f..2a4f7ed 100644
--- a/lib9p/idl/2002-9P2000.9p
+++ b/lib9p/idl/2002-9P2000.9p
@@ -42,7 +42,7 @@ bitfield dm = 4
# that the file is mounted by the kernel as a 9P transport;
# that the kernel has a lock on doing I/O on it, so userspace
# can't do I/O on it.
- "28=_PLAN9_MOUNT"
+ "28=reserved(PLAN9_MOUNT)"
"27=AUTH"
"26=TMP"
#...
@@ -63,7 +63,7 @@ bitfield qt = 1
"7=DIR"
"6=APPEND"
"5=EXCL"
- "4=_PLAN9_MOUNT" # See "_PLAN9_MOUNT" in "dm" above.
+ "4=reserved(PLAN9_MOUNT)" # See "PLAN9_MOUNT" in "dm" above.
"3=AUTH"
# Fun historical fact: QTTMP was a relatively late addition to
# Plan 9, in 2003-12.
@@ -107,12 +107,12 @@ struct stat = "stat_size[2,val=end-&kern_type]"
# "O"pen flags (flags to pass to Topen and Tcreate)
# Unused bits *must* be 0.
bitfield o = 1
- "0=mode_0" # low bit of the 2-bit READ/WRITE/RDWR/EXEC enum
- "1=mode_1" # high bit of the 2-bit READ/WRITE/RDWR/EXEC enum
+ "0=subfield(mode)" # low bit of the 2-bit READ/WRITE/RDWR/EXEC enum
+ "1=subfield(mode)" # high bit of the 2-bit READ/WRITE/RDWR/EXEC enum
#"2=unused"
#"3=unused"
"4=TRUNC"
- #"5=_reserved_CEXEC" # close-on-exec
+ "5=reserved(CEXEC)" # close-on-exec
"6=RCLOSE" # remove-on-close
#"7=unused"
diff --git a/lib9p/idl/2005-9P2000.u.9p b/lib9p/idl/2005-9P2000.u.9p
index d96bbce..fefe3e9 100644
--- a/lib9p/idl/2005-9P2000.u.9p
+++ b/lib9p/idl/2005-9P2000.u.9p
@@ -14,6 +14,9 @@ from ./2002-9P2000.9p import *
num nuid = 4
"NONUID = ~0"
+num errno = 4
+ "NOERROR = 0"
+
struct stat += "file_extension[s]"
"file_owner_n_uid[nuid]"
"file_owner_n_gid[nuid]"
@@ -22,7 +25,7 @@ struct stat += "file_extension[s]"
msg Tauth += "n_uid[nuid]"
msg Tattach += "n_uid[nuid]"
-msg Rerror += "errno[4]"
+msg Rerror += "errno[errno]"
bitfield dm += "23=DEVICE"
"21=NAMEDPIPE"
diff --git a/lib9p/idl/2010-9P2000.L.9p b/lib9p/idl/2010-9P2000.L.9p
index e21d411..7ac86a6 100644
--- a/lib9p/idl/2010-9P2000.L.9p
+++ b/lib9p/idl/2010-9P2000.L.9p
@@ -5,82 +5,206 @@
# "9P2000.L" Linux extension
# https://github.com/chaos/diod/blob/master/protocol.md
+# https://github.com/chaos/diod/blob/master/src/libnpfs/protocol.h
version "9P2000.L"
from ./2002-9P2000.9p import tag, fid, s, qt, qid
from ./2002-9P2000.9p import Rerror
from ./2002-9P2000.9p import Tversion, Rversion, Tflush, Rflush, Twalk, Rwalk, Tread, Rread, Twrite, Rwrite, Tclunk, Rclunk, Tremove, Rremove
-from ./2005-9P2000.u.9p import nuid, Tauth, Rauth, Tattach, Rattach
+from ./2005-9P2000.u.9p import nuid, errno, Tauth, Rauth, Tattach, Rattach
+
+#num errno += # TODO
+
+num super_magic = 4
+ # See <linux/magic.h> (linux.git include/uapi/linux/magic.h).
+ #
+ # To quote `util-linux.git:include/statfs_magic.h`:
+ # "Unfortunately, Linux kernel header file <linux/magic.h> is
+ # incomplete mess and kernel returns by statfs f_type many numbers
+ # that are nowhere specified (in API)."
+ #
+ # util-linux <statfs_magic.h> is also incomplete. As is the
+ # statfs(2) man-page.
+ #
+ # I'm working on a patchset to the kernel to get <linux/magic.h>
+ # to be complete, but in the mean-time I'm just not going to
+ # bother with putting a list here.
+ #
+ # TODO
+ "V9FS_MAGIC=0x01021997"
+
+# "L"inux "O"pen flags (flags to pass to Tlopen and Tlcreate)
+#
+# The values are not specified in in protocol.md, but are specified in
+# protocol.h (and are different than the Linux kernel's values, which
+# vary by architecture).
+bitfield lo = 4
+ "0=subfield(mode)" # low bit of the 2-bit RDONLY/WRONLY/RDWR/NOACCESS enum
+ "1=subfield(mode)" # high bit of the 2-bit RDONLY/WRONLY/RDWR/NOACCESS enum
+ #"2=unused"
+ #"3=unused"
+ #"4=unused"
+ #"5=unused"
+ "6=CREATE"
+ "7=EXCL"
+ "8=NOCTTY"
+ "9=TRUNC"
+ "10=APPEND"
+ "11=NONBLOCK"
+ "12=DSYNC"
+ "13=BSD_FASYNC"
+ "14=DIRECT"
+ "15=LARGEFILE"
+ "16=DIRECTORY"
+ "17=NOFOLLOW"
+ "18=NOATIME"
+ "19=CLOEXEC"
+ "20=SYNC"
+
+ "RDONLY = 0"
+ "WRONLY = 1"
+ "RDWR = 2"
+ "NOACCESS = 3"
+
+ "MODE_MASK = 0b000000000000000000011"
+ "FLAG_MASK = 0b111111111111111000000"
+
+# "D"irentry "T"ype
+#
+# These match the Linux kernel's values.
+num dt = 1
+ "UNKNOWN = 0"
+ "NAMED_PIPE = 1"
+ "CHAR_DEV = 2"
+ "DIRECTORY = 4"
+ "BLOCK_DEV = 6"
+ "REGULAR = 8"
+ "SYMLINK = 10"
+ "SOCKET = 12"
+ "WHITEOUT = 14"
+
+# Mode
+#
+# These match the Linux kernel's values. Why is this 32-bits wide
+# instead of just 16? Who knows?
+bitfield mode = 4
+ #...
+ "15=subfield(fmt)" # bit of the 4-bit FMT_ enum
+ "14=subfield(fmt)" # bit of the 4-bit FMT_ enum
+ "13=subfield(fmt)" # bit of the 4-bit FMT_ enum
+ "12=subfield(fmt)" # bit of the 4-bit FMT_ enum
+ #...
+ "11=PERM_SETGROUP"
+ "10=PERM_SETUSER"
+ "9=PERM_STICKY"
+ "8=PERM_OWNER_R"
+ "7=PERM_OWNER_W"
+ "6=PERM_OWNER_X"
+ "5=PERM_GROUP_R"
+ "4=PERM_GROUP_W"
+ "3=PERM_GROUP_X"
+ "2=PERM_OTHER_R"
+ "1=PERM_OTHER_W"
+ "0=PERM_OTHER_X"
+
+ "FMT_NAMED_PIPE = LIB9P_DT_NAMED_PIPE<<12"
+ "FMT_CHAR_DEV = LIB9P_DT_CHAR_DEV<<12"
+ "FMT_DIRECTORY = LIB9P_DT_DIRECTORY<<12"
+ "FMT_BLOCK_DEV = LIB9P_DT_BLOCK_DEV<<12"
+ "FMT_REGULAR = LIB9P_DT_REGULAR<<12"
+ "FMT_SYMLINK = LIB9P_DT_SYMLINK<<12"
+ "FMT_SOCKET = LIB9P_DT_SOCKET<<12"
+
+ "PERM_MASK = 0000777" # PERM_*
+ "FMT_MASK = 0170000" # _fmt_*
+
+# A boolean value that is for some reason 4 bytes wide.
+num b4 = 4
+ "FALSE=0"
+ "TRUE=1"
+ # all other values are true also
bitfield getattr = 8
- "0=MODE"
- "1=NLINK"
- "2=UID"
- "3=GID"
- "4=RDEV"
- "5=ATIME"
- "6=MTIME"
- "7=CTIME"
- "8=INO"
- "9=SIZE"
- "10=BLOCKS"
-
- "11=BTIME"
- "12=GEN"
- "13=DATA_VERSION"
-
- "BASIC=0x000007ff" # Mask for fields up to BLOCKS
- "ALL =0x00003fff" # Mask for All fields above
+ "0=MODE"
+ "1=NLINK"
+ "2=UID"
+ "3=GID"
+ "4=RDEV"
+ "5=ATIME"
+ "6=MTIME"
+ "7=CTIME"
+ "8=INO"
+ "9=SIZE"
+ "10=BLOCKS"
+
+ "11=BTIME"
+ "12=GEN"
+ "13=DATA_VERSION"
+
+ "BASIC=0x000007ff" # Mask for fields up to BLOCKS
+ "ALL =0x00003fff" # Mask for All fields above
bitfield setattr = 4
- "0=MODE"
- "1=UID"
- "2=GID"
- "3=SIZE"
- "4=ATIME"
- "5=MTIME"
- "6=CTIME"
- "7=ATIME_SET"
- "8=MTIME_SET"
+ "0=MODE"
+ "1=UID"
+ "2=GID"
+ "3=SIZE"
+ "4=ATIME"
+ "5=MTIME"
+ "6=CTIME"
+ "7=ATIME_SET"
+ "8=MTIME_SET"
num lock_type = 1
- "RDLCK=0"
- "WRLCK=1"
- "UNLCK=2"
+ "RDLCK=0"
+ "WRLCK=1"
+ "UNLCK=2"
bitfield lock_flags = 4
- "0=BLOCK"
- "1=RECLAIM"
+ "0=BLOCK"
+ "1=RECLAIM"
num lock_status = 1
- "SUCCESS=0"
- "BLOCKED=1"
- "ERROR=2"
- "GRACE=3"
+ "SUCCESS=0"
+ "BLOCKED=1"
+ "ERROR=2"
+ "GRACE=3"
#msg Tlerror = "size[4,val=end-&size] typ[1,val=6] tag[tag] illegal" # analogous to 106/Terror
-msg Rlerror = "size[4,val=end-&size] typ[1,val=7] tag[tag] ecode[4]" # analogous to 107/Rerror
+msg Rlerror = "size[4,val=end-&size] typ[1,val=7] tag[tag] ecode[errno]" # analogous to 107/Rerror
msg Tstatfs = "size[4,val=end-&size] typ[1,val=8] tag[tag] fid[fid]"
-msg Rstatfs = "size[4,val=end-&size] typ[1,val=9] tag[tag] type[4] bsize[4] blocks[8] bfree[8] bavail[8] files[8] ffree[8] fsid[8] namelen[4]"
-msg Tlopen = "size[4,val=end-&size] typ[1,val=12] tag[tag] fid[fid] flags[4]" # analogous to 112/Topen
+msg Rstatfs = "size[4,val=end-&size] typ[1,val=9] tag[tag]" # Description | statfs | statvfs
+ "type[super_magic]" # Type of filesystem | f_type | -
+ "bsize[4]" # Block size in bytes | f_bsize | f_bsize
+ # - # Fragment size in bytes | f_frsize (since Linux 2.6) | f_frsize
+ "blocks[8]" # Size of FS in f_frsize units | f_blocks | f_blocks
+ "bfree[8]" # Number of free blocks | f_bfree | f_bfree
+ "bavail[8]" # Number of free blocks for unprivileged users | f_bavail | b_avail
+ "files[8]" # Number of inodes | f_files | f_files
+ "ffree[8]" # Number of free inodes | f_ffree | f_ffree
+ # - # Number of free inodes for unprivileged users | - | f_favail
+ "fsid[8]" # Filesystem instance ID | f_fsid | f_fsid
+ # - # Mount flags | f_flags (since Linux 2.6.36) | f_flag
+ "namelen[4]" # Maximum filename length | f_namemax | f_namemax
+msg Tlopen = "size[4,val=end-&size] typ[1,val=12] tag[tag] fid[fid] flags[lo]" # analogous to 112/Topen
msg Rlopen = "size[4,val=end-&size] typ[1,val=13] tag[tag] qid[qid] iounit[4]" # analogous to 113/Ropen
-msg Tlcreate = "size[4,val=end-&size] typ[1,val=14] tag[tag] fid[fid] name[s] flags[4] mode[4] gid[nuid]" # analogous to 114/Tcreate
+msg Tlcreate = "size[4,val=end-&size] typ[1,val=14] tag[tag] fid[fid] name[s] flags[lo] mode[mode] gid[nuid]" # analogous to 114/Tcreate
msg Rlcreate = "size[4,val=end-&size] typ[1,val=15] tag[tag] qid[qid] iounit[4]" # analogous to 115/Rcreate
msg Tsymlink = "size[4,val=end-&size] typ[1,val=16] tag[tag] fid[fid] name[s] symtgt[s] gid[nuid]"
msg Rsymlink = "size[4,val=end-&size] typ[1,val=17] tag[tag] qid[qid]"
-msg Tmknod = "size[4,val=end-&size] typ[1,val=18] tag[tag] dfid[fid] name[s] mode[4] major[4] minor[4] gid[nuid]"
+msg Tmknod = "size[4,val=end-&size] typ[1,val=18] tag[tag] dfid[fid] name[s] mode[mode] major[4] minor[4] gid[nuid]"
msg Rmknod = "size[4,val=end-&size] typ[1,val=19] tag[tag] qid[qid]"
msg Trename = "size[4,val=end-&size] typ[1,val=20] tag[tag] fid[fid] dfid[fid] name[s]"
msg Rrename = "size[4,val=end-&size] typ[1,val=21] tag[tag]"
msg Treadlink = "size[4,val=end-&size] typ[1,val=22] tag[tag] fid[fid]"
msg Rreadlink = "size[4,val=end-&size] typ[1,val=23] tag[tag] target[s]"
msg Tgetattr = "size[4,val=end-&size] typ[1,val=24] tag[tag] fid[fid] request_mask[getattr]"
-msg Rgetattr = "size[4,val=end-&size] typ[1,val=25] tag[tag] valid[8] qid[qid] mode[4] uid[nuid] gid[nuid] nlink[8]"
+msg Rgetattr = "size[4,val=end-&size] typ[1,val=25] tag[tag] valid[getattr] qid[qid] mode[mode] uid[nuid] gid[nuid] nlink[8]"
"rdev[8] filesize[8] blksize[8] blocks[8]"
"atime_sec[8] atime_nsec[8] mtime_sec[8] mtime_nsec[8]"
"ctime_sec[8] ctime_nsec[8] btime_sec[8] btime_nsec[8]"
"gen[8] data_version[8]"
-msg Tsetattr = "size[4,val=end-&size] typ[1,val=26] tag[tag] fid[fid] valid[setattr] mode[4] uid[nuid] gid[nuid] filesize[8] atime_sec[8] atime_nsec[8] mtime_sec[8] mtime_nsec[8]"
+msg Tsetattr = "size[4,val=end-&size] typ[1,val=26] tag[tag] fid[fid] valid[setattr] mode[mode] uid[nuid] gid[nuid] filesize[8] atime_sec[8] atime_nsec[8] mtime_sec[8] mtime_nsec[8]"
msg Rsetattr = "size[4,val=end-&size] typ[1,val=27] tag[tag]"
#...
msg Txattrwalk = "size[4,val=end-&size] typ[1,val=30] tag[tag] fid[fid] newfid[fid] name[s]"
@@ -89,18 +213,18 @@ msg Txattrcreate = "size[4,val=end-&size] typ[1,val=32] tag[tag] fid[fid] name[s
msg Rxattrcreate = "size[4,val=end-&size] typ[1,val=33] tag[tag]"
#...
msg Treaddir = "size[4,val=end-&size] typ[1,val=40] tag[tag] fid[fid] offset[8] count[4]"
-msg Rreaddir = "size[4,val=end-&size] typ[1,val=41] tag[tag] count[4] count*(data[1])" # data is "qid[qid] offset[8] type[1] name[s]"
+msg Rreaddir = "size[4,val=end-&size] typ[1,val=41] tag[tag] count[4] count*(data[1])" # data is "qid[qid] offset[8] type[dt] name[s]"
#...
-msg Tfsync = "size[4,val=end-&size] typ[1,val=50] tag[tag] fid[fid] datasync[4]"
+msg Tfsync = "size[4,val=end-&size] typ[1,val=50] tag[tag] fid[fid] datasync[b4]"
msg Rfsync = "size[4,val=end-&size] typ[1,val=51] tag[tag]"
msg Tlock = "size[4,val=end-&size] typ[1,val=52] tag[tag] fid[fid] type[lock_type] flags[lock_flags] start[8] length[8] proc_id[4] client_id[s]"
msg Rlock = "size[4,val=end-&size] typ[1,val=53] tag[tag] status[lock_status]"
-msg Tgetlock = "size[4,val=end-&size] typ[1,val=54] tag[tag] fid[fid] type[1] start[8] length[8] proc_id[4] client_id[s]"
-msg Rgetlock = "size[4,val=end-&size] typ[1,val=55] tag[tag] type[1] start[8] length[8] proc_id[4] client_id[s]"
+msg Tgetlock = "size[4,val=end-&size] typ[1,val=54] tag[tag] fid[fid] type[lock_type] start[8] length[8] proc_id[4] client_id[s]"
+msg Rgetlock = "size[4,val=end-&size] typ[1,val=55] tag[tag] type[lock_type] start[8] length[8] proc_id[4] client_id[s]"
# ...
msg Tlink = "size[4,val=end-&size] typ[1,val=70] tag[tag] dfid[fid] fid[fid] name[s]"
msg Rlink = "size[4,val=end-&size] typ[1,val=71] tag[tag]"
-msg Tmkdir = "size[4,val=end-&size] typ[1,val=72] tag[tag] dfid[fid] name[s] mode[4] gid[nuid]"
+msg Tmkdir = "size[4,val=end-&size] typ[1,val=72] tag[tag] dfid[fid] name[s] mode[mode] gid[nuid]"
msg Rmkdir = "size[4,val=end-&size] typ[1,val=73] tag[tag] qid[qid]"
msg Trenameat = "size[4,val=end-&size] typ[1,val=74] tag[tag] olddirfid[fid] oldname[s] newdirfid[fid] newname[s]"
msg Rrenameat = "size[4,val=end-&size] typ[1,val=75] tag[tag]"
diff --git a/lib9p/idl/__init__.py b/lib9p/idl/__init__.py
index a01c38f..e7b3670 100644
--- a/lib9p/idl/__init__.py
+++ b/lib9p/idl/__init__.py
@@ -6,8 +6,9 @@
import enum
import os.path
import re
-from typing import Callable, Literal, TypeVar, cast
+import typing
+# pylint: disable=unused-variable
__all__ = [
# entrypoint
"Parser",
@@ -15,7 +16,7 @@ __all__ = [
"Type",
"Primitive",
"Number",
- *["Bitfield", "BitfieldVal"],
+ *["Bitfield", "Bit", "BitCat", "BitAlias"],
*["Struct", "StructMember", "Expr", "ExprOp", "ExprSym", "ExprLit"],
"Message",
]
@@ -36,7 +37,7 @@ class Primitive(enum.Enum):
return set()
@property
- def name(self) -> str:
+ def typname(self) -> str:
return str(self.value)
@property
@@ -51,7 +52,7 @@ class Primitive(enum.Enum):
class Number:
- name: str
+ typname: str
in_versions: set[str]
prim: Primitive
@@ -73,27 +74,49 @@ class Number:
return self.static_size
-class BitfieldVal:
- name: str
+class BitCat(enum.Enum):
+ UNUSED = 1
+ USED = 2
+ RESERVED = 3
+ SUBFIELD = 4
+
+
+class Bit:
+ bitname: str
in_versions: set[str]
+ num: int
+ cat: BitCat
- val: str
+ def __init__(self, num: int) -> None:
+ self.bitname = ""
+ self.in_versions = set()
+ self.num = num
+ self.cat = BitCat.UNUSED
- def __init__(self) -> None:
+
+class BitAlias:
+ bitname: str
+ in_versions: set[str]
+ val: str # FIXME: Don't have bitfield aliases be raw C expressions
+
+ def __init__(self, name: str, val: str) -> None:
+ self.bitname = name
self.in_versions = set()
+ self.val = val
class Bitfield:
- name: str
+ typname: str
in_versions: set[str]
-
prim: Primitive
+ bits: list[Bit]
+ names: dict[str, Bit | BitAlias]
- bits: list[str] # bitnames
- names: dict[str, BitfieldVal] # bits *and* aliases
-
- def __init__(self) -> None:
+ def __init__(self, name: str, prim: Primitive) -> None:
+ self.typname = name
self.in_versions = set()
+ self.prim = prim
+ self.bits = [Bit(i) for i in range(prim.static_size * 8)]
self.names = {}
@property
@@ -106,21 +129,6 @@ class Bitfield:
def max_size(self, version: str) -> int:
return self.static_size
- def bit_is_valid(self, bit: str | int, ver: str | None = None) -> bool:
- """Return whether the given bit is valid in the given protocol
- version.
-
- """
- bitname = self.bits[bit] if isinstance(bit, int) else bit
- assert bitname in self.bits
- if not bitname:
- return False
- if bitname.startswith("_"):
- return False
- if ver and (ver not in self.names[bitname].in_versions):
- return False
- return True
-
class ExprLit:
val: int
@@ -130,16 +138,16 @@ class ExprLit:
class ExprSym:
- name: str
+ symname: str
def __init__(self, name: str) -> None:
- self.name = name
+ self.symname = name
class ExprOp:
- op: Literal["-", "+"]
+ op: typing.Literal["-", "+"]
- def __init__(self, op: Literal["-", "+"]) -> None:
+ def __init__(self, op: typing.Literal["-", "+"]) -> None:
self.op = op
@@ -156,7 +164,7 @@ class Expr:
class StructMember:
# from left-to-right when parsing
cnt: "StructMember | None" = None
- name: str
+ membname: str
typ: "Type"
max: Expr
val: Expr
@@ -168,10 +176,10 @@ class StructMember:
assert self.cnt
if not isinstance(self.cnt.typ, Primitive):
raise ValueError(
- f"list count must be an integer type: {repr(self.cnt.name)}"
+ f"list count must be an integer type: {self.cnt.membname!r}"
)
if self.cnt.val: # TODO: allow this?
- raise ValueError(f"list count may not have ,val=: {repr(self.cnt.name)}")
+ raise ValueError(f"list count may not have ,val=: {self.cnt.membname!r}")
return 0
@property
@@ -179,26 +187,26 @@ class StructMember:
assert self.cnt
if not isinstance(self.cnt.typ, Primitive):
raise ValueError(
- f"list count must be an integer type: {repr(self.cnt.name)}"
+ f"list count must be an integer type: {self.cnt.membname!r}"
)
if self.cnt.val: # TODO: allow this?
- raise ValueError(f"list count may not have ,val=: {repr(self.cnt.name)}")
+ raise ValueError(f"list count may not have ,val=: {self.cnt.membname!r}")
if self.cnt.max:
# TODO: be more flexible?
if len(self.cnt.max.tokens) != 1:
raise ValueError(
- f"list count ,max= may only have 1 token: {repr(self.cnt.name)}"
+ f"list count ,max= may only have 1 token: {self.cnt.membname!r}"
)
match tok := self.cnt.max.tokens[0]:
case ExprLit():
return tok.val
- case ExprSym(name="s32_max"):
+ case ExprSym(symname="s32_max"):
return (1 << 31) - 1
- case ExprSym(name="s64_max"):
+ case ExprSym(symname="s64_max"):
return (1 << 63) - 1
case _:
raise ValueError(
- f'list count ,max= only allows literal, "s32_max", and "s64_max" tokens: {repr(self.cnt.name)}'
+ f'list count ,max= only allows literal, "s32_max", and "s64_max" tokens: {self.cnt.membname!r}'
)
return (1 << (self.cnt.typ.value * 8)) - 1
@@ -218,7 +226,7 @@ class StructMember:
class Struct:
- name: str
+ typname: str
in_versions: set[str]
members: list[StructMember]
@@ -257,7 +265,7 @@ class Message(Struct):
@property
def msgid(self) -> int:
assert len(self.members) >= 3
- assert self.members[1].name == "typ"
+ assert self.members[1].membname == "typ"
assert self.members[1].static_size == 1
assert self.members[1].val
assert len(self.members[1].val.tokens) == 1
@@ -266,12 +274,15 @@ class Message(Struct):
type Type = Primitive | Number | Bitfield | Struct | Message
-T = TypeVar("T", Number, Bitfield, Struct, Message)
+type UserType = Number | Bitfield | Struct | Message
+T = typing.TypeVar("T", Number, Bitfield, Struct, Message)
# Parse ########################################################################
re_priname = "(?:1|2|4|8)" # primitive names
re_symname = "(?:[a-zA-Z_][a-zA-Z_0-9]*)" # "symbol" names; most *.9p-defined names
+re_symname_u = "(?:[A-Z_][A-Z_0-9]*)" # upper-case "symbol" names; bit names
+re_symname_l = "(?:[a-z_][a-z_0-9]*)" # lower-case "symbol" names; bit names
re_impname = r"(?:\*|" + re_symname + ")" # names we can import
re_msgname = r"(?:[TR][a-zA-Z_0-9]*)" # names a message can be
@@ -281,8 +292,18 @@ re_expr = f"(?:(?:-|\\+|[0-9]+|&?{re_symname})+)"
re_numspec = f"(?P<name>{re_symname})\\s*=\\s*(?P<val>\\S+)"
-re_bitspec_bit = f"(?P<bit>[0-9]+)\\s*=\\s*(?P<name>{re_symname})"
-re_bitspec_alias = f"(?P<name>{re_symname})\\s*=\\s*(?P<val>\\S+)"
+re_bitspec_bit = (
+ "(?P<bitnum>[0-9]+)\\s*=\\s*(?:"
+ + "|".join(
+ [
+ f"(?P<name_used>{re_symname_u})",
+ f"reserved\\((?P<name_reserved>{re_symname_u})\\)",
+ f"subfield\\((?P<name_subfield>{re_symname_l})\\)",
+ ]
+ )
+ + ")"
+)
+re_bitspec_alias = f"(?P<name>{re_symname_u})\\s*=\\s*(?P<val>\\S+)"
re_memberspec = f"(?:(?P<cnt>{re_symname})\\*\\()?(?P<name>{re_symname})\\[(?P<typ>{re_memtype})(?:,max=(?P<max>{re_expr})|,val=(?P<val>{re_expr}))*\\]\\)?"
@@ -294,55 +315,67 @@ def parse_numspec(ver: str, n: Number, spec: str) -> None:
name = m.group("name")
val = m.group("val")
if name in n.vals:
- raise ValueError(f"{n.name}: name {repr(name)} already assigned")
+ raise ValueError(f"{n.typname}: name {name!r} already assigned")
n.vals[name] = val
else:
- raise SyntaxError(f"invalid num spec {repr(spec)}")
+ raise SyntaxError(f"invalid num spec {spec!r}")
def parse_bitspec(ver: str, bf: Bitfield, spec: str) -> None:
spec = spec.strip()
- bit: int | None
- val: BitfieldVal
if m := re.fullmatch(re_bitspec_bit, spec):
- bit = int(m.group("bit"))
- name = m.group("name")
-
- val = BitfieldVal()
- val.name = name
- val.val = f"1<<{bit}"
- val.in_versions.add(ver)
-
- if bit < 0 or bit >= len(bf.bits):
- raise ValueError(f"{bf.name}: bit {bit} is out-of-bounds")
- if bf.bits[bit]:
- raise ValueError(f"{bf.name}: bit {bit} already assigned")
- bf.bits[bit] = val.name
+ bitnum = int(m.group("bitnum"))
+ if bitnum < 0 or bitnum >= len(bf.bits):
+ raise ValueError(f"{bf.typname}: bit num {bitnum} out-of-bounds")
+ bit = bf.bits[bitnum]
+ if bit.cat != BitCat.UNUSED:
+ raise ValueError(f"{bf.typname}: bit num {bitnum} already assigned")
+ if name := m.group("name_used"):
+ bit.bitname = name
+ bit.cat = BitCat.USED
+ bit.in_versions.add(ver)
+ elif name := m.group("name_reserved"):
+ bit.bitname = name
+ bit.cat = BitCat.RESERVED
+ bit.in_versions.add(ver)
+ elif name := m.group("name_subfield"):
+ bit.bitname = name
+ bit.cat = BitCat.SUBFIELD
+ bit.in_versions.add(ver)
+ if bit.bitname:
+ if bit.bitname in bf.names:
+ other = bf.names[bit.bitname]
+ if (
+ isinstance(other, Bit)
+ and other.cat == bit.cat
+ and bit.cat == BitCat.SUBFIELD
+ ):
+ return
+ raise ValueError(
+ f"{bf.typname}: bit name {bit.bitname!r} already assigned"
+ )
+ bf.names[bit.bitname] = bit
elif m := re.fullmatch(re_bitspec_alias, spec):
- name = m.group("name")
- valstr = m.group("val")
-
- val = BitfieldVal()
- val.name = name
- val.val = valstr
- val.in_versions.add(ver)
+ alias = BitAlias(m.group("name"), m.group("val"))
+ alias.in_versions.add(ver)
+ if alias.bitname in bf.names:
+ raise ValueError(
+ f"{bf.typname}: bit name {alias.bitname!r} already assigned"
+ )
+ bf.names[alias.bitname] = alias
else:
- raise SyntaxError(f"invalid bitfield spec {repr(spec)}")
-
- if val.name in bf.names:
- raise ValueError(f"{bf.name}: name {val.name} already assigned")
- bf.names[val.name] = val
+ raise SyntaxError(f"invalid bitfield spec {spec!r}")
def parse_expr(expr: str) -> Expr:
assert re.fullmatch(re_expr, expr)
ret = Expr()
for tok in re.split("([-+])", expr):
- if tok == "-" or tok == "+":
+ if tok in ("-", "+"):
# I, for the life of me, do not understand why I need this
- # cast() to keep mypy happy.
- ret.tokens += [ExprOp(cast(Literal["-", "+"], tok))]
+ # typing.cast() to keep mypy happy.
+ ret.tokens += [ExprOp(typing.cast(typing.Literal["-", "+"], tok))]
elif re.fullmatch("[0-9]+", tok):
ret.tokens += [ExprLit(int(tok))]
else:
@@ -354,22 +387,22 @@ def parse_members(ver: str, env: dict[str, Type], struct: Struct, specs: str) ->
for spec in specs.split():
m = re.fullmatch(re_memberspec, spec)
if not m:
- raise SyntaxError(f"invalid member spec {repr(spec)}")
+ raise SyntaxError(f"invalid member spec {spec!r}")
member = StructMember()
member.in_versions = {ver}
- member.name = m.group("name")
- if any(x.name == member.name for x in struct.members):
- raise ValueError(f"duplicate member name {repr(member.name)}")
+ member.membname = m.group("name")
+ if any(x.membname == member.membname for x in struct.members):
+ raise ValueError(f"duplicate member name {member.membname!r}")
if m.group("typ") not in env:
- raise NameError(f"Unknown type {repr(m.group('typ'))}")
+ raise NameError(f"Unknown type {m.group('typ')!r}")
member.typ = env[m.group("typ")]
if cnt := m.group("cnt"):
- if len(struct.members) == 0 or struct.members[-1].name != cnt:
- raise ValueError(f"list count must be previous item: {repr(cnt)}")
+ if len(struct.members) == 0 or struct.members[-1].membname != cnt:
+ raise ValueError(f"list count must be previous item: {cnt!r}")
cnt_mem = struct.members[-1]
member.cnt = cnt_mem
_ = member.max_cnt # force validation
@@ -412,8 +445,8 @@ re_line_cont = f"\\s+{re_string('specs')}" # could be bitfield/struct/msg
def parse_file(
- filename: str, get_include: Callable[[str], tuple[str, list[Type]]]
-) -> tuple[str, list[Type]]:
+ filename: str, get_include: typing.Callable[[str], tuple[str, list[UserType]]]
+) -> tuple[str, list[UserType]]:
version: str | None = None
env: dict[str, Type] = {
"1": Primitive.u8,
@@ -425,13 +458,13 @@ def parse_file(
def get_type(name: str, tc: type[T]) -> T:
nonlocal env
if name not in env:
- raise NameError(f"Unknown type {repr(name)}")
+ raise NameError(f"Unknown type {name!r}")
ret = env[name]
if (not isinstance(ret, tc)) or (ret.__class__.__name__ != tc.__name__):
- raise NameError(f"Type {repr(ret.name)} is not a {tc.__name__}")
+ raise NameError(f"Type {ret.typname!r} is not a {tc.__name__}")
return ret
- with open(filename, "r") as fh:
+ with open(filename, "r", encoding="utf-8") as fh:
prev: Type | None = None
for lineno, line in enumerate(fh):
try:
@@ -452,7 +485,7 @@ def parse_file(
symname = symname.strip()
found = False
for typ in other_typs:
- if typ.name == symname or symname == "*":
+ if symname in (typ.typname, "*"):
found = True
match typ:
case Primitive():
@@ -461,6 +494,9 @@ def parse_file(
typ.in_versions.add(version)
case Bitfield():
typ.in_versions.add(version)
+ for bit in typ.bits:
+ if other_version in bit.in_versions:
+ bit.in_versions.add(version)
for val in typ.names.values():
if other_version in val.in_versions:
val.in_versions.add(version)
@@ -469,42 +505,38 @@ def parse_file(
for member in typ.members:
if other_version in member.in_versions:
member.in_versions.add(version)
- if typ.name in env and env[typ.name] != typ:
+ if typ.typname in env and env[typ.typname] != typ:
raise ValueError(
- f"duplicate type name {repr(typ.name)}"
+ f"duplicate type name {typ.typname!r}"
)
- env[typ.name] = typ
+ env[typ.typname] = typ
if symname != "*" and not found:
raise ValueError(
- f"import: {m.group('file')}: no symbol {repr(symname)}"
+ f"import: {m.group('file')}: no symbol {symname!r}"
)
elif m := re.fullmatch(re_line_num, line):
num = Number()
- num.name = m.group("name")
+ num.typname = m.group("name")
num.in_versions.add(version)
prim = env[m.group("prim")]
assert isinstance(prim, Primitive)
num.prim = prim
- if num.name in env:
- raise ValueError(f"duplicate type name {repr(num.name)}")
- env[num.name] = num
+ if num.typname in env:
+ raise ValueError(f"duplicate type name {num.typname!r}")
+ env[num.typname] = num
prev = num
elif m := re.fullmatch(re_line_bitfield, line):
- bf = Bitfield()
- bf.name = m.group("name")
- bf.in_versions.add(version)
-
prim = env[m.group("prim")]
assert isinstance(prim, Primitive)
- bf.prim = prim
- bf.bits = (prim.static_size * 8) * [""]
+ bf = Bitfield(m.group("name"), prim)
+ bf.in_versions.add(version)
- if bf.name in env:
- raise ValueError(f"duplicate type name {repr(bf.name)}")
- env[bf.name] = bf
+ if bf.typname in env:
+ raise ValueError(f"duplicate type name {bf.typname!r}")
+ env[bf.typname] = bf
prev = bf
elif m := re.fullmatch(re_line_bitfield_, line):
bf = get_type(m.group("name"), Bitfield)
@@ -515,16 +547,16 @@ def parse_file(
match m.group("op"):
case "=":
struct = Struct()
- struct.name = m.group("name")
+ struct.typname = m.group("name")
struct.in_versions.add(version)
struct.members = []
parse_members(version, env, struct, m.group("members"))
- if struct.name in env:
+ if struct.typname in env:
raise ValueError(
- f"duplicate type name {repr(struct.name)}"
+ f"duplicate type name {struct.typname!r}"
)
- env[struct.name] = struct
+ env[struct.typname] = struct
prev = struct
case "+=":
struct = get_type(m.group("name"), Struct)
@@ -535,16 +567,14 @@ def parse_file(
match m.group("op"):
case "=":
msg = Message()
- msg.name = m.group("name")
+ msg.typname = m.group("name")
msg.in_versions.add(version)
msg.members = []
parse_members(version, env, msg, m.group("members"))
- if msg.name in env:
- raise ValueError(
- f"duplicate type name {repr(msg.name)}"
- )
- env[msg.name] = msg
+ if msg.typname in env:
+ raise ValueError(f"duplicate type name {msg.typname!r}")
+ env[msg.typname] = msg
prev = msg
case "+=":
msg = get_type(m.group("name"), Message)
@@ -574,22 +604,27 @@ def parse_file(
if not version:
raise SyntaxError("must have exactly 1 version line")
- typs: list[Type] = [x for x in env.values() if not isinstance(x, Primitive)]
+ typs: list[UserType] = [x for x in env.values() if not isinstance(x, Primitive)]
for typ in [typ for typ in typs if isinstance(typ, Struct)]:
- valid_syms = ["end", "s32_max", "s64_max", *["&" + m.name for m in typ.members]]
+ valid_syms = [
+ "end",
+ "s32_max",
+ "s64_max",
+ *["&" + m.membname for m in typ.members],
+ ]
for member in typ.members:
if (
not isinstance(member.typ, Primitive)
and member.typ.in_versions < member.in_versions
):
raise ValueError(
- f"{typ.name}.{member.name}: type {member.typ.name} does not exist in {member.in_versions.difference(member.typ.in_versions)}"
+ f"{typ.typname}.{member.membname}: type {member.typ.typname} does not exist in {member.in_versions.difference(member.typ.in_versions)}"
)
for tok in [*member.max.tokens, *member.val.tokens]:
- if isinstance(tok, ExprSym) and tok.name not in valid_syms:
+ if isinstance(tok, ExprSym) and tok.symname not in valid_syms:
raise ValueError(
- f"{typ.name}.{member.name}: invalid sym: {tok.name}"
+ f"{typ.typname}.{member.membname}: invalid sym: {tok.symname}"
)
return version, typs
@@ -599,35 +634,35 @@ def parse_file(
class Parser:
- cache: dict[str, tuple[str, list[Type]]] = {}
+ cache: dict[str, tuple[str, list[UserType]]] = {}
- def parse_file(self, filename: str) -> tuple[str, list[Type]]:
+ def parse_file(self, filename: str) -> tuple[str, list[UserType]]:
filename = os.path.normpath(filename)
if filename not in self.cache:
- def get_include(other_filename: str) -> tuple[str, list[Type]]:
+ def get_include(other_filename: str) -> tuple[str, list[UserType]]:
return self.parse_file(os.path.join(filename, "..", other_filename))
self.cache[filename] = parse_file(filename, get_include)
return self.cache[filename]
- def all(self) -> tuple[set[str], list[Type]]:
+ def all(self) -> tuple[set[str], list[UserType]]:
ret_versions: set[str] = set()
- ret_typs: dict[str, Type] = {}
+ ret_typs: dict[str, UserType] = {}
for version, typs in self.cache.values():
if version in ret_versions:
- raise ValueError(f"duplicate protocol version {repr(version)}")
+ raise ValueError(f"duplicate protocol version {version!r}")
ret_versions.add(version)
for typ in typs:
- if typ.name in ret_typs:
- if typ != ret_typs[typ.name]:
- raise ValueError(f"duplicate type name {repr(typ.name)}")
+ if typ.typname in ret_typs:
+ if typ != ret_typs[typ.typname]:
+ raise ValueError(f"duplicate type name {typ.typname!r}")
else:
- ret_typs[typ.name] = typ
+ ret_typs[typ.typname] = typ
msgids: set[int] = set()
for typ in ret_typs.values():
if isinstance(typ, Message):
if typ.msgid in msgids:
- raise ValueError(f"duplicate msgid {repr(typ.msgid)}")
+ raise ValueError(f"duplicate msgid {typ.msgid!r}")
msgids.add(typ.msgid)
return ret_versions, list(ret_typs.values())
diff --git a/lib9p/include/lib9p/9p.generated.h b/lib9p/include/lib9p/9p.generated.h
index d34a0f6..7a50537 100644
--- a/lib9p/include/lib9p/9p.generated.h
+++ b/lib9p/include/lib9p/9p.generated.h
@@ -1,4 +1,4 @@
-/* Generated by `lib9p/idl.gen lib9p/idl/2002-9P2000.9p lib9p/idl/2003-9P2000.p9p.9p lib9p/idl/2005-9P2000.u.9p lib9p/idl/2010-9P2000.L.9p lib9p/idl/2012-9P2000.e.9p`. DO NOT EDIT! */
+/* Generated by `lib9p/proto.gen lib9p/idl/2002-9P2000.9p lib9p/idl/2003-9P2000.p9p.9p lib9p/idl/2005-9P2000.u.9p lib9p/idl/2010-9P2000.L.9p lib9p/idl/2012-9P2000.e.9p`. DO NOT EDIT! */
#ifndef _LIB9P_9P_H_
#error Do not include <lib9p/9p.generated.h> directly; include <lib9p/9p.h> instead
@@ -24,7 +24,7 @@
#error config.h must define CONFIG_9P_ENABLE_9P2000_e
#else
#if CONFIG_9P_ENABLE_9P2000_e
- #ifndef(CONFIG_9P_MAX_9P2000_e_WELEM)
+ #ifndef CONFIG_9P_MAX_9P2000_e_WELEM
#error if CONFIG_9P_ENABLE_9P2000_e then config.h must define CONFIG_9P_MAX_9P2000_e_WELEM
#endif
static_assert(CONFIG_9P_MAX_9P2000_e_WELEM > 0);
@@ -176,62 +176,62 @@ struct lib9p_s {
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_dm_t;
-#define LIB9P_DM_DIR ((lib9p_dm_t)(1<<31))
-#define LIB9P_DM_APPEND ((lib9p_dm_t)(1<<30))
-#define LIB9P_DM_EXCL ((lib9p_dm_t)(1<<29))
-#define _LIB9P_DM_PLAN9_MOUNT ((lib9p_dm_t)(1<<28))
-#define LIB9P_DM_AUTH ((lib9p_dm_t)(1<<27))
-#define LIB9P_DM_TMP ((lib9p_dm_t)(1<<26))
-/* unused ((lib9p_dm_t)(1<<25)) */
-/* unused ((lib9p_dm_t)(1<<24)) */
+#define LIB9P_DM_DIR ((lib9p_dm_t)(1<<31))
+#define LIB9P_DM_APPEND ((lib9p_dm_t)(1<<30))
+#define LIB9P_DM_EXCL ((lib9p_dm_t)(1<<29))
+#define _LIB9P_DM_RESERVED_PLAN9_MOUNT ((lib9p_dm_t)(1<<28))
+#define LIB9P_DM_AUTH ((lib9p_dm_t)(1<<27))
+#define LIB9P_DM_TMP ((lib9p_dm_t)(1<<26))
+/* unused ((lib9p_dm_t)(1<<25)) */
+/* unused ((lib9p_dm_t)(1<<24)) */
#if CONFIG_9P_ENABLE_9P2000_u
-# define LIB9P_DM_DEVICE ((lib9p_dm_t)(1<<23))
+# define LIB9P_DM_DEVICE ((lib9p_dm_t)(1<<23))
#endif /* CONFIG_9P_ENABLE_9P2000_u */
-/* unused ((lib9p_dm_t)(1<<22)) */
+/* unused ((lib9p_dm_t)(1<<22)) */
#if CONFIG_9P_ENABLE_9P2000_u
-# define LIB9P_DM_NAMEDPIPE ((lib9p_dm_t)(1<<21))
-# define LIB9P_DM_SOCKET ((lib9p_dm_t)(1<<20))
-# define LIB9P_DM_SETUID ((lib9p_dm_t)(1<<19))
-# define LIB9P_DM_SETGID ((lib9p_dm_t)(1<<18))
+# define LIB9P_DM_NAMEDPIPE ((lib9p_dm_t)(1<<21))
+# define LIB9P_DM_SOCKET ((lib9p_dm_t)(1<<20))
+# define LIB9P_DM_SETUID ((lib9p_dm_t)(1<<19))
+# define LIB9P_DM_SETGID ((lib9p_dm_t)(1<<18))
#endif /* CONFIG_9P_ENABLE_9P2000_u */
-/* unused ((lib9p_dm_t)(1<<17)) */
-/* unused ((lib9p_dm_t)(1<<16)) */
-/* unused ((lib9p_dm_t)(1<<15)) */
-/* unused ((lib9p_dm_t)(1<<14)) */
-/* unused ((lib9p_dm_t)(1<<13)) */
-/* unused ((lib9p_dm_t)(1<<12)) */
-/* unused ((lib9p_dm_t)(1<<11)) */
-/* unused ((lib9p_dm_t)(1<<10)) */
-/* unused ((lib9p_dm_t)(1<<9)) */
-#define LIB9P_DM_OWNER_R ((lib9p_dm_t)(1<<8))
-#define LIB9P_DM_OWNER_W ((lib9p_dm_t)(1<<7))
-#define LIB9P_DM_OWNER_X ((lib9p_dm_t)(1<<6))
-#define LIB9P_DM_GROUP_R ((lib9p_dm_t)(1<<5))
-#define LIB9P_DM_GROUP_W ((lib9p_dm_t)(1<<4))
-#define LIB9P_DM_GROUP_X ((lib9p_dm_t)(1<<3))
-#define LIB9P_DM_OTHER_R ((lib9p_dm_t)(1<<2))
-#define LIB9P_DM_OTHER_W ((lib9p_dm_t)(1<<1))
-#define LIB9P_DM_OTHER_X ((lib9p_dm_t)(1<<0))
-
-#define LIB9P_DM_PERM_MASK ((lib9p_dm_t)(0777))
+/* unused ((lib9p_dm_t)(1<<17)) */
+/* unused ((lib9p_dm_t)(1<<16)) */
+/* unused ((lib9p_dm_t)(1<<15)) */
+/* unused ((lib9p_dm_t)(1<<14)) */
+/* unused ((lib9p_dm_t)(1<<13)) */
+/* unused ((lib9p_dm_t)(1<<12)) */
+/* unused ((lib9p_dm_t)(1<<11)) */
+/* unused ((lib9p_dm_t)(1<<10)) */
+/* unused ((lib9p_dm_t)(1<<9)) */
+#define LIB9P_DM_OWNER_R ((lib9p_dm_t)(1<<8))
+#define LIB9P_DM_OWNER_W ((lib9p_dm_t)(1<<7))
+#define LIB9P_DM_OWNER_X ((lib9p_dm_t)(1<<6))
+#define LIB9P_DM_GROUP_R ((lib9p_dm_t)(1<<5))
+#define LIB9P_DM_GROUP_W ((lib9p_dm_t)(1<<4))
+#define LIB9P_DM_GROUP_X ((lib9p_dm_t)(1<<3))
+#define LIB9P_DM_OTHER_R ((lib9p_dm_t)(1<<2))
+#define LIB9P_DM_OTHER_W ((lib9p_dm_t)(1<<1))
+#define LIB9P_DM_OTHER_X ((lib9p_dm_t)(1<<0))
+
+#define LIB9P_DM_PERM_MASK ((lib9p_dm_t)(0777))
#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
/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_qt_t;
-#define LIB9P_QT_DIR ((lib9p_qt_t)(1<<7))
-#define LIB9P_QT_APPEND ((lib9p_qt_t)(1<<6))
-#define LIB9P_QT_EXCL ((lib9p_qt_t)(1<<5))
-#define _LIB9P_QT_PLAN9_MOUNT ((lib9p_qt_t)(1<<4))
-#define LIB9P_QT_AUTH ((lib9p_qt_t)(1<<3))
-#define LIB9P_QT_TMP ((lib9p_qt_t)(1<<2))
+#define LIB9P_QT_DIR ((lib9p_qt_t)(1<<7))
+#define LIB9P_QT_APPEND ((lib9p_qt_t)(1<<6))
+#define LIB9P_QT_EXCL ((lib9p_qt_t)(1<<5))
+#define _LIB9P_QT_RESERVED_PLAN9_MOUNT ((lib9p_qt_t)(1<<4))
+#define LIB9P_QT_AUTH ((lib9p_qt_t)(1<<3))
+#define LIB9P_QT_TMP ((lib9p_qt_t)(1<<2))
#if CONFIG_9P_ENABLE_9P2000_u
-# define LIB9P_QT_SYMLINK ((lib9p_qt_t)(1<<1))
+# define LIB9P_QT_SYMLINK ((lib9p_qt_t)(1<<1))
#endif /* CONFIG_9P_ENABLE_9P2000_u */
-/* unused ((lib9p_qt_t)(1<<0)) */
+/* unused ((lib9p_qt_t)(1<<0)) */
-#define LIB9P_QT_FILE ((lib9p_qt_t)(0))
+#define LIB9P_QT_FILE ((lib9p_qt_t)(0))
#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 || CONFIG_9P_ENABLE_9P2000_u
@@ -244,24 +244,140 @@ typedef uint32_t lib9p_nuid_t;
/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_o_t;
-/* unused ((lib9p_o_t)(1<<7)) */
-#define LIB9P_O_RCLOSE ((lib9p_o_t)(1<<6))
-/* unused ((lib9p_o_t)(1<<5)) */
-#define LIB9P_O_TRUNC ((lib9p_o_t)(1<<4))
-/* unused ((lib9p_o_t)(1<<3)) */
-/* unused ((lib9p_o_t)(1<<2)) */
-#define LIB9P_O_mode_1 ((lib9p_o_t)(1<<1))
-#define LIB9P_O_mode_0 ((lib9p_o_t)(1<<0))
-
-#define LIB9P_O_READ ((lib9p_o_t)(0))
-#define LIB9P_O_WRITE ((lib9p_o_t)(1))
-#define LIB9P_O_RDWR ((lib9p_o_t)(2))
-#define LIB9P_O_EXEC ((lib9p_o_t)(3))
-#define LIB9P_O_MODE_MASK ((lib9p_o_t)(0b00000011))
-#define LIB9P_O_FLAG_MASK ((lib9p_o_t)(0b11111100))
+/* unused ((lib9p_o_t)(1<<7)) */
+#define LIB9P_O_RCLOSE ((lib9p_o_t)(1<<6))
+#define _LIB9P_O_RESERVED_CEXEC ((lib9p_o_t)(1<<5))
+#define LIB9P_O_TRUNC ((lib9p_o_t)(1<<4))
+/* unused ((lib9p_o_t)(1<<3)) */
+/* unused ((lib9p_o_t)(1<<2)) */
+#define _LIB9P_O_mode_1 ((lib9p_o_t)(1<<1))
+#define _LIB9P_O_mode_0 ((lib9p_o_t)(1<<0))
+
+#define LIB9P_O_READ ((lib9p_o_t)(0))
+#define LIB9P_O_WRITE ((lib9p_o_t)(1))
+#define LIB9P_O_RDWR ((lib9p_o_t)(2))
+#define LIB9P_O_EXEC ((lib9p_o_t)(3))
+#define LIB9P_O_MODE_MASK ((lib9p_o_t)(0b00000011))
+#define LIB9P_O_FLAG_MASK ((lib9p_o_t)(0b11111100))
#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 || CONFIG_9P_ENABLE_9P2000_u
+/* size = 4 ; max_iov = 1 ; max_copy = 4 */
+typedef uint32_t lib9p_errno_t;
+#define LIB9P_ERRNO_NOERROR ((lib9p_errno_t)UINT32_C(0))
+
+#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
+/* size = 4 ; max_iov = 1 ; max_copy = 4 */
+typedef uint32_t lib9p_super_magic_t;
+#define LIB9P_SUPER_MAGIC_V9FS_MAGIC ((lib9p_super_magic_t)UINT32_C(0x01021997))
+
+/* size = 4 ; max_iov = 1 ; max_copy = 4 */
+typedef uint32_t lib9p_lo_t;
+
+/* unused ((lib9p_lo_t)(1<<31)) */
+/* unused ((lib9p_lo_t)(1<<30)) */
+/* unused ((lib9p_lo_t)(1<<29)) */
+/* unused ((lib9p_lo_t)(1<<28)) */
+/* unused ((lib9p_lo_t)(1<<27)) */
+/* unused ((lib9p_lo_t)(1<<26)) */
+/* unused ((lib9p_lo_t)(1<<25)) */
+/* unused ((lib9p_lo_t)(1<<24)) */
+/* unused ((lib9p_lo_t)(1<<23)) */
+/* unused ((lib9p_lo_t)(1<<22)) */
+/* unused ((lib9p_lo_t)(1<<21)) */
+#define LIB9P_LO_SYNC ((lib9p_lo_t)(1<<20))
+#define LIB9P_LO_CLOEXEC ((lib9p_lo_t)(1<<19))
+#define LIB9P_LO_NOATIME ((lib9p_lo_t)(1<<18))
+#define LIB9P_LO_NOFOLLOW ((lib9p_lo_t)(1<<17))
+#define LIB9P_LO_DIRECTORY ((lib9p_lo_t)(1<<16))
+#define LIB9P_LO_LARGEFILE ((lib9p_lo_t)(1<<15))
+#define LIB9P_LO_DIRECT ((lib9p_lo_t)(1<<14))
+#define LIB9P_LO_BSD_FASYNC ((lib9p_lo_t)(1<<13))
+#define LIB9P_LO_DSYNC ((lib9p_lo_t)(1<<12))
+#define LIB9P_LO_NONBLOCK ((lib9p_lo_t)(1<<11))
+#define LIB9P_LO_APPEND ((lib9p_lo_t)(1<<10))
+#define LIB9P_LO_TRUNC ((lib9p_lo_t)(1<<9))
+#define LIB9P_LO_NOCTTY ((lib9p_lo_t)(1<<8))
+#define LIB9P_LO_EXCL ((lib9p_lo_t)(1<<7))
+#define LIB9P_LO_CREATE ((lib9p_lo_t)(1<<6))
+/* unused ((lib9p_lo_t)(1<<5)) */
+/* unused ((lib9p_lo_t)(1<<4)) */
+/* unused ((lib9p_lo_t)(1<<3)) */
+/* unused ((lib9p_lo_t)(1<<2)) */
+#define _LIB9P_LO_mode_1 ((lib9p_lo_t)(1<<1))
+#define _LIB9P_LO_mode_0 ((lib9p_lo_t)(1<<0))
+
+#define LIB9P_LO_RDONLY ((lib9p_lo_t)(0))
+#define LIB9P_LO_WRONLY ((lib9p_lo_t)(1))
+#define LIB9P_LO_RDWR ((lib9p_lo_t)(2))
+#define LIB9P_LO_NOACCESS ((lib9p_lo_t)(3))
+#define LIB9P_LO_MODE_MASK ((lib9p_lo_t)(0b000000000000000000011))
+#define LIB9P_LO_FLAG_MASK ((lib9p_lo_t)(0b111111111111111000000))
+
+/* size = 1 ; max_iov = 1 ; max_copy = 1 */
+typedef uint8_t lib9p_dt_t;
+#define LIB9P_DT_UNKNOWN ((lib9p_dt_t)UINT8_C(0))
+#define LIB9P_DT_NAMED_PIPE ((lib9p_dt_t)UINT8_C(1))
+#define LIB9P_DT_CHAR_DEV ((lib9p_dt_t)UINT8_C(2))
+#define LIB9P_DT_DIRECTORY ((lib9p_dt_t)UINT8_C(4))
+#define LIB9P_DT_BLOCK_DEV ((lib9p_dt_t)UINT8_C(6))
+#define LIB9P_DT_REGULAR ((lib9p_dt_t)UINT8_C(8))
+#define LIB9P_DT_SYMLINK ((lib9p_dt_t)UINT8_C(10))
+#define LIB9P_DT_SOCKET ((lib9p_dt_t)UINT8_C(12))
+#define LIB9P_DT_WHITEOUT ((lib9p_dt_t)UINT8_C(14))
+
+/* size = 4 ; max_iov = 1 ; max_copy = 4 */
+typedef uint32_t lib9p_mode_t;
+
+/* unused ((lib9p_mode_t)(1<<31)) */
+/* unused ((lib9p_mode_t)(1<<30)) */
+/* unused ((lib9p_mode_t)(1<<29)) */
+/* unused ((lib9p_mode_t)(1<<28)) */
+/* unused ((lib9p_mode_t)(1<<27)) */
+/* unused ((lib9p_mode_t)(1<<26)) */
+/* unused ((lib9p_mode_t)(1<<25)) */
+/* unused ((lib9p_mode_t)(1<<24)) */
+/* unused ((lib9p_mode_t)(1<<23)) */
+/* unused ((lib9p_mode_t)(1<<22)) */
+/* unused ((lib9p_mode_t)(1<<21)) */
+/* unused ((lib9p_mode_t)(1<<20)) */
+/* unused ((lib9p_mode_t)(1<<19)) */
+/* unused ((lib9p_mode_t)(1<<18)) */
+/* unused ((lib9p_mode_t)(1<<17)) */
+/* unused ((lib9p_mode_t)(1<<16)) */
+#define _LIB9P_MODE_fmt_3 ((lib9p_mode_t)(1<<15))
+#define _LIB9P_MODE_fmt_2 ((lib9p_mode_t)(1<<14))
+#define _LIB9P_MODE_fmt_1 ((lib9p_mode_t)(1<<13))
+#define _LIB9P_MODE_fmt_0 ((lib9p_mode_t)(1<<12))
+#define LIB9P_MODE_PERM_SETGROUP ((lib9p_mode_t)(1<<11))
+#define LIB9P_MODE_PERM_SETUSER ((lib9p_mode_t)(1<<10))
+#define LIB9P_MODE_PERM_STICKY ((lib9p_mode_t)(1<<9))
+#define LIB9P_MODE_PERM_OWNER_R ((lib9p_mode_t)(1<<8))
+#define LIB9P_MODE_PERM_OWNER_W ((lib9p_mode_t)(1<<7))
+#define LIB9P_MODE_PERM_OWNER_X ((lib9p_mode_t)(1<<6))
+#define LIB9P_MODE_PERM_GROUP_R ((lib9p_mode_t)(1<<5))
+#define LIB9P_MODE_PERM_GROUP_W ((lib9p_mode_t)(1<<4))
+#define LIB9P_MODE_PERM_GROUP_X ((lib9p_mode_t)(1<<3))
+#define LIB9P_MODE_PERM_OTHER_R ((lib9p_mode_t)(1<<2))
+#define LIB9P_MODE_PERM_OTHER_W ((lib9p_mode_t)(1<<1))
+#define LIB9P_MODE_PERM_OTHER_X ((lib9p_mode_t)(1<<0))
+
+#define LIB9P_MODE_FMT_NAMED_PIPE ((lib9p_mode_t)(LIB9P_DT_NAMED_PIPE<<12))
+#define LIB9P_MODE_FMT_CHAR_DEV ((lib9p_mode_t)(LIB9P_DT_CHAR_DEV<<12))
+#define LIB9P_MODE_FMT_DIRECTORY ((lib9p_mode_t)(LIB9P_DT_DIRECTORY<<12))
+#define LIB9P_MODE_FMT_BLOCK_DEV ((lib9p_mode_t)(LIB9P_DT_BLOCK_DEV<<12))
+#define LIB9P_MODE_FMT_REGULAR ((lib9p_mode_t)(LIB9P_DT_REGULAR<<12))
+#define LIB9P_MODE_FMT_SYMLINK ((lib9p_mode_t)(LIB9P_DT_SYMLINK<<12))
+#define LIB9P_MODE_FMT_SOCKET ((lib9p_mode_t)(LIB9P_DT_SOCKET<<12))
+#define LIB9P_MODE_PERM_MASK ((lib9p_mode_t)(0000777))
+#define LIB9P_MODE_FMT_MASK ((lib9p_mode_t)(0170000))
+
+/* size = 4 ; max_iov = 1 ; max_copy = 4 */
+typedef uint32_t lib9p_b4_t;
+#define LIB9P_B4_FALSE ((lib9p_b4_t)UINT32_C(0))
+#define LIB9P_B4_TRUE ((lib9p_b4_t)UINT32_C(1))
+
/* size = 8 ; max_iov = 1 ; max_copy = 8 */
typedef uint64_t lib9p_getattr_t;
@@ -463,26 +579,6 @@ struct lib9p_msg_Rwstat {
#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
-/* size = 11 ; max_iov = 1 ; max_copy = 11 */
-struct lib9p_msg_Rlerror {
- lib9p_tag_t tag;
- uint32_t ecode;
-};
-
-/* size = 67 ; max_iov = 1 ; max_copy = 67 */
-struct lib9p_msg_Rstatfs {
- lib9p_tag_t tag;
- uint32_t type;
- uint32_t bsize;
- uint64_t blocks;
- uint64_t bfree;
- uint64_t bavail;
- uint64_t files;
- uint64_t ffree;
- uint64_t fsid;
- uint32_t namelen;
-};
-
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rrename {
lib9p_tag_t tag;
@@ -604,13 +700,6 @@ struct lib9p_msg_Tstatfs {
lib9p_fid_t fid;
};
-/* size = 15 ; max_iov = 1 ; max_copy = 15 */
-struct lib9p_msg_Tlopen {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- uint32_t flags;
-};
-
/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Treadlink {
lib9p_tag_t tag;
@@ -625,13 +714,6 @@ struct lib9p_msg_Treaddir {
uint32_t count;
};
-/* size = 15 ; max_iov = 1 ; max_copy = 15 */
-struct lib9p_msg_Tfsync {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- uint32_t datasync;
-};
-
#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
/* min_size = 13 ; exp_size = 40 ; max_size = 65,548 ; max_iov = 2 ; max_copy = 13 */
@@ -648,19 +730,6 @@ struct lib9p_msg_Rversion {
struct lib9p_s version;
};
-/* LIB9P_VER_9P2000 : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
-/* LIB9P_VER_9P2000_L : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
-/* LIB9P_VER_9P2000_e : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
-/* LIB9P_VER_9P2000_p9p: min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
-/* LIB9P_VER_9P2000_u : min_size = 13 ; exp_size = 40 ; max_size = 65,548 ; max_iov = 3 ; max_copy = 13 */
-struct lib9p_msg_Rerror {
- lib9p_tag_t tag;
- struct lib9p_s ename;
-#if CONFIG_9P_ENABLE_9P2000_u
- uint32_t errno;
-#endif /* CONFIG_9P_ENABLE_9P2000_u */
-};
-
/* min_size = 17 ; exp_size = 481 ; max_size = 1,048,609 ; max_iov = 32 ; max_copy = 49 */
struct lib9p_msg_Twalk {
lib9p_tag_t tag;
@@ -703,27 +772,6 @@ struct lib9p_msg_Txattrcreate {
uint32_t flags;
};
-/* min_size = 34 ; exp_size = 61 ; max_size = 65,569 ; max_iov = 2 ; max_copy = 34 */
-struct lib9p_msg_Tgetlock {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- uint8_t type;
- uint64_t start;
- uint64_t length;
- uint32_t proc_id;
- struct lib9p_s client_id;
-};
-
-/* min_size = 30 ; exp_size = 57 ; max_size = 65,565 ; max_iov = 2 ; max_copy = 30 */
-struct lib9p_msg_Rgetlock {
- lib9p_tag_t tag;
- uint8_t type;
- uint64_t start;
- uint64_t length;
- uint32_t proc_id;
- struct lib9p_s client_id;
-};
-
/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
struct lib9p_msg_Tlink {
lib9p_tag_t tag;
@@ -811,16 +859,6 @@ struct lib9p_msg_Tattach {
#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
-/* min_size = 25 ; exp_size = 52 ; max_size = 65,560 ; max_iov = 3 ; max_copy = 25 */
-struct lib9p_msg_Tlcreate {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- struct lib9p_s name;
- uint32_t flags;
- uint32_t mode;
- lib9p_nuid_t gid;
-};
-
/* min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 5 ; max_copy = 19 */
struct lib9p_msg_Tsymlink {
lib9p_tag_t tag;
@@ -830,26 +868,6 @@ struct lib9p_msg_Tsymlink {
lib9p_nuid_t gid;
};
-/* min_size = 29 ; exp_size = 56 ; max_size = 65,564 ; max_iov = 3 ; max_copy = 29 */
-struct lib9p_msg_Tmknod {
- lib9p_tag_t tag;
- lib9p_fid_t dfid;
- struct lib9p_s name;
- uint32_t mode;
- uint32_t major;
- uint32_t minor;
- lib9p_nuid_t gid;
-};
-
-/* min_size = 21 ; exp_size = 48 ; max_size = 65,556 ; max_iov = 3 ; max_copy = 21 */
-struct lib9p_msg_Tmkdir {
- lib9p_tag_t tag;
- lib9p_fid_t dfid;
- struct lib9p_s name;
- uint32_t mode;
- lib9p_nuid_t 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
/* size = 12 ; max_iov = 1 ; max_copy = 12 */
@@ -878,7 +896,86 @@ struct lib9p_msg_Topenfd {
};
#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
+/* LIB9P_VER_9P2000 : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
+/* LIB9P_VER_9P2000_L : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
+/* LIB9P_VER_9P2000_e : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
+/* LIB9P_VER_9P2000_p9p: min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
+/* LIB9P_VER_9P2000_u : min_size = 13 ; exp_size = 40 ; max_size = 65,548 ; max_iov = 3 ; max_copy = 13 */
+struct lib9p_msg_Rerror {
+ lib9p_tag_t tag;
+ struct lib9p_s ename;
+#if CONFIG_9P_ENABLE_9P2000_u
+ lib9p_errno_t errno;
+#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
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
+struct lib9p_msg_Rlerror {
+ lib9p_tag_t tag;
+ lib9p_errno_t ecode;
+};
+
+/* size = 67 ; max_iov = 1 ; max_copy = 67 */
+struct lib9p_msg_Rstatfs {
+ lib9p_tag_t tag;
+ lib9p_super_magic_t type;
+ uint32_t bsize;
+ uint64_t blocks;
+ uint64_t bfree;
+ uint64_t bavail;
+ uint64_t files;
+ uint64_t ffree;
+ uint64_t fsid;
+ uint32_t namelen;
+};
+
+/* size = 15 ; max_iov = 1 ; max_copy = 15 */
+struct lib9p_msg_Tlopen {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_lo_t flags;
+};
+
+/* min_size = 25 ; exp_size = 52 ; max_size = 65,560 ; max_iov = 3 ; max_copy = 25 */
+struct lib9p_msg_Tlcreate {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ struct lib9p_s name;
+ lib9p_lo_t flags;
+ lib9p_mode_t mode;
+ lib9p_nuid_t gid;
+};
+
+/* min_size = 29 ; exp_size = 56 ; max_size = 65,564 ; max_iov = 3 ; max_copy = 29 */
+struct lib9p_msg_Tmknod {
+ lib9p_tag_t tag;
+ lib9p_fid_t dfid;
+ struct lib9p_s name;
+ lib9p_mode_t mode;
+ uint32_t major;
+ uint32_t minor;
+ lib9p_nuid_t gid;
+};
+
+/* min_size = 21 ; exp_size = 48 ; max_size = 65,556 ; max_iov = 3 ; max_copy = 21 */
+struct lib9p_msg_Tmkdir {
+ lib9p_tag_t tag;
+ lib9p_fid_t dfid;
+ struct lib9p_s name;
+ lib9p_mode_t mode;
+ lib9p_nuid_t gid;
+};
+
+/* size = 15 ; max_iov = 1 ; max_copy = 15 */
+struct lib9p_msg_Tfsync {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_b4_t datasync;
+};
+
/* size = 19 ; max_iov = 1 ; max_copy = 19 */
struct lib9p_msg_Tgetattr {
lib9p_tag_t tag;
@@ -891,7 +988,7 @@ struct lib9p_msg_Tsetattr {
lib9p_tag_t tag;
lib9p_fid_t fid;
lib9p_setattr_t valid;
- uint32_t mode;
+ lib9p_mode_t mode;
lib9p_nuid_t uid;
lib9p_nuid_t gid;
uint64_t filesize;
@@ -901,6 +998,27 @@ struct lib9p_msg_Tsetattr {
uint64_t mtime_nsec;
};
+/* min_size = 34 ; exp_size = 61 ; max_size = 65,569 ; max_iov = 2 ; max_copy = 34 */
+struct lib9p_msg_Tgetlock {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_lock_type_t type;
+ uint64_t start;
+ uint64_t length;
+ uint32_t proc_id;
+ struct lib9p_s client_id;
+};
+
+/* min_size = 30 ; exp_size = 57 ; max_size = 65,565 ; max_iov = 2 ; max_copy = 30 */
+struct lib9p_msg_Rgetlock {
+ lib9p_tag_t tag;
+ lib9p_lock_type_t type;
+ uint64_t start;
+ uint64_t length;
+ uint32_t proc_id;
+ struct lib9p_s client_id;
+};
+
/* min_size = 38 ; exp_size = 65 ; max_size = 65,573 ; max_iov = 2 ; max_copy = 38 */
struct lib9p_msg_Tlock {
lib9p_tag_t tag;
@@ -1023,9 +1141,9 @@ struct lib9p_msg_Rmknod {
/* size = 160 ; max_iov = 1 ; max_copy = 160 */
struct lib9p_msg_Rgetattr {
lib9p_tag_t tag;
- uint64_t valid;
+ lib9p_getattr_t valid;
struct lib9p_qid qid;
- uint32_t mode;
+ lib9p_mode_t mode;
lib9p_nuid_t uid;
lib9p_nuid_t gid;
uint64_t nlink;
diff --git a/lib9p/include/lib9p/9p.h b/lib9p/include/lib9p/9p.h
index 7724fc8..ffac453 100644
--- a/lib9p/include/lib9p/9p.h
+++ b/lib9p/include/lib9p/9p.h
@@ -46,7 +46,7 @@ struct lib9p_ctx {
/* state */
#ifdef CONFIG_9P_ENABLE_9P2000_u
- uint32_t err_num;
+ lib9p_errno_t err_num;
#endif
[[gnu::nonstring]] char err_msg[CONFIG_9P_MAX_ERR_SIZE];
};
@@ -56,9 +56,9 @@ void lib9p_ctx_clear_error(struct lib9p_ctx *ctx);
bool lib9p_ctx_has_error(struct lib9p_ctx *ctx);
/** Write an static error into ctx, return -1. */
-int lib9p_error(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *msg);
+int lib9p_error(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *msg);
/** Write a printf-style error into ctx, return -1. */
-int lib9p_errorf(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *fmt, ...);
+int lib9p_errorf(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *fmt, ...) [[gnu::format(printf, 3, 4)]];
/* main T-message functions ***************************************************/
@@ -139,12 +139,11 @@ bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *bo
/** Assert that a `struct lib9p_stat` object looks valid. */
static inline void lib9p_stat_assert(struct lib9p_stat stat) {
- assert( ((bool)(stat.file_mode & LIB9P_DM_DIR )) == ((bool)(stat.file_qid.type & LIB9P_QT_DIR )) );
- assert( ((bool)(stat.file_mode & LIB9P_DM_APPEND )) == ((bool)(stat.file_qid.type & LIB9P_QT_APPEND )) );
- assert( ((bool)(stat.file_mode & LIB9P_DM_EXCL )) == ((bool)(stat.file_qid.type & LIB9P_QT_EXCL )) );
- assert( ((bool)(stat.file_mode & _LIB9P_DM_PLAN9_MOUNT)) == ((bool)(stat.file_qid.type & _LIB9P_QT_PLAN9_MOUNT)) );
- assert( ((bool)(stat.file_mode & LIB9P_DM_AUTH )) == ((bool)(stat.file_qid.type & LIB9P_QT_AUTH )) );
- assert( ((bool)(stat.file_mode & LIB9P_DM_TMP )) == ((bool)(stat.file_qid.type & LIB9P_QT_TMP )) );
+ assert( ((bool)(stat.file_mode & LIB9P_DM_DIR )) == ((bool)(stat.file_qid.type & LIB9P_QT_DIR )) );
+ assert( ((bool)(stat.file_mode & LIB9P_DM_APPEND)) == ((bool)(stat.file_qid.type & LIB9P_QT_APPEND)) );
+ assert( ((bool)(stat.file_mode & LIB9P_DM_EXCL )) == ((bool)(stat.file_qid.type & LIB9P_QT_EXCL )) );
+ assert( ((bool)(stat.file_mode & LIB9P_DM_AUTH )) == ((bool)(stat.file_qid.type & LIB9P_QT_AUTH )) );
+ assert( ((bool)(stat.file_mode & LIB9P_DM_TMP )) == ((bool)(stat.file_qid.type & LIB9P_QT_TMP )) );
assert( (stat.file_size == 0) || !(stat.file_mode & LIB9P_DM_DIR) );
}
@@ -160,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`.
@@ -171,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/include/lib9p/linux-errno.h.gen b/lib9p/include/lib9p/linux-errno.h.gen
index 8f4e0c8..2c736a2 100755
--- a/lib9p/include/lib9p/linux-errno.h.gen
+++ b/lib9p/include/lib9p/linux-errno.h.gen
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# lib9p/linux-errno.h.gen - Generate a C header from a list of errno numbers
#
-# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
import sys
@@ -13,7 +13,7 @@ def print_errnos() -> None:
)
errnos: dict[str, tuple[int, str]] = {}
for txtlist in sys.argv[1:]:
- with open(txtlist, "r") as fh:
+ with open(txtlist, "r", encoding="utf-8") as fh:
for line in fh:
if line.startswith("#"):
print(f"/* {line[1:].strip()} */")
@@ -26,12 +26,10 @@ def print_errnos() -> None:
print("#ifndef _LIB9P_LINUX_ERRNO_H_")
print("#define _LIB9P_LINUX_ERRNO_H_")
print()
- namelen = max(len(name) for name in errnos.keys())
+ namelen = max(len(name) for name in errnos)
numlen = max(len(str(num)) for (num, desc) in errnos.values())
- for name in errnos:
- print(
- f"#define LINUX_{name.ljust(namelen)} {str(errnos[name][0]).rjust(numlen)} /* {errnos[name][1]} */"
- )
+ for name, [num, msg] in errnos.items():
+ print(f"#define LINUX_{name:<{namelen}} {num:>{numlen}} /* {msg} */")
print()
print("#endif /* _LIB9P_LINUX_ERRNO_H_ */")
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/proto.gen b/lib9p/proto.gen
new file mode 100755
index 0000000..60f1347
--- /dev/null
+++ b/lib9p/proto.gen
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+# lib9p/proto.gen - Generate C marshalers/unmarshalers for .9p files
+# defining 9P protocol variants.
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+import os.path
+import sys
+
+sys.path.insert(0, os.path.normpath(os.path.join(__file__, "..")))
+import protogen # pylint: disable=wrong-import-position
+
+if __name__ == "__main__":
+ protogen.main()
diff --git a/lib9p/protogen/__init__.py b/lib9p/protogen/__init__.py
new file mode 100644
index 0000000..c2c6173
--- /dev/null
+++ b/lib9p/protogen/__init__.py
@@ -0,0 +1,57 @@
+# lib9p/protogen/__init__.py - Generate C marshalers/unmarshalers for
+# .9p files defining 9P protocol variants
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+import os.path
+import sys
+import typing
+
+import idl
+
+from . import c, h
+
+# pylint: disable=unused-variable
+__all__ = ["main"]
+
+
+def main() -> None:
+ if typing.TYPE_CHECKING:
+
+ class ANSIColors:
+ MAGENTA = "\x1b[35m"
+ RED = "\x1b[31m"
+ RESET = "\x1b[0m"
+
+ else:
+ from _colorize import ANSIColors # Present in Python 3.13+
+
+ if len(sys.argv) < 2:
+ raise ValueError("requires at least 1 .9p filename")
+ parser = idl.Parser()
+ for txtname in sys.argv[1:]:
+ try:
+ parser.parse_file(txtname)
+ except SyntaxError as e:
+ print(
+ f"{ANSIColors.RED}{e.filename}{ANSIColors.RESET}:{ANSIColors.MAGENTA}{e.lineno}{ANSIColors.RESET}: {e.msg}",
+ file=sys.stderr,
+ )
+ assert e.text
+ print(f"\t{e.text}", file=sys.stderr)
+ text_suffix = e.text.lstrip()
+ text_prefix = e.text[: -len(text_suffix)]
+ print(
+ f"\t{text_prefix}{ANSIColors.RED}{'~'*len(text_suffix)}{ANSIColors.RESET}",
+ file=sys.stderr,
+ )
+ sys.exit(2)
+ versions, typs = parser.all()
+ outdir = os.path.normpath(os.path.join(sys.argv[0], ".."))
+ with open(
+ os.path.join(outdir, "include/lib9p/9p.generated.h"), "w", encoding="utf-8"
+ ) as fh:
+ fh.write(h.gen_h(versions, typs))
+ with open(os.path.join(outdir, "9p.generated.c"), "w", encoding="utf-8") as fh:
+ fh.write(c.gen_c(versions, typs))
diff --git a/lib9p/protogen/c.py b/lib9p/protogen/c.py
new file mode 100644
index 0000000..5e67939
--- /dev/null
+++ b/lib9p/protogen/c.py
@@ -0,0 +1,200 @@
+# lib9p/protogen/c.py - Generate 9p.generated.c
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+import sys
+
+import idl
+
+from . import c9util, c_marshal, c_unmarshal, c_validate, cutil
+
+# This strives to be "general-purpose" in that it just acts on the
+# *.9p inputs; but (unfortunately?) there are a few special-cases in
+# this script, marked with "SPECIAL".
+
+
+# pylint: disable=unused-variable
+__all__ = ["gen_c"]
+
+
+def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
+ cutil.ifdef_init()
+
+ ret = f"""/* Generated by `{' '.join(sys.argv)}`. DO NOT EDIT! */
+
+#include <stdbool.h>
+#include <stddef.h> /* for size_t */
+#include <inttypes.h> /* for PRI* macros */
+#include <string.h> /* for memset() */
+
+#include <libmisc/assert.h>
+
+#include <lib9p/9p.h>
+
+#include "internal.h"
+"""
+
+ # utilities ################################################################
+ ret += """
+/* utilities ******************************************************************/
+"""
+
+ id2typ: dict[int, idl.Message] = {}
+ for msg in [msg for msg in typs if isinstance(msg, idl.Message)]:
+ id2typ[msg.msgid] = msg
+
+ def msg_table(grp: str, meth: str, tentry: str, rng: tuple[int, int, int]) -> str:
+ ret = f"const {tentry} {c9util.ident(f'_table_{grp}_{meth}')}[{c9util.ver_enum('NUM')}][{hex(len(range(*rng)))}] = {{\n"
+ for ver in ["unknown", *sorted(versions)]:
+ if ver != "unknown":
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
+ ret += f"\t[{c9util.ver_enum(ver)}] = {{\n"
+ for n in range(*rng):
+ xmsg: idl.Message | None = id2typ.get(n, None)
+ if xmsg:
+ if ver == "unknown": # SPECIAL (initialization)
+ if xmsg.typname not in ["Tversion", "Rversion", "Rerror"]:
+ xmsg = None
+ else:
+ if ver not in xmsg.in_versions:
+ xmsg = None
+ if xmsg:
+ ret += f"\t\t_MSG_{meth.upper()}({xmsg.typname}),\n"
+ ret += "\t},\n"
+ ret += cutil.ifdef_pop(0)
+ ret += "};\n"
+ return ret
+
+ for v in sorted(versions):
+ ret += f"#if CONFIG_9P_ENABLE_{v.replace('.', '_')}\n"
+ ret += (
+ f"\t#define _is_ver_{v.replace('.', '_')}(v) (v == {c9util.ver_enum(v)})\n"
+ )
+ ret += "#else\n"
+ ret += f"\t#define _is_ver_{v.replace('.', '_')}(v) false\n"
+ ret += "#endif\n"
+ ret += "\n"
+ ret += "/**\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)->version)\n"
+
+ # strings ##################################################################
+ ret += f"""
+/* strings ********************************************************************/
+
+const char *const {c9util.ident('_table_ver_name')}[{c9util.ver_enum('NUM')}] = {{
+"""
+ for ver in ["unknown", *sorted(versions)]:
+ if ver in versions:
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
+ ret += f'\t[{c9util.ver_enum(ver)}] = "{ver}",\n'
+ ret += cutil.ifdef_pop(0)
+ ret += "};\n"
+
+ ret += "\n"
+ ret += f"#define _MSG_NAME(typ) [{c9util.Ident('TYP_')}##typ] = #typ\n"
+ ret += msg_table("msg", "name", "char *const", (0, 0x100, 1))
+
+ # bitmasks #################################################################
+ ret += """
+/* bitmasks *******************************************************************/
+"""
+ for typ in typs:
+ if not isinstance(typ, idl.Bitfield):
+ continue
+ ret += "\n"
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef(typ.in_versions))
+ ret += f"static const {c9util.typename(typ)} {typ.typname}_masks[{c9util.ver_enum('NUM')}] = {{\n"
+ verwidth = max(len(ver) for ver in versions)
+ for ver in sorted(versions):
+ ret += cutil.ifdef_push(2, c9util.ver_ifdef({ver}))
+ ret += (
+ f"\t[{c9util.ver_enum(ver)}]{' '*(verwidth-len(ver))} = 0b"
+ + "".join(
+ (
+ "1"
+ if bit.cat in (idl.BitCat.USED, idl.BitCat.SUBFIELD)
+ and ver in bit.in_versions
+ else "0"
+ )
+ for bit in reversed(typ.bits)
+ )
+ + ",\n"
+ )
+ ret += cutil.ifdef_pop(1)
+ ret += "};\n"
+ ret += cutil.ifdef_pop(0)
+
+ # validate_* ###############################################################
+ ret += c_validate.gen_c_validate(versions, typs)
+
+ # unmarshal_* ##############################################################
+ ret += c_unmarshal.gen_c_unmarshal(versions, typs)
+
+ # marshal_* ################################################################
+ ret += c_marshal.gen_c_marshal(versions, typs)
+
+ # function tables ##########################################################
+ ret += """
+/* function tables ************************************************************/
+"""
+
+ ret += "\n"
+ ret += f"const uint32_t {c9util.ident('_table_msg_min_size')}[{c9util.ver_enum('NUM')}] = {{\n"
+ rerror = next(typ for typ in typs if typ.typname == "Rerror")
+ ret += f"\t[{c9util.ver_enum('unknown')}] = {rerror.min_size('9P2000')},\n" # SPECIAL (initialization)
+ for ver in sorted(versions):
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
+ ret += f"\t[{c9util.ver_enum(ver)}] = {rerror.min_size(ver)},\n"
+ ret += cutil.ifdef_pop(0)
+ ret += "};\n"
+
+ ret += "\n"
+ ret += cutil.macro(
+ f"#define _MSG_RECV(typ) [{c9util.Ident('TYP_')}##typ/2] = {{\n"
+ f"\t\t.basesize = sizeof(struct {c9util.ident('msg_')}##typ),\n"
+ f"\t\t.validate = validate_##typ,\n"
+ f"\t\t.unmarshal = (_unmarshal_fn_t)unmarshal_##typ,\n"
+ f"\t}}\n"
+ )
+ ret += cutil.macro(
+ f"#define _MSG_SEND(typ) [{c9util.Ident('TYP_')}##typ/2] = {{\n"
+ f"\t\t.marshal = (_marshal_fn_t)marshal_##typ,\n"
+ f"\t}}\n"
+ )
+ ret += "\n"
+ ret += msg_table(
+ "Tmsg", "recv", f"struct {c9util.ident('_recv_tentry')}", (0, 0x100, 2)
+ )
+ ret += "\n"
+ ret += msg_table(
+ "Rmsg", "recv", f"struct {c9util.ident('_recv_tentry')}", (1, 0x100, 2)
+ )
+ ret += "\n"
+ ret += msg_table(
+ "Tmsg", "send", f"struct {c9util.ident('_send_tentry')}", (0, 0x100, 2)
+ )
+ ret += "\n"
+ ret += msg_table(
+ "Rmsg", "send", f"struct {c9util.ident('_send_tentry')}", (1, 0x100, 2)
+ )
+
+ ret += f"""
+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 lib9p_ctx *ctx, uint8_t *net_bytes, void *out) {{
+\tunmarshal_stat(ctx, net_bytes, out);
+}}
+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);
+}}
+"""
+
+ ############################################################################
+ return ret
diff --git a/lib9p/protogen/c9util.py b/lib9p/protogen/c9util.py
new file mode 100644
index 0000000..e7ad999
--- /dev/null
+++ b/lib9p/protogen/c9util.py
@@ -0,0 +1,109 @@
+# lib9p/protogen/c9util.py - Utilities for generating lib9p-specific C
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+import typing
+
+import idl
+
+# This strives to be "general-purpose" in that it just acts on the
+# *.9p inputs; but (unfortunately?) there are a few special-cases in
+# this script, marked with "SPECIAL".
+
+# pylint: disable=unused-variable
+__all__ = [
+ "add_prefix",
+ "ident",
+ "Ident",
+ "IDENT",
+ "ver_enum",
+ "ver_ifdef",
+ "ver_cond",
+ "typename",
+ "idl_expr",
+]
+
+# idents #######################################################################
+
+
+def add_prefix(p: str, s: str) -> str:
+ if s.startswith("_"):
+ return "_" + p + s[1:]
+ return p + s
+
+
+def _ident(p: str, s: str) -> str:
+ return add_prefix(p, s.replace(".", "_"))
+
+
+def ident(s: str) -> str:
+ return _ident("lib9p_", s)
+
+
+def Ident(s: str) -> str:
+ return _ident("lib9p_".upper(), s)
+
+
+def IDENT(s: str) -> str:
+ return _ident("lib9p_", s).upper()
+
+
+# versions #####################################################################
+
+
+def ver_enum(ver: str) -> str:
+ return Ident("VER_" + ver)
+
+
+def ver_ifdef(versions: typing.Collection[str]) -> str:
+ return " || ".join(
+ f"CONFIG_9P_ENABLE_{v.replace('.', '_')}" for v in sorted(versions)
+ )
+
+
+def ver_cond(versions: typing.Collection[str]) -> str:
+ if len(versions) == 1:
+ v = next(v for v in versions)
+ return f"is_ver(ctx, {v.replace('.', '_')})"
+ return "( " + (" || ".join(ver_cond({v}) for v in sorted(versions))) + " )"
+
+
+# misc #########################################################################
+
+
+def typename(typ: idl.Type, parent: idl.StructMember | None = None) -> str:
+ match typ:
+ case idl.Primitive():
+ if typ.value == 1 and parent and parent.cnt: # SPECIAL (string)
+ return "[[gnu::nonstring]] char"
+ return f"uint{typ.value*8}_t"
+ case idl.Number():
+ return ident(f"{typ.typname}_t")
+ case idl.Bitfield():
+ return ident(f"{typ.typname}_t")
+ case idl.Message():
+ return f"struct {ident(f'msg_{typ.typname}')}"
+ case idl.Struct():
+ return f"struct {ident(typ.typname)}"
+ case _:
+ raise ValueError(f"not a type: {typ.__class__.__name__}")
+
+
+def idl_expr(expr: idl.Expr, lookup_sym: typing.Callable[[str], str]) -> str:
+ ret: list[str] = []
+ for tok in expr.tokens:
+ match tok:
+ case idl.ExprOp():
+ ret.append(tok.op)
+ case idl.ExprLit():
+ ret.append(str(tok.val))
+ case idl.ExprSym(symname="s32_max"):
+ ret.append("INT32_MAX")
+ case idl.ExprSym(symname="s64_max"):
+ ret.append("INT64_MAX")
+ case idl.ExprSym():
+ ret.append(lookup_sym(tok.symname))
+ case _:
+ assert False
+ return " ".join(ret)
diff --git a/lib9p/protogen/c_marshal.py b/lib9p/protogen/c_marshal.py
new file mode 100644
index 0000000..74b64f5
--- /dev/null
+++ b/lib9p/protogen/c_marshal.py
@@ -0,0 +1,386 @@
+# lib9p/protogen/c_marshal.py - Generate C marshal functions
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+import typing
+
+import idl
+
+from . import c9util, cutil, idlutil
+
+# This strives to be "general-purpose" in that it just acts on the
+# *.9p inputs; but (unfortunately?) there are a few special-cases in
+# this script, marked with "SPECIAL".
+
+
+# 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 = """
+/* marshal_* ******************************************************************/
+
+"""
+ ret += cutil.macro(
+ "#define MARSHAL_BYTES_ZEROCOPY(ctx, data, len)\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 (!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 (!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 (!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 (!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 (!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 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)
+
+ 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 (
+ 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"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)
+
+ if max_size > cutil.UINT32_MAX: # SPECIAL (9P2000.e)
+ ret += get_offset_expr(typ, go_to_end).gen_c(
+ "uint64_t", "needed_size", "val->", 1, 0
+ )
+ 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->max_msg_size) {\n"
+ if isinstance(typ, idl.Message): # SPECIAL (disable for stat)
+ 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->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
+ indent_stack = [IndentLevel(ifdef=True)]
+ idlutil.walk(typ, handle)
+ 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)
+ return ret
diff --git a/lib9p/protogen/c_unmarshal.py b/lib9p/protogen/c_unmarshal.py
new file mode 100644
index 0000000..018d750
--- /dev/null
+++ b/lib9p/protogen/c_unmarshal.py
@@ -0,0 +1,133 @@
+# lib9p/protogen/c_unmarshal.py - Generate C unmarshal functions
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+import typing
+
+import idl
+
+from . import c9util, cutil, idlutil
+
+# This strives to be "general-purpose" in that it just acts on the
+# *.9p inputs; but (unfortunately?) there are a few special-cases in
+# this script, marked with "SPECIAL".
+
+
+# pylint: disable=unused-variable
+__all__ = ["gen_c_unmarshal"]
+
+
+def gen_c_unmarshal(versions: set[str], typs: list[idl.UserType]) -> str:
+ ret = """
+/* unmarshal_* ****************************************************************/
+
+"""
+ 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"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
new file mode 100644
index 0000000..e315b60
--- /dev/null
+++ b/lib9p/protogen/c_validate.py
@@ -0,0 +1,287 @@
+# lib9p/protogen/c_validate.py - Generate C validation functions
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+import typing
+
+import idl
+
+from . import c9util, cutil, idlutil
+
+# This strives to be "general-purpose" in that it just acts on the
+# *.9p inputs; but (unfortunately?) there are a few special-cases in
+# this script, marked with "SPECIAL".
+
+
+# pylint: disable=unused-variable
+__all__ = ["gen_c_validate"]
+
+
+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_* *****************************************************************/
+
+"""
+ 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
+
+ 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))
+ 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
new file mode 100644
index 0000000..8df6db9
--- /dev/null
+++ b/lib9p/protogen/cutil.py
@@ -0,0 +1,84 @@
+# lib9p/protogen/cutil.py - Utilities for generating C code
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+# pylint: disable=unused-variable
+__all__ = [
+ "UINT32_MAX",
+ "UINT64_MAX",
+ "macro",
+ "ifdef_init",
+ "ifdef_push",
+ "ifdef_pop",
+ "ifdef_leaf_is_noop",
+]
+
+UINT32_MAX = (1 << 32) - 1
+UINT64_MAX = (1 << 64) - 1
+
+
+def tab_ljust(s: str, width: int) -> str:
+ cur = len(s.expandtabs(tabsize=8))
+ if cur >= width:
+ return s
+ return s + " " * (width - cur)
+
+
+def macro(full: str) -> str:
+ full = full.rstrip()
+ assert "\n" in full
+ 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"
+
+
+_ifdef_stack: list[str | None] = []
+
+
+def ifdef_init() -> None:
+ global _ifdef_stack
+ _ifdef_stack = []
+
+
+def ifdef_push(n: int, _newval: str) -> str:
+ # Grow the stack as needed
+ while len(_ifdef_stack) < n:
+ _ifdef_stack.append(None)
+
+ # Set some variables
+ parentval: str | None = None
+ for x in _ifdef_stack[:-1]:
+ if x is not None:
+ parentval = x
+ oldval = _ifdef_stack[-1]
+ newval: str | None = _newval
+ if newval == parentval:
+ newval = None
+
+ # Put newval on the stack.
+ _ifdef_stack[-1] = newval
+
+ # Build output.
+ ret = ""
+ if newval != oldval:
+ if oldval is not None:
+ ret += f"#endif /* {oldval} */\n"
+ if newval is not None:
+ ret += f"#if {newval}\n"
+ return ret
+
+
+def ifdef_pop(n: int) -> str:
+ global _ifdef_stack
+ ret = ""
+ while len(_ifdef_stack) > n:
+ if _ifdef_stack[-1] is not None:
+ ret += f"#endif /* {_ifdef_stack[-1]} */\n"
+ _ifdef_stack = _ifdef_stack[:-1]
+ return ret
+
+
+def ifdef_leaf_is_noop() -> bool:
+ return not _ifdef_stack[-1]
diff --git a/lib9p/protogen/h.py b/lib9p/protogen/h.py
new file mode 100644
index 0000000..7785ca1
--- /dev/null
+++ b/lib9p/protogen/h.py
@@ -0,0 +1,447 @@
+# lib9p/protogen/h.py - Generate 9p.generated.h
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+import sys
+import typing
+
+import idl
+
+from . import c9util, cutil, idlutil
+
+# This strives to be "general-purpose" in that it just acts on the
+# *.9p inputs; but (unfortunately?) there are a few special-cases in
+# this script, marked with "SPECIAL".
+
+# pylint: disable=unused-variable
+__all__ = ["gen_h"]
+
+# get_buffer_size() ############################################################
+
+
+class BufferSize(typing.NamedTuple):
+ min_size: int # really just here to sanity-check against typ.min_size(version)
+ exp_size: int # "expected" or max-reasonable size
+ max_size: int # really just here to sanity-check against typ.max_size(version)
+ max_copy: int
+ max_copy_extra: str
+ max_iov: int
+ max_iov_extra: str
+
+
+class TmpBufferSize:
+ min_size: int
+ exp_size: int
+ max_size: int
+ max_copy: int
+ max_copy_extra: str
+ max_iov: int
+ max_iov_extra: str
+
+ tmp_starts_with_copy: bool
+ tmp_ends_with_copy: bool
+
+ def __init__(self) -> None:
+ self.min_size = 0
+ self.exp_size = 0
+ self.max_size = 0
+ self.max_copy = 0
+ self.max_copy_extra = ""
+ self.max_iov = 0
+ self.max_iov_extra = ""
+ self.tmp_starts_with_copy = False
+ self.tmp_ends_with_copy = False
+
+
+def _get_buffer_size(typ: idl.Type, version: str) -> TmpBufferSize:
+ assert isinstance(typ, idl.Primitive) or (version in typ.in_versions)
+
+ ret = TmpBufferSize()
+
+ if not isinstance(typ, idl.Struct):
+ assert typ.static_size
+ ret.min_size = typ.static_size
+ ret.exp_size = typ.static_size
+ ret.max_size = typ.static_size
+ ret.max_copy = typ.static_size
+ ret.max_iov = 1
+ ret.tmp_starts_with_copy = True
+ ret.tmp_ends_with_copy = True
+ return ret
+
+ def handle(path: idlutil.Path) -> tuple[idlutil.WalkCmd, None]:
+ nonlocal ret
+ if path.elems:
+ child = path.elems[-1]
+ if version not in child.in_versions:
+ return idlutil.WalkCmd.DONT_RECURSE, None
+ if child.cnt:
+ if child.typ.static_size == 1: # SPECIAL (zerocopy)
+ ret.max_iov += 1
+ # HEURISTIC: 27 for strings (max-strlen from 9P1), 8KiB for other data
+ ret.exp_size += 27 if child.membname == "utf8" else 8192
+ ret.max_size += child.max_cnt
+ ret.tmp_ends_with_copy = False
+ return idlutil.WalkCmd.DONT_RECURSE, None
+ sub = _get_buffer_size(child.typ, version)
+ ret.exp_size += sub.exp_size * 16 # HEURISTIC: MAXWELEM
+ ret.max_size += sub.max_size * child.max_cnt
+ if child.membname == "wname" and path.root.typname in (
+ "Tsread",
+ "Tswrite",
+ ): # SPECIAL (9P2000.e)
+ assert ret.tmp_ends_with_copy
+ assert sub.tmp_starts_with_copy
+ assert not sub.tmp_ends_with_copy
+ ret.max_copy_extra = (
+ f" + (CONFIG_9P_MAX_9P2000_e_WELEM * {sub.max_copy})"
+ )
+ ret.max_iov_extra = (
+ f" + (CONFIG_9P_MAX_9P2000_e_WELEM * {sub.max_iov})"
+ )
+ ret.max_iov -= 1
+ else:
+ ret.max_copy += sub.max_copy * child.max_cnt
+ if sub.max_iov == 1 and sub.tmp_starts_with_copy: # is purely copy
+ ret.max_iov += 1
+ else: # contains zero-copy segments
+ ret.max_iov += sub.max_iov * child.max_cnt
+ if ret.tmp_ends_with_copy and sub.tmp_starts_with_copy:
+ # we can merge this one
+ ret.max_iov -= 1
+ if (
+ sub.tmp_ends_with_copy
+ and sub.tmp_starts_with_copy
+ and sub.max_iov > 1
+ ):
+ # we can merge these
+ ret.max_iov -= child.max_cnt - 1
+ ret.tmp_ends_with_copy = sub.tmp_ends_with_copy
+ return idlutil.WalkCmd.DONT_RECURSE, None
+ if not isinstance(child.typ, idl.Struct):
+ assert child.typ.static_size
+ if not ret.tmp_ends_with_copy:
+ if ret.max_size == 0:
+ ret.tmp_starts_with_copy = True
+ ret.max_iov += 1
+ ret.tmp_ends_with_copy = True
+ ret.min_size += child.typ.static_size
+ ret.exp_size += child.typ.static_size
+ ret.max_size += child.typ.static_size
+ ret.max_copy += child.typ.static_size
+ return idlutil.WalkCmd.KEEP_GOING, None
+
+ idlutil.walk(typ, handle)
+ assert ret.min_size == typ.min_size(version)
+ assert ret.max_size == typ.max_size(version)
+ return ret
+
+
+def get_buffer_size(typ: idl.Type, version: str) -> BufferSize:
+ tmp = _get_buffer_size(typ, version)
+ return BufferSize(
+ min_size=tmp.min_size,
+ exp_size=tmp.exp_size,
+ max_size=tmp.max_size,
+ max_copy=tmp.max_copy,
+ max_copy_extra=tmp.max_copy_extra,
+ max_iov=tmp.max_iov,
+ max_iov_extra=tmp.max_iov_extra,
+ )
+
+
+# Generate .h ##################################################################
+
+
+def gen_h(versions: set[str], typs: list[idl.UserType]) -> str:
+ cutil.ifdef_init()
+
+ ret = f"""/* Generated by `{' '.join(sys.argv)}`. DO NOT EDIT! */
+
+#ifndef _LIB9P_9P_H_
+\t#error Do not include <lib9p/9p.generated.h> directly; include <lib9p/9p.h> instead
+#endif
+
+#include <stdint.h> /* for uint{{n}}_t types */
+
+#include <libhw/generic/net.h> /* for struct iovec */
+"""
+
+ id2typ: dict[int, idl.Message] = {}
+ for msg in [msg for msg in typs if isinstance(msg, idl.Message)]:
+ id2typ[msg.msgid] = msg
+
+ ret += """
+/* config *********************************************************************/
+
+#include "config.h"
+"""
+ for ver in sorted(versions):
+ ret += "\n"
+ ret += f"#ifndef {c9util.ver_ifdef({ver})}\n"
+ ret += f"\t#error config.h must define {c9util.ver_ifdef({ver})}\n"
+ if ver == "9P2000.e": # SPECIAL (9P2000.e)
+ ret += "#else\n"
+ ret += f"\t#if {c9util.ver_ifdef({ver})}\n"
+ ret += "\t\t#ifndef CONFIG_9P_MAX_9P2000_e_WELEM\n"
+ ret += f"\t\t\t#error if {c9util.ver_ifdef({ver})} then config.h must define CONFIG_9P_MAX_9P2000_e_WELEM\n"
+ ret += "\t\t#endif\n"
+ ret += "\t\tstatic_assert(CONFIG_9P_MAX_9P2000_e_WELEM > 0);\n"
+ ret += "\t#endif\n"
+ ret += "#endif\n"
+
+ ret += f"""
+/* enum version ***************************************************************/
+
+enum {c9util.ident('version')} {{
+"""
+ fullversions = ["unknown = 0", *sorted(versions)]
+ verwidth = max(len(v) for v in fullversions)
+ for ver in fullversions:
+ if ver in versions:
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
+ ret += f"\t{c9util.ver_enum(ver)},"
+ ret += (" " * (verwidth - len(ver))) + ' /* "' + ver.split()[0] + '" */\n'
+ ret += cutil.ifdef_pop(0)
+ ret += f"\t{c9util.ver_enum('NUM')},\n"
+ ret += "};\n"
+
+ ret += """
+/* enum msg_type **************************************************************/
+
+"""
+ ret += f"enum {c9util.ident('msg_type')} {{ /* uint8_t */\n"
+ namewidth = max(len(msg.typname) for msg in typs if isinstance(msg, idl.Message))
+ for n in range(0x100):
+ if n not in id2typ:
+ continue
+ msg = id2typ[n]
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef(msg.in_versions))
+ ret += f"\t{c9util.Ident(f'TYP_{msg.typname:<{namewidth}}')} = {msg.msgid},\n"
+ ret += cutil.ifdef_pop(0)
+ ret += "};\n"
+
+ ret += """
+/* payload types **************************************************************/
+"""
+
+ def per_version_comment(
+ typ: idl.UserType, fn: typing.Callable[[idl.UserType, str], str]
+ ) -> str:
+ lines: dict[str, str] = {}
+ for version in sorted(typ.in_versions):
+ lines[version] = fn(typ, version)
+ if len(set(lines.values())) == 1:
+ for _, line in lines.items():
+ return f"/* {line} */\n"
+ assert False
+ else:
+ ret = ""
+ v_width = max(len(c9util.ver_enum(v)) for v in typ.in_versions)
+ for version, line in lines.items():
+ ret += f"/* {c9util.ver_enum(version):<{v_width}}: {line} */\n"
+ return ret
+
+ for typ in idlutil.topo_sorted(typs):
+ ret += "\n"
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef(typ.in_versions))
+
+ def sum_size(typ: idl.UserType, version: str) -> str:
+ sz = get_buffer_size(typ, version)
+ assert (
+ sz.min_size <= sz.exp_size
+ and sz.exp_size <= sz.max_size
+ and sz.max_size < cutil.UINT64_MAX
+ )
+ ret = ""
+ if sz.min_size == sz.max_size:
+ ret += f"size = {sz.min_size:,}"
+ else:
+ ret += f"min_size = {sz.min_size:,} ; exp_size = {sz.exp_size:,} ; max_size = {sz.max_size:,}"
+ if sz.max_size > cutil.UINT32_MAX:
+ ret += " (warning: >UINT32_MAX)"
+ ret += f" ; max_iov = {sz.max_iov:,}{sz.max_iov_extra} ; max_copy = {sz.max_copy:,}{sz.max_copy_extra}"
+ return ret
+
+ ret += per_version_comment(typ, sum_size)
+
+ match typ:
+ case idl.Number():
+ ret += f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n"
+ prefix = f"{c9util.IDENT(typ.typname)}_"
+ namewidth = max(len(name) for name in typ.vals)
+ for name, val in typ.vals.items():
+ ret += f"#define {prefix}{name:<{namewidth}} (({c9util.typename(typ)})UINT{typ.static_size*8}_C({val}))\n"
+ case idl.Bitfield():
+ ret += f"typedef {c9util.typename(typ.prim)} {c9util.typename(typ)};\n"
+
+ def bitname(val: idl.Bit | idl.BitAlias) -> str:
+ s = val.bitname
+ match val:
+ case idl.Bit(cat=idl.BitCat.RESERVED):
+ s = "_RESERVED_" + s
+ case idl.Bit(cat=idl.BitCat.SUBFIELD):
+ assert isinstance(typ, idl.Bitfield)
+ n = sum(
+ 1
+ for b in typ.bits[: val.num]
+ if b.cat == idl.BitCat.SUBFIELD
+ and b.bitname == val.bitname
+ )
+ s = f"_{s}_{n}"
+ case idl.Bit(cat=idl.BitCat.UNUSED):
+ return ""
+ return c9util.Ident(c9util.add_prefix(typ.typname.upper() + "_", s))
+
+ namewidth = max(
+ len(bitname(val)) for val in [*typ.bits, *typ.names.values()]
+ )
+
+ ret += "\n"
+ for bit in reversed(typ.bits):
+ vers = bit.in_versions
+ if bit.cat == idl.BitCat.UNUSED:
+ vers = typ.in_versions
+ ret += cutil.ifdef_push(2, c9util.ver_ifdef(vers))
+
+ # It is important all of the `beg` strings have
+ # the same length.
+ end = ""
+ match bit.cat:
+ case (
+ idl.BitCat.USED | idl.BitCat.RESERVED | idl.BitCat.SUBFIELD
+ ):
+ if cutil.ifdef_leaf_is_noop():
+ beg = "#define "
+ else:
+ beg = "# define"
+ case idl.BitCat.UNUSED:
+ beg = "/* unused"
+ end = " */"
+
+ c_name = bitname(bit)
+ c_val = f"1<<{bit.num}"
+ ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n"
+ if aliases := [
+ alias
+ for alias in typ.names.values()
+ if isinstance(alias, idl.BitAlias)
+ ]:
+ ret += "\n"
+
+ for alias in aliases:
+ ret += cutil.ifdef_push(2, c9util.ver_ifdef(alias.in_versions))
+
+ end = ""
+ if cutil.ifdef_leaf_is_noop():
+ beg = "#define "
+ else:
+ beg = "# define"
+
+ c_name = bitname(alias)
+ c_val = alias.val
+ ret += f"{beg} {c_name:<{namewidth}} (({c9util.typename(typ)})({c_val})){end}\n"
+ ret += cutil.ifdef_pop(1)
+ del bitname
+ case idl.Struct(): # and idl.Message():
+ ret += c9util.typename(typ) + " {"
+ if not typ.members:
+ ret += "};\n"
+ continue
+ ret += "\n"
+
+ typewidth = max(len(c9util.typename(m.typ, m)) for m in typ.members)
+
+ for member in typ.members:
+ if member.val:
+ continue
+ ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions))
+ ret += f"\t{c9util.typename(member.typ, member):<{typewidth}} {'*' if member.cnt else ' '}{member.membname};\n"
+ ret += cutil.ifdef_pop(1)
+ ret += "};\n"
+ del typ
+ ret += cutil.ifdef_pop(0)
+
+ ret += """
+/* containers *****************************************************************/
+"""
+ ret += "\n"
+ ret += f"#define {c9util.IDENT('_MAX')}(a, b) ((a) > (b)) ? (a) : (b)\n"
+
+ tmsg_max_iov: dict[str, int] = {}
+ tmsg_max_copy: dict[str, int] = {}
+ rmsg_max_iov: dict[str, int] = {}
+ rmsg_max_copy: dict[str, int] = {}
+ for typ in typs:
+ if not isinstance(typ, idl.Message):
+ continue
+ if typ.typname in ("Tsread", "Tswrite"): # SPECIAL (9P2000.e)
+ continue
+ max_iov = tmsg_max_iov if typ.msgid % 2 == 0 else rmsg_max_iov
+ max_copy = tmsg_max_copy if typ.msgid % 2 == 0 else rmsg_max_copy
+ for version in typ.in_versions:
+ if version not in max_iov:
+ max_iov[version] = 0
+ max_copy[version] = 0
+ sz = get_buffer_size(typ, version)
+ if sz.max_iov > max_iov[version]:
+ max_iov[version] = sz.max_iov
+ if sz.max_copy > max_copy[version]:
+ max_copy[version] = sz.max_copy
+
+ for name, table in [
+ ("tmsg_max_iov", tmsg_max_iov),
+ ("tmsg_max_copy", tmsg_max_copy),
+ ("rmsg_max_iov", rmsg_max_iov),
+ ("rmsg_max_copy", rmsg_max_copy),
+ ]:
+ inv: dict[int, set[str]] = {}
+ for version, maxval in table.items():
+ if maxval not in inv:
+ inv[maxval] = set()
+ inv[maxval].add(version)
+
+ ret += "\n"
+ directive = "if"
+ seen_e = False # SPECIAL (9P2000.e)
+ for maxval in sorted(inv, reverse=True):
+ ret += f"#{directive} {c9util.ver_ifdef(inv[maxval])}\n"
+ indent = 1
+ if name.startswith("tmsg") and not seen_e: # SPECIAL (9P2000.e)
+ typ = next(typ for typ in typs if typ.typname == "Tswrite")
+ sz = get_buffer_size(typ, "9P2000.e")
+ match name:
+ case "tmsg_max_iov":
+ maxexpr = f"{sz.max_iov}{sz.max_iov_extra}"
+ case "tmsg_max_copy":
+ maxexpr = f"{sz.max_copy}{sz.max_copy_extra}"
+ case _:
+ assert False
+ ret += f"\t#if {c9util.ver_ifdef({"9P2000.e"})}\n"
+ ret += f"\t\t#define {c9util.IDENT(name)} {c9util.IDENT('_MAX')}({maxval}, {maxexpr})\n"
+ ret += "\t#else\n"
+ indent += 1
+ ret += f"{'\t'*indent}#define {c9util.IDENT(name)} {maxval}\n"
+ if name.startswith("tmsg") and not seen_e: # SPECIAL (9P2000.e)
+ ret += "\t#endif\n"
+ if "9P2000.e" in inv[maxval]:
+ seen_e = True
+ directive = "elif"
+ ret += "#endif\n"
+
+ ret += "\n"
+ ret += f"struct {c9util.ident('Tmsg_send_buf')} {{\n"
+ ret += "\tsize_t iov_cnt;\n"
+ ret += f"\tstruct iovec iov[{c9util.IDENT('TMSG_MAX_IOV')}];\n"
+ ret += f"\tuint8_t copied[{c9util.IDENT('TMSG_MAX_COPY')}];\n"
+ ret += "};\n"
+
+ ret += "\n"
+ ret += f"struct {c9util.ident('Rmsg_send_buf')} {{\n"
+ ret += "\tsize_t iov_cnt;\n"
+ ret += f"\tstruct iovec iov[{c9util.IDENT('RMSG_MAX_IOV')}];\n"
+ ret += f"\tuint8_t copied[{c9util.IDENT('RMSG_MAX_COPY')}];\n"
+ ret += "};\n"
+
+ return ret
diff --git a/lib9p/protogen/idlutil.py b/lib9p/protogen/idlutil.py
new file mode 100644
index 0000000..dc4d012
--- /dev/null
+++ b/lib9p/protogen/idlutil.py
@@ -0,0 +1,112 @@
+# lib9p/protogen/idlutil.py - Utilities for working with the 9P idl package
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+import enum
+import graphlib
+import typing
+
+import idl
+
+# pylint: disable=unused-variable
+__all__ = [
+ "topo_sorted",
+ "Path",
+ "WalkCmd",
+ "WalkHandler",
+ "walk",
+]
+
+# topo_sorted() ################################################################
+
+
+def topo_sorted(typs: list[idl.UserType]) -> typing.Iterable[idl.UserType]:
+ ts: graphlib.TopologicalSorter[idl.UserType] = graphlib.TopologicalSorter()
+ for typ in typs:
+ match typ:
+ case idl.Number():
+ ts.add(typ)
+ case idl.Bitfield():
+ ts.add(typ)
+ case idl.Struct(): # and idl.Message():
+ deps = [
+ member.typ
+ for member in typ.members
+ if not isinstance(member.typ, idl.Primitive)
+ ]
+ ts.add(typ, *deps)
+ return ts.static_order()
+
+
+# walk() #######################################################################
+
+
+class Path:
+ root: idl.Type
+ elems: list[idl.StructMember]
+
+ def __init__(
+ self, root: idl.Type, elems: list[idl.StructMember] | None = None
+ ) -> None:
+ self.root = root
+ self.elems = elems if elems is not None else []
+
+ def add(self, elem: idl.StructMember) -> "Path":
+ return Path(self.root, self.elems + [elem])
+
+ def parent(self) -> "Path":
+ return Path(self.root, self.elems[:-1])
+
+ def c_str(self, base: str, loopdepth: int = 0) -> str:
+ ret = base
+ for i, elem in enumerate(self.elems):
+ if i > 0:
+ ret += "."
+ ret += elem.membname
+ if elem.cnt:
+ ret += f"[{chr(ord('i')+loopdepth)}]"
+ loopdepth += 1
+ return ret
+
+ def __str__(self) -> str:
+ return self.c_str(self.root.typname + "->")
+
+
+class WalkCmd(enum.Enum):
+ KEEP_GOING = 1
+ DONT_RECURSE = 2
+ ABORT = 3
+
+
+type WalkHandler = typing.Callable[
+ [Path], tuple[WalkCmd, typing.Callable[[], None] | None]
+]
+
+
+def _walk(path: Path, handle: WalkHandler) -> WalkCmd:
+ typ = path.elems[-1].typ if path.elems else path.root
+
+ ret, atexit = handle(path)
+
+ if isinstance(typ, idl.Struct):
+ match ret:
+ case WalkCmd.KEEP_GOING:
+ for member in typ.members:
+ if _walk(path.add(member), handle) == WalkCmd.ABORT:
+ ret = WalkCmd.ABORT
+ break
+ case WalkCmd.DONT_RECURSE:
+ ret = WalkCmd.KEEP_GOING
+ case WalkCmd.ABORT:
+ ret = WalkCmd.ABORT
+ case _:
+ assert False, f"invalid cmd: {ret}"
+
+ if atexit:
+ atexit()
+ return ret
+
+
+def walk(typ: idl.Type, handle: WalkHandler) -> None:
+ _walk(Path(typ), handle)
diff --git a/lib9p/srv.c b/lib9p/srv.c
index 932cd4d..2475baf 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -81,7 +81,7 @@ struct _srv_fidinfo {
uint8_t flags;
uint32_t iounit;
size_t dir_idx;
- uint32_t dir_off;
+ uint64_t dir_off;
};
#define NAME fidmap
@@ -566,7 +566,7 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx,
if (req->max_msg_size < min_msg_size) {
lib9p_errorf(&ctx->ctx.basectx,
LINUX_EDOM, "requested max_msg_size is less than minimum for %s (%"PRIu32" < %"PRIu32")",
- version, req->max_msg_size, min_msg_size);
+ lib9p_version_str(version), req->max_msg_size, min_msg_size);
return;
}
@@ -935,7 +935,7 @@ static void handle_Tread(struct _lib9p_srv_req *ctx,
idx = fidinfo->dir_idx;
else {
lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EINVAL, "invalid offset (must be 0 or %"PRIu32"): %"PRIu32,
+ LINUX_EINVAL, "invalid offset (must be 0 or %"PRIu64"): %"PRIu64,
fidinfo->dir_off, req->offset);
return;
}
diff --git a/lib9p/tests/runtest b/lib9p/tests/runtest
index c2f6c41..a745f12 100755
--- a/lib9p/tests/runtest
+++ b/lib9p/tests/runtest
@@ -7,11 +7,12 @@
set -euE -o pipefail
set -x
-valgrind --error-exitcode=2 ./tests/test_server/test_server &
+port=$(python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()')
+valgrind --error-exitcode=2 ./tests/test_server/test_server "$port" &
server_pid=$!
# shellcheck disable=SC2064
trap "kill $server_pid || true; wait $server_pid || true" EXIT
-server_addr='localhost:9000'
+server_addr="localhost:${port}"
client=(9p -a "$server_addr")
@@ -31,7 +32,7 @@ expect_lines \
out=$("${client[@]}" ls -l 'Documentation/')
expect_lines \
- '--r--r--r-- M 0 root root 162 Oct 7 15:51 x'
+ '--r--r--r-- M 0 root root 166 Oct 7 15:51 x'
out=$("${client[@]}" read 'README.md')
expect_lines \
@@ -46,7 +47,7 @@ expect_lines \
out=$("${client[@]}" read 'Documentation/x')
expect_lines \
'<!--' \
- ' Documentation/x - test static file' \
+ ' Documentation/x.txt - test static file' \
'' \
' Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>' \
' SPDX-License-Identifier: AGPL-3.0-or-later' \
@@ -55,7 +56,7 @@ expect_lines \
out=$("${client[@]}" stat 'Documentation/x')
expect_lines \
- "'x' 'root' 'root' 'root' q (0000000000000001 1 ) m 0444 at 1728337905 mt 1728337904 l 162 t 0 d 0"
+ "'x' 'root' 'root' 'root' q (0000000000000001 1 ) m 0444 at 1728337905 mt 1728337904 l 166 t 0 d 0"
out=$("${client[@]}" write 'shutdown' <<<1)
expect_lines ''
diff --git a/lib9p/tests/test_compile.c b/lib9p/tests/test_compile.c
new file mode 100644
index 0000000..6abee05
--- /dev/null
+++ b/lib9p/tests/test_compile.c
@@ -0,0 +1,157 @@
+/* lib9p/tests/test_compile.c - Generated by lib9p/tests/test_compile.c.gen. DO NOT EDIT! */
+
+#include <lib9p/9p.h>
+int main(void) {
+ [[gnu::unused]] uint64_t x;
+ x = LIB9P_TAG_NOTAG;
+ x = LIB9P_FID_NOFID;
+ x = LIB9P_DM_DIR;
+ x = LIB9P_DM_APPEND;
+ x = LIB9P_DM_EXCL;
+ x = _LIB9P_DM_RESERVED_PLAN9_MOUNT;
+ x = LIB9P_DM_AUTH;
+ x = LIB9P_DM_TMP;
+ x = LIB9P_DM_DEVICE;
+ x = LIB9P_DM_NAMEDPIPE;
+ x = LIB9P_DM_SOCKET;
+ x = LIB9P_DM_SETUID;
+ x = LIB9P_DM_SETGID;
+ x = LIB9P_DM_OWNER_R;
+ x = LIB9P_DM_OWNER_W;
+ x = LIB9P_DM_OWNER_X;
+ x = LIB9P_DM_GROUP_R;
+ x = LIB9P_DM_GROUP_W;
+ x = LIB9P_DM_GROUP_X;
+ x = LIB9P_DM_OTHER_R;
+ x = LIB9P_DM_OTHER_W;
+ x = LIB9P_DM_OTHER_X;
+ x = LIB9P_DM_PERM_MASK;
+ x = LIB9P_QT_DIR;
+ x = LIB9P_QT_APPEND;
+ x = LIB9P_QT_EXCL;
+ x = _LIB9P_QT_RESERVED_PLAN9_MOUNT;
+ x = LIB9P_QT_AUTH;
+ x = LIB9P_QT_TMP;
+ x = LIB9P_QT_SYMLINK;
+ x = LIB9P_QT_FILE;
+ x = LIB9P_NUID_NONUID;
+ x = LIB9P_O_RCLOSE;
+ x = _LIB9P_O_RESERVED_CEXEC;
+ x = LIB9P_O_TRUNC;
+ x = _LIB9P_O_mode_1;
+ x = _LIB9P_O_mode_0;
+ x = LIB9P_O_READ;
+ x = LIB9P_O_WRITE;
+ x = LIB9P_O_RDWR;
+ x = LIB9P_O_EXEC;
+ x = LIB9P_O_MODE_MASK;
+ x = LIB9P_O_FLAG_MASK;
+ x = LIB9P_ERRNO_NOERROR;
+ x = LIB9P_SUPER_MAGIC_V9FS_MAGIC;
+ x = LIB9P_LO_SYNC;
+ x = LIB9P_LO_CLOEXEC;
+ x = LIB9P_LO_NOATIME;
+ x = LIB9P_LO_NOFOLLOW;
+ x = LIB9P_LO_DIRECTORY;
+ x = LIB9P_LO_LARGEFILE;
+ x = LIB9P_LO_DIRECT;
+ x = LIB9P_LO_BSD_FASYNC;
+ x = LIB9P_LO_DSYNC;
+ x = LIB9P_LO_NONBLOCK;
+ x = LIB9P_LO_APPEND;
+ x = LIB9P_LO_TRUNC;
+ x = LIB9P_LO_NOCTTY;
+ x = LIB9P_LO_EXCL;
+ x = LIB9P_LO_CREATE;
+ x = _LIB9P_LO_mode_1;
+ x = _LIB9P_LO_mode_0;
+ x = LIB9P_LO_RDONLY;
+ x = LIB9P_LO_WRONLY;
+ x = LIB9P_LO_RDWR;
+ x = LIB9P_LO_NOACCESS;
+ x = LIB9P_LO_MODE_MASK;
+ x = LIB9P_LO_FLAG_MASK;
+ x = LIB9P_DT_UNKNOWN;
+ x = LIB9P_DT_NAMED_PIPE;
+ x = LIB9P_DT_CHAR_DEV;
+ x = LIB9P_DT_DIRECTORY;
+ x = LIB9P_DT_BLOCK_DEV;
+ x = LIB9P_DT_REGULAR;
+ x = LIB9P_DT_SYMLINK;
+ x = LIB9P_DT_SOCKET;
+ x = LIB9P_DT_WHITEOUT;
+ x = _LIB9P_MODE_fmt_3;
+ x = _LIB9P_MODE_fmt_2;
+ x = _LIB9P_MODE_fmt_1;
+ x = _LIB9P_MODE_fmt_0;
+ x = LIB9P_MODE_PERM_SETGROUP;
+ x = LIB9P_MODE_PERM_SETUSER;
+ x = LIB9P_MODE_PERM_STICKY;
+ x = LIB9P_MODE_PERM_OWNER_R;
+ x = LIB9P_MODE_PERM_OWNER_W;
+ x = LIB9P_MODE_PERM_OWNER_X;
+ x = LIB9P_MODE_PERM_GROUP_R;
+ x = LIB9P_MODE_PERM_GROUP_W;
+ x = LIB9P_MODE_PERM_GROUP_X;
+ x = LIB9P_MODE_PERM_OTHER_R;
+ x = LIB9P_MODE_PERM_OTHER_W;
+ x = LIB9P_MODE_PERM_OTHER_X;
+ x = LIB9P_MODE_FMT_NAMED_PIPE;
+ x = LIB9P_MODE_FMT_CHAR_DEV;
+ x = LIB9P_MODE_FMT_DIRECTORY;
+ x = LIB9P_MODE_FMT_BLOCK_DEV;
+ x = LIB9P_MODE_FMT_REGULAR;
+ x = LIB9P_MODE_FMT_SYMLINK;
+ x = LIB9P_MODE_FMT_SOCKET;
+ x = LIB9P_MODE_PERM_MASK;
+ x = LIB9P_MODE_FMT_MASK;
+ x = LIB9P_B4_FALSE;
+ x = LIB9P_B4_TRUE;
+ x = LIB9P_GETATTR_DATA_VERSION;
+ x = LIB9P_GETATTR_GEN;
+ x = LIB9P_GETATTR_BTIME;
+ x = LIB9P_GETATTR_BLOCKS;
+ x = LIB9P_GETATTR_SIZE;
+ x = LIB9P_GETATTR_INO;
+ x = LIB9P_GETATTR_CTIME;
+ x = LIB9P_GETATTR_MTIME;
+ x = LIB9P_GETATTR_ATIME;
+ x = LIB9P_GETATTR_RDEV;
+ x = LIB9P_GETATTR_GID;
+ x = LIB9P_GETATTR_UID;
+ x = LIB9P_GETATTR_NLINK;
+ x = LIB9P_GETATTR_MODE;
+ x = LIB9P_GETATTR_BASIC;
+ x = LIB9P_GETATTR_ALL;
+ x = LIB9P_SETATTR_MTIME_SET;
+ x = LIB9P_SETATTR_ATIME_SET;
+ x = LIB9P_SETATTR_CTIME;
+ x = LIB9P_SETATTR_MTIME;
+ x = LIB9P_SETATTR_ATIME;
+ x = LIB9P_SETATTR_SIZE;
+ x = LIB9P_SETATTR_GID;
+ x = LIB9P_SETATTR_UID;
+ x = LIB9P_SETATTR_MODE;
+ x = LIB9P_LOCK_TYPE_RDLCK;
+ x = LIB9P_LOCK_TYPE_WRLCK;
+ x = LIB9P_LOCK_TYPE_UNLCK;
+ x = LIB9P_LOCK_FLAGS_RECLAIM;
+ x = LIB9P_LOCK_FLAGS_BLOCK;
+ x = LIB9P_LOCK_STATUS_SUCCESS;
+ x = LIB9P_LOCK_STATUS_BLOCKED;
+ x = LIB9P_LOCK_STATUS_ERROR;
+ x = LIB9P_LOCK_STATUS_GRACE;
+ x = LIB9P_TMSG_MAX_IOV;
+ x = LIB9P_TMSG_MAX_IOV;
+ x = LIB9P_TMSG_MAX_COPY;
+ x = LIB9P_TMSG_MAX_COPY;
+ x = LIB9P_TMSG_MAX_COPY;
+ x = LIB9P_TMSG_MAX_COPY;
+ x = LIB9P_TMSG_MAX_COPY;
+ x = LIB9P_TMSG_MAX_COPY;
+ x = LIB9P_RMSG_MAX_IOV;
+ x = LIB9P_RMSG_MAX_IOV;
+ x = LIB9P_RMSG_MAX_IOV;
+ x = LIB9P_RMSG_MAX_COPY;
+ return 0;
+}
diff --git a/lib9p/tests/test_compile.c.gen b/lib9p/tests/test_compile.c.gen
new file mode 100755
index 0000000..47046b3
--- /dev/null
+++ b/lib9p/tests/test_compile.c.gen
@@ -0,0 +1,19 @@
+#!/bin/sh
+# lib9p/tests/test_compile.c.gen - Generate code to make sure all generated macros work
+#
+# Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+generated_h=$1
+outfile=$2
+
+{
+ echo "/* ${outfile} - Generated by $0. DO NOT EDIT! */"
+ echo
+ echo "#include <lib9p/9p.h>"
+ echo 'int main(void) {'
+ echo ' [[gnu::unused]] uint64_t x;'
+ sed -nE 's/^\s*#\s*define\s*(\S[^ (]*)\s.*/ x = \1;/p' <"$generated_h"
+ echo ' return 0;'
+ echo '}'
+} >"$outfile"
diff --git a/lib9p/tests/test_compile_config/config.h b/lib9p/tests/test_compile_config/config.h
new file mode 100644
index 0000000..38ab0c0
--- /dev/null
+++ b/lib9p/tests/test_compile_config/config.h
@@ -0,0 +1,38 @@
+/* config.h - Compile-time configuration for lib9p/test/test_compile
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _CONFIG_H_
+#define _CONFIG_H_
+
+/* 9P *************************************************************************/
+
+#define CONFIG_9P_MAX_MSG_SIZE ((4*1024)+24)
+#define CONFIG_9P_MAX_HOSTMSG_SIZE CONFIG_9P_MAX_MSG_SIZE+16
+#define CONFIG_9P_MAX_ERR_SIZE 128
+#define CONFIG_9P_MAX_9P2000_e_WELEM 16
+
+#define CONFIG_9P_SRV_MAX_FIDS 16
+#define CONFIG_9P_SRV_MAX_REQS 2
+#define CONFIG_9P_SRV_MAX_DEPTH 3
+
+#define CONFIG_9P_ENABLE_9P2000 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_u 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_e 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_L 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_p9p 1 /* bool */
+
+/* COROUTINE ******************************************************************/
+
+#define CONFIG_COROUTINE_STACK_SIZE_DEFAULT (32*1024)
+#define CONFIG_COROUTINE_NAME_LEN 16
+#define CONFIG_COROUTINE_MEASURE_STACK 1 /* bool */
+#define CONFIG_COROUTINE_PROTECT_STACK 1 /* bool */
+#define CONFIG_COROUTINE_DEBUG 0 /* bool */
+#define CONFIG_COROUTINE_VALGRIND 1 /* bool */
+#define CONFIG_COROUTINE_GDB 1 /* bool */
+#define CONFIG_COROUTINE_NUM 2
+
+#endif /* _CONFIG_H_ */
diff --git a/lib9p/tests/test_server/CMakeLists.txt b/lib9p/tests/test_server/CMakeLists.txt
index a107b75..74a759d 100644
--- a/lib9p/tests/test_server/CMakeLists.txt
+++ b/lib9p/tests/test_server/CMakeLists.txt
@@ -18,6 +18,7 @@ target_link_libraries(test_server_objs
libmisc
lib9p
lib9p_util
+ libhw
)
# Analyze the stack ############################################################
@@ -36,7 +37,7 @@ target_sources(test_server PRIVATE
target_embed_sources(test_server_objs test_server static.h
static/README.md
- static/Documentation/x
+ static/Documentation/x.txt
)
endif()
diff --git a/lib9p/tests/test_server/config/config.h b/lib9p/tests/test_server/config/config.h
index 67960ca..afe6dc0 100644
--- a/lib9p/tests/test_server/config/config.h
+++ b/lib9p/tests/test_server/config/config.h
@@ -1,4 +1,4 @@
-/* config.h - Compile-time configuration for srv9p
+/* config.h - Compile-time configuration for lib9p/test/test_server
*
* Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -12,7 +12,6 @@
/* 9P *************************************************************************/
-#define CONFIG_9P_PORT LIB9P_DEFAULT_PORT_9FS
/**
* This max-msg-size is sized so that a Twrite message can return
* 8KiB of data.
diff --git a/lib9p/tests/test_server/main.c b/lib9p/tests/test_server/main.c
index c60dd71..074dbe7 100644
--- a/lib9p/tests/test_server/main.c
+++ b/lib9p/tests/test_server/main.c
@@ -5,6 +5,7 @@
*/
#include <error.h>
+#include <stdlib.h> /* for atoi() */
#include <lib9p/srv.h>
#include <libcr/coroutine.h>
@@ -32,6 +33,7 @@ static lo_interface lib9p_srv_file get_root(struct lib9p_srv_ctx *, struct lib9p
const char *hexdig = "0123456789abcdef";
struct {
+ uint16_t port;
struct hostnet_tcp_listener listeners[CONFIG_SRV9P_NUM_CONNS];
struct lib9p_srv srv;
} globals = {
@@ -130,7 +132,7 @@ enum { PATH_BASE = __COUNTER__ };
struct lib9p_srv_file root =
STATIC_DIR("",
STATIC_DIR("Documentation",
- STATIC_FILE("x", Documentation_x),
+ STATIC_FILE("x", Documentation_x_txt),
),
STATIC_FILE("README.md", README_md),
lo_box_api_as_lib9p_srv_file(&(struct api_file){.pathnum = PATH_COUNTER}),
@@ -146,7 +148,7 @@ static COROUTINE read_cr(void *_i) {
int i = *((int *)_i);
cr_begin();
- hostnet_tcp_listener_init(&globals.listeners[i], 9000);
+ hostnet_tcp_listener_init(&globals.listeners[i], globals.port);
lib9p_srv_read_cr(&globals.srv, lo_box_hostnet_tcplist_as_net_stream_listener(&globals.listeners[i]));
@@ -172,7 +174,10 @@ static COROUTINE init_cr(void *) {
cr_exit();
}
-int main() {
+int main(int argc, char *argv[]) {
+ if (argc != 2)
+ error(2, 0, "usage: %s PORT_NUMBER", argv[0]);
+ globals.port = atoi(argv[1]);
struct hostclock clock_monotonic = {
.clock_id = CLOCK_MONOTONIC,
};
diff --git a/lib9p/tests/test_server/static/Documentation/x b/lib9p/tests/test_server/static/Documentation/x.txt
index b9b08d4..e85ee4e 100644
--- a/lib9p/tests/test_server/static/Documentation/x
+++ b/lib9p/tests/test_server/static/Documentation/x.txt
@@ -1,5 +1,5 @@
<!--
- Documentation/x - test static file
+ Documentation/x.txt - test static file
Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
SPDX-License-Identifier: AGPL-3.0-or-later