summaryrefslogtreecommitdiff
path: root/usr/src/test/util-tests/tests/ctf/check-forward.c
blob: 7418b9922e0194f131a49f99e67a51ecb22d0c7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright 2019, Joyent, Inc.
 */

/*
 * Verify that we can properly handle forward declarations.
 *
 * In test-forward.c barp is declared as a union, not a struct. However, today
 * the CTF tooling does not contain enough information to know whether a forward
 * declaration was for a struct or a union, only that it was a forward.
 * Therefore, the type printing information assumes at the moment that the type
 * is a struct. In a future revision of the CTF type data, we should encode this
 * information in the equivalent of ctt_info so we can properly distinguish
 * between these.
 */

#include "check-common.h"

static check_symbol_t check_syms[] = {
	{ "forward", "struct forward" },
	{ "foop", "struct foo *" },
	{ "barp", "struct bar *" },
	{ "bazp", "enum baz *" },
	{ NULL }
};

static check_member_t check_member_forward[] = {
#ifdef	TARGET_LP64
	{ "prev", "struct foo *", 0 },
	{ "next", "struct foo *", 8 * NBBY },
	{ "data", "struct bar *", 16 * NBBY },
	{ "tag", "enum baz *", 24 * NBBY },
#else
	{ "prev", "struct foo *", 0 },
	{ "next", "struct foo *", 4 * NBBY },
	{ "data", "struct bar *", 8 * NBBY },
	{ "tag", "enum baz *", 12 * NBBY },
#endif
	{ NULL }
};


static check_member_test_t members[] = {
#ifdef	TARGET_LP64
	{ "struct forward", CTF_K_STRUCT, 32, check_member_forward },
#else
	{ "struct forward", CTF_K_STRUCT, 16, check_member_forward },
#endif
	{ NULL }
};

static check_descent_t check_descent_foo[] = {
	{ "struct foo *", CTF_K_POINTER },
	{ "struct foo", CTF_K_FORWARD },
	{ NULL }
};

static check_descent_t check_descent_bar[] = {
	{ "struct bar *", CTF_K_POINTER },
	{ "struct bar", CTF_K_FORWARD },
	{ NULL }
};

static check_descent_t check_descent_baz[] = {
	{ "enum baz *", CTF_K_POINTER },
	{ "enum baz", CTF_K_ENUM },
	{ NULL }
};

static check_descent_test_t descents[] = {
	{ "foop", check_descent_foo },
	{ "barp", check_descent_bar },
	{ "bazp", check_descent_baz },
	{ NULL }
};
int
main(int argc, char *argv[])
{
	int i, ret = 0;

	if (argc < 2) {
		errx(EXIT_FAILURE, "missing test files");
	}

	for (i = 1; i < argc; i++) {
		ctf_file_t *fp;
		uint_t j;

		if ((fp = ctf_open(argv[i], &ret)) == NULL) {
			warnx("failed to open %s: %s", argv[i],
			    ctf_errmsg(ret));
			ret = EXIT_FAILURE;
			continue;
		}

		if (!ctftest_check_symbols(fp, check_syms))
			ret = EXIT_FAILURE;

		for (j = 0; descents[j].cdt_sym != NULL; j++) {
			if (!ctftest_check_descent(descents[j].cdt_sym, fp,
			    descents[j].cdt_tests, B_FALSE)) {
				ret = EXIT_FAILURE;
			}
		}


		for (j = 0; members[j].cmt_type != NULL; j++) {
			if (!ctftest_check_members(members[j].cmt_type, fp,
			    members[j].cmt_kind, members[j].cmt_size,
			    members[j].cmt_members)) {
				ret = EXIT_FAILURE;
			}
		}

		ctf_close(fp);
	}

	return (ret);
}