WvStreams
loader.cc
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 *
3 * XPLC - Cross-Platform Lightweight Components
4 * Copyright (C) 2002, Net Integration Technologies, Inc.
5 * Copyright (C) 2002-2004, Pierre Phaneuf
6 * Copyright (C) 2002-2004, Stéphane Lajoie
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 */
23
24#include <stdlib.h>
25#include <stdio.h>
26
27#include "config.h"
28#include "loader.h"
29
30#ifdef HAVE_DLFCN_H
31#include <dlfcn.h>
32#endif
33
34#ifdef HAVE_MACH_O_DYLD_H
35#include <mach-o/dyld.h>
36#endif
37
38#if defined(WITH_DLOPEN) && defined(ENABLE_LOADER)
39const char* loaderOpen(const char* aFilename,
40 void** aHandle) {
41 const char* rv = 0;
42
43 /* clear out dl error */
44 static_cast<void>(dlerror());
45
46 *aHandle = dlopen(aFilename, RTLD_NOW);
47
48 if(!*aHandle)
49 rv = dlerror();
50
51 return rv;
52}
53
54const char* loaderSymbol(void* aHandle,
55 const char* aSymbol,
56 void** aPointer) {
57 /* clear out dl error */
58 static_cast<void>(dlerror());
59
60 *aPointer = dlsym(aHandle, aSymbol);
61
62 return dlerror();
63}
64
65bool loaderClose(void*& aHandle) {
66 bool rv;
67
68 rv = dlclose(aHandle) == 0;
69 aHandle = 0;
70
71 return rv;
72}
73
74#elif defined(WITH_DYLD) && defined(ENABLE_LOADER)
75
76const char* loaderOpen(const char* aFilename,
77 void** aHandle) {
78 NSObjectFileImage ofi = 0;
79 NSObjectFileImageReturnCode ofirc;
80
81 ofirc = NSCreateObjectFileImageFromFile(aFilename, &ofi);
82 switch(ofirc) {
83 case NSObjectFileImageSuccess:
84 *aHandle = NSLinkModule(ofi, aFilename,
85 NSLINKMODULE_OPTION_RETURN_ON_ERROR
86 | NSLINKMODULE_OPTION_PRIVATE
87 | NSLINKMODULE_OPTION_BINDNOW);
88 NSDestroyObjectFileImage(ofi);
89 break;
90 case NSObjectFileImageInappropriateFile:
91 *aHandle =
92 const_cast<void*>(reinterpret_cast<const void*>(NSAddImage(aFilename, NSADDIMAGE_OPTION_RETURN_ON_ERROR)));
93 break;
94 default:
95 return "could not open dynamic library";
96 break;
97 }
98
99 return 0;
100}
101
102const char* loaderSymbol(void* aHandle,
103 const char* aSymbol,
104 void** aPointer) {
105 int len = strlen(aSymbol);
106 char* sym = static_cast<char*>(malloc(len + 2));
107 NSSymbol* nssym = 0;
108
109 snprintf(sym, len + 2, "_%s", aSymbol);
110
111 /* Check for both possible magic numbers depending on x86/ppc byte order */
112 if ((((struct mach_header *)aHandle)->magic == MH_MAGIC) ||
113 (((struct mach_header *)aHandle)->magic == MH_CIGAM)) {
114 if (NSIsSymbolNameDefinedInImage((struct mach_header *)aHandle, sym)) {
115 nssym = (NSModule *)NSLookupSymbolInImage((struct mach_header *)aHandle,
116 sym,
117 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
118 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
119 }
120 } else {
121 nssym = (NSModule *)NSLookupSymbolInModule(aHandle, sym);
122 }
123
124 free(sym);
125
126 if(!nssym) {
127 *aPointer = 0;
128 return "symbol not found";
129 }
130
131 return 0;
132}
133
134bool loaderClose(void*& aHandle) {
135 aHandle = 0;
136 return false;
137}
138
139#elif defined(WIN32)
140
141#include <windows.h>
142
143const char* getErrorMessage() {
144 static char error[1024];
145 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, error, sizeof(error), 0);
146 return error;
147}
148
149const char* loaderOpen(const char* aFilename,
150 void** aHandle) {
151 const char* rv = 0;
152
153 UINT oldErrorMode = SetErrorMode(0);
154 SetErrorMode(oldErrorMode | SEM_FAILCRITICALERRORS);
155 *aHandle = LoadLibrary(aFilename);
156 SetErrorMode(oldErrorMode);
157
158 if(!*aHandle)
159 rv = getErrorMessage();
160
161 return rv;
162}
163
164const char* loaderSymbol(void* aHandle,
165 const char* aSymbol,
166 void** aPointer) {
167 const char* rv = 0;
168
169 *aPointer = (void *)GetProcAddress(static_cast<HMODULE>(aHandle), aSymbol);
170
171 if(!aPointer)
172 rv = getErrorMessage();
173
174 return rv;
175}
176
177bool loaderClose(void*& aHandle) {
178 bool rv;
179
180 rv = FreeLibrary(static_cast<HMODULE>(aHandle)) != 0;
181 aHandle = 0;
182
183 return rv;
184}
185
186#else
187
188const char* loaderOpen(const char* aFilename,
189 void** aHandle) {
190 *aHandle = 0;
191 return "dynamic loading not supported on this platform";
192}
193
194const char* loaderSymbol(void* aHandle,
195 const char* aSymbol,
196 void** aPointer) {
197 *aPointer = 0;
198 return "dynamic loading not supported on this platform";
199}
200
201bool loaderClose(void*& aHandle) {
202 aHandle = 0;
203 return false;
204}
205
206#endif