diff options
Diffstat (limited to 'cooker/emit.c')
-rw-r--r-- | cooker/emit.c | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/cooker/emit.c b/cooker/emit.c index 33355b6..7d13a02 100644 --- a/cooker/emit.c +++ b/cooker/emit.c @@ -217,18 +217,19 @@ void emit_store(struct gluten_ctx *g, struct gluten_offset dst, * @iov: Pointer to msg_iov, already stored in gluten * @iovlen: Pointer to msg_iovlen, already stored in gluten * @dst: gluten destination to copy dereferenced data + * @alloc: Allocation size (alloc - len bytes filled with zeroes) * @len: Maximum length of data to copy altogether */ struct gluten_offset emit_iovload(struct gluten_ctx *g, struct gluten_offset iov, struct gluten_offset iovlen, - size_t len) + size_t alloc, size_t len) { struct op *op = (struct op *)gluten_ptr(&g->g, g->ip); struct op_iovload *load = &op->op.iovload; struct gluten_offset dst; - dst = gluten_rw_alloc(g, len); + dst = gluten_rw_alloc(g, alloc); op->type = OP_IOVLOAD; @@ -237,6 +238,7 @@ struct gluten_offset emit_iovload(struct gluten_ctx *g, load->dst = dst; load->size = len; + load->zero_fill = alloc - len; debug(" %i: OP_IOVLOAD: #%i < (#%i) as iovec (size: %lu)", g->ip.offset, dst.offset, iov.offset, len); @@ -294,6 +296,7 @@ void emit_resolvefd(struct gluten_ctx *g, enum type type, * emit_bitwise(): Emit OP_BITWISE instruction: bitwise operation and store * @g: gluten context * @type: Type of operands + * @vec: Description of vector structure, NULL for scalar operation * @op_type: Type of bitwise operation * @dst: gluten pointer to destination operand, can be OFFSET_NULL * @x: gluten pointer to first source operand @@ -302,6 +305,7 @@ void emit_resolvefd(struct gluten_ctx *g, enum type type, * Return: offset to destination operand, allocated here if not given */ struct gluten_offset emit_bitwise(struct gluten_ctx *g, enum type type, + struct vec_desc *vec, enum bitwise_type op_type, struct gluten_offset dst, struct gluten_offset x, @@ -311,6 +315,7 @@ struct gluten_offset emit_bitwise(struct gluten_ctx *g, enum type type, struct op_bitwise *op_bitwise = &op->op.bitwise; struct gluten_offset o; struct bitwise_desc *desc; + char ip_str[BUFSIZ]; op->type = OP_BITWISE; @@ -319,21 +324,42 @@ struct gluten_offset emit_bitwise(struct gluten_ctx *g, enum type type, desc->size = gluten_size[type]; desc->type = op_type; - if (dst.type == OFFSET_NULL) - desc->dst = gluten_rw_alloc(g, desc->size); - else + + if (vec) + desc->vec = *vec; + + if (dst.type == OFFSET_NULL) { + size_t dst_size; + if (vec) /* FIXME: UIO_MAXIOV (1024) is a dubious choice */ + dst_size = (desc->size + sizeof(uint32_t)) * 1024; + else + dst_size = desc->size; + + desc->dst = gluten_rw_alloc(g, dst_size); + } else { desc->dst = dst; + } + desc->x = x; desc->y = y; op_bitwise->desc = o; - debug(" %i: OP_BITWISE: %s: #%lu (size: %lu) := %s: #%lu %s %s: #%lu", - g->ip.offset, + snprintf(ip_str, BUFSIZ, "%i", g->ip.offset); + + debug(" %s: OP_BITWISE: %s: #%lu (size: %lu) := %s: #%lu %s %s: #%lu", + ip_str, gluten_offset_name[desc->dst.type], desc->dst.offset, desc->size, gluten_offset_name[desc->x.type], desc->x.offset, bitwise_type_str[op_type], gluten_offset_name[desc->y.type], desc->y.offset); + if (vec) { + memset(ip_str, ' ', strlen(ip_str)); + debug(" %s vector start: %s: #%lu, length descriptor at %lu", + ip_str, + gluten_offset_name[vec->start.type], vec->start.offset, + vec->len_offset); + } if (++g->ip.offset > INST_MAX) die("Too many instructions"); @@ -345,12 +371,14 @@ struct gluten_offset emit_bitwise(struct gluten_ctx *g, enum type type, * emit_cmp(): Emit OP_CMP instruction: compare data from two offsets * @g: gluten context * @cmp_type: Type of comparison + * @vec: Description of vector structure, NULL for scalar comparison * @x: gluten pointer to first operand of comparison * @y: gluten pointer to second operand of comparison * @size: Size of comparison * @jmp: Jump direction if comparison is true */ void emit_cmp(struct gluten_ctx *g, enum op_cmp_type cmp_type, + struct vec_desc *vec, struct gluten_offset x, struct gluten_offset y, size_t size, enum jump_type jmp) { @@ -367,6 +395,11 @@ void emit_cmp(struct gluten_ctx *g, enum op_cmp_type cmp_type, desc->x = x; desc->y = y; desc->size = size; + if (vec) + desc->vec = *vec; + else + desc->vec.start.type = OFFSET_NULL; + desc->cmp = cmp_type; desc->jmp.type = OFFSET_INSTRUCTION; desc->jmp.offset = jmp; @@ -388,17 +421,18 @@ void emit_cmp(struct gluten_ctx *g, enum op_cmp_type cmp_type, * emit_cmp_field() - Emit OP_CMP for a given field type * @g: gluten context * @cmp: Type of comparison + * @vec: Description of vector structure, NULL for scalar comparison * @field: Description of field from system call model * @x: gluten pointer to first operand of comparison * @y: gluten pointer to second operand of comparison * @jmp: Jump direction if comparison is true */ void emit_cmp_field(struct gluten_ctx *g, enum op_cmp_type cmp, - struct field *field, + struct vec_desc *vec, struct field *field, struct gluten_offset x, struct gluten_offset y, enum jump_type jmp) { - emit_cmp(g, cmp, x, y, + emit_cmp(g, cmp, vec, x, y, field->size ? field->size : gluten_size[field->type], jmp); } |