|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 /* |
|
6 * Allow freebl and softoken to be loaded without util or NSPR. |
|
7 * |
|
8 * These symbols are overridden once real NSPR, and libutil are attached. |
|
9 */ |
|
10 #define _GNU_SOURCE 1 |
|
11 #include <stdlib.h> |
|
12 #include <stdio.h> |
|
13 #include <stdarg.h> |
|
14 #include <fcntl.h> |
|
15 #include <time.h> |
|
16 #include <unistd.h> |
|
17 #include <sys/time.h> |
|
18 #include <dlfcn.h> |
|
19 #include <prio.h> |
|
20 #include <prlink.h> |
|
21 #include <prlog.h> |
|
22 #include <prthread.h> |
|
23 #include <plstr.h> |
|
24 #include <prinit.h> |
|
25 #include <prlock.h> |
|
26 #include <prmem.h> |
|
27 #include <prerror.h> |
|
28 #include <prmon.h> |
|
29 #include <pratom.h> |
|
30 #include <prsystem.h> |
|
31 #include <prinrval.h> |
|
32 #include <prtime.h> |
|
33 #include <prcvar.h> |
|
34 #include <secasn1.h> |
|
35 #include <secdig.h> |
|
36 #include <secport.h> |
|
37 #include <secitem.h> |
|
38 #include <blapi.h> |
|
39 #include <private/pprio.h> |
|
40 |
|
41 #define FREEBL_NO_WEAK 1 |
|
42 |
|
43 #define WEAK __attribute__((weak)) |
|
44 |
|
45 #ifdef FREEBL_NO_WEAK |
|
46 |
|
47 /* |
|
48 * This uses function pointers. |
|
49 * |
|
50 * CONS: A separate function is needed to |
|
51 * fill in the function pointers. |
|
52 * |
|
53 * PROS: it works on all platforms. |
|
54 * it allows for dynamically finding nspr and libutil, even once |
|
55 * softoken is loaded and running. (NOTE: this may be a problem if |
|
56 * we switch between the stubs and real NSPR on the fly. NSPR will |
|
57 * do bad things if passed an _FakeArena to free or allocate from). |
|
58 */ |
|
59 #define STUB_DECLARE(ret, fn, args) \ |
|
60 typedef ret (*type_##fn) args; \ |
|
61 static type_##fn ptr_##fn = NULL |
|
62 |
|
63 #define STUB_SAFE_CALL0(fn) \ |
|
64 if (ptr_##fn) { return ptr_##fn(); } |
|
65 #define STUB_SAFE_CALL1(fn,a1) \ |
|
66 if (ptr_##fn) { return ptr_##fn(a1); } |
|
67 #define STUB_SAFE_CALL2(fn,a1,a2) \ |
|
68 if (ptr_##fn) { return ptr_##fn(a1,a2); } |
|
69 #define STUB_SAFE_CALL3(fn,a1,a2,a3) \ |
|
70 if (ptr_##fn) { return ptr_##fn(a1,a2,a3); } |
|
71 #define STUB_SAFE_CALL4(fn,a1,a2,a3,a4) \ |
|
72 if (ptr_##fn) { return ptr_##fn(a1,a2,a3,a4); } |
|
73 #define STUB_SAFE_CALL6(fn,a1,a2,a3,a4,a5,a6) \ |
|
74 if (ptr_##fn) { return ptr_##fn(a1,a2,a3,a4,a5,a6); } |
|
75 |
|
76 #define STUB_FETCH_FUNCTION(fn) \ |
|
77 ptr_##fn = (type_##fn) dlsym(lib,#fn); \ |
|
78 if (ptr_##fn == NULL) { \ |
|
79 return SECFailure; \ |
|
80 } |
|
81 |
|
82 #else |
|
83 /* |
|
84 * this uses the loader weak attribute. it works automatically, but once |
|
85 * freebl is loaded, the symbols are 'fixed' (later loading of NSPR or |
|
86 * libutil will not resolve these symbols. |
|
87 */ |
|
88 |
|
89 #define STUB_DECLARE(ret, fn, args) \ |
|
90 WEAK extern ret fn args |
|
91 |
|
92 #define STUB_SAFE_CALL0(fn) \ |
|
93 if (fn) { return fn(); } |
|
94 #define STUB_SAFE_CALL1(fn,a1) \ |
|
95 if (fn) { return fn(a1); } |
|
96 #define STUB_SAFE_CALL2(fn,a1,a2) \ |
|
97 if (fn) { return fn(a1,a2); } |
|
98 #define STUB_SAFE_CALL3(fn,a1,a2,a3) \ |
|
99 if (fn) { return fn(a1,a2,a3); } |
|
100 #define STUB_SAFE_CALL4(fn,a1,a2,a3,a4) \ |
|
101 if (fn) { return fn(a1,a2,a3,a4); } |
|
102 #define STUB_SAFE_CALL6(fn,a1,a2,a3,a4,a5,a6) \ |
|
103 if (fn) { return fn(a1,a2,a3,a4,a5,a6); } |
|
104 #endif |
|
105 |
|
106 |
|
107 STUB_DECLARE(void *,PORT_Alloc_Util,(size_t len)); |
|
108 STUB_DECLARE(void *,PORT_ArenaAlloc_Util,(PLArenaPool *arena, size_t size)); |
|
109 STUB_DECLARE(void *,PORT_ArenaZAlloc_Util,(PLArenaPool *arena, size_t size)); |
|
110 STUB_DECLARE(void ,PORT_Free_Util,(void *ptr)); |
|
111 STUB_DECLARE(void ,PORT_FreeArena_Util,(PLArenaPool *arena, PRBool zero)); |
|
112 STUB_DECLARE(int,PORT_GetError_Util,(void)); |
|
113 STUB_DECLARE(PLArenaPool *,PORT_NewArena_Util,(unsigned long chunksize)); |
|
114 STUB_DECLARE(void,PORT_SetError_Util,(int value)); |
|
115 STUB_DECLARE(void *,PORT_ZAlloc_Util,(size_t len)); |
|
116 STUB_DECLARE(void,PORT_ZFree_Util,(void *ptr, size_t len)); |
|
117 |
|
118 STUB_DECLARE(void,PR_Assert,(const char *s, const char *file, PRIntn ln)); |
|
119 STUB_DECLARE(PRStatus,PR_CallOnce,(PRCallOnceType *once, PRCallOnceFN func)); |
|
120 STUB_DECLARE(PRStatus,PR_Close,(PRFileDesc *fd)); |
|
121 STUB_DECLARE(void,PR_DestroyLock,(PRLock *lock)); |
|
122 STUB_DECLARE(void,PR_DestroyCondVar,(PRCondVar *cvar)); |
|
123 STUB_DECLARE(void,PR_Free,(void *ptr)); |
|
124 STUB_DECLARE(char * ,PR_GetLibraryFilePathname,(const char *name, |
|
125 PRFuncPtr addr)); |
|
126 STUB_DECLARE(PRFileDesc *,PR_ImportPipe,(PROsfd osfd)); |
|
127 STUB_DECLARE(void,PR_Lock,(PRLock *lock)); |
|
128 STUB_DECLARE(PRCondVar *,PR_NewCondVar,(PRLock *lock)); |
|
129 STUB_DECLARE(PRLock *,PR_NewLock,(void)); |
|
130 STUB_DECLARE(PRStatus,PR_NotifyCondVar,(PRCondVar *cvar)); |
|
131 STUB_DECLARE(PRStatus,PR_NotifyAllCondVar,(PRCondVar *cvar)); |
|
132 STUB_DECLARE(PRFileDesc *,PR_Open,(const char *name, PRIntn flags, |
|
133 PRIntn mode)); |
|
134 STUB_DECLARE(PRInt32,PR_Read,(PRFileDesc *fd, void *buf, PRInt32 amount)); |
|
135 STUB_DECLARE(PROffset32,PR_Seek,(PRFileDesc *fd, PROffset32 offset, |
|
136 PRSeekWhence whence)); |
|
137 STUB_DECLARE(PRStatus,PR_Sleep,(PRIntervalTime ticks)); |
|
138 STUB_DECLARE(PRStatus,PR_Unlock,(PRLock *lock)); |
|
139 STUB_DECLARE(PRStatus,PR_WaitCondVar,(PRCondVar *cvar, |
|
140 PRIntervalTime timeout)); |
|
141 |
|
142 |
|
143 STUB_DECLARE(SECItem *,SECITEM_AllocItem_Util,(PLArenaPool *arena, |
|
144 SECItem *item,unsigned int len)); |
|
145 STUB_DECLARE(SECComparison,SECITEM_CompareItem_Util,(const SECItem *a, |
|
146 const SECItem *b)); |
|
147 STUB_DECLARE(SECStatus,SECITEM_CopyItem_Util,(PLArenaPool *arena, |
|
148 SECItem *to,const SECItem *from)); |
|
149 STUB_DECLARE(void,SECITEM_FreeItem_Util,(SECItem *zap, PRBool freeit)); |
|
150 STUB_DECLARE(void,SECITEM_ZfreeItem_Util,(SECItem *zap, PRBool freeit)); |
|
151 STUB_DECLARE(SECOidTag,SECOID_FindOIDTag_Util,(const SECItem *oid)); |
|
152 STUB_DECLARE(int, NSS_SecureMemcmp,(const void *a, const void *b, size_t n)); |
|
153 |
|
154 |
|
155 #define PORT_ZNew_stub(type) (type*)PORT_ZAlloc_stub(sizeof(type)) |
|
156 #define PORT_New_stub(type) (type*)PORT_Alloc_stub(sizeof(type)) |
|
157 #define PORT_ZNewArray_stub(type, num) \ |
|
158 (type*) PORT_ZAlloc_stub (sizeof(type)*(num)) |
|
159 |
|
160 |
|
161 /* |
|
162 * NOTE: in order to support hashing only the memory allocation stubs, |
|
163 * the get library name stubs, and the file io stubs are needed (the latter |
|
164 * two are for the library verification). The remaining stubs are simply to |
|
165 * compile. Attempts to use the library for other operations without NSPR |
|
166 * will most likely fail. |
|
167 */ |
|
168 |
|
169 |
|
170 /* memory */ |
|
171 extern void * |
|
172 PORT_Alloc_stub(size_t len) |
|
173 { |
|
174 STUB_SAFE_CALL1(PORT_Alloc_Util, len); |
|
175 return malloc(len); |
|
176 } |
|
177 |
|
178 extern void |
|
179 PORT_Free_stub(void *ptr) |
|
180 { |
|
181 STUB_SAFE_CALL1(PORT_Free_Util, ptr); |
|
182 return free(ptr); |
|
183 } |
|
184 |
|
185 extern void * |
|
186 PORT_ZAlloc_stub(size_t len) |
|
187 { |
|
188 STUB_SAFE_CALL1(PORT_ZAlloc_Util, len); |
|
189 void *ptr = malloc(len); |
|
190 if (ptr) { |
|
191 memset(ptr, 0, len); |
|
192 } |
|
193 return ptr; |
|
194 } |
|
195 |
|
196 |
|
197 extern void |
|
198 PORT_ZFree_stub(void *ptr, size_t len) |
|
199 { |
|
200 STUB_SAFE_CALL2(PORT_ZFree_Util, ptr, len); |
|
201 memset(ptr, 0, len); |
|
202 return free(ptr); |
|
203 } |
|
204 |
|
205 extern void |
|
206 PR_Free_stub(void *ptr) |
|
207 { |
|
208 STUB_SAFE_CALL1(PR_Free, ptr); |
|
209 return free(ptr); |
|
210 } |
|
211 |
|
212 /* |
|
213 * arenas |
|
214 * |
|
215 */ |
|
216 extern PLArenaPool * |
|
217 PORT_NewArena_stub(unsigned long chunksize) |
|
218 { |
|
219 STUB_SAFE_CALL1(PORT_NewArena_Util, chunksize); |
|
220 abort(); |
|
221 return NULL; |
|
222 } |
|
223 |
|
224 extern void * |
|
225 PORT_ArenaAlloc_stub(PLArenaPool *arena, size_t size) |
|
226 { |
|
227 |
|
228 STUB_SAFE_CALL2(PORT_ArenaZAlloc_Util, arena, size); |
|
229 abort(); |
|
230 return NULL; |
|
231 } |
|
232 |
|
233 extern void * |
|
234 PORT_ArenaZAlloc_stub(PLArenaPool *arena, size_t size) |
|
235 { |
|
236 |
|
237 STUB_SAFE_CALL2(PORT_ArenaZAlloc_Util, arena, size); |
|
238 abort(); |
|
239 return NULL; |
|
240 } |
|
241 |
|
242 extern void |
|
243 PORT_FreeArena_stub(PLArenaPool *arena, PRBool zero) |
|
244 { |
|
245 |
|
246 STUB_SAFE_CALL2(PORT_FreeArena_Util, arena, zero); |
|
247 abort(); |
|
248 } |
|
249 |
|
250 |
|
251 /* io */ |
|
252 extern PRFileDesc * |
|
253 PR_Open_stub(const char *name, PRIntn flags, PRIntn mode) |
|
254 { |
|
255 int *lfd = NULL; |
|
256 int fd; |
|
257 int lflags = 0; |
|
258 |
|
259 STUB_SAFE_CALL3(PR_Open, name, flags, mode); |
|
260 |
|
261 if (flags & PR_RDWR) { |
|
262 lflags = O_RDWR; |
|
263 } else if (flags & PR_WRONLY) { |
|
264 lflags = O_WRONLY; |
|
265 } else { |
|
266 lflags = O_RDONLY; |
|
267 } |
|
268 |
|
269 if (flags & PR_EXCL) |
|
270 lflags |= O_EXCL; |
|
271 if (flags & PR_APPEND) |
|
272 lflags |= O_APPEND; |
|
273 if (flags & PR_TRUNCATE) |
|
274 lflags |= O_TRUNC; |
|
275 |
|
276 fd = open(name, lflags, mode); |
|
277 if (fd >= 0) { |
|
278 lfd = PORT_New_stub(int); |
|
279 if (lfd != NULL) { |
|
280 *lfd = fd; |
|
281 } |
|
282 } |
|
283 return (PRFileDesc *)lfd; |
|
284 } |
|
285 |
|
286 extern PRFileDesc * |
|
287 PR_ImportPipe_stub(PROsfd fd) |
|
288 { |
|
289 int *lfd = NULL; |
|
290 |
|
291 STUB_SAFE_CALL1(PR_ImportPipe, fd); |
|
292 |
|
293 lfd = PORT_New_stub(int); |
|
294 if (lfd != NULL) { |
|
295 *lfd = fd; |
|
296 } |
|
297 return (PRFileDesc *)lfd; |
|
298 } |
|
299 |
|
300 extern PRStatus |
|
301 PR_Close_stub(PRFileDesc *fd) |
|
302 { |
|
303 int *lfd; |
|
304 STUB_SAFE_CALL1(PR_Close, fd); |
|
305 |
|
306 lfd = (int *)fd; |
|
307 close(*lfd); |
|
308 PORT_Free_stub(lfd); |
|
309 |
|
310 return PR_SUCCESS; |
|
311 } |
|
312 |
|
313 extern PRInt32 |
|
314 PR_Read_stub(PRFileDesc *fd, void *buf, PRInt32 amount) |
|
315 { |
|
316 int *lfd; |
|
317 STUB_SAFE_CALL3(PR_Read, fd, buf, amount); |
|
318 |
|
319 lfd = (int *)fd; |
|
320 return read(*lfd, buf, amount); |
|
321 } |
|
322 |
|
323 extern PROffset32 |
|
324 PR_Seek_stub(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence) |
|
325 { |
|
326 int *lfd; |
|
327 int lwhence = SEEK_SET;; |
|
328 STUB_SAFE_CALL3(PR_Seek, fd, offset, whence); |
|
329 lfd = (int *)fd; |
|
330 switch (whence) { |
|
331 case PR_SEEK_CUR: |
|
332 lwhence = SEEK_CUR; |
|
333 break; |
|
334 case PR_SEEK_END: |
|
335 lwhence = SEEK_END; |
|
336 break; |
|
337 } |
|
338 |
|
339 return lseek(*lfd, offset, lwhence); |
|
340 } |
|
341 |
|
342 |
|
343 /* |
|
344 * library |
|
345 */ |
|
346 extern char * |
|
347 PR_GetLibraryFilePathname_stub(const char *name, PRFuncPtr addr) |
|
348 { |
|
349 Dl_info dli; |
|
350 char *result; |
|
351 |
|
352 STUB_SAFE_CALL2(PR_GetLibraryFilePathname, name, addr); |
|
353 |
|
354 if (dladdr((void *)addr, &dli) == 0) { |
|
355 return NULL; |
|
356 } |
|
357 result = PORT_Alloc_stub(strlen(dli.dli_fname)+1); |
|
358 if (result != NULL) { |
|
359 strcpy(result, dli.dli_fname); |
|
360 } |
|
361 return result; |
|
362 } |
|
363 |
|
364 |
|
365 #include <errno.h> |
|
366 |
|
367 /* errors */ |
|
368 extern int |
|
369 PORT_GetError_stub(void) |
|
370 { |
|
371 STUB_SAFE_CALL0(PORT_GetError_Util); |
|
372 return errno; |
|
373 } |
|
374 |
|
375 extern void |
|
376 PORT_SetError_stub(int value) |
|
377 { |
|
378 STUB_SAFE_CALL1(PORT_SetError_Util, value); |
|
379 errno = value; |
|
380 } |
|
381 |
|
382 /* misc */ |
|
383 extern void |
|
384 PR_Assert_stub(const char *s, const char *file, PRIntn ln) |
|
385 { |
|
386 STUB_SAFE_CALL3(PR_Assert, s, file, ln); |
|
387 fprintf(stderr, "%s line %d: %s\n", file, ln, s); |
|
388 abort(); |
|
389 } |
|
390 |
|
391 /* time */ |
|
392 extern PRStatus |
|
393 PR_Sleep_stub(PRIntervalTime ticks) |
|
394 { |
|
395 STUB_SAFE_CALL1(PR_Sleep, ticks); |
|
396 usleep(ticks*1000); |
|
397 return PR_SUCCESS; |
|
398 } |
|
399 |
|
400 |
|
401 /* locking */ |
|
402 extern PRLock * |
|
403 PR_NewLock_stub(void) |
|
404 { |
|
405 STUB_SAFE_CALL0(PR_NewLock); |
|
406 abort(); |
|
407 return NULL; |
|
408 } |
|
409 |
|
410 extern PRStatus |
|
411 PR_Unlock_stub(PRLock *lock) |
|
412 { |
|
413 STUB_SAFE_CALL1(PR_Unlock, lock); |
|
414 abort(); |
|
415 return PR_FAILURE; |
|
416 } |
|
417 |
|
418 extern void |
|
419 PR_Lock_stub(PRLock *lock) |
|
420 { |
|
421 STUB_SAFE_CALL1(PR_Lock, lock); |
|
422 abort(); |
|
423 return; |
|
424 } |
|
425 |
|
426 extern void |
|
427 PR_DestroyLock_stub(PRLock *lock) |
|
428 { |
|
429 STUB_SAFE_CALL1(PR_DestroyLock, lock); |
|
430 abort(); |
|
431 return; |
|
432 } |
|
433 |
|
434 extern PRCondVar * |
|
435 PR_NewCondVar_stub(PRLock *lock) |
|
436 { |
|
437 STUB_SAFE_CALL1(PR_NewCondVar, lock); |
|
438 abort(); |
|
439 return NULL; |
|
440 } |
|
441 |
|
442 extern PRStatus |
|
443 PR_NotifyCondVar_stub(PRCondVar *cvar) |
|
444 { |
|
445 STUB_SAFE_CALL1(PR_NotifyCondVar, cvar); |
|
446 abort(); |
|
447 return PR_FAILURE; |
|
448 } |
|
449 |
|
450 extern PRStatus |
|
451 PR_NotifyAllCondVar_stub(PRCondVar *cvar) |
|
452 { |
|
453 STUB_SAFE_CALL1(PR_NotifyAllCondVar, cvar); |
|
454 abort(); |
|
455 return PR_FAILURE; |
|
456 } |
|
457 |
|
458 extern PRStatus |
|
459 PR_WaitCondVar_stub(PRCondVar *cvar, PRIntervalTime timeout) |
|
460 { |
|
461 STUB_SAFE_CALL2(PR_WaitCondVar, cvar, timeout); |
|
462 abort(); |
|
463 return PR_FAILURE; |
|
464 } |
|
465 |
|
466 |
|
467 |
|
468 extern void |
|
469 PR_DestroyCondVar_stub(PRCondVar *cvar) |
|
470 { |
|
471 STUB_SAFE_CALL1(PR_DestroyCondVar, cvar); |
|
472 abort(); |
|
473 return; |
|
474 } |
|
475 |
|
476 /* |
|
477 * NOTE: this presupposes GCC 4.1 |
|
478 */ |
|
479 extern PRStatus |
|
480 PR_CallOnce_stub(PRCallOnceType *once, PRCallOnceFN func) |
|
481 { |
|
482 STUB_SAFE_CALL2(PR_CallOnce, once, func); |
|
483 abort(); |
|
484 return PR_FAILURE; |
|
485 } |
|
486 |
|
487 |
|
488 /* |
|
489 * SECITEMS implement Item Utilities |
|
490 */ |
|
491 extern void |
|
492 SECITEM_FreeItem_stub(SECItem *zap, PRBool freeit) |
|
493 { |
|
494 STUB_SAFE_CALL2(SECITEM_FreeItem_Util, zap, freeit); |
|
495 abort(); |
|
496 } |
|
497 |
|
498 extern SECItem * |
|
499 SECITEM_AllocItem_stub(PLArenaPool *arena, SECItem *item, unsigned int len) |
|
500 { |
|
501 STUB_SAFE_CALL3(SECITEM_AllocItem_Util, arena, item, len); |
|
502 abort(); |
|
503 return NULL; |
|
504 } |
|
505 |
|
506 extern SECComparison |
|
507 SECITEM_CompareItem_stub(const SECItem *a, const SECItem *b) |
|
508 { |
|
509 STUB_SAFE_CALL2(SECITEM_CompareItem_Util, a, b); |
|
510 abort(); |
|
511 return SECEqual; |
|
512 } |
|
513 |
|
514 extern SECStatus |
|
515 SECITEM_CopyItem_stub(PLArenaPool *arena, SECItem *to, const SECItem *from) |
|
516 { |
|
517 STUB_SAFE_CALL3(SECITEM_CopyItem_Util, arena, to, from); |
|
518 abort(); |
|
519 return SECFailure; |
|
520 } |
|
521 |
|
522 extern SECOidTag |
|
523 SECOID_FindOIDTag_stub(const SECItem *oid) |
|
524 { |
|
525 STUB_SAFE_CALL1(SECOID_FindOIDTag_Util, oid); |
|
526 abort(); |
|
527 return SEC_OID_UNKNOWN; |
|
528 } |
|
529 |
|
530 extern void |
|
531 SECITEM_ZfreeItem_stub(SECItem *zap, PRBool freeit) |
|
532 { |
|
533 STUB_SAFE_CALL2(SECITEM_ZfreeItem_Util, zap, freeit); |
|
534 abort(); |
|
535 } |
|
536 |
|
537 extern int |
|
538 NSS_SecureMemcmp_stub(const void *a, const void *b, size_t n) |
|
539 { |
|
540 STUB_SAFE_CALL3(NSS_SecureMemcmp, a, b, n); |
|
541 abort(); |
|
542 } |
|
543 |
|
544 #ifdef FREEBL_NO_WEAK |
|
545 |
|
546 static const char *nsprLibName = SHLIB_PREFIX"nspr4."SHLIB_SUFFIX; |
|
547 static const char *nssutilLibName = SHLIB_PREFIX"nssutil3."SHLIB_SUFFIX; |
|
548 |
|
549 static SECStatus |
|
550 freebl_InitNSPR(void *lib) |
|
551 { |
|
552 STUB_FETCH_FUNCTION(PR_Free); |
|
553 STUB_FETCH_FUNCTION(PR_Open); |
|
554 STUB_FETCH_FUNCTION(PR_ImportPipe); |
|
555 STUB_FETCH_FUNCTION(PR_Close); |
|
556 STUB_FETCH_FUNCTION(PR_Read); |
|
557 STUB_FETCH_FUNCTION(PR_Seek); |
|
558 STUB_FETCH_FUNCTION(PR_GetLibraryFilePathname); |
|
559 STUB_FETCH_FUNCTION(PR_Assert); |
|
560 STUB_FETCH_FUNCTION(PR_Sleep); |
|
561 STUB_FETCH_FUNCTION(PR_CallOnce); |
|
562 STUB_FETCH_FUNCTION(PR_NewCondVar); |
|
563 STUB_FETCH_FUNCTION(PR_NotifyCondVar); |
|
564 STUB_FETCH_FUNCTION(PR_NotifyAllCondVar); |
|
565 STUB_FETCH_FUNCTION(PR_WaitCondVar); |
|
566 STUB_FETCH_FUNCTION(PR_DestroyCondVar); |
|
567 STUB_FETCH_FUNCTION(PR_NewLock); |
|
568 STUB_FETCH_FUNCTION(PR_Unlock); |
|
569 STUB_FETCH_FUNCTION(PR_Lock); |
|
570 STUB_FETCH_FUNCTION(PR_DestroyLock); |
|
571 return SECSuccess; |
|
572 } |
|
573 |
|
574 static SECStatus |
|
575 freebl_InitNSSUtil(void *lib) |
|
576 { |
|
577 STUB_FETCH_FUNCTION(PORT_Alloc_Util); |
|
578 STUB_FETCH_FUNCTION(PORT_Free_Util); |
|
579 STUB_FETCH_FUNCTION(PORT_ZAlloc_Util); |
|
580 STUB_FETCH_FUNCTION(PORT_ZFree_Util); |
|
581 STUB_FETCH_FUNCTION(PORT_NewArena_Util); |
|
582 STUB_FETCH_FUNCTION(PORT_ArenaAlloc_Util); |
|
583 STUB_FETCH_FUNCTION(PORT_ArenaZAlloc_Util); |
|
584 STUB_FETCH_FUNCTION(PORT_FreeArena_Util); |
|
585 STUB_FETCH_FUNCTION(PORT_GetError_Util); |
|
586 STUB_FETCH_FUNCTION(PORT_SetError_Util); |
|
587 STUB_FETCH_FUNCTION(SECITEM_FreeItem_Util); |
|
588 STUB_FETCH_FUNCTION(SECITEM_AllocItem_Util); |
|
589 STUB_FETCH_FUNCTION(SECITEM_CompareItem_Util); |
|
590 STUB_FETCH_FUNCTION(SECITEM_CopyItem_Util); |
|
591 STUB_FETCH_FUNCTION(SECITEM_ZfreeItem_Util); |
|
592 STUB_FETCH_FUNCTION(SECOID_FindOIDTag_Util); |
|
593 STUB_FETCH_FUNCTION(NSS_SecureMemcmp); |
|
594 return SECSuccess; |
|
595 } |
|
596 |
|
597 /* |
|
598 * fetch the library if it's loaded. For NSS it should already be loaded |
|
599 */ |
|
600 #define freebl_getLibrary(libName) \ |
|
601 dlopen (libName, RTLD_LAZY|RTLD_NOLOAD) |
|
602 |
|
603 #define freebl_releaseLibrary(lib) \ |
|
604 if (lib) dlclose(lib) |
|
605 |
|
606 static void * FREEBLnsprGlobalLib = NULL; |
|
607 static void * FREEBLnssutilGlobalLib = NULL; |
|
608 |
|
609 void __attribute ((destructor)) FREEBL_unload() |
|
610 { |
|
611 freebl_releaseLibrary(FREEBLnsprGlobalLib); |
|
612 freebl_releaseLibrary(FREEBLnssutilGlobalLib); |
|
613 } |
|
614 #endif |
|
615 |
|
616 /* |
|
617 * load the symbols from the real libraries if available. |
|
618 * |
|
619 * if force is set, explicitly load the libraries if they are not already |
|
620 * loaded. If we could not use the real libraries, return failure. |
|
621 */ |
|
622 extern SECStatus |
|
623 FREEBL_InitStubs() |
|
624 { |
|
625 SECStatus rv = SECSuccess; |
|
626 #ifdef FREEBL_NO_WEAK |
|
627 void *nspr = NULL; |
|
628 void *nssutil = NULL; |
|
629 |
|
630 /* NSPR should be first */ |
|
631 if (!FREEBLnsprGlobalLib) { |
|
632 nspr = freebl_getLibrary(nsprLibName); |
|
633 if (!nspr) { |
|
634 return SECFailure; |
|
635 } |
|
636 rv = freebl_InitNSPR(nspr); |
|
637 if (rv != SECSuccess) { |
|
638 freebl_releaseLibrary(nspr); |
|
639 return rv; |
|
640 } |
|
641 FREEBLnsprGlobalLib = nspr; /* adopt */ |
|
642 } |
|
643 /* now load NSSUTIL */ |
|
644 if (!FREEBLnssutilGlobalLib) { |
|
645 nssutil= freebl_getLibrary(nssutilLibName); |
|
646 if (!nssutil) { |
|
647 return SECFailure; |
|
648 } |
|
649 rv = freebl_InitNSSUtil(nssutil); |
|
650 if (rv != SECSuccess) { |
|
651 freebl_releaseLibrary(nssutil); |
|
652 return rv; |
|
653 } |
|
654 FREEBLnssutilGlobalLib = nssutil; /* adopt */ |
|
655 } |
|
656 #endif |
|
657 |
|
658 return rv; |
|
659 } |