static int LoadALSALibrary(void) { int i, retval = -1; /* alsa_handle = SDL_LoadObject(alsa_library);*/ alsa_handle = dlopen(alsa_library,RTLD_NOW); if (alsa_handle) { alsa_loaded = 1; retval = 0; for (i = 0; i < SDL_arraysize(alsa_functions); i++) { /* *alsa_functions[i].func = SDL_LoadFunction(alsa_handle,alsa_functions[i].name);*/ #if HAVE_DLVSYM *alsa_functions[i].func = dlvsym(alsa_handle,alsa_functions[i].name,"ALSA_0.9"); if (!*alsa_functions[i].func) #endif *alsa_functions[i].func = dlsym(alsa_handle,alsa_functions[i].name); if (!*alsa_functions[i].func) { retval = -1; UnloadALSALibrary(); break; } } } return retval; }
static int do_test (void) { void *handle = dlopen ("modstatic2-nonexistent.so", RTLD_LAZY); if (handle == NULL) printf ("nonexistent: %s\n", dlerror ()); else exit (1); handle = dlopen ("modstatic2.so", RTLD_LAZY); if (handle == NULL) { printf ("%s\n", dlerror ()); exit (1); } int (*test) (FILE *, int); test = dlsym (handle, "test"); if (test == NULL) { printf ("%s\n", dlerror ()); exit (1); } Dl_info info; int res = dladdr (test, &info); if (res == 0) { puts ("dladdr returned 0"); exit (1); } else { if (strstr (info.dli_fname, "modstatic2.so") == NULL || strcmp (info.dli_sname, "test") != 0) { printf ("fname %s sname %s\n", info.dli_fname, info.dli_sname); exit (1); } if (info.dli_saddr != (void *) test) { printf ("saddr %p != test %p\n", info.dli_saddr, test); exit (1); } } ElfW(Sym) *sym; void *symp; res = dladdr1 (test, &info, &symp, RTLD_DL_SYMENT); if (res == 0) { puts ("dladdr1 returned 0"); exit (1); } else { if (strstr (info.dli_fname, "modstatic2.so") == NULL || strcmp (info.dli_sname, "test") != 0) { printf ("fname %s sname %s\n", info.dli_fname, info.dli_sname); exit (1); } if (info.dli_saddr != (void *) test) { printf ("saddr %p != test %p\n", info.dli_saddr, test); exit (1); } sym = symp; if (sym == NULL) { puts ("sym == NULL\n"); exit (1); } if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL || ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT) { printf ("bind %d visibility %d\n", (int) ELF32_ST_BIND (sym->st_info), (int) ELF32_ST_VISIBILITY (sym->st_other)); exit (1); } } Lmid_t lmid; res = dlinfo (handle, RTLD_DI_LMID, &lmid); if (res != 0) { printf ("dlinfo returned %d %s\n", res, dlerror ()); exit (1); } else if (lmid != LM_ID_BASE) { printf ("lmid %d != %d\n", (int) lmid, (int) LM_ID_BASE); exit (1); } res = test (stdout, 2); if (res != 4) { printf ("Got %i, expected 4\n", res); exit (1); } void *handle2 = dlopen (LIBDL_SO, RTLD_LAZY); if (handle2 == NULL) { printf ("libdl.so: %s\n", dlerror ()); exit (1); } if (dlvsym (handle2, "_dlfcn_hook", "GLIBC_PRIVATE") == NULL) { printf ("dlvsym: %s\n", dlerror ()); exit (1); } void *(*dlsymfn) (void *, const char *); dlsymfn = dlsym (handle2, "dlsym"); if (dlsymfn == NULL) { printf ("dlsym \"dlsym\": %s\n", dlerror ()); exit (1); } void *test2 = dlsymfn (handle, "test"); if (test2 == NULL) { printf ("%s\n", dlerror ()); exit (1); } else if (test2 != (void *) test) { printf ("test %p != test2 %p\n", test, test2); exit (1); } dlclose (handle2); dlclose (handle); handle = dlmopen (LM_ID_BASE, "modstatic2.so", RTLD_LAZY); if (handle == NULL) { printf ("%s\n", dlerror ()); exit (1); } dlclose (handle); handle = dlmopen (LM_ID_NEWLM, "modstatic2.so", RTLD_LAZY); if (handle == NULL) printf ("LM_ID_NEWLM: %s\n", dlerror ()); else { puts ("LM_ID_NEWLM unexpectedly succeeded"); exit (1); } return 0; }
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) { if(silent == 2) { if(getenv("BN_SILENT")) silent = 0; else silent = 1; } if (!connect_real) { if(getenv("BN_NODEFAULT")) { if(getenv("BN_LIBC_PATH")) libc = dlopen(getenv("BN_LIBC_PATH"), RTLD_LAZY); else libc = dlopen(LIBC_PATH, RTLD_LAZY); if(libdl) { connect_real = dlvsym(libc, "connect", GLIBC_VER); if(!connect_real) { if(silent != 0) { if(getenv("BN_LIBC_PATH")) fprintf(stderr, "Failed to load real connect() from %s, the application will probably fail.\n", getenv("BN_LIBC_PATH")); else fprintf(stderr, "Failed to load real connect() from " LIBC_PATH ", the application will probably fail.\n"); } errno = EACCES; return(-1); } } else { if(silent != 0) { if(getenv("BN_LIBC_PATH")) fprintf(stderr, "Failed to open %s, the application will probably fail.\n", getenv("BN_LIBC_PATH")); else fprintf(stderr, "Failed to open " LIBC_PATH ", the application will probably fail\n"); } } } else { connect_real = dlvsym(RTLD_DEFAULT, "connect", GLIBC_VER); if(!connect_real) { if(silent == 0) fprintf(stderr, "Failed to find real connect(), the application will be unable to connect any sockets.\n"); errno = EACCES; return(-1); } } } if(!serv_addr) { if(silent == 0) fprintf(stderr, "serv_addr is NULL? Passing to connect() anyway.\n"); return connect_real(sockfd, serv_addr, addrlen); } if(serv_addr->sa_family != AF_INET) { return connect_real(sockfd,serv_addr,addrlen); } // Allow all contacts with localhost if((((struct sockaddr_in *)serv_addr)->sin_addr.s_addr & 0x000000FF) == 0x0000007F) return connect_real(sockfd,serv_addr,addrlen); if(silent == 0) fprintf(stderr,"connect() denied to address %X\n", ((struct sockaddr_in *)serv_addr)->sin_addr.s_addr); errno = EACCES; return(-1); }
LIB_PRIVATE void fred_get_libc_func_addr() { _real_func_addr[empty_event] = _real_dlsym(RTLD_NEXT, "empty"); _real_func_addr[accept_event] = _real_dlsym(RTLD_NEXT, "accept"); _real_func_addr[accept4_event] = _real_dlsym(RTLD_NEXT, "accept4"); _real_func_addr[access_event] = _real_dlsym(RTLD_NEXT, "access"); _real_func_addr[bind_event] = _real_dlsym(RTLD_NEXT, "bind"); _real_func_addr[calloc_event] = _real_dlsym(RTLD_NEXT, "calloc"); _real_func_addr[chmod_event] = _real_dlsym(RTLD_NEXT, "chmod"); _real_func_addr[chown_event] = _real_dlsym(RTLD_NEXT, "chown"); _real_func_addr[close_event] = _real_dlsym(RTLD_NEXT, "close"); _real_func_addr[connect_event] = _real_dlsym(RTLD_NEXT, "connect"); _real_func_addr[dup_event] = _real_dlsym(RTLD_NEXT, "dup"); _real_func_addr[dup2_event] = _real_dlsym(RTLD_NEXT, "dup2"); _real_func_addr[dup3_event] = _real_dlsym(RTLD_NEXT, "dup3"); _real_func_addr[fcntl_event] = _real_dlsym(RTLD_NEXT, "fcntl"); _real_func_addr[fchdir_event] = _real_dlsym(RTLD_NEXT, "fchdir"); _real_func_addr[fdatasync_event] = _real_dlsym(RTLD_NEXT, "fdatasync"); _real_func_addr[getcwd_event] = _real_dlsym(RTLD_NEXT, "getcwd"); _real_func_addr[gettimeofday_event] = _real_dlsym(RTLD_NEXT, "gettimeofday"); _real_func_addr[getpeername_event] = _real_dlsym(RTLD_NEXT, "getpeername"); _real_func_addr[getsockname_event] = _real_dlsym(RTLD_NEXT, "getsockname"); _real_func_addr[link_event] = _real_dlsym(RTLD_NEXT, "link"); _real_func_addr[symlink_event] = _real_dlsym(RTLD_NEXT, "symlink"); _real_func_addr[listen_event] = _real_dlsym(RTLD_NEXT, "listen"); _real_func_addr[localtime_r_event] = _real_dlsym(RTLD_NEXT, "localtime_r"); _real_func_addr[utime_event] = _real_dlsym(RTLD_NEXT, "utime"); _real_func_addr[utimes_event] = _real_dlsym(RTLD_NEXT, "utimes"); _real_func_addr[lutimes_event] = _real_dlsym(RTLD_NEXT, "lutimes"); _real_func_addr[futimes_event] = _real_dlsym(RTLD_NEXT, "futimes"); _real_func_addr[clock_getres_event] = _real_dlsym(RTLD_NEXT, "clock_getres"); _real_func_addr[clock_gettime_event] = _real_dlsym(RTLD_NEXT, "clock_gettime"); _real_func_addr[clock_settime_event] = _real_dlsym(RTLD_NEXT, "clock_settime"); _real_func_addr[lseek_event] = _real_dlsym(RTLD_NEXT, "lseek"); _real_func_addr[lseek64_event] = _real_dlsym(RTLD_NEXT, "lseek64"); _real_func_addr[llseek_event] = _real_dlsym(RTLD_NEXT, "llseek"); _real_func_addr[malloc_event] = _real_dlsym(RTLD_NEXT, "malloc"); _real_func_addr[free_event] = _real_dlsym(RTLD_NEXT, "free"); _real_func_addr[mkdir_event] = _real_dlsym(RTLD_NEXT, "mkdir"); _real_func_addr[mkstemp_event] = _real_dlsym(RTLD_NEXT, "mkstemp"); _real_func_addr[mmap_event] = _real_dlsym(RTLD_NEXT, "mmap"); _real_func_addr[mmap64_event] = _real_dlsym(RTLD_NEXT, "mmap64"); _real_func_addr[munmap_event] = _real_dlsym(RTLD_NEXT, "munmap"); _real_func_addr[mremap_event] = _real_dlsym(RTLD_NEXT, "mremap"); _real_func_addr[open_event] = _real_dlsym(RTLD_NEXT, "open"); _real_func_addr[open64_event] = _real_dlsym(RTLD_NEXT, "open64"); _real_func_addr[openat_event] = _real_dlsym(RTLD_NEXT, "openat"); _real_func_addr[pread_event] = _real_dlsym(RTLD_NEXT, "pread"); _real_func_addr[preadv_event] = _real_dlsym(RTLD_NEXT, "preadv"); _real_func_addr[pwrite_event] = _real_dlsym(RTLD_NEXT, "pwrite"); _real_func_addr[pwritev_event] = _real_dlsym(RTLD_NEXT, "pwritev"); _real_func_addr[pthread_rwlock_unlock_event] = _real_dlsym(RTLD_NEXT, "pthread_rwlock_unlock"); _real_func_addr[pthread_rwlock_rdlock_event] = _real_dlsym(RTLD_NEXT, "pthread_rwlock_rdlock"); _real_func_addr[pthread_rwlock_wrlock_event] = _real_dlsym(RTLD_NEXT, "pthread_rwlock_wrlock"); _real_func_addr[pthread_create_event] = _real_dlsym(RTLD_NEXT, "pthread_create"); _real_func_addr[pthread_detach_event] = _real_dlsym(RTLD_NEXT, "pthread_detach"); _real_func_addr[pthread_exit_event] = _real_dlsym(RTLD_NEXT, "pthread_exit"); _real_func_addr[pthread_join_event] = _real_dlsym(RTLD_NEXT, "pthread_join"); _real_func_addr[pthread_kill_event] = _real_dlsym(RTLD_NEXT, "pthread_kill"); _real_func_addr[pthread_mutex_lock_event] = _real_dlsym(RTLD_NEXT, "pthread_mutex_lock"); _real_func_addr[pthread_mutex_trylock_event] = _real_dlsym(RTLD_NEXT, "pthread_mutex_trylock"); _real_func_addr[pthread_mutex_unlock_event] = _real_dlsym(RTLD_NEXT, "pthread_mutex_unlock"); _real_func_addr[rand_event] = _real_dlsym(RTLD_NEXT, "rand"); _real_func_addr[fork_event] = _real_dlsym(RTLD_NEXT, "fork"); _real_func_addr[read_event] = _real_dlsym(RTLD_NEXT, "read"); _real_func_addr[readv_event] = _real_dlsym(RTLD_NEXT, "readv"); _real_func_addr[readlink_event] = _real_dlsym(RTLD_NEXT, "readlink"); _real_func_addr[realpath_event] = _real_dlsym(RTLD_NEXT, "realpath"); _real_func_addr[realloc_event] = _real_dlsym(RTLD_NEXT, "realloc"); _real_func_addr[rename_event] = _real_dlsym(RTLD_NEXT, "rename"); _real_func_addr[rmdir_event] = _real_dlsym(RTLD_NEXT, "rmdir"); _real_func_addr[select_event] = _real_dlsym(RTLD_NEXT, "select"); _real_func_addr[ppoll_event] = _real_dlsym(RTLD_NEXT, "ppoll"); _real_func_addr[setsockopt_event] = _real_dlsym(RTLD_NEXT, "setsockopt"); _real_func_addr[getsockopt_event] = _real_dlsym(RTLD_NEXT, "getsockopt"); _real_func_addr[ioctl_event] = _real_dlsym(RTLD_NEXT, "ioctl"); _real_func_addr[shutdown_event] = _real_dlsym(RTLD_NEXT, "shutdown"); _real_func_addr[sigwait_event] = _real_dlsym(RTLD_NEXT, "sigwait"); _real_func_addr[srand_event] = _real_dlsym(RTLD_NEXT, "srand"); _real_func_addr[socket_event] = _real_dlsym(RTLD_NEXT, "socket"); _real_func_addr[socketpair_event] = _real_dlsym(RTLD_NEXT, "socketpair"); _real_func_addr[time_event] = _real_dlsym(RTLD_NEXT, "time"); _real_func_addr[truncate_event] = _real_dlsym(RTLD_NEXT, "truncate"); _real_func_addr[ftruncate_event] = _real_dlsym(RTLD_NEXT, "ftruncate"); _real_func_addr[truncate64_event] = _real_dlsym(RTLD_NEXT, "truncate64"); _real_func_addr[ftruncate64_event] = _real_dlsym(RTLD_NEXT, "ftruncate64"); _real_func_addr[unlink_event] = _real_dlsym(RTLD_NEXT, "unlink"); _real_func_addr[write_event] = _real_dlsym(RTLD_NEXT, "write"); _real_func_addr[writev_event] = _real_dlsym(RTLD_NEXT, "writev"); _real_func_addr[epoll_create_event] = _real_dlsym(RTLD_NEXT, "epoll_create"); _real_func_addr[epoll_create1_event] = _real_dlsym(RTLD_NEXT, "epoll_create1"); _real_func_addr[epoll_ctl_event] = _real_dlsym(RTLD_NEXT, "epoll_ctl"); _real_func_addr[epoll_wait_event] = _real_dlsym(RTLD_NEXT, "epoll_wait"); _real_func_addr[getpwnam_r_event] = _real_dlsym(RTLD_NEXT, "getpwnam_r"); _real_func_addr[getpwuid_r_event] = _real_dlsym(RTLD_NEXT, "getpwuid_r"); _real_func_addr[getgrnam_r_event] = _real_dlsym(RTLD_NEXT, "getgrnam_r"); _real_func_addr[getgrgid_r_event] = _real_dlsym(RTLD_NEXT, "getgrgid_r"); _real_func_addr[getaddrinfo_event] = _real_dlsym(RTLD_NEXT, "getaddrinfo"); _real_func_addr[freeaddrinfo_event] = _real_dlsym(RTLD_NEXT, "freeaddrinfo"); _real_func_addr[getnameinfo_event] = _real_dlsym(RTLD_NEXT, "getnameinfo"); _real_func_addr[sendto_event] = _real_dlsym(RTLD_NEXT, "sendto"); _real_func_addr[sendmsg_event] = _real_dlsym(RTLD_NEXT, "sendmsg"); _real_func_addr[recvfrom_event] = _real_dlsym(RTLD_NEXT, "recvfrom"); _real_func_addr[recvmsg_event] = _real_dlsym(RTLD_NEXT, "recvmsg"); _real_func_addr[waitid_event] = _real_dlsym(RTLD_NEXT, "waitid"); _real_func_addr[wait4_event] = _real_dlsym(RTLD_NEXT, "wait4"); _real_func_addr[sigaction_event] = _real_dlsym(RTLD_NEXT, "sigaction"); _real_func_addr[signal_event] = _real_dlsym(RTLD_NEXT, "signal"); _real_func_addr[sigset_event] = _real_dlsym(RTLD_NEXT, "sigset"); _real_func_addr[fopen_event] = _real_dlsym(RTLD_NEXT, "fopen"); _real_func_addr[fopen64_event] = _real_dlsym(RTLD_NEXT, "fopen64"); _real_func_addr[freopen_event] = _real_dlsym(RTLD_NEXT, "freopen"); _real_func_addr[fclose_event] = _real_dlsym(RTLD_NEXT, "fclose"); _real_func_addr[fdopen_event] = _real_dlsym(RTLD_NEXT, "fdopen"); _real_func_addr[fgets_event] = _real_dlsym(RTLD_NEXT, "fgets"); _real_func_addr[ferror_event] = _real_dlsym(RTLD_NEXT, "ferror"); _real_func_addr[feof_event] = _real_dlsym(RTLD_NEXT, "feof"); _real_func_addr[fileno_event] = _real_dlsym(RTLD_NEXT, "fileno"); _real_func_addr[fflush_event] = _real_dlsym(RTLD_NEXT, "fflush"); _real_func_addr[setvbuf_event] = _real_dlsym(RTLD_NEXT, "setvbuf"); _real_func_addr[fseek_event] = _real_dlsym(RTLD_NEXT, "fseek"); _real_func_addr[fputs_event] = _real_dlsym(RTLD_NEXT, "fputs"); _real_func_addr[puts_event] = _real_dlsym(RTLD_NEXT, "puts"); _real_func_addr[fputc_event] = _real_dlsym(RTLD_NEXT, "fputc"); _real_func_addr[fsync_event] = _real_dlsym(RTLD_NEXT, "fsync"); _real_func_addr[ftell_event] = _real_dlsym(RTLD_NEXT, "ftell"); _real_func_addr[fgetpos_event] = _real_dlsym(RTLD_NEXT, "fgetpos"); _real_func_addr[fgetpos64_event] = _real_dlsym(RTLD_NEXT, "fgetpos64"); _real_func_addr[fsetpos_event] = _real_dlsym(RTLD_NEXT, "fsetpos"); _real_func_addr[fsetpos64_event] = _real_dlsym(RTLD_NEXT, "fsetpos64"); _real_func_addr[fwrite_event] = _real_dlsym(RTLD_NEXT, "fwrite"); _real_func_addr[fread_event] = _real_dlsym(RTLD_NEXT, "fread"); _real_func_addr[getc_event] = _real_dlsym(RTLD_NEXT, "getc"); _real_func_addr[fgetc_event] = _real_dlsym(RTLD_NEXT, "fgetc"); _real_func_addr[ungetc_event] = _real_dlsym(RTLD_NEXT, "ungetc"); _real_func_addr[getline_event] = _real_dlsym(RTLD_NEXT, "getline"); _real_func_addr[getdelim_event] = _real_dlsym(RTLD_NEXT, "getdelim"); _real_func_addr[putc_event] = _real_dlsym(RTLD_NEXT, "putc"); _real_func_addr[rewind_event] = _real_dlsym(RTLD_NEXT, "rewind"); _real_func_addr[tmpfile_event] = _real_dlsym(RTLD_NEXT, "tmpfile"); _real_func_addr[flockfile_event] = _real_dlsym(RTLD_NEXT, "flockfile"); _real_func_addr[ftrylockfile_event] = _real_dlsym(RTLD_NEXT, "ftrylockfile"); _real_func_addr[funlockfile_event] = _real_dlsym(RTLD_NEXT, "funlockfile"); _real_func_addr[closedir_event] = _real_dlsym(RTLD_NEXT, "closedir"); _real_func_addr[opendir_event] = _real_dlsym(RTLD_NEXT, "opendir"); _real_func_addr[fdopendir_event] = _real_dlsym(RTLD_NEXT, "fdopendir"); _real_func_addr[readdir_event] = _real_dlsym(RTLD_NEXT, "readdir"); _real_func_addr[readdir_r_event] = _real_dlsym(RTLD_NEXT, "readdir_r"); _real_func_addr[pthread_cond_broadcast_event] = dlvsym(RTLD_NEXT, "pthread_cond_broadcast", "GLIBC_2.3.2"); _real_func_addr[pthread_cond_signal_event] = dlvsym(RTLD_NEXT, "pthread_cond_signal", "GLIBC_2.3.2"); _real_func_addr[pthread_cond_wait_event] = dlvsym(RTLD_NEXT, "pthread_cond_wait", "GLIBC_2.3.2"); _real_func_addr[pthread_cond_timedwait_event] = dlvsym(RTLD_NEXT, "pthread_cond_timedwait", "GLIBC_2.3.2"); _real_func_addr[pthread_cond_destroy_event] = dlvsym(RTLD_NEXT, "pthread_cond_destroy", "GLIBC_2.3.2"); _real_func_addr[fxstat_event] = _real_dlsym(RTLD_NEXT, "__fxstat"); _real_func_addr[fxstat64_event] = _real_dlsym(RTLD_NEXT, "__fxstat64"); _real_func_addr[lxstat_event] = _real_dlsym(RTLD_NEXT, "__lxstat"); _real_func_addr[lxstat64_event] = _real_dlsym(RTLD_NEXT, "__lxstat64"); _real_func_addr[xstat_event] = _real_dlsym(RTLD_NEXT, "__xstat"); _real_func_addr[xstat64_event] = _real_dlsym(RTLD_NEXT, "__xstat64"); _real_func_addr[libc_memalign_event] = _real_dlsym(RTLD_NEXT, "__libc_memalign"); _real_func_addr[vfprintf_event] = _real_dlsym(RTLD_NEXT, "vfprintf"); _real_func_addr[vfscanf_event] = _real_dlsym(RTLD_NEXT, "vfscanf"); _real_func_addr[exec_barrier_event] = _real_dlsym(RTLD_NEXT, "exec_barrier"); _real_func_addr[signal_handler_event] = _real_dlsym(RTLD_NEXT, "signal_handler"); _real_func_addr[user_event] = _real_dlsym(RTLD_NEXT, "user"); _real_func_addr[syscall_event] = _real_dlsym(RTLD_NEXT, "syscall"); }
int test (FILE *out, int a) { fputs ("in modstatic2.c (test)\n", out); void *handle = dlopen ("modstatic2-nonexistent.so", RTLD_LAZY); if (handle == NULL) fprintf (out, "nonexistent: %s\n", dlerror ()); else exit (1); handle = dlopen ("modstatic2.so", RTLD_LAZY); if (handle == NULL) { fprintf (out, "%s\n", dlerror ()); exit (1); } int (*test2) (FILE *, int); test2 = dlsym (handle, "test"); if (test2 == NULL) { fprintf (out, "%s\n", dlerror ()); exit (1); } if (test2 != test) { fprintf (out, "test %p != test2 %p\n", test, test2); exit (1); } Dl_info info; int res = dladdr (test2, &info); if (res == 0) { fputs ("dladdr returned 0\n", out); exit (1); } else { if (strstr (info.dli_fname, "modstatic2.so") == NULL || strcmp (info.dli_sname, "test") != 0) { fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname); exit (1); } if (info.dli_saddr != (void *) test2) { fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test2); exit (1); } } ElfW(Sym) *sym; void *symp; res = dladdr1 (test2, &info, &symp, RTLD_DL_SYMENT); if (res == 0) { fputs ("dladdr1 returned 0\n", out); exit (1); } else { if (strstr (info.dli_fname, "modstatic2.so") == NULL || strcmp (info.dli_sname, "test") != 0) { fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname); exit (1); } if (info.dli_saddr != (void *) test2) { fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test2); exit (1); } sym = symp; if (sym == NULL) { fputs ("sym == NULL\n", out); exit (1); } if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL || ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT) { fprintf (out, "bind %d visibility %d\n", (int) ELF32_ST_BIND (sym->st_info), (int) ELF32_ST_VISIBILITY (sym->st_other)); exit (1); } } Lmid_t lmid; res = dlinfo (handle, RTLD_DI_LMID, &lmid); if (res != 0) { fprintf (out, "dlinfo returned %d %s\n", res, dlerror ()); exit (1); } else if (lmid != LM_ID_BASE) { fprintf (out, "lmid %d != %d\n", (int) lmid, (int) LM_ID_BASE); exit (1); } void *handle2 = dlopen (LIBDL_SO, RTLD_LAZY); if (handle2 == NULL) { fprintf (out, "libdl.so: %s\n", dlerror ()); exit (1); } #ifdef DO_VERSIONING if (dlvsym (handle2, "_dlfcn_hook", "GLIBC_PRIVATE") == NULL) { fprintf (out, "dlvsym: %s\n", dlerror ()); exit (1); } #endif void *(*dlsymfn) (void *, const char *); dlsymfn = dlsym (handle2, "dlsym"); if (dlsymfn == NULL) { fprintf (out, "dlsym \"dlsym\": %s\n", dlerror ()); exit (1); } void *test3 = dlsymfn (handle, "test"); if (test3 == NULL) { fprintf (out, "%s\n", dlerror ()); exit (1); } else if (test3 != (void *) test2) { fprintf (out, "test2 %p != test3 %p\n", test2, test3); exit (1); } dlclose (handle2); dlclose (handle); handle = dlmopen (LM_ID_BASE, "modstatic2.so", RTLD_LAZY); if (handle == NULL) { fprintf (out, "%s\n", dlerror ()); exit (1); } dlclose (handle); handle = dlmopen (LM_ID_NEWLM, "modstatic2.so", RTLD_LAZY); if (handle == NULL) fprintf (out, "LM_ID_NEWLM: %s\n", dlerror ()); else { fputs ("LM_ID_NEWLM unexpectedly succeeded\n", out); exit (1); } handle = dlopen ("modstatic.so", RTLD_LAZY); if (handle == NULL) { fprintf (out, "%s\n", dlerror ()); exit (1); } int (*test4) (int); test4 = dlsym (handle, "test"); if (test4 == NULL) { fprintf (out, "%s\n", dlerror ()); exit (1); } res = test4 (16); if (res != 16 + 16) { fprintf (out, "modstatic.so (test) returned %d\n", res); exit (1); } res = dladdr1 (test4, &info, &symp, RTLD_DL_SYMENT); if (res == 0) { fputs ("dladdr1 returned 0\n", out); exit (1); } else { if (strstr (info.dli_fname, "modstatic.so") == NULL || strcmp (info.dli_sname, "test") != 0) { fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname); exit (1); } if (info.dli_saddr != (void *) test4) { fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test4); exit (1); } sym = symp; if (sym == NULL) { fputs ("sym == NULL\n", out); exit (1); } if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL || ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT) { fprintf (out, "bind %d visibility %d\n", (int) ELF32_ST_BIND (sym->st_info), (int) ELF32_ST_VISIBILITY (sym->st_other)); exit (1); } } dlclose (handle); fputs ("leaving modstatic2.c (test)\n", out); return a + a; }
static void * dlvsym_glibc_private (void *handle, const char *name) { return dlvsym (handle, name, "GLIBC_PRIVATE"); }
static void * dlvsym_no_such_version (void *handle, const char *name) { return dlvsym (handle, name, "NO_SUCH_VERSION"); }