From c021082abcc9d94c2e94679f6729265fe65529a3 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Sun, 4 Jun 2023 09:51:15 +0200 Subject: cooker: Generic attributes and ATTR_SIZE Signed-off-by: Stefano Brivio --- cooker/call.c | 28 ++++++++-------------------- cooker/calls/ioctl.c | 6 +++--- cooker/calls/net.c | 12 ++++++------ cooker/cooker.h | 21 ++++++++++++++++++++- cooker/gluten.c | 30 ++++++++++++++++++++++++++++++ cooker/gluten.h | 6 ++++++ cooker/parse.c | 16 +++++++++++++++- cooker/parse.h | 1 + 8 files changed, 89 insertions(+), 31 deletions(-) diff --git a/cooker/call.c b/cooker/call.c index 6182a5b..d44ff6f 100644 --- a/cooker/call.c +++ b/cooker/call.c @@ -142,27 +142,15 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args, case INT: case LONG: case U32: - if (f->flags == SIZE && !dry_run) { - unsigned i; - - for (i = 0; args[i].f.type; i++) { - if (args[i].pos == f->desc.d_arg_size) - break; - } - if (!args[i].f.type) - die("no argument found for SIZE field"); - - v.v_num = args[i].f.size; + if (f->flags == SIZE) { + v.v_num = value_get_size(g, f->desc.d_size); + } else if (f->flags == FLAGS) { + /* fetch/combine expr algebra loop */ + v.v_num = value_get_num(f->desc.d_num, jvalue); + } else if (f->flags == MASK) { + /* calculate mask first */ + v.v_num = value_get_num(f->desc.d_num, jvalue); } else { - if (f->flags == FLAGS) { - /* fetch/combine expr algebra loop */ - ; - } - if (f->flags == MASK) { - /* calculate mask first */ - ; - } - v.v_num = value_get_num(f->desc.d_num, jvalue); } diff --git a/cooker/calls/ioctl.c b/cooker/calls/ioctl.c index c9f01d0..1609541 100644 --- a/cooker/calls/ioctl.c +++ b/cooker/calls/ioctl.c @@ -83,7 +83,7 @@ static struct field tun_ifr[] = { /* netdevice(7) */ }; static struct select_num ioctl_request_arg[] = { - { FS_IOC_GETFLAGS, + { FS_IOC_GETFLAGS, -1, { 2, { "argp", INT, FLAGS, @@ -92,7 +92,7 @@ static struct select_num ioctl_request_arg[] = { } } }, - { FS_IOC_SETFLAGS, + { FS_IOC_SETFLAGS, -1, { 2, { "argp", INT, FLAGS, @@ -101,7 +101,7 @@ static struct select_num ioctl_request_arg[] = { } } }, - { TUNSETIFF, + { TUNSETIFF, -1, { 2, { "ifr", STRUCT, 0, diff --git a/cooker/calls/net.c b/cooker/calls/net.c index 746a08e..7231a0e 100644 --- a/cooker/calls/net.c +++ b/cooker/calls/net.c @@ -168,7 +168,7 @@ static struct field connect_family = { }; static struct select_num connect_addr_select_family[] = { - { AF_UNIX, + { AF_UNIX, sizeof(struct sockaddr_un), { 1, { NULL, STRUCT, 0, 0, 0, @@ -176,7 +176,7 @@ static struct select_num connect_addr_select_family[] = { } } }, - { AF_INET, + { AF_INET, sizeof(struct sockaddr_in), { 1, { NULL, STRUCT, 0, 0, 0, @@ -184,7 +184,7 @@ static struct select_num connect_addr_select_family[] = { } } }, - { AF_INET6, + { AF_INET6, sizeof(struct sockaddr_in6), { 1, { NULL, STRUCT, 0, 0, 0, @@ -192,7 +192,7 @@ static struct select_num connect_addr_select_family[] = { } } }, - { AF_NETLINK, + { AF_NETLINK, sizeof(struct sockaddr_nl), { 1, { NULL, STRUCT, 0, 0, 0, @@ -228,7 +228,7 @@ static struct arg connect_args[] = { { "addr", SELECT, 0, 0, - sizeof(struct sockaddr_un), + sizeof(struct sockaddr_storage), { .d_select = &connect_addr_select }, }, }, @@ -237,7 +237,7 @@ static struct arg connect_args[] = { "addrlen", LONG, SIZE, 0, 0, - { .d_arg_size = 1 }, + { .d_size = (intptr_t)&connect_addr_select }, }, }, { 0 } diff --git a/cooker/cooker.h b/cooker/cooker.h index c59a5dc..40277c2 100644 --- a/cooker/cooker.h +++ b/cooker/cooker.h @@ -20,6 +20,7 @@ #include #define TAGS_MAX 256 +#define ATTRS_MAX 256 #define CALL_ARGS 6 struct num; @@ -38,7 +39,7 @@ union desc { struct num *d_num; struct field *d_struct; struct select *d_select; - int d_arg_size; + intptr_t d_size; }; /** @@ -152,10 +153,12 @@ struct arg { /** * struct select_num - List of possible selections based on numeric selector * @value: Numeric value of the selector + * @sel_size: Size associated with selection (not necessarily argument size) * @target: Argument description defined by this selector */ struct select_num { long long value; + ssize_t sel_size; struct arg target; }; @@ -172,4 +175,20 @@ struct select { } desc; }; +enum attr_type { + ATTR_NONE = 0, + ATTR_SIZE, +}; + +/** + * struct attr - Generic attribute for syscall model with link + * @id: Link + * @v: Attribute value + */ +struct attr { + enum attr_type type; + intptr_t id; + union value v; +}; + #endif /* COOKER_H */ diff --git a/cooker/gluten.c b/cooker/gluten.c index a488dfd..01c2369 100644 --- a/cooker/gluten.c +++ b/cooker/gluten.c @@ -123,6 +123,36 @@ struct gluten_offset gluten_get_tag(struct gluten_ctx *g, const char *name) return g->tags[0].offset; /* Pro forma, not actually happening */ } +void gluten_add_attr(struct gluten_ctx *g, enum attr_type type, intptr_t id, + union value v) +{ + int i; + + for (i = 0; i < ATTRS_MAX && g->attrs[i].id; i++); + if (i == ATTRS_MAX) + die("Too many attributes"); + + g->attrs[i].type = type; + g->attrs[i].id = id; + g->attrs[i].v = v; + + debug(" attribute '%p' set", id); +} + +union value gluten_get_attr(struct gluten_ctx *g, enum attr_type type, + intptr_t id) +{ + int i; + + for (i = 0; i < ATTRS_MAX && g->attrs[i].type; i++) { + if (g->attrs[i].type == type && g->attrs[i].id == id) + return g->attrs[i].v; + } + + die(" attribute '%p' not found", id); + return g->attrs[0].v; /* Pro forma, not actually happening */ +} + /** * gluten_init() - Initialise gluten structures and layout * @g: gluten context diff --git a/cooker/gluten.h b/cooker/gluten.h index 17d762b..9474700 100644 --- a/cooker/gluten.h +++ b/cooker/gluten.h @@ -34,6 +34,8 @@ struct gluten_ctx { struct gluten_tag_data tags[TAGS_MAX]; + struct attr attrs[ATTRS_MAX]; + struct arg *selected_arg[6]; }; @@ -56,6 +58,10 @@ void gluten_add_tag(struct gluten_ctx *g, const char *name, void gluten_add_tag_post(struct gluten_ctx *g, const char *name, struct gluten_offset offset); struct gluten_offset gluten_get_tag(struct gluten_ctx *g, const char *name); +void gluten_add_attr(struct gluten_ctx *g, enum attr_type type, intptr_t id, + union value v); +union value gluten_get_attr(struct gluten_ctx *g, enum attr_type type, + intptr_t id); void gluten_init(struct gluten_ctx *g); void gluten_block_init(struct gluten_ctx *g); void gluten_write(struct gluten_ctx *g, const char *path); diff --git a/cooker/parse.c b/cooker/parse.c index 5a474f8..ab77e6b 100644 --- a/cooker/parse.c +++ b/cooker/parse.c @@ -57,7 +57,7 @@ static void handle_fd(struct gluten_ctx *g, JSON_Value *value) } if (json_object_get_value(obj, "return")) - desc.do_return = json_object_get_boolean(obj, "return") + desc.do_return = json_object_get_boolean(obj, "return"); if (json_object_get_value(obj, "close_on_exec")) desc.cloexec = json_object_get_boolean(obj, "close_on_exec"); @@ -139,6 +139,14 @@ long long value_get_num(struct num *desc, JSON_Value *value) return n; } +ssize_t value_get_size(struct gluten_ctx *g, intptr_t id) +{ + if (!g) + return -1; + + return gluten_get_attr(g, ATTR_SIZE, id).v_num; +} + /** * value_get() - Get generic value from description matching JSON input * @desc: Description of possible values from model @@ -170,6 +178,12 @@ struct field *select_field(struct gluten_ctx *g, int pos, for (d_num = s->desc.d_num; d_num->target.f.type; d_num++) { if (d_num->value == v.v_num) { + if (g && d_num->sel_size != -1) { + v.v_num = d_num->sel_size; + gluten_add_attr(g, ATTR_SIZE, + (intptr_t)s, v); + } + if (d_num->target.pos == pos) return &d_num->target.f; diff --git a/cooker/parse.h b/cooker/parse.h index ece2848..8bb37a4 100644 --- a/cooker/parse.h +++ b/cooker/parse.h @@ -7,6 +7,7 @@ #define PARSE_H long long value_get_num(struct num *desc, JSON_Value *value); +size_t value_get_size(struct gluten_ctx *g, intptr_t id); void value_get(union desc desc, enum type type, JSON_Value *value, union value *out); struct field *select_field(struct gluten_ctx *g, int pos, -- cgit v1.2.3