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