Ejemplo n.º 1
0
static void write_const(CTX *ctx, struct ir_const_val v)
{
    char *s = const_unparse(NULL, v);
    if (TEST_UNION(IR_TYPE, tarray, &v.type)) {
        fprintf(ctx->f, "{%s}", s);
    } else if (type_is_integer(v.type)) {
        // Get rid of annoying-but-correct gcc warning. This happens because we
        // negate a value not representable in intmax_t, even though the result
        // is representable, i.e. the only case is INT64_MIN.
        if (type_equals(v.type, type_integer(true, 64))
            && *GET_UNION(VALUE, vuint64, &v.value) == INT64_MIN)
        {
            fprintf(ctx->f, "INT64_MIN");
        } else {
            fprintf(ctx->f, "%s(%s)", int_const(v.type), s);
        }
    } else if (TEST_UNION(IR_TYPE, tslice, &v.type)) {
        if (TEST_UNION0(VALUE, vempty, &v.value)) {
            fprintf(ctx->f, "{0}");
        } else if (type_equals(v.type, TYPE_STRING)) {
            char *raw = *GET_UNION(VALUE, vstring, &v.value);
            fprintf(ctx->f, "{ %s, %zd }", s, raw ? strlen(raw) : 0);
        } else {
            assert(false);
        }
    } else {
        fprintf(ctx->f, "%s", s);
    }
    talloc_free(s);
}
Ejemplo n.º 2
0
static int
type_equals(mdb_ctf_id_t a, mdb_ctf_id_t b)
{
	size_t asz, bsz;
	int akind, bkind;
	mdb_ctf_arinfo_t aar, bar;

	/*
	 * Resolve both types down to their fundamental types, and make
	 * sure their sizes and kinds match.
	 */
	if (mdb_ctf_type_resolve(a, &a) != 0 ||
	    mdb_ctf_type_resolve(b, &b) != 0 ||
	    (asz = mdb_ctf_type_size(a)) == -1UL ||
	    (bsz = mdb_ctf_type_size(b)) == -1UL ||
	    (akind = mdb_ctf_type_kind(a)) == -1 ||
	    (bkind = mdb_ctf_type_kind(b)) == -1 ||
	    asz != bsz || akind != bkind) {
		return (0);
	}

	switch (akind) {
	case CTF_K_INTEGER:
	case CTF_K_FLOAT:
	case CTF_K_POINTER:
		/*
		 * For pointers we could be a little stricter and require
		 * both pointers to reference types which look vaguely
		 * similar (for example, we could insist that the two types
		 * have the same name). However, all we really care about
		 * here is that the structure of the two types are the same,
		 * and, in that regard, one pointer is as good as another.
		 */
		return (1);

	case CTF_K_UNION:
	case CTF_K_STRUCT:
		/*
		 * The test for the number of members is only strictly
		 * necessary for unions since we'll find other problems with
		 * structs. However, the extra check will do no harm.
		 */
		return (mdb_ctf_num_members(a) == mdb_ctf_num_members(b) &&
		    mdb_ctf_member_iter(a, type_equals_cb, &b) == 0);

	case CTF_K_ARRAY:
		return (mdb_ctf_array_info(a, &aar) == 0 &&
		    mdb_ctf_array_info(b, &bar) == 0 &&
		    aar.mta_nelems == bar.mta_nelems &&
		    type_equals(aar.mta_index, bar.mta_index) &&
		    type_equals(aar.mta_contents, bar.mta_contents));
	}

	return (0);
}
Ejemplo n.º 3
0
Archivo: type.c Proyecto: ryvnf/zc1
bool type_equals(const struct type *a, const struct type *b) {
	if (a->val != b->val)
		return false;
	switch (a->val) {
	case TYPE_POINTER:
		return type_equals(a->next, b->next);
	case TYPE_ARRAY:
		return (
			a->u.n_elems == b->u.n_elems &&
			type_equals(a->next, b->next)
		);
	case TYPE_FUNCTION:
		if (a->u.func.n_params != b->u.func.n_params)
			return false;
		/* check if parameters are not equal */
		for (unsigned i = 0; i < a->u.func.n_params; ++i) {
			if (!type_equals(
				a->u.func.params[i],
				b->u.func.params[i]
			)) {
				return false;
			}
		}
		/* check if return is not equal */
		if (!type_equals(a->next, b->next))
			return false;
		/* check if both have the the same variadic value */
		if (a->u.func.is_variadic != b->u.func.is_variadic)
			return false;
		return true;
	case TYPE_INT:
	case TYPE_UINT:
		return a->u.n_bits == b->u.n_bits;
	case TYPE_VOID:
	case TYPE_BOOL:
	case TYPE_HALF:
	case TYPE_FLOAT:
	case TYPE_DOUBLE:
		return true;
	default:
		ERROR_HERE;
		break;
	}
}
Ejemplo n.º 4
0
static int
type_equals_cb(const char *name, mdb_ctf_id_t amem, ulong_t aoff, void *data)
{
	mdb_ctf_id_t b = *(mdb_ctf_id_t *)data;
	ulong_t boff;
	mdb_ctf_id_t bmem;

	/*
	 * Look up the corresponding member in the other composite type.
	 */
	if (mdb_ctf_member_info(b, name, &boff, &bmem) != 0)
		return (1);

	/*
	 * We don't allow members to be shuffled around.
	 */
	if (aoff != boff)
		return (1);

	return (type_equals(amem, bmem) ? 0 : 1);
}
Ejemplo n.º 5
0
static int
vread_helper(mdb_ctf_id_t modid, char *modbuf,
    mdb_ctf_id_t tgtid, char *tgtbuf, uint_t flags)
{
	size_t modsz, tgtsz;
	int modkind, tgtkind;
	member_t mbr;
	int ret;
	mdb_ctf_arinfo_t tar, mar;
	int i;

	/*
	 * Resolve the types to their canonical form.
	 */
	(void) mdb_ctf_type_resolve(modid, &modid);
	(void) mdb_ctf_type_resolve(tgtid, &tgtid);

	if ((modkind = mdb_ctf_type_kind(modid)) == -1)
		return (-1); /* errno is set for us */
	if ((tgtkind = mdb_ctf_type_kind(tgtid)) == -1)
		return (-1); /* errno is set for us */

	if (tgtkind != modkind)
		return (set_errno(EMDB_INCOMPAT));

	switch (modkind) {
	case CTF_K_INTEGER:
	case CTF_K_FLOAT:
	case CTF_K_POINTER:
		if ((modsz = mdb_ctf_type_size(modid)) == -1UL)
			return (-1); /* errno is set for us */

		if ((tgtsz = mdb_ctf_type_size(tgtid)) == -1UL)
			return (-1); /* errno is set for us */

		/*
		 * If the sizes don't match we need to be tricky to make
		 * sure that the caller gets the correct data.
		 */
		if (modsz < tgtsz) {
			if (!(flags & MDB_CTF_VREAD_IGNORE_GROW))
				return (set_errno(EMDB_INCOMPAT));
#ifdef _BIG_ENDIAN
			bcopy(tgtbuf + tgtsz - modsz, modbuf, modsz);
#else
			bcopy(tgtbuf, modbuf, modsz);
#endif
		} else if (modsz > tgtsz) {
			bzero(modbuf, modsz);
#ifdef _BIG_ENDIAN
			bcopy(tgtbuf, modbuf + modsz - tgtsz, tgtsz);
#else
			bcopy(tgtbuf, modbuf, tgtsz);
#endif
		} else {
			bcopy(tgtbuf, modbuf, modsz);
		}

		return (0);

	case CTF_K_STRUCT:
		mbr.m_modbuf = modbuf;
		mbr.m_tgtbuf = tgtbuf;
		mbr.m_tgtid = tgtid;
		mbr.m_flags = flags;

		return (mdb_ctf_member_iter(modid, member_cb, &mbr));

	case CTF_K_UNION:

		/*
		 * Unions are a little tricky. The only time it's truly
		 * safe to read in a union is if no part of the union or
		 * any of its component types have changed. We allow the
		 * consumer to ignore unions. The correct use of this
		 * feature is to read the containing structure, figure
		 * out which component of the union is valid, compute
		 * the location of that in the target and then read in
		 * that part of the structure.
		 */
		if (flags & MDB_CTF_VREAD_IGNORE_UNIONS)
			return (0);

		if (!type_equals(modid, tgtid))
			return (set_errno(EMDB_INCOMPAT));

		modsz = mdb_ctf_type_size(modid);
		tgtsz = mdb_ctf_type_size(tgtid);

		ASSERT(modsz == tgtsz);

		bcopy(tgtbuf, modbuf, modsz);

		return (0);

	case CTF_K_ARRAY:
		if (mdb_ctf_array_info(tgtid, &tar) != 0)
			return (-1); /* errno is set for us */
		if (mdb_ctf_array_info(modid, &mar) != 0)
			return (-1); /* errno is set for us */

		if (tar.mta_nelems != mar.mta_nelems)
			return (set_errno(EMDB_INCOMPAT));

		if ((modsz = mdb_ctf_type_size(mar.mta_contents)) == -1UL)
			return (-1); /* errno is set for us */

		if ((tgtsz = mdb_ctf_type_size(tar.mta_contents)) == -1UL)
			return (-1); /* errno is set for us */

		for (i = 0; i < tar.mta_nelems; i++) {
			ret = vread_helper(mar.mta_contents, modbuf + i * modsz,
			    tar.mta_contents, tgtbuf + i * tgtsz, flags);

			if (ret != 0)
				return (ret);
		}

		return (0);
	}

	return (set_errno(EMDB_INCOMPAT));
}