diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2023-06-02 06:21:21 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2023-06-02 06:21:21 +0200 |
commit | 80309fbd77cbafa3784fa7295afb56c446d59b93 (patch) | |
tree | 27cfa1ce846e1d2dc0aa2e55487db66120312aff /cooker/emit.c | |
parent | 1644bbec6161ec971a2ba3c213ce285b995cac22 (diff) | |
download | seitan-80309fbd77cbafa3784fa7295afb56c446d59b93.tar seitan-80309fbd77cbafa3784fa7295afb56c446d59b93.tar.gz seitan-80309fbd77cbafa3784fa7295afb56c446d59b93.tar.bz2 seitan-80309fbd77cbafa3784fa7295afb56c446d59b93.tar.lz seitan-80309fbd77cbafa3784fa7295afb56c446d59b93.tar.xz seitan-80309fbd77cbafa3784fa7295afb56c446d59b93.tar.zst seitan-80309fbd77cbafa3784fa7295afb56c446d59b93.zip |
cooker, seitan: OP_CALL arguments and context
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'cooker/emit.c')
-rw-r--r-- | cooker/emit.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/cooker/emit.c b/cooker/emit.c index 403f1ba..705df4b 100644 --- a/cooker/emit.c +++ b/cooker/emit.c @@ -53,6 +53,60 @@ void emit_nr(struct gluten_ctx *g, struct gluten_offset number) } /** + * emit_call() - Emit OP_CALL instruction: execute a system call + * @g: gluten context + * @ns: NS_SPEC_NONE-terminated array of namespaces references + * @nr: System call number + * @count: Argument count + * @is_ptr: Array indicating whether arguments need to be dereferenced + * @args: Offsets of arguments + * @ret_offset: Offset where return value must be saved, can be OFFSET_NULL + */ +void emit_call(struct gluten_ctx *g, struct ns_spec *ns, long nr, + unsigned count, bool is_ptr[6], + struct gluten_offset offset[6], struct gluten_offset ret_offset) +{ + struct op *op = (struct op *)gluten_ptr(&g->g, g->ip); + struct gluten_offset o1 = { 0 }, o2 = { 0 }; + struct op_call *call = &op->op.call; + struct syscall_desc *desc; + unsigned ns_count, i; + struct ns_spec *ctx; + + for (ns_count = 0; ns[ns_count].spec != NS_SPEC_NONE; ns_count++); + + if (ns_count) { + o1 = gluten_ro_alloc(g, sizeof(struct ns_spec) * ns_count); + ctx = (struct ns_spec *)gluten_ptr(&g->g, o1); + memcpy(ctx, ns, sizeof(struct ns_spec) * ns_count); + } + + o2 = gluten_ro_alloc(g, sizeof(struct syscall_desc) + + sizeof(struct gluten_offset) * + (count + (ret_offset.type != OFFSET_NULL))); + desc = (struct syscall_desc *)gluten_ptr(&g->g, o2); + desc->nr = nr; + desc->arg_count = count; + desc->has_ret = ret_offset.type != OFFSET_NULL; + for (i = 0; i < count; i++) + desc->arg_deref |= BIT(i) * is_ptr[i]; + desc->context = o1; + memcpy(desc->args, offset, sizeof(struct gluten_offset) * count); + desc->args[count + 1] = ret_offset; + + debug(" %i: OP_CALL: %i, arguments:", g->ip.offset, nr); + for (i = 0; i < count; i++) { + debug("\t%i: %s %s%i", i, gluten_offset_name[offset[i].type], + is_ptr[i] ? "*" : "", offset[i].offset); + } + + call->desc = o2; + + if (++g->ip.offset > INST_MAX) + die("Too many instructions"); +} + +/** * emit_load() - Emit OP_LOAD instruction: dereference and copy syscall argument * @g: gluten context * @dst: gluten destination to copy dereferenced data @@ -152,6 +206,7 @@ void emit_return(struct gluten_ctx *g, struct gluten_offset v) if (++g->ip.offset > INST_MAX) die("Too many instructions"); } + /** * emit_block() - Emit OP_BLOCK instruction: return error value * @g: gluten context |