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