1da2e3ebdSchin /*********************************************************************** 2da2e3ebdSchin * * 3da2e3ebdSchin * This software is part of the ast package * 4*34f9b3eeSRoland Mainz * Copyright (c) 1997-2009 AT&T Intellectual Property * 5da2e3ebdSchin * and is licensed under the * 6da2e3ebdSchin * Common Public License, Version 1.0 * 77c2fbfb3SApril Chin * by AT&T Intellectual Property * 8da2e3ebdSchin * * 9da2e3ebdSchin * A copy of the License is available at * 10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt * 11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12da2e3ebdSchin * * 13da2e3ebdSchin * Information and Software Systems Research * 14da2e3ebdSchin * AT&T Research * 15da2e3ebdSchin * Florham Park NJ * 16da2e3ebdSchin * * 17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> * 18da2e3ebdSchin * * 19da2e3ebdSchin ***********************************************************************/ 20da2e3ebdSchin #pragma prototyped 21da2e3ebdSchin /* 22da2e3ebdSchin * Glenn Fowler 23da2e3ebdSchin * AT&T Research 24da2e3ebdSchin */ 25da2e3ebdSchin 26da2e3ebdSchin #ifndef _GNU_SOURCE 27da2e3ebdSchin #define _GNU_SOURCE 1 28da2e3ebdSchin #endif 29da2e3ebdSchin #ifndef __EXTENSIONS__ 30da2e3ebdSchin #define __EXTENSIONS__ 1 31da2e3ebdSchin #endif 32da2e3ebdSchin 33da2e3ebdSchin #include <ast.h> 34da2e3ebdSchin #include <dlldefs.h> 35da2e3ebdSchin 36da2e3ebdSchin #if _hdr_rld_interface 37da2e3ebdSchin #include <rld_interface.h> 38da2e3ebdSchin #endif 39da2e3ebdSchin 40da2e3ebdSchin /* 41da2e3ebdSchin * return a handle for the next layer down, 42da2e3ebdSchin * i.e., the next layer that has symbols covered 43da2e3ebdSchin * by the main prog and dll's loaded so far 44da2e3ebdSchin * 45da2e3ebdSchin * intentionally light on external lib calls 46da2e3ebdSchin * so this routine can be used early in process 47da2e3ebdSchin * startup 48da2e3ebdSchin */ 49da2e3ebdSchin 50da2e3ebdSchin #ifdef _DLL_RLD_SYM 51da2e3ebdSchin 52da2e3ebdSchin #define DEBUG 1 53da2e3ebdSchin 54da2e3ebdSchin #if DEBUG 55da2e3ebdSchin 56da2e3ebdSchin typedef ssize_t (*Write_f)(int, const void*, size_t); 57da2e3ebdSchin 58da2e3ebdSchin #endif 59da2e3ebdSchin 60da2e3ebdSchin #undef dllnext 61da2e3ebdSchin 62da2e3ebdSchin void* 63da2e3ebdSchin _dll_next(int flags, _DLL_RLD_SYM_TYPE* here) 64da2e3ebdSchin { 65da2e3ebdSchin register char* vp; 66da2e3ebdSchin register void* lp; 67da2e3ebdSchin register int found = 0; 68da2e3ebdSchin char* s; 69da2e3ebdSchin char* b; 70da2e3ebdSchin char* e; 71da2e3ebdSchin char dummy[256]; 72da2e3ebdSchin #if DEBUG 73da2e3ebdSchin Write_f wr = 0; 74da2e3ebdSchin Write_f xr; 75da2e3ebdSchin char buf[1024]; 76da2e3ebdSchin #endif 77da2e3ebdSchin 78da2e3ebdSchin #if DEBUG 79da2e3ebdSchin if (getenv("DLL_DEBUG") && (vp = (char*)_rld_new_interface(_RLD_FIRST_PATHNAME))) 80da2e3ebdSchin { 81da2e3ebdSchin do 82da2e3ebdSchin { 83*34f9b3eeSRoland Mainz if (strcmp(vp, "MAIN") && (lp = dllopen(vp, flags))) 84da2e3ebdSchin { 85da2e3ebdSchin if (xr = (Write_f)dlsym(lp, "write")) 86da2e3ebdSchin wr = xr; 87da2e3ebdSchin } 88da2e3ebdSchin } while (vp = (char*)_rld_new_interface(_RLD_NEXT_PATHNAME)); 89da2e3ebdSchin } 90da2e3ebdSchin #endif 91da2e3ebdSchin if (vp = (char*)_rld_new_interface(_RLD_FIRST_PATHNAME)) 92da2e3ebdSchin { 93da2e3ebdSchin do 94da2e3ebdSchin { 95*34f9b3eeSRoland Mainz if (lp = dllopen(strcmp(vp, "MAIN") ? vp : (char*)0, flags)) 96da2e3ebdSchin { 97da2e3ebdSchin if (found) 98da2e3ebdSchin { 99da2e3ebdSchin b = e = 0; 100da2e3ebdSchin s = vp; 101da2e3ebdSchin for (;;) 102da2e3ebdSchin { 103da2e3ebdSchin switch (*s++) 104da2e3ebdSchin { 105da2e3ebdSchin case 0: 106da2e3ebdSchin break; 107da2e3ebdSchin case '/': 108da2e3ebdSchin b = s; 109da2e3ebdSchin e = 0; 110da2e3ebdSchin continue; 111da2e3ebdSchin case '.': 112da2e3ebdSchin if (!e) 113da2e3ebdSchin e = s - 1; 114da2e3ebdSchin continue; 115da2e3ebdSchin default: 116da2e3ebdSchin continue; 117da2e3ebdSchin } 118da2e3ebdSchin break; 119da2e3ebdSchin } 120da2e3ebdSchin if (b && e) 121da2e3ebdSchin { 122da2e3ebdSchin s = dummy; 123da2e3ebdSchin *s++ = '_'; 124da2e3ebdSchin *s++ = '_'; 125da2e3ebdSchin while (b < e) 126da2e3ebdSchin *s++ = *b++; 127da2e3ebdSchin b = "_dummy"; 128da2e3ebdSchin while (*s++ = *b++); 129da2e3ebdSchin if (dlsym(lp, dummy)) 130da2e3ebdSchin { 131da2e3ebdSchin dlclose(lp); 132da2e3ebdSchin lp = 0; 133da2e3ebdSchin } 134da2e3ebdSchin } 135da2e3ebdSchin if (lp) 136da2e3ebdSchin { 137da2e3ebdSchin #if DEBUG 138da2e3ebdSchin if (wr) 139da2e3ebdSchin (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: next %s\n", vp)); 140da2e3ebdSchin #endif 141da2e3ebdSchin return lp; 142da2e3ebdSchin } 143da2e3ebdSchin #if DEBUG 144da2e3ebdSchin else if (wr) 145da2e3ebdSchin (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: skip %s\n", vp)); 146da2e3ebdSchin #endif 147da2e3ebdSchin } 148da2e3ebdSchin else if ((_DLL_RLD_SYM_TYPE*)dlsym(lp, _DLL_RLD_SYM_STR) == here) 149da2e3ebdSchin { 150da2e3ebdSchin #if DEBUG 151da2e3ebdSchin if (wr) 152da2e3ebdSchin (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: this %s\n", vp)); 153da2e3ebdSchin #endif 154da2e3ebdSchin found = 1; 155da2e3ebdSchin } 156da2e3ebdSchin } 157da2e3ebdSchin } while (vp = (char*)_rld_new_interface(_RLD_NEXT_PATHNAME)); 158da2e3ebdSchin } 159da2e3ebdSchin return dllnext(flags); 160da2e3ebdSchin } 161da2e3ebdSchin 162da2e3ebdSchin #endif 163da2e3ebdSchin 164da2e3ebdSchin #ifndef RTLD_NEXT 165da2e3ebdSchin #if _dll_DYNAMIC 166da2e3ebdSchin 167da2e3ebdSchin #include <link.h> 168da2e3ebdSchin 169da2e3ebdSchin extern struct link_dynamic _DYNAMIC; 170da2e3ebdSchin 171da2e3ebdSchin #endif 172da2e3ebdSchin #endif 173da2e3ebdSchin 174da2e3ebdSchin void* 175da2e3ebdSchin dllnext(int flags) 176da2e3ebdSchin { 177da2e3ebdSchin register void* dll; 178da2e3ebdSchin #ifndef RTLD_NEXT 179da2e3ebdSchin #if _dll_DYNAMIC 180da2e3ebdSchin register struct link_map* map; 181da2e3ebdSchin register char* s; 182da2e3ebdSchin register char* b; 183da2e3ebdSchin #endif 184da2e3ebdSchin register char* ver; 185da2e3ebdSchin char* path; 186da2e3ebdSchin 187da2e3ebdSchin static char next[] = { _DLL_NEXT_PATH }; 188da2e3ebdSchin #endif 189da2e3ebdSchin 190da2e3ebdSchin #ifdef RTLD_NEXT 191da2e3ebdSchin dll = RTLD_NEXT; 192da2e3ebdSchin #else 193da2e3ebdSchin path = next; 194da2e3ebdSchin #if _dll_DYNAMIC 195da2e3ebdSchin for (map = _DYNAMIC.ld_un.ld_1->ld_loaded; map; map = map->lm_next) 196da2e3ebdSchin { 197da2e3ebdSchin b = 0; 198da2e3ebdSchin s = map->lm_name; 199da2e3ebdSchin while (*s) 200da2e3ebdSchin if (*s++ == '/') 201da2e3ebdSchin b = s; 202da2e3ebdSchin if (b && b[0] == 'l' && b[1] == 'i' && b[2] == 'b' && b[3] == 'c' && b[4] == '.') 203da2e3ebdSchin { 204da2e3ebdSchin path = map->lm_name; 205da2e3ebdSchin break; 206da2e3ebdSchin } 207da2e3ebdSchin } 208da2e3ebdSchin #endif 209da2e3ebdSchin ver = path + strlen(path); 210*34f9b3eeSRoland Mainz while (!(dll = dllopen(path, flags))) 211da2e3ebdSchin { 212da2e3ebdSchin do 213da2e3ebdSchin { 214da2e3ebdSchin if (ver <= path) 215da2e3ebdSchin return 0; 216da2e3ebdSchin } while (*--ver != '.'); 217da2e3ebdSchin if (*(ver + 1) <= '0' || *(ver + 1) >= '9') 218da2e3ebdSchin return 0; 219da2e3ebdSchin *ver = 0; 220da2e3ebdSchin } 221da2e3ebdSchin #endif 222da2e3ebdSchin return dll; 223da2e3ebdSchin } 224