static int allocate_gpr_pair(struct fetch_context *ctx, struct Process *proc, struct arg_type_info *info, struct value *valuep, size_t sz) { assert(!s390x(ctx)); assert(sz <= 8); if (ctx->greg > 5) { ctx->greg = 7; return allocate_stack_slot(ctx, proc, info, valuep, sz); } if (value_reserve(valuep, sz) == NULL) return -1; unsigned char *ptr = value_get_raw_data(valuep); union { struct { uint32_t a; uint32_t b; }; unsigned char buf[8]; } u; u.a = ctx->regs.gprs[ctx->greg++]; u.b = ctx->regs.gprs[ctx->greg++]; memcpy(ptr, u.buf, sz); return 0; }
unsigned char * value_get_data(struct value *val, struct value_dict *arguments) { if (value_reify(val, arguments) < 0) return NULL; return value_get_raw_data(val); }
unsigned char * value_reserve(struct value *valp, size_t size) { value_release(valp); if (size <= sizeof(valp->u.value)) { valp->where = VAL_LOC_WORD; valp->u.value = 0; } else { valp->where = VAL_LOC_COPY; valp->u.address = calloc(size, 1); if (valp->u.address == 0) return NULL; } return value_get_raw_data(valp); }
static int allocate_fpr(struct fetch_context *ctx, struct Process *proc, struct arg_type_info *info, struct value *valuep, size_t sz) { int pool = s390x(ctx) ? 6 : 2; if (ctx->freg > pool) return allocate_stack_slot(ctx, proc, info, valuep, sz); if (value_reserve(valuep, sz) == NULL) return -1; memcpy(value_get_raw_data(valuep), &ctx->regs.fp_regs.fprs[ctx->freg], sz); ctx->freg += 2; return 0; }
int value_init_element(struct value *ret_val, struct value *val, size_t element) { size_t off = type_offsetof(val->inferior, val->type, element); if (off == (size_t)-1) return -1; struct arg_type_info *e_info = type_element(val->type, element); if (e_info == NULL) return -1; value_common_init(ret_val, val->inferior, val, e_info, 0); switch (val->where) { case VAL_LOC_COPY: case VAL_LOC_SHARED: ret_val->u.address = val->u.address + off; ret_val->where = VAL_LOC_SHARED; return 0; case VAL_LOC_WORD: ret_val->u.address = value_get_raw_data(val) + off; ret_val->where = VAL_LOC_SHARED; return 0; case VAL_LOC_INFERIOR: ret_val->u.inf_address = val->u.inf_address + off; ret_val->where = VAL_LOC_INFERIOR; return 0; case VAL_LOC_NODATA: assert(!"Can't offset NODATA."); abort(); } abort(); }