xref: /illumos-gate/usr/src/test/util-tests/tests/ctf/check-merge-forward.c (revision 55d6cb5d63bcf69dfa47b8c41c770a2d34f169b0)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright (c) 2019, Joyent, Inc.
14  */
15 
16 /*
17  * This tests that a forward declared in one object file that is defined in
18  * another doesn't end up in the final one.
19  */
20 
21 #include "check-common.h"
22 
23 static check_symbol_t check_syms[] = {
24 	{ "list", "foo_list_t" },
25 	{ NULL }
26 };
27 
28 static check_member_t check_member_foo_list[] = {
29 	{ "count", "int", 0 },
30 #ifdef	TARGET_LP64
31 	{ "head", "struct foo *", 8 * NBBY },
32 	{ "tail", "struct foo *", 16 * NBBY },
33 #else
34 	{ "head", "struct foo *", 4 * NBBY },
35 	{ "tail", "struct foo *", 8 * NBBY },
36 #endif
37 	{ NULL }
38 };
39 
40 static check_member_t check_member_foo[] = {
41 	{ "next", "struct foo *", 0 * NBBY },
42 #ifdef	TARGET_LP64
43 	{ "left", "int", 8 * NBBY },
44 	{ "right", "int", 12 * NBBY },
45 	{ "count", "int", 16 * NBBY },
46 #else
47 	{ "left", "int", 4 * NBBY },
48 	{ "right", "int", 8 * NBBY },
49 	{ "count", "int", 12 * NBBY },
50 #endif
51 	{ NULL }
52 };
53 
54 static check_member_test_t members[] = {
55 #ifdef	TARGET_LP64
56 	{ "struct foo_list", CTF_K_STRUCT, 24, check_member_foo_list },
57 	{ "struct foo", CTF_K_STRUCT, 24, check_member_foo },
58 #else
59 	{ "struct foo_list", CTF_K_STRUCT, 12, check_member_foo_list },
60 	{ "struct foo", CTF_K_STRUCT, 16, check_member_foo },
61 #endif
62 	{ NULL }
63 };
64 
65 static int
66 ctf_merge_forward_cb(ctf_id_t id, boolean_t root, void *arg)
67 {
68 	ctf_file_t *fp = arg;
69 	char buf[2048];
70 
71 	if (ctf_type_kind(fp, id) != CTF_K_FORWARD)
72 		return (0);
73 
74 	if (ctf_type_name(fp, id, buf, sizeof (buf)) == NULL) {
75 		warnx("failed to lookup the name of type %ld: %s", id,
76 		    ctf_errmsg(ctf_errno(fp)));
77 		return (1);
78 	}
79 
80 	/*
81 	 * If a forward shows up, that's OK. It's only bad if it's the name of
82 	 * the one we created.
83 	 */
84 	if (strcmp("struct foo", buf) == 0) {
85 		warnx("encountered forward type for struct foo that "
86 		    "shouldn't exist");
87 		return (1);
88 	}
89 
90 	return (0);
91 }
92 
93 int
94 main(int argc, char *argv[])
95 {
96 	int i, ret = 0;
97 
98 	if (argc < 2) {
99 		errx(EXIT_FAILURE, "missing test files");
100 	}
101 
102 	for (i = 1; i < argc; i++) {
103 		ctf_file_t *fp;
104 		uint_t j;
105 
106 		if ((fp = ctf_open(argv[i], &ret)) == NULL) {
107 			warnx("failed to open %s: %s", argv[i],
108 			    ctf_errmsg(ret));
109 			ret = EXIT_FAILURE;
110 			continue;
111 		}
112 
113 		if (!ctftest_check_symbols(fp, check_syms))
114 			ret = EXIT_FAILURE;
115 
116 		for (j = 0; members[j].cmt_type != NULL; j++) {
117 			if (!ctftest_check_members(members[j].cmt_type, fp,
118 			    members[j].cmt_kind, members[j].cmt_size,
119 			    members[j].cmt_members)) {
120 				ret = EXIT_FAILURE;
121 			}
122 		}
123 
124 		if (ctf_type_iter(fp, B_TRUE, ctf_merge_forward_cb, fp) != 0) {
125 			ret = EXIT_FAILURE;
126 		}
127 
128 		ctf_close(fp);
129 	}
130 
131 	return (ret);
132 }
133