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