1 1.1 joerg /*- 2 1.1 joerg * Copyright (c) 2011 The NetBSD Foundation, Inc. 3 1.1 joerg * All rights reserved. 4 1.1 joerg * 5 1.1 joerg * This code is derived from software contributed to The NetBSD Foundation 6 1.1 joerg * by Joerg Sonnenberger. 7 1.1 joerg * 8 1.1 joerg * Redistribution and use in source and binary forms, with or without 9 1.1 joerg * modification, are permitted provided that the following conditions 10 1.1 joerg * are met: 11 1.1 joerg * 1. Redistributions of source code must retain the above copyright 12 1.1 joerg * notice, this list of conditions and the following disclaimer. 13 1.1 joerg * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 joerg * notice, this list of conditions and the following disclaimer in the 15 1.1 joerg * documentation and/or other materials provided with the distribution. 16 1.1 joerg * 17 1.1 joerg * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 1.1 joerg * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 1.1 joerg * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 1.1 joerg * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 1.1 joerg * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 1.1 joerg * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 1.1 joerg * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 1.1 joerg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 1.1 joerg * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 1.1 joerg * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 1.1 joerg * POSSIBILITY OF SUCH DAMAGE. 28 1.1 joerg */ 29 1.1 joerg 30 1.1 joerg #include <dlfcn.h> 31 1.1 joerg #include <link_elf.h> 32 1.1 joerg #include <pthread.h> 33 1.1 joerg #include <stdlib.h> 34 1.1 joerg #include <stdio.h> 35 1.1 joerg #include <string.h> 36 1.1 joerg #include <unistd.h> 37 1.1 joerg 38 1.1 joerg int sleep_init; 39 1.1 joerg int sleep_fini; 40 1.1 joerg int dlopen_cookie; 41 1.1 joerg int dlclose_cookie; 42 1.1 joerg 43 1.1 joerg void (*tls_callback_sym)(void); 44 1.1 joerg 45 1.1 joerg static int 46 1.1 joerg dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) 47 1.1 joerg { 48 1.1 joerg (*tls_callback_sym)(); 49 1.1 joerg return 0; 50 1.1 joerg } 51 1.1 joerg 52 1.1 joerg static void * 53 1.1 joerg test_dl_iterate_phdr_helper(void *dummy) 54 1.1 joerg { 55 1.1 joerg sleep(10); 56 1.1 joerg _exit(1); 57 1.1 joerg } 58 1.1 joerg 59 1.1 joerg static void 60 1.1 joerg test_dl_iterate_phdr(void) 61 1.1 joerg { 62 1.1 joerg pthread_t t; 63 1.1 joerg void *dso; 64 1.1 joerg sleep_init = 0; 65 1.1 joerg sleep_fini = 0; 66 1.1 joerg if ((dso = dlopen("libh_helper_dso2.so", RTLD_LAZY)) == NULL) { 67 1.1 joerg fprintf(stderr, "opening helper failed\n"); 68 1.1 joerg _exit(1); 69 1.1 joerg } 70 1.1 joerg tls_callback_sym = dlsym(dso, "tls_callback"); 71 1.1 joerg if (tls_callback_sym == NULL) { 72 1.1 joerg fprintf(stderr, "bad helper\n"); 73 1.1 joerg _exit(1); 74 1.1 joerg } 75 1.1 joerg pthread_create(&t, NULL, test_dl_iterate_phdr_helper, NULL); 76 1.1 joerg if (dl_iterate_phdr(dl_iterate_phdr_cb, NULL)) 77 1.1 joerg _exit(1); 78 1.1 joerg _exit(0); 79 1.1 joerg } 80 1.1 joerg 81 1.1 joerg static void * 82 1.1 joerg init_fini_helper(void *arg) 83 1.1 joerg { 84 1.1 joerg void *dso; 85 1.1 joerg if ((dso = dlopen(arg, RTLD_LAZY)) == NULL) { 86 1.1 joerg fprintf(stderr, "opening %s failed\n", (char *)arg); 87 1.1 joerg exit(1); 88 1.1 joerg } 89 1.1 joerg dlclose(dso); 90 1.1 joerg return NULL; 91 1.1 joerg } 92 1.1 joerg 93 1.1 joerg static void 94 1.1 joerg test_dlopen(void) 95 1.1 joerg { 96 1.1 joerg pthread_t t1, t2; 97 1.1 joerg sleep_init = 1; 98 1.1 joerg sleep_fini = 0; 99 1.1 joerg printf("%d\n", dlopen_cookie); 100 1.1 joerg pthread_create(&t1, NULL, init_fini_helper, 101 1.1 joerg __UNCONST("libh_helper_dso2.so")); 102 1.1 joerg sleep(1); 103 1.1 joerg printf("%d\n", dlopen_cookie); 104 1.1 joerg if (dlopen_cookie != 1) 105 1.1 joerg _exit(1); 106 1.1 joerg sleep(1); 107 1.1 joerg pthread_create(&t2, NULL, init_fini_helper, 108 1.1 joerg __UNCONST("libutil.so")); 109 1.1 joerg printf("%d\n", dlopen_cookie); 110 1.1 joerg if (dlopen_cookie != 1) 111 1.1 joerg _exit(1); 112 1.1 joerg _exit(0); 113 1.1 joerg } 114 1.1 joerg 115 1.1 joerg static void 116 1.1 joerg test_dlclose(void) 117 1.1 joerg { 118 1.1 joerg pthread_t t1, t2; 119 1.1 joerg sleep_init = 0; 120 1.1 joerg sleep_fini = 1; 121 1.1 joerg printf("%d\n", dlclose_cookie); 122 1.1 joerg pthread_create(&t1, NULL, init_fini_helper, 123 1.1 joerg __UNCONST("libh_helper_dso2.so")); 124 1.1 joerg sleep(1); 125 1.1 joerg printf("%d\n", dlclose_cookie); 126 1.1 joerg if (dlclose_cookie != 2) 127 1.1 joerg _exit(1); 128 1.1 joerg pthread_create(&t2, NULL, init_fini_helper, 129 1.1 joerg __UNCONST("libutil.so")); 130 1.1 joerg sleep(1); 131 1.1 joerg printf("%d\n", dlclose_cookie); 132 1.1 joerg if (dlclose_cookie != 2) 133 1.1 joerg _exit(1); 134 1.1 joerg _exit(0); 135 1.1 joerg } 136 1.1 joerg 137 1.1 joerg int 138 1.1 joerg main(int argc, char **argv) 139 1.1 joerg { 140 1.1 joerg if (argc != 2) 141 1.1 joerg return 1; 142 1.1 joerg if (strcmp(argv[1], "dl_iterate_phdr") == 0) 143 1.1 joerg test_dl_iterate_phdr(); 144 1.1 joerg if (strcmp(argv[1], "dlopen") == 0) 145 1.1 joerg test_dlopen(); 146 1.1 joerg if (strcmp(argv[1], "dlclose") == 0) 147 1.1 joerg test_dlclose(); 148 1.1 joerg return 1; 149 1.1 joerg } 150