119304Speter/*- 219304Speter * Copyright (c) 2011 The NetBSD Foundation, Inc. 319304Speter * All rights reserved. 419304Speter * 519304Speter * This code is derived from software contributed to The NetBSD Foundation 619304Speter * by Joerg Sonnenberger. 719304Speter * 819304Speter * Redistribution and use in source and binary forms, with or without 919304Speter * modification, are permitted provided that the following conditions 1019304Speter * are met: 1119304Speter * 1. Redistributions of source code must retain the above copyright 1219304Speter * notice, this list of conditions and the following disclaimer. 1319304Speter * 2. Redistributions in binary form must reproduce the above copyright 1419304Speter * notice, this list of conditions and the following disclaimer in the 1519304Speter * documentation and/or other materials provided with the distribution. 1619304Speter * 1719304Speter * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 1819304Speter * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1919304Speter * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2019304Speter * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2119304Speter * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2219304Speter * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2319304Speter * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2419304Speter * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2519304Speter * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2619304Speter * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2719304Speter * POSSIBILITY OF SUCH DAMAGE. 2819304Speter */ 2919304Speter 3019304Speter#include <dlfcn.h> 3119304Speter#include <link_elf.h> 3219304Speter#include <pthread.h> 3319304Speter#include <stdlib.h> 3419304Speter#include <stdio.h> 3519304Speter#include <string.h> 3619304Speter#include <unistd.h> 3719304Speter 3819304Speterint sleep_init; 3919304Speterint sleep_fini; 4019304Speterint dlopen_cookie; 4119304Speterint dlclose_cookie; 4219304Speter 4319304Spetervoid (*tls_callback_sym)(void); 4419304Speter 4519304Speterstatic int 4619304Speterdl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) 4719304Speter{ 4819304Speter (*tls_callback_sym)(); 4919304Speter return 0; 5019304Speter} 5119304Speter 5219304Speterstatic void * 5319304Spetertest_dl_iterate_phdr_helper(void *dummy) 5419304Speter{ 5519304Speter sleep(10); 5619304Speter _exit(1); 5719304Speter} 5819304Speter 5919304Speterstatic void 6019304Spetertest_dl_iterate_phdr(void) 6119304Speter{ 6219304Speter pthread_t t; 6319304Speter void *dso; 6419304Speter sleep_init = 0; 6519304Speter sleep_fini = 0; 6619304Speter if ((dso = dlopen("libh_helper_dso2.so", RTLD_LAZY)) == NULL) { 6719304Speter fprintf(stderr, "opening helper failed\n"); 6819304Speter _exit(1); 6919304Speter } 7019304Speter tls_callback_sym = dlsym(dso, "tls_callback"); 7119304Speter if (tls_callback_sym == NULL) { 7219304Speter fprintf(stderr, "bad helper\n"); 7319304Speter _exit(1); 7419304Speter } 7519304Speter pthread_create(&t, NULL, test_dl_iterate_phdr_helper, NULL); 7619304Speter if (dl_iterate_phdr(dl_iterate_phdr_cb, NULL)) 7719304Speter _exit(1); 7819304Speter _exit(0); 7919304Speter} 8019304Speter 8119304Speterstatic void * 8219304Speterinit_fini_helper(void *arg) 8319304Speter{ 8419304Speter void *dso; 8519304Speter if ((dso = dlopen(arg, RTLD_LAZY)) == NULL) { 8619304Speter fprintf(stderr, "opening %s failed\n", (char *)arg); 8719304Speter exit(1); 8819304Speter } 8919304Speter dlclose(dso); 9019304Speter return NULL; 9119304Speter} 9219304Speter 9319304Speterstatic void 9419304Spetertest_dlopen(void) 9519304Speter{ 9619304Speter pthread_t t1, t2; 9719304Speter sleep_init = 1; 9819304Speter sleep_fini = 0; 9919304Speter printf("%d\n", dlopen_cookie); 10019304Speter pthread_create(&t1, NULL, init_fini_helper, 10119304Speter __UNCONST("libh_helper_dso2.so")); 10219304Speter sleep(1); 10319304Speter printf("%d\n", dlopen_cookie); 10419304Speter if (dlopen_cookie != 1) 10519304Speter _exit(1); 10619304Speter sleep(1); 10719304Speter pthread_create(&t2, NULL, init_fini_helper, 10819304Speter __UNCONST("libutil.so")); 10919304Speter printf("%d\n", dlopen_cookie); 11019304Speter if (dlopen_cookie != 1) 11119304Speter _exit(1); 11219304Speter _exit(0); 11319304Speter} 11419304Speter 11519304Speterstatic void 11619304Spetertest_dlclose(void) 11719304Speter{ 11819304Speter pthread_t t1, t2; 11919304Speter sleep_init = 0; 12019304Speter sleep_fini = 1; 12119304Speter printf("%d\n", dlclose_cookie); 12219304Speter pthread_create(&t1, NULL, init_fini_helper, 12319304Speter __UNCONST("libh_helper_dso2.so")); 12419304Speter sleep(1); 12519304Speter printf("%d\n", dlclose_cookie); 12619304Speter if (dlclose_cookie != 2) 12719304Speter _exit(1); 12819304Speter pthread_create(&t2, NULL, init_fini_helper, 12919304Speter __UNCONST("libutil.so")); 13019304Speter sleep(1); 13119304Speter printf("%d\n", dlclose_cookie); 13219304Speter if (dlclose_cookie != 2) 13319304Speter _exit(1); 13419304Speter _exit(0); 13519304Speter} 13619304Speter 13719304Speterint 13819304Spetermain(int argc, char **argv) 13919304Speter{ 14019304Speter if (argc != 2) 14119304Speter return 1; 14219304Speter if (strcmp(argv[1], "dl_iterate_phdr") == 0) 14319304Speter test_dl_iterate_phdr(); 14419304Speter if (strcmp(argv[1], "dlopen") == 0) 14519304Speter test_dlopen(); 14619304Speter if (strcmp(argv[1], "dlclose") == 0) 14719304Speter test_dlclose(); 14819304Speter return 1; 14919304Speter} 15019304Speter