aboutgitcodelistschat:MatrixIRC
path: root/cooker/parse.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2023-05-02 09:48:50 +0200
committerStefano Brivio <sbrivio@redhat.com>2023-05-02 10:39:32 +0200
commit82b77505f9420f11d614c2ae0f74153ca4ee3cb5 (patch)
treeec93abd39cd8c7ff2818c7446da6cc01864b2ae1 /cooker/parse.c
parenta2c20b2caf4e9cedb32b0930ffd7ca2e9ec72086 (diff)
downloadseitan-82b77505f9420f11d614c2ae0f74153ca4ee3cb5.tar
seitan-82b77505f9420f11d614c2ae0f74153ca4ee3cb5.tar.gz
seitan-82b77505f9420f11d614c2ae0f74153ca4ee3cb5.tar.bz2
seitan-82b77505f9420f11d614c2ae0f74153ca4ee3cb5.tar.lz
seitan-82b77505f9420f11d614c2ae0f74153ca4ee3cb5.tar.xz
seitan-82b77505f9420f11d614c2ae0f74153ca4ee3cb5.tar.zst
seitan-82b77505f9420f11d614c2ae0f74153ca4ee3cb5.zip
cooker updates spilling all over the place
Only tangentially related: - make seitan C99 again, so that I can build cooker without warnings - make Makefiles make use of the usual conventions about assigning directory paths in variables, drop numbers.h as requirement for cooker and make it convenient to run stand-alone Makefiles - fix up nr_syscalls.sh to be POSIX, otherwise it will give syntax errors on my system - define a single, common way to refer to offsets in gluten, and functions to use those offsets in a safe way. Immediates are gone: cooker will write any bit of "data" to the read-only section - call const what has to be const - define on-disk layout for gluten - add OP_NR (to check syscall numbers), rename OP_COPY_ARGS to OP_LOAD (it loads _selected_ stuff from arguments) As for cooker itself: - drop ARG_ and arg_ prefixes from struct names, and similar - add/rework functions to build OP_NR, OP_LOAD, OP_CMP, and to write constant data to gluten - add parsing for "compound" arguments, but that's not completely hooked into evaluation for numeric arguments yet Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'cooker/parse.c')
-rw-r--r--cooker/parse.c100
1 files changed, 87 insertions, 13 deletions
diff --git a/cooker/parse.c b/cooker/parse.c
index 9d8a7be..0a87088 100644
--- a/cooker/parse.c
+++ b/cooker/parse.c
@@ -35,7 +35,7 @@ static int parse_match_load(struct gluten_ctx *g, struct arg *a)
return 0;
}
-static long long parse_match_expr_num(struct arg_num *desc, JSON_Value *value)
+static long long parse_match_expr_num(struct num *desc, JSON_Value *value)
{
const char *s = NULL;
long long n;
@@ -59,35 +59,109 @@ static long long parse_match_expr_num(struct arg_num *desc, JSON_Value *value)
return n;
}
-static int parse_match_key(struct gluten_ctx *g, int index, enum arg_type type,
- union arg_value desc, JSON_Value *value)
+static void parse_match_expr_value(union desc desc, enum type type,
+ JSON_Value *value, union value *out)
+{
+ if (TYPE_IS_NUM(type))
+ out->v_num = parse_match_expr_num(desc.d_num, value);
+}
+
+/**
+ * parse_match_select() - Get description and type for selected value
+ * @s: Possible selection choices
+ * @v: Selector value
+ * @type: Type of selected value, set on return
+ * @desc: Description of selected value, set on return
+ */
+static void parse_match_select(struct select *s, union value v,
+ enum type *type, union desc *desc)
+{
+ if (TYPE_IS_NUM(s->field->type)) {
+ struct select_num *d_num;
+
+ for (d_num = s->desc.d_num; d_num->type; d_num++) {
+ if (d_num->value == v.v_num) {
+ *type = d_num->type;
+ *desc = d_num->desc;
+ return;
+ }
+ }
+
+ if (!d_num->type)
+ die(" No match for numeric selector %i", v.v_num);
+ }
+
+ die(" not supported yet");
+}
+
+/*
+ * parse_match_arg()
+ * load argument
+ * parse_match_key()
+ * compound types? demux, parse_match_expr
+ * parse_match_expr
+ * in/all/not/false-true array: demux, parse_match_expr_{num,string}
+ * parse_match_expr_{num,string}
+ *
+ * at terminal values
+ * store ref *pointers*! no copies
+ * emit additional bpf statement if syscall arg is also terminal
+*/
+static int parse_match_key(struct gluten_ctx *g, int index, enum type type,
+ union desc desc, JSON_Value *value)
{
JSON_Object *tmp;
const char *ref;
- (void)index;
+ if (type == SELECT) {
+ struct gluten_offset base_offset, const_offset;
+ struct select *select = desc.d_select;
+ struct field *field = select->field;
+ JSON_Value *selector;
+ union value v;
+
+ if (!(tmp = json_value_get_object(value)))
+ die(" no object for compound value");
+
+ if (!(selector = json_object_get_value(tmp, field->name)))
+ die(" missing selector for '%s'", field->name);
+
+ parse_match_expr_value(field->desc, field->type, selector, &v);
+
+ base_offset = g->match_dst[index].offset;
+ const_offset = emit_data(g, field->type, &v);
+ emit_cmp_field(g, CMP_NE, field, base_offset, const_offset,
+ NEXT_BLOCK);
+
+ parse_match_select(select, v, &type, &desc);
+ }
if (json_value_get_type(value) == JSONObject &&
(tmp = json_value_get_object(value)) &&
(ref = json_object_get_string(tmp, "ref"))) {
+ if (TYPE_IS_COMPOUND(type))
+ die("Reference '%s' to compound value");
+
debug(" setting reference '%s'", ref);
- gluten_alloc_type(g, type);
value = json_object_get_value(tmp, "value");
+
+ emit_load(g, gluten_alloc_type(g, type), index, type);
}
+ /* Nothing to match on: just store as reference */
if (!value)
return 0;
switch (type) {
- case ARG_INTFLAGS:
- case ARG_LONGFLAGS:
- case ARG_U32FLAGS:
+ case INTFLAGS:
+ case LONGFLAGS:
+ case U32FLAGS:
/* fetch/combine expr algebra loop */
- case ARG_INTMASK:
+ case INTMASK:
/* calculate mask first */
- case ARG_INT:
- case ARG_LONG:
- case ARG_U32:
+ case INT:
+ case LONG:
+ case U32:
parse_match_expr_num(desc.d_num, value);
//emit_cmp(...);
default:
@@ -139,7 +213,6 @@ static int parse_matches(struct gluten_ctx *g, JSON_Value *value)
const char *name;
g->lr = g->ip;
- g->sp = 0;
match = json_array_get_object(matches, i);
name = json_object_get_name(match, 0);
@@ -229,6 +302,7 @@ int parse_file(struct gluten_ctx *g, const char *path)
blocks = json_value_get_array(root);
for (i = 0; i < json_array_get_count(blocks); i++) {
obj = json_array_get_object(blocks, i);
+
debug("Parsing block %i", i);
parse_block(g, obj);
}