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
ctf_merge_forward_cb(ctf_id_t id,boolean_t root,void * arg)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
main(int argc,char * argv[])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