ucommon  7.0.0
About: GNU uCommon C++ is a portable and optimized class framework for writing C++ applications that need to use threads and support concurrent synchronization, and that use sockets, XML parsing, object serialization, thread-optimized string and data structure classes, etc..
  Fossies Dox: ucommon-7.0.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

Loading...
Searching...
No Matches
dso.cpp
Go to the documentation of this file.
1// Copyright (C) 1999-2005 Open Source Telecom Corporation.
2// Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
3// Copyright (C) 2015 Cherokees of Idaho.
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19// As a special exception, you may use this file as part of a free software
20// library without restriction. Specifically, if other files instantiate
21// templates or use macros or inline functions from this file, or you compile
22// this file and link it with other files to produce an executable, this
23// file does not by itself cause the resulting executable to be covered by
24// the GNU General Public License. This exception does not however
25// invalidate any other reasons why the executable file might be covered by
26// the GNU General Public License.
27//
28// This exception applies only to the code released under the name GNU
29// Common C++. If you copy code from other releases into a copy of GNU
30// Common C++, as the General Public License permits, the exception does
31// not apply to the code that you add in this way. To avoid misleading
32// anyone as to the status of such modified files, you must delete
33// this exception notice from them.
34//
35// If you write modifications of your own for GNU Common C++, it is your choice
36// whether to permit this exception to apply to your modifications.
37// If you do not wish that, delete this exception notice.
38//
39
40#include <ucommon-config.h>
41#include <commoncpp/config.h>
42#include <commoncpp/export.h>
43#include <commoncpp/string.h>
44#include <commoncpp/exception.h>
45#include <commoncpp/slog.h>
46#include <commoncpp/file.h>
47#include <commoncpp/process.h>
48
49#if defined(HAVE_DLFCN_H)
50
51extern "C" {
52#include <dlfcn.h>
53}
54
55#ifndef RTLD_GLOBAL
56#define RTLD_GLOBAL 0
57#endif
58
59#endif // HAVE_DLFN_H
60
61#ifdef HAVE_SHL_LOAD
62#include <dl.h>
63#endif
64
65#ifdef HAVE_MACH_O_DYLD_H
66#include <mach-o/dyld.h>
67#define oModule ((oModule)(image))
68#endif
69
70#ifdef _MSWINDOWS_
71#define hImage ((HMODULE)(image))
72#endif
73
74namespace ost {
75
76DSO *DSO::first = NULL;
77DSO *DSO::last = NULL;
78Mutex DSO::mutex;
79
81{
82 while (last) {
83 DSO *prev = last->prev;
84 delete last;
85 last = prev;
86 }
87 last = first = NULL;
88}
89
91{
92#if defined(HAVE_MACH_DYLD)
93 NSSymbol sym;
94 void (*fini)(void);
95#endif
96 MutexLock lock(mutex);
97#if defined(_MSWINDOWS_)
98 if(image)
99 FreeLibrary(hImage);
100#elif defined(HAVE_MACH_DYLD)
101 if(image == NULL)
102 return;
103
104 sym = NSLookupSymbolInModule(oModule, "__fini");
105 if(sym != NULL) {
106 fini = (void (*)(void))NSAddressOfSymbol(sym);
107 fini();
108 }
109
110 NSUnLinkModule(oModule, NSUNLINKMODULE_OPTION_NONE);
111#elif defined(HAVE_SHL_LOAD)
112 if(image)
113 shl_unload(image);
114#elif defined(HAVE_DLFCN_H)
115 if(image)
116 dlclose(image);
117#endif
118
119 if(first == this && last == this)
120 first = last = NULL;
121
122 if(!next && !prev)
123 return;
124
125 if(prev)
126 prev->next = next;
127
128 if(next)
129 next->prev = prev;
130
131 if(first == this)
132 first = next;
133 if(last == this)
134 last = prev;
135}
136
137void DSO::loader(const char *filename, bool flag)
138{
139#if defined(HAVE_MACH_DYLD)
140 NSObjectFileImage oImage;
141 NSSymbol sym = NULL;
142 void (*init)(void);
143#endif
144
145 id = strrchr(filename, '/');
146 if(id)
147 ++id;
148 else
149 id = filename;
150
151 next = prev = NULL;
152
153#if defined(_MSWINDOWS_)
154 image = LoadLibrary(filename);
155 err = "none";
156#elif defined(HAVE_MACH_DYLD)
157 err = "none";
158 image = NULL;
159
160 switch(NSCreateObjectFileImageFromFile(filename, &oImage)) {
161 case NSObjectFileImageSuccess:
162 break;
163 default:
164 err = "unknown error";
165 return;
166 }
167 if(flag)
168 image = NSLinkModule(oImage, filename, NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
169 else
170 image = NSLinkModule(oImage, filename, NSLINKMODULE_OPTION_RETURN_ON_ERROR);
171 NSDestroyObjectFileImage(oImage);
172 if(oModule != NULL)
173 sym = NSLookupSymbolInModule(oModule, "__init");
174 if(sym) {
175 init = (void (*)(void))NSAddressOfSymbol(sym);
176 init();
177 }
178
179#elif defined(HAVE_SHL_LOAD)
180 err = "none";
181 if(flag)
182 image = shl_load(filename, BIND_IMMEDIATE, 0L);
183 else
184 image = shl_load(filename, BIND_DEFERRED, 0L);
185#elif defined(HAVE_DLFCN_H)
186 if(flag)
187 image = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
188 else
189 image = dlopen(filename, RTLD_LAZY | RTLD_GLOBAL);
190
191#endif
192
193#if defined(_MSWINDOWS_)
194 if(!image) {
195 err = "load failed";
196#elif defined(HAVE_MACH_DYLD)
197 if(image == NULL) {
198 err = "load failed";
199#elif defined(HAVE_SHL_LOAD)
200 if(!image) {
201 err = "load failed";
202#elif defined(HAVE_DLFCN_H)
203 if(!image) {
204 err = dlerror();
205#else
206 if(1) {
207 err = "load unsupported";
208#endif
209
210// since generally failure to map or load a plugin is fatel in most
211// cases, we should generally log the error to syslog as well as notify
212// the upper level system of the failure through exception.
213
214 slog.error() << "dso: " << id << ": " << err << std::endl;
215
216#ifdef CCXX_EXCEPTIONS
218 throw(this);
219#ifdef COMMON_STD_EXCEPTION
221 throw(DSOException(String(id) + err));
222#endif
223#endif
224 return;
225 }
226
227 if(!last) {
228 last = first = this;
229 return;
230 }
231
233 last->next = this;
234 prev = last;
235 last = this;
237}
238
239DSO *DSO::getObject(const char *id)
240{
241 const char *chk = strrchr(id, '/');
242 DSO *dso;
243
244 if(chk)
245 ++chk;
246 else
247 chk = id;
248
250 dso = first;
251 while(dso) {
252 if(!stricmp(dso->id, chk))
253 break;
254 dso = dso->next;
255 }
257 return dso;
258}
259
260bool DSO::isValid(void)
261{
262#if defined(_MSWINDOWS_)
263 if(!image)
264#elif defined(HAVE_MACH_DYLD)
265 if(image == NULL)
266#else
267 if(!image)
268#endif
269 return false;
270
271 return true;
272}
273
275{
276#if defined(HAVE_SHL_LOAD)
277 int value;
278 shl_t handle = (shl_t)image;
279
280 if(shl_findsym(&handle, sym, 0, &value) == 0)
281 return (DSO::addr_t)value;
282 else
283 return NULL;
284#elif defined(HAVE_MACH_DYLD)
285 NSSymbol oSymbol = NSLookupSymbolInModule(oModule, sym);
286 if(oSymbol)
287 return (DSO::addr_t)NSAddressOfSymbol(oSymbol);
288 else
289 return (DSO::addr_t)NULL;
290#elif defined(_MSWINDOWS_)
291 DSO::addr_t addr = (DSO::addr_t)GetProcAddress(hImage, sym);
292 if(!addr)
293 err = "symbol missing";
294
295 return addr;
296#elif defined(HAVE_DLFCN_H)
297 return (DSO::addr_t)dlsym(image, (char *)sym);
298#else
299 return (DSO::addr_t)NULL;
300#endif
301}
302
303#ifdef HAVE_MACH_DYLD
304static void MyLinkError(NSLinkEditErrors c, int errorNumber, const char *filename, const char *errstr)
305{
306 slog.error() << "dyld: " << filename << ": " << errstr << std::endl;
307}
308
309static void MyUndefined(const char *symname)
310{
311 slog.error() << "dyld: undefined: " << symname << std::endl;
312}
313
314static NSModule MyMultiple(NSSymbol s, NSModule oMod, NSModule nMod)
315{
316 slog.error() << "dyld: multiply defined symbols" << std::endl;
317}
318
319void DSO::setDebug(void)
320{
321 static NSLinkEditErrorHandlers handlers = {
322 &MyUndefined,
323 &MyMultiple,
324 &MyLinkError};
325
326 NSInstallLinkEditErrorHandlers(&handlers);
327}
328
329#else
330
332{
333}
334
335#endif
336
337} // namespace ost
The DSO dynamic loader class is used to load object files.
Definition: file.h:809
static DSO * first
Definition: file.h:813
bool isValid(void)
See if DSO object is valid.
Definition: dso.cpp:260
void * image
Definition: file.h:817
virtual ~DSO()
Detach a DSO object from running memory.
Definition: dso.cpp:90
static DSO * getObject(const char *name)
Find a specific DSO object by filename.
Definition: dso.cpp:239
addr_t operator[](const char *sym)
Lookup a symbol in the loaded file.
Definition: dso.cpp:274
const char * id
Definition: file.h:816
ucommon::dso::addr_t addr_t
Definition: file.h:819
DSO * next
Definition: file.h:815
const char * err
Definition: file.h:811
DSO * prev
Definition: file.h:815
static Mutex mutex
Definition: file.h:812
void loader(const char *filename, bool resolve)
Definition: dso.cpp:137
static void dynunload(void)
Definition: dso.cpp:80
static DSO * last
Definition: file.h:814
static void setDebug(void)
Install debug handler...
Definition: dso.cpp:331
The MutexLock class is used to protect a section of code so that at any given time only a single thre...
Definition: thread.h:154
void leaveMutex(void)
Definition: thread.h:74
void enterMutex(void)
Definition: thread.h:70
void error(const char *format,...)
Print a formatted syslog string.
Definition: slog.cpp:184
static Throw getException(void)
Get exception mode of the current thread.
Definition: thread.cpp:287
@ throwException
throw an object relative to error
Definition: thread.h:415
@ throwObject
throw object that cause error (throw this)
Definition: thread.h:414
A copy-on-write string class that operates by reference count.
Definition: string.h:79
Convenience class for library plugins.
Definition: fsys.h:663
Export interfaces for library interfaces.
Common C++ generic string class.
int stricmp(const char *s1, const char *s2)
Definition: cpr.cpp:95
GNU Common C++ exception model base classes.
Files and dynamic loader services.
Definition: address.cpp:63
Slog slog
Definition: slog.cpp:64
const struct sockaddr * addr(Socket::address &address)
A convenience function to convert a socket address list into a socket address.
Definition: socket.h:2089
T * init(T *memory)
Template function to initialize memory by invoking default constructor.
Definition: platform.h:551
Process services.
System logging facilities abstraction.