Esempio n. 1
0
int
arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
		    struct Process *proc,
		    struct arg_type_info *info, struct value *valuep)
{
	size_t sz = type_sizeof(proc, info);
	if (sz == (size_t)-1)
		return -1;

	switch (info->type) {
	case ARGTYPE_VOID:
		value_set_word(valuep, 0);
		return 0;

	case ARGTYPE_STRUCT:
		if (type_get_fp_equivalent(info) != NULL)
			/* fall through */
	case ARGTYPE_FLOAT:
	case ARGTYPE_DOUBLE:
			return allocate_fpr(ctx, proc, info, valuep, sz);

		/* Structures<4 bytes on s390 and structures<8 bytes
		 * on s390x are passed in register.  On s390, long
		 * long and structures<8 bytes are passed in two
		 * consecutive registers (if two are available).  */

		if (sz <= (s390x(ctx) ? 8 : 4))
			return allocate_gpr(ctx, proc, info, valuep, sz);
		else if (sz <= 8)
			return allocate_gpr_pair(ctx, proc, info, valuep, sz);

		/* fall through */

	case ARGTYPE_ARRAY:
		if (value_pass_by_reference(valuep) < 0)
			return -1;
		/* fall through */

	case ARGTYPE_INT:
	case ARGTYPE_UINT:
	case ARGTYPE_LONG:
	case ARGTYPE_ULONG:
	case ARGTYPE_CHAR:
	case ARGTYPE_SHORT:
	case ARGTYPE_USHORT:
	case ARGTYPE_POINTER:
		return allocate_gpr(ctx, proc, info, valuep, sz);

	default:
		assert(info->type != info->type);
		abort();
	}
	return -1;
}
Esempio n. 2
0
static int
zero_callback_max(struct value *ret_value, struct value *lhs,
		  struct value_dict *arguments,
		  size_t max, void *data)
{
	size_t i;
	for (i = 0; i < max; ++i) {
		struct value element;
		if (value_init_element(&element, lhs, i) < 0)
			return -1;

		int zero = value_is_zero(&element, arguments);

		value_destroy(&element);

		if (zero)
			break;
	}

	struct arg_type_info *long_type = type_get_simple(ARGTYPE_LONG);
	value_init_detached(ret_value, NULL, long_type, 0);
	value_set_word(ret_value, i);
	return 0;
}
Esempio n. 3
0
static void
copy_gpr(struct fetch_context *ctx, struct value *valuep, int regno)
{
	value_set_word(valuep, ctx->regs.gprs[regno]);
}
/* Syntax:
 *   enum (keyname[=value],keyname[=value],... )
 *   enum<type> (keyname[=value],keyname[=value],... )
 */
static int
parse_enum(struct protolib *plib, struct locus *loc, char **str,
	   struct arg_type_info **retp, int *ownp)
{
	/* Optional type argument.  */
	eat_spaces(str);
	if (**str == '[') {
		parse_char(loc, str, '[');
		eat_spaces(str);
		*retp = parse_nonpointer_type(plib, loc, str, NULL, 0, ownp, 0);
		if (*retp == NULL)
			return -1;

		if (!type_is_integral((*retp)->type)) {
			report_error(loc->filename, loc->line_no,
				     "integral type required as enum argument");
		fail:
			if (*ownp) {
				/* This also releases associated lens
				 * if any was set so far.  */
				type_destroy(*retp);
				free(*retp);
			}
			return -1;
		}

		eat_spaces(str);
		if (parse_char(loc, str, ']') < 0)
			goto fail;

	} else {
		*retp = type_get_simple(ARGTYPE_INT);
		*ownp = 0;
	}

	/* We'll need to set the lens, so unshare.  */
	if (unshare_type_info(loc, retp, ownp) < 0)
		goto fail;

	eat_spaces(str);
	if (parse_char(loc, str, '(') < 0)
		goto fail;

	struct enum_lens *lens = malloc(sizeof(*lens));
	if (lens == NULL) {
		report_error(loc->filename, loc->line_no,
			     "malloc enum lens: %s", strerror(errno));
		return -1;
	}

	lens_init_enum(lens);
	(*retp)->lens = &lens->super;
	(*retp)->own_lens = 1;

	long last_val = 0;
	while (1) {
		eat_spaces(str);
		if (**str == 0 || **str == ')') {
			parse_char(loc, str, ')');
			return 0;
		}

		/* Field delimiter.  XXX should we support the C
		 * syntax, where the enumeration can end in pending
		 * comma?  */
		if (lens_enum_size(lens) > 0)
			parse_char(loc, str, ',');

		eat_spaces(str);
		char *key = parse_ident(loc, str);
		if (key == NULL) {
		err:
			free(key);
			goto fail;
		}

		if (**str == '=') {
			++*str;
			eat_spaces(str);
			if (parse_int(loc, str, &last_val) < 0)
				goto err;
		}

		struct value *value = malloc(sizeof(*value));
		if (value == NULL)
			goto err;
		value_init_detached(value, NULL, *retp, 0);
		value_set_word(value, last_val);

		if (lens_enum_add(lens, key, 1, value, 1) < 0)
			goto err;

		last_val++;
	}

	return 0;
}