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