14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1997-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * *
194887Schin ***********************************************************************/
204887Schin #pragma prototyped
214887Schin /*
224887Schin * Glenn Fowler
234887Schin * AT&T Research
244887Schin */
254887Schin
264887Schin #ifndef _GNU_SOURCE
274887Schin #define _GNU_SOURCE 1
284887Schin #endif
294887Schin #ifndef __EXTENSIONS__
304887Schin #define __EXTENSIONS__ 1
314887Schin #endif
324887Schin
334887Schin #include <ast.h>
344887Schin #include <dlldefs.h>
354887Schin
364887Schin #if _hdr_rld_interface
374887Schin #include <rld_interface.h>
384887Schin #endif
394887Schin
404887Schin /*
414887Schin * return a handle for the next layer down,
424887Schin * i.e., the next layer that has symbols covered
434887Schin * by the main prog and dll's loaded so far
444887Schin *
454887Schin * intentionally light on external lib calls
464887Schin * so this routine can be used early in process
474887Schin * startup
484887Schin */
494887Schin
504887Schin #ifdef _DLL_RLD_SYM
514887Schin
524887Schin #define DEBUG 1
534887Schin
544887Schin #if DEBUG
554887Schin
564887Schin typedef ssize_t (*Write_f)(int, const void*, size_t);
574887Schin
584887Schin #endif
594887Schin
604887Schin #undef dllnext
614887Schin
624887Schin void*
_dll_next(int flags,_DLL_RLD_SYM_TYPE * here)634887Schin _dll_next(int flags, _DLL_RLD_SYM_TYPE* here)
644887Schin {
654887Schin register char* vp;
664887Schin register void* lp;
674887Schin register int found = 0;
684887Schin char* s;
694887Schin char* b;
704887Schin char* e;
714887Schin char dummy[256];
724887Schin #if DEBUG
734887Schin Write_f wr = 0;
744887Schin Write_f xr;
754887Schin char buf[1024];
764887Schin #endif
774887Schin
784887Schin #if DEBUG
794887Schin if (getenv("DLL_DEBUG") && (vp = (char*)_rld_new_interface(_RLD_FIRST_PATHNAME)))
804887Schin {
814887Schin do
824887Schin {
8310898Sroland.mainz@nrubsig.org if (strcmp(vp, "MAIN") && (lp = dllopen(vp, flags)))
844887Schin {
854887Schin if (xr = (Write_f)dlsym(lp, "write"))
864887Schin wr = xr;
874887Schin }
884887Schin } while (vp = (char*)_rld_new_interface(_RLD_NEXT_PATHNAME));
894887Schin }
904887Schin #endif
914887Schin if (vp = (char*)_rld_new_interface(_RLD_FIRST_PATHNAME))
924887Schin {
934887Schin do
944887Schin {
9510898Sroland.mainz@nrubsig.org if (lp = dllopen(strcmp(vp, "MAIN") ? vp : (char*)0, flags))
964887Schin {
974887Schin if (found)
984887Schin {
994887Schin b = e = 0;
1004887Schin s = vp;
1014887Schin for (;;)
1024887Schin {
1034887Schin switch (*s++)
1044887Schin {
1054887Schin case 0:
1064887Schin break;
1074887Schin case '/':
1084887Schin b = s;
1094887Schin e = 0;
1104887Schin continue;
1114887Schin case '.':
1124887Schin if (!e)
1134887Schin e = s - 1;
1144887Schin continue;
1154887Schin default:
1164887Schin continue;
1174887Schin }
1184887Schin break;
1194887Schin }
1204887Schin if (b && e)
1214887Schin {
1224887Schin s = dummy;
1234887Schin *s++ = '_';
1244887Schin *s++ = '_';
1254887Schin while (b < e)
1264887Schin *s++ = *b++;
1274887Schin b = "_dummy";
1284887Schin while (*s++ = *b++);
1294887Schin if (dlsym(lp, dummy))
1304887Schin {
1314887Schin dlclose(lp);
1324887Schin lp = 0;
1334887Schin }
1344887Schin }
1354887Schin if (lp)
1364887Schin {
1374887Schin #if DEBUG
1384887Schin if (wr)
1394887Schin (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: next %s\n", vp));
1404887Schin #endif
1414887Schin return lp;
1424887Schin }
1434887Schin #if DEBUG
1444887Schin else if (wr)
1454887Schin (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: skip %s\n", vp));
1464887Schin #endif
1474887Schin }
1484887Schin else if ((_DLL_RLD_SYM_TYPE*)dlsym(lp, _DLL_RLD_SYM_STR) == here)
1494887Schin {
1504887Schin #if DEBUG
1514887Schin if (wr)
1524887Schin (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: this %s\n", vp));
1534887Schin #endif
1544887Schin found = 1;
1554887Schin }
1564887Schin }
1574887Schin } while (vp = (char*)_rld_new_interface(_RLD_NEXT_PATHNAME));
1584887Schin }
1594887Schin return dllnext(flags);
1604887Schin }
1614887Schin
1624887Schin #endif
1634887Schin
1644887Schin #ifndef RTLD_NEXT
1654887Schin #if _dll_DYNAMIC
1664887Schin
1674887Schin #include <link.h>
1684887Schin
1694887Schin extern struct link_dynamic _DYNAMIC;
1704887Schin
1714887Schin #endif
1724887Schin #endif
1734887Schin
1744887Schin void*
dllnext(int flags)1754887Schin dllnext(int flags)
1764887Schin {
1774887Schin register void* dll;
1784887Schin #ifndef RTLD_NEXT
1794887Schin #if _dll_DYNAMIC
1804887Schin register struct link_map* map;
1814887Schin register char* s;
1824887Schin register char* b;
1834887Schin #endif
1844887Schin register char* ver;
1854887Schin char* path;
1864887Schin
1874887Schin static char next[] = { _DLL_NEXT_PATH };
1884887Schin #endif
1894887Schin
1904887Schin #ifdef RTLD_NEXT
1914887Schin dll = RTLD_NEXT;
1924887Schin #else
1934887Schin path = next;
1944887Schin #if _dll_DYNAMIC
1954887Schin for (map = _DYNAMIC.ld_un.ld_1->ld_loaded; map; map = map->lm_next)
1964887Schin {
1974887Schin b = 0;
1984887Schin s = map->lm_name;
1994887Schin while (*s)
2004887Schin if (*s++ == '/')
2014887Schin b = s;
2024887Schin if (b && b[0] == 'l' && b[1] == 'i' && b[2] == 'b' && b[3] == 'c' && b[4] == '.')
2034887Schin {
2044887Schin path = map->lm_name;
2054887Schin break;
2064887Schin }
2074887Schin }
2084887Schin #endif
2094887Schin ver = path + strlen(path);
21010898Sroland.mainz@nrubsig.org while (!(dll = dllopen(path, flags)))
2114887Schin {
2124887Schin do
2134887Schin {
2144887Schin if (ver <= path)
2154887Schin return 0;
2164887Schin } while (*--ver != '.');
2174887Schin if (*(ver + 1) <= '0' || *(ver + 1) >= '9')
2184887Schin return 0;
2194887Schin *ver = 0;
2204887Schin }
2214887Schin #endif
2224887Schin return dll;
2234887Schin }
224