Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: third_party/dlfcn-win32/dlfcn.c

Issue 137143003: Add dlfcn-win32 to third_party (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/deps/
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/dlfcn-win32/dlfcn.h ('k') | third_party/dlfcn-win32/test.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 * dlfcn-win32
3 * Copyright (c) 2007 Ramiro Polla
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library 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 GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 US A
18 */
19
20 #include <windows.h>
21 #include <stdio.h>
22
23 #include "dlfcn.h"
24
25 /* Note:
26 * MSDN says these functions are not thread-safe. We make no efforts to have
27 * any kind of thread safety.
28 */
29
30 typedef struct global_object {
31 HMODULE hModule;
32 struct global_object *previous;
33 struct global_object *next;
34 } global_object;
35
36 static global_object first_object;
37
38 /* These functions implement a double linked list for the global objects. */
39 static global_object *global_search( HMODULE hModule )
40 {
41 global_object *pobject;
42
43 if( hModule == NULL )
44 return NULL;
45
46 for( pobject = &first_object; pobject ; pobject = pobject->next )
47 if( pobject->hModule == hModule )
48 return pobject;
49
50 return NULL;
51 }
52
53 static void global_add( HMODULE hModule )
54 {
55 global_object *pobject;
56 global_object *nobject;
57
58 if( hModule == NULL )
59 return;
60
61 pobject = global_search( hModule );
62
63 /* Do not add object again if it's already on the list */
64 if( pobject )
65 return;
66
67 for( pobject = &first_object; pobject->next ; pobject = pobject->next );
68
69 nobject = malloc( sizeof(global_object) );
70
71 /* Should this be enough to fail global_add, and therefore also fail
72 * dlopen?
73 */
74 if( !nobject )
75 return;
76
77 pobject->next = nobject;
78 nobject->next = NULL;
79 nobject->previous = pobject;
80 nobject->hModule = hModule;
81 }
82
83 static void global_rem( HMODULE hModule )
84 {
85 global_object *pobject;
86
87 if( hModule == NULL )
88 return;
89
90 pobject = global_search( hModule );
91
92 if( !pobject )
93 return;
94
95 if( pobject->next )
96 pobject->next->previous = pobject->previous;
97 if( pobject->previous )
98 pobject->previous->next = pobject->next;
99
100 free( pobject );
101 }
102
103 /* POSIX says dlerror( ) doesn't have to be thread-safe, so we use one
104 * static buffer.
105 * MSDN says the buffer cannot be larger than 64K bytes, so we set it to
106 * the limit.
107 */
108 static char error_buffer[65535];
109 static char *current_error;
110
111 static int copy_string( char *dest, int dest_size, const char *src )
112 {
113 int i = 0;
114
115 /* gcc should optimize this out */
116 if( !src || !dest )
117 return 0;
118
119 for( i = 0 ; i < dest_size-1 ; i++ )
120 {
121 if( !src[i] )
122 break;
123 else
124 dest[i] = src[i];
125 }
126 dest[i] = '\0';
127
128 return i;
129 }
130
131 static void save_err_str( const char *str )
132 {
133 DWORD dwMessageId;
134 DWORD pos;
135
136 dwMessageId = GetLastError( );
137
138 if( dwMessageId == 0 )
139 return;
140
141 /* Format error message to:
142 * "<argument to function that failed>": <Windows localized error message>
143 */
144 pos = copy_string( error_buffer, sizeof(error_buffer), "\"" );
145 pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, str );
146 pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, "\": " );
147 pos += FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId,
148 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
149 error_buffer+pos, sizeof(error_buffer)-pos, NULL );
150
151 if( pos > 1 )
152 {
153 /* POSIX says the string must not have trailing <newline> */
154 if( error_buffer[pos-2] == '\r' && error_buffer[pos-1] == '\n' )
155 error_buffer[pos-2] = '\0';
156 }
157
158 current_error = error_buffer;
159 }
160
161 static void save_err_ptr_str( const void *ptr )
162 {
163 char ptr_buf[19]; /* 0x<pointer> up to 64 bits. */
164
165 sprintf( ptr_buf, "0x%p", ptr );
166
167 save_err_str( ptr_buf );
168 }
169
170 void *dlopen( const char *file, int mode )
171 {
172 HMODULE hModule;
173 UINT uMode;
174
175 current_error = NULL;
176
177 /* Do not let Windows display the critical-error-handler message box */
178 uMode = SetErrorMode( SEM_FAILCRITICALERRORS );
179
180 if( file == 0 )
181 {
182 /* POSIX says that if the value of file is 0, a handle on a global
183 * symbol object must be provided. That object must be able to access
184 * all symbols from the original program file, and any objects loaded
185 * with the RTLD_GLOBAL flag.
186 * The return value from GetModuleHandle( ) allows us to retrieve
187 * symbols only from the original program file. For objects loaded with
188 * the RTLD_GLOBAL flag, we create our own list later on.
189 */
190 hModule = GetModuleHandle( NULL );
191
192 if( !hModule )
193 save_err_ptr_str( file );
194 }
195 else
196 {
197 char lpFileName[MAX_PATH];
198 int i;
199
200 /* MSDN says backslashes *must* be used instead of forward slashes. */
201 for( i = 0 ; i < sizeof(lpFileName)-1 ; i++ )
202 {
203 if( !file[i] )
204 break;
205 else if( file[i] == '/' )
206 lpFileName[i] = '\\';
207 else
208 lpFileName[i] = file[i];
209 }
210 lpFileName[i] = '\0';
211
212 /* POSIX says the search path is implementation-defined.
213 * LOAD_WITH_ALTERED_SEARCH_PATH is used to make it behave more closely
214 * to UNIX's search paths (start with system folders instead of current
215 * folder).
216 */
217 hModule = LoadLibraryEx( (LPSTR) lpFileName, NULL,
218 LOAD_WITH_ALTERED_SEARCH_PATH );
219
220 /* If the object was loaded with RTLD_GLOBAL, add it to list of global
221 * objects, so that its symbols may be retrieved even if the handle for
222 * the original program file is passed. POSIX says that if the same
223 * file is specified in multiple invocations, and any of them are
224 * RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the
225 * symbols will remain global.
226 */
227 if( !hModule )
228 save_err_str( lpFileName );
229 else if( (mode & RTLD_GLOBAL) )
230 global_add( hModule );
231 }
232
233 /* Return to previous state of the error-mode bit flags. */
234 SetErrorMode( uMode );
235
236 return (void *) hModule;
237 }
238
239 int dlclose( void *handle )
240 {
241 HMODULE hModule = (HMODULE) handle;
242 BOOL ret;
243
244 current_error = NULL;
245
246 ret = FreeLibrary( hModule );
247
248 /* If the object was loaded with RTLD_GLOBAL, remove it from list of global
249 * objects.
250 */
251 if( ret )
252 global_rem( hModule );
253 else
254 save_err_ptr_str( handle );
255
256 /* dlclose's return value in inverted in relation to FreeLibrary's. */
257 ret = !ret;
258
259 return (int) ret;
260 }
261
262 void *dlsym( void *handle, const char *name )
263 {
264 FARPROC symbol;
265
266 current_error = NULL;
267
268 symbol = GetProcAddress( handle, name );
269
270 if( symbol == NULL )
271 {
272 HMODULE hModule;
273
274 /* If the handle for the original program file is passed, also search
275 * in all globally loaded objects.
276 */
277
278 hModule = GetModuleHandle( NULL );
279
280 if( hModule == handle )
281 {
282 global_object *pobject;
283
284 for( pobject = &first_object; pobject ; pobject = pobject->next )
285 {
286 if( pobject->hModule )
287 {
288 symbol = GetProcAddress( pobject->hModule, name );
289 if( symbol != NULL )
290 break;
291 }
292 }
293 }
294 }
295
296 if( symbol == NULL )
297 save_err_str( name );
298
299 return (void*) symbol;
300 }
301
302 char *dlerror( void )
303 {
304 char *error_pointer = current_error;
305
306 /* POSIX says that invoking dlerror( ) a second time, immediately following
307 * a prior invocation, shall result in NULL being returned.
308 */
309 current_error = NULL;
310
311 return error_pointer;
312 }
OLDNEW
« no previous file with comments | « third_party/dlfcn-win32/dlfcn.h ('k') | third_party/dlfcn-win32/test.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698