summaryrefslogtreecommitdiff
path: root/usr/src/test/util-tests/tests/ctf/check-merge-forward.c
blob: e396beb133e1fdc778c9f03024b5bd78871a4a86 (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
131
132
/*
 * 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 (c) 2019, Joyent, Inc.
 */

/*
 * This tests that a forward declared in one object file that is defined in
 * another doesn't end up in the final one.
 */

#include "check-common.h"

static check_symbol_t check_syms[] = {
	{ "list", "foo_list_t" },
	{ NULL }
};

static check_member_t check_member_foo_list[] = {
	{ "count", "int", 0 },
#ifdef	TARGET_LP64
	{ "head", "struct foo *", 8 * NBBY },
	{ "tail", "struct foo *", 16 * NBBY },
#else
	{ "head", "struct foo *", 4 * NBBY },
	{ "tail", "struct foo *", 8 * NBBY },
#endif
	{ NULL }
};

static check_member_t check_member_foo[] = {
	{ "next", "struct foo *", 0 * NBBY },
#ifdef	TARGET_LP64
	{ "left", "int", 8 * NBBY },
	{ "right", "int", 12 * NBBY },
	{ "count", "int", 16 * NBBY },
#else
	{ "left", "int", 4 * NBBY },
	{ "right", "int", 8 * NBBY },
	{ "count", "int", 12 * NBBY },
#endif
	{ NULL }
};

static check_member_test_t members[] = {
#ifdef	TARGET_LP64
	{ "struct foo_list", CTF_K_STRUCT, 24, check_member_foo_list },
	{ "struct foo", CTF_K_STRUCT, 24, check_member_foo },
#else
	{ "struct foo_list", CTF_K_STRUCT, 12, check_member_foo_list },
	{ "struct foo", CTF_K_STRUCT, 16, check_member_foo },
#endif
	{ NULL }
};

static int
ctf_merge_forward_cb(ctf_id_t id, boolean_t root, void *arg)
{
	ctf_file_t *fp = arg;
	char buf[2048];

	if (ctf_type_kind(fp, id) != CTF_K_FORWARD)
		return (0);

	if (ctf_type_name(fp, id, buf, sizeof (buf)) == NULL) {
		warnx("failed to lookup the name of type %ld: %s", id,
		    ctf_errmsg(ctf_errno(fp)));
		return (1);
	}

	/*
	 * If a forward shows up, that's OK. It's only bad if it's the name of
	 * the one we created.
	 */
	if (strcmp("struct foo", buf) == 0) {
		warnx("encountered forward type for struct foo that "
		    "shouldn't exist");
		return (1);
	}

	return (0);
}

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; 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;
			}
		}

		if (ctf_type_iter(fp, B_TRUE, ctf_merge_forward_cb, fp) != 0) {
			ret = EXIT_FAILURE;
		}

		ctf_close(fp);
	}

	return (ret);
}