michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * Allow freebl and softoken to be loaded without util or NSPR. michael@0: * michael@0: * These symbols are overridden once real NSPR, and libutil are attached. michael@0: */ michael@0: #define _GNU_SOURCE 1 michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #define FREEBL_NO_WEAK 1 michael@0: michael@0: #define WEAK __attribute__((weak)) michael@0: michael@0: #ifdef FREEBL_NO_WEAK michael@0: michael@0: /* michael@0: * This uses function pointers. michael@0: * michael@0: * CONS: A separate function is needed to michael@0: * fill in the function pointers. michael@0: * michael@0: * PROS: it works on all platforms. michael@0: * it allows for dynamically finding nspr and libutil, even once michael@0: * softoken is loaded and running. (NOTE: this may be a problem if michael@0: * we switch between the stubs and real NSPR on the fly. NSPR will michael@0: * do bad things if passed an _FakeArena to free or allocate from). michael@0: */ michael@0: #define STUB_DECLARE(ret, fn, args) \ michael@0: typedef ret (*type_##fn) args; \ michael@0: static type_##fn ptr_##fn = NULL michael@0: michael@0: #define STUB_SAFE_CALL0(fn) \ michael@0: if (ptr_##fn) { return ptr_##fn(); } michael@0: #define STUB_SAFE_CALL1(fn,a1) \ michael@0: if (ptr_##fn) { return ptr_##fn(a1); } michael@0: #define STUB_SAFE_CALL2(fn,a1,a2) \ michael@0: if (ptr_##fn) { return ptr_##fn(a1,a2); } michael@0: #define STUB_SAFE_CALL3(fn,a1,a2,a3) \ michael@0: if (ptr_##fn) { return ptr_##fn(a1,a2,a3); } michael@0: #define STUB_SAFE_CALL4(fn,a1,a2,a3,a4) \ michael@0: if (ptr_##fn) { return ptr_##fn(a1,a2,a3,a4); } michael@0: #define STUB_SAFE_CALL6(fn,a1,a2,a3,a4,a5,a6) \ michael@0: if (ptr_##fn) { return ptr_##fn(a1,a2,a3,a4,a5,a6); } michael@0: michael@0: #define STUB_FETCH_FUNCTION(fn) \ michael@0: ptr_##fn = (type_##fn) dlsym(lib,#fn); \ michael@0: if (ptr_##fn == NULL) { \ michael@0: return SECFailure; \ michael@0: } michael@0: michael@0: #else michael@0: /* michael@0: * this uses the loader weak attribute. it works automatically, but once michael@0: * freebl is loaded, the symbols are 'fixed' (later loading of NSPR or michael@0: * libutil will not resolve these symbols. michael@0: */ michael@0: michael@0: #define STUB_DECLARE(ret, fn, args) \ michael@0: WEAK extern ret fn args michael@0: michael@0: #define STUB_SAFE_CALL0(fn) \ michael@0: if (fn) { return fn(); } michael@0: #define STUB_SAFE_CALL1(fn,a1) \ michael@0: if (fn) { return fn(a1); } michael@0: #define STUB_SAFE_CALL2(fn,a1,a2) \ michael@0: if (fn) { return fn(a1,a2); } michael@0: #define STUB_SAFE_CALL3(fn,a1,a2,a3) \ michael@0: if (fn) { return fn(a1,a2,a3); } michael@0: #define STUB_SAFE_CALL4(fn,a1,a2,a3,a4) \ michael@0: if (fn) { return fn(a1,a2,a3,a4); } michael@0: #define STUB_SAFE_CALL6(fn,a1,a2,a3,a4,a5,a6) \ michael@0: if (fn) { return fn(a1,a2,a3,a4,a5,a6); } michael@0: #endif michael@0: michael@0: michael@0: STUB_DECLARE(void *,PORT_Alloc_Util,(size_t len)); michael@0: STUB_DECLARE(void *,PORT_ArenaAlloc_Util,(PLArenaPool *arena, size_t size)); michael@0: STUB_DECLARE(void *,PORT_ArenaZAlloc_Util,(PLArenaPool *arena, size_t size)); michael@0: STUB_DECLARE(void ,PORT_Free_Util,(void *ptr)); michael@0: STUB_DECLARE(void ,PORT_FreeArena_Util,(PLArenaPool *arena, PRBool zero)); michael@0: STUB_DECLARE(int,PORT_GetError_Util,(void)); michael@0: STUB_DECLARE(PLArenaPool *,PORT_NewArena_Util,(unsigned long chunksize)); michael@0: STUB_DECLARE(void,PORT_SetError_Util,(int value)); michael@0: STUB_DECLARE(void *,PORT_ZAlloc_Util,(size_t len)); michael@0: STUB_DECLARE(void,PORT_ZFree_Util,(void *ptr, size_t len)); michael@0: michael@0: STUB_DECLARE(void,PR_Assert,(const char *s, const char *file, PRIntn ln)); michael@0: STUB_DECLARE(PRStatus,PR_CallOnce,(PRCallOnceType *once, PRCallOnceFN func)); michael@0: STUB_DECLARE(PRStatus,PR_Close,(PRFileDesc *fd)); michael@0: STUB_DECLARE(void,PR_DestroyLock,(PRLock *lock)); michael@0: STUB_DECLARE(void,PR_DestroyCondVar,(PRCondVar *cvar)); michael@0: STUB_DECLARE(void,PR_Free,(void *ptr)); michael@0: STUB_DECLARE(char * ,PR_GetLibraryFilePathname,(const char *name, michael@0: PRFuncPtr addr)); michael@0: STUB_DECLARE(PRFileDesc *,PR_ImportPipe,(PROsfd osfd)); michael@0: STUB_DECLARE(void,PR_Lock,(PRLock *lock)); michael@0: STUB_DECLARE(PRCondVar *,PR_NewCondVar,(PRLock *lock)); michael@0: STUB_DECLARE(PRLock *,PR_NewLock,(void)); michael@0: STUB_DECLARE(PRStatus,PR_NotifyCondVar,(PRCondVar *cvar)); michael@0: STUB_DECLARE(PRStatus,PR_NotifyAllCondVar,(PRCondVar *cvar)); michael@0: STUB_DECLARE(PRFileDesc *,PR_Open,(const char *name, PRIntn flags, michael@0: PRIntn mode)); michael@0: STUB_DECLARE(PRInt32,PR_Read,(PRFileDesc *fd, void *buf, PRInt32 amount)); michael@0: STUB_DECLARE(PROffset32,PR_Seek,(PRFileDesc *fd, PROffset32 offset, michael@0: PRSeekWhence whence)); michael@0: STUB_DECLARE(PRStatus,PR_Sleep,(PRIntervalTime ticks)); michael@0: STUB_DECLARE(PRStatus,PR_Unlock,(PRLock *lock)); michael@0: STUB_DECLARE(PRStatus,PR_WaitCondVar,(PRCondVar *cvar, michael@0: PRIntervalTime timeout)); michael@0: michael@0: michael@0: STUB_DECLARE(SECItem *,SECITEM_AllocItem_Util,(PLArenaPool *arena, michael@0: SECItem *item,unsigned int len)); michael@0: STUB_DECLARE(SECComparison,SECITEM_CompareItem_Util,(const SECItem *a, michael@0: const SECItem *b)); michael@0: STUB_DECLARE(SECStatus,SECITEM_CopyItem_Util,(PLArenaPool *arena, michael@0: SECItem *to,const SECItem *from)); michael@0: STUB_DECLARE(void,SECITEM_FreeItem_Util,(SECItem *zap, PRBool freeit)); michael@0: STUB_DECLARE(void,SECITEM_ZfreeItem_Util,(SECItem *zap, PRBool freeit)); michael@0: STUB_DECLARE(SECOidTag,SECOID_FindOIDTag_Util,(const SECItem *oid)); michael@0: STUB_DECLARE(int, NSS_SecureMemcmp,(const void *a, const void *b, size_t n)); michael@0: michael@0: michael@0: #define PORT_ZNew_stub(type) (type*)PORT_ZAlloc_stub(sizeof(type)) michael@0: #define PORT_New_stub(type) (type*)PORT_Alloc_stub(sizeof(type)) michael@0: #define PORT_ZNewArray_stub(type, num) \ michael@0: (type*) PORT_ZAlloc_stub (sizeof(type)*(num)) michael@0: michael@0: michael@0: /* michael@0: * NOTE: in order to support hashing only the memory allocation stubs, michael@0: * the get library name stubs, and the file io stubs are needed (the latter michael@0: * two are for the library verification). The remaining stubs are simply to michael@0: * compile. Attempts to use the library for other operations without NSPR michael@0: * will most likely fail. michael@0: */ michael@0: michael@0: michael@0: /* memory */ michael@0: extern void * michael@0: PORT_Alloc_stub(size_t len) michael@0: { michael@0: STUB_SAFE_CALL1(PORT_Alloc_Util, len); michael@0: return malloc(len); michael@0: } michael@0: michael@0: extern void michael@0: PORT_Free_stub(void *ptr) michael@0: { michael@0: STUB_SAFE_CALL1(PORT_Free_Util, ptr); michael@0: return free(ptr); michael@0: } michael@0: michael@0: extern void * michael@0: PORT_ZAlloc_stub(size_t len) michael@0: { michael@0: STUB_SAFE_CALL1(PORT_ZAlloc_Util, len); michael@0: void *ptr = malloc(len); michael@0: if (ptr) { michael@0: memset(ptr, 0, len); michael@0: } michael@0: return ptr; michael@0: } michael@0: michael@0: michael@0: extern void michael@0: PORT_ZFree_stub(void *ptr, size_t len) michael@0: { michael@0: STUB_SAFE_CALL2(PORT_ZFree_Util, ptr, len); michael@0: memset(ptr, 0, len); michael@0: return free(ptr); michael@0: } michael@0: michael@0: extern void michael@0: PR_Free_stub(void *ptr) michael@0: { michael@0: STUB_SAFE_CALL1(PR_Free, ptr); michael@0: return free(ptr); michael@0: } michael@0: michael@0: /* michael@0: * arenas michael@0: * michael@0: */ michael@0: extern PLArenaPool * michael@0: PORT_NewArena_stub(unsigned long chunksize) michael@0: { michael@0: STUB_SAFE_CALL1(PORT_NewArena_Util, chunksize); michael@0: abort(); michael@0: return NULL; michael@0: } michael@0: michael@0: extern void * michael@0: PORT_ArenaAlloc_stub(PLArenaPool *arena, size_t size) michael@0: { michael@0: michael@0: STUB_SAFE_CALL2(PORT_ArenaZAlloc_Util, arena, size); michael@0: abort(); michael@0: return NULL; michael@0: } michael@0: michael@0: extern void * michael@0: PORT_ArenaZAlloc_stub(PLArenaPool *arena, size_t size) michael@0: { michael@0: michael@0: STUB_SAFE_CALL2(PORT_ArenaZAlloc_Util, arena, size); michael@0: abort(); michael@0: return NULL; michael@0: } michael@0: michael@0: extern void michael@0: PORT_FreeArena_stub(PLArenaPool *arena, PRBool zero) michael@0: { michael@0: michael@0: STUB_SAFE_CALL2(PORT_FreeArena_Util, arena, zero); michael@0: abort(); michael@0: } michael@0: michael@0: michael@0: /* io */ michael@0: extern PRFileDesc * michael@0: PR_Open_stub(const char *name, PRIntn flags, PRIntn mode) michael@0: { michael@0: int *lfd = NULL; michael@0: int fd; michael@0: int lflags = 0; michael@0: michael@0: STUB_SAFE_CALL3(PR_Open, name, flags, mode); michael@0: michael@0: if (flags & PR_RDWR) { michael@0: lflags = O_RDWR; michael@0: } else if (flags & PR_WRONLY) { michael@0: lflags = O_WRONLY; michael@0: } else { michael@0: lflags = O_RDONLY; michael@0: } michael@0: michael@0: if (flags & PR_EXCL) michael@0: lflags |= O_EXCL; michael@0: if (flags & PR_APPEND) michael@0: lflags |= O_APPEND; michael@0: if (flags & PR_TRUNCATE) michael@0: lflags |= O_TRUNC; michael@0: michael@0: fd = open(name, lflags, mode); michael@0: if (fd >= 0) { michael@0: lfd = PORT_New_stub(int); michael@0: if (lfd != NULL) { michael@0: *lfd = fd; michael@0: } michael@0: } michael@0: return (PRFileDesc *)lfd; michael@0: } michael@0: michael@0: extern PRFileDesc * michael@0: PR_ImportPipe_stub(PROsfd fd) michael@0: { michael@0: int *lfd = NULL; michael@0: michael@0: STUB_SAFE_CALL1(PR_ImportPipe, fd); michael@0: michael@0: lfd = PORT_New_stub(int); michael@0: if (lfd != NULL) { michael@0: *lfd = fd; michael@0: } michael@0: return (PRFileDesc *)lfd; michael@0: } michael@0: michael@0: extern PRStatus michael@0: PR_Close_stub(PRFileDesc *fd) michael@0: { michael@0: int *lfd; michael@0: STUB_SAFE_CALL1(PR_Close, fd); michael@0: michael@0: lfd = (int *)fd; michael@0: close(*lfd); michael@0: PORT_Free_stub(lfd); michael@0: michael@0: return PR_SUCCESS; michael@0: } michael@0: michael@0: extern PRInt32 michael@0: PR_Read_stub(PRFileDesc *fd, void *buf, PRInt32 amount) michael@0: { michael@0: int *lfd; michael@0: STUB_SAFE_CALL3(PR_Read, fd, buf, amount); michael@0: michael@0: lfd = (int *)fd; michael@0: return read(*lfd, buf, amount); michael@0: } michael@0: michael@0: extern PROffset32 michael@0: PR_Seek_stub(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence) michael@0: { michael@0: int *lfd; michael@0: int lwhence = SEEK_SET;; michael@0: STUB_SAFE_CALL3(PR_Seek, fd, offset, whence); michael@0: lfd = (int *)fd; michael@0: switch (whence) { michael@0: case PR_SEEK_CUR: michael@0: lwhence = SEEK_CUR; michael@0: break; michael@0: case PR_SEEK_END: michael@0: lwhence = SEEK_END; michael@0: break; michael@0: } michael@0: michael@0: return lseek(*lfd, offset, lwhence); michael@0: } michael@0: michael@0: michael@0: /* michael@0: * library michael@0: */ michael@0: extern char * michael@0: PR_GetLibraryFilePathname_stub(const char *name, PRFuncPtr addr) michael@0: { michael@0: Dl_info dli; michael@0: char *result; michael@0: michael@0: STUB_SAFE_CALL2(PR_GetLibraryFilePathname, name, addr); michael@0: michael@0: if (dladdr((void *)addr, &dli) == 0) { michael@0: return NULL; michael@0: } michael@0: result = PORT_Alloc_stub(strlen(dli.dli_fname)+1); michael@0: if (result != NULL) { michael@0: strcpy(result, dli.dli_fname); michael@0: } michael@0: return result; michael@0: } michael@0: michael@0: michael@0: #include michael@0: michael@0: /* errors */ michael@0: extern int michael@0: PORT_GetError_stub(void) michael@0: { michael@0: STUB_SAFE_CALL0(PORT_GetError_Util); michael@0: return errno; michael@0: } michael@0: michael@0: extern void michael@0: PORT_SetError_stub(int value) michael@0: { michael@0: STUB_SAFE_CALL1(PORT_SetError_Util, value); michael@0: errno = value; michael@0: } michael@0: michael@0: /* misc */ michael@0: extern void michael@0: PR_Assert_stub(const char *s, const char *file, PRIntn ln) michael@0: { michael@0: STUB_SAFE_CALL3(PR_Assert, s, file, ln); michael@0: fprintf(stderr, "%s line %d: %s\n", file, ln, s); michael@0: abort(); michael@0: } michael@0: michael@0: /* time */ michael@0: extern PRStatus michael@0: PR_Sleep_stub(PRIntervalTime ticks) michael@0: { michael@0: STUB_SAFE_CALL1(PR_Sleep, ticks); michael@0: usleep(ticks*1000); michael@0: return PR_SUCCESS; michael@0: } michael@0: michael@0: michael@0: /* locking */ michael@0: extern PRLock * michael@0: PR_NewLock_stub(void) michael@0: { michael@0: STUB_SAFE_CALL0(PR_NewLock); michael@0: abort(); michael@0: return NULL; michael@0: } michael@0: michael@0: extern PRStatus michael@0: PR_Unlock_stub(PRLock *lock) michael@0: { michael@0: STUB_SAFE_CALL1(PR_Unlock, lock); michael@0: abort(); michael@0: return PR_FAILURE; michael@0: } michael@0: michael@0: extern void michael@0: PR_Lock_stub(PRLock *lock) michael@0: { michael@0: STUB_SAFE_CALL1(PR_Lock, lock); michael@0: abort(); michael@0: return; michael@0: } michael@0: michael@0: extern void michael@0: PR_DestroyLock_stub(PRLock *lock) michael@0: { michael@0: STUB_SAFE_CALL1(PR_DestroyLock, lock); michael@0: abort(); michael@0: return; michael@0: } michael@0: michael@0: extern PRCondVar * michael@0: PR_NewCondVar_stub(PRLock *lock) michael@0: { michael@0: STUB_SAFE_CALL1(PR_NewCondVar, lock); michael@0: abort(); michael@0: return NULL; michael@0: } michael@0: michael@0: extern PRStatus michael@0: PR_NotifyCondVar_stub(PRCondVar *cvar) michael@0: { michael@0: STUB_SAFE_CALL1(PR_NotifyCondVar, cvar); michael@0: abort(); michael@0: return PR_FAILURE; michael@0: } michael@0: michael@0: extern PRStatus michael@0: PR_NotifyAllCondVar_stub(PRCondVar *cvar) michael@0: { michael@0: STUB_SAFE_CALL1(PR_NotifyAllCondVar, cvar); michael@0: abort(); michael@0: return PR_FAILURE; michael@0: } michael@0: michael@0: extern PRStatus michael@0: PR_WaitCondVar_stub(PRCondVar *cvar, PRIntervalTime timeout) michael@0: { michael@0: STUB_SAFE_CALL2(PR_WaitCondVar, cvar, timeout); michael@0: abort(); michael@0: return PR_FAILURE; michael@0: } michael@0: michael@0: michael@0: michael@0: extern void michael@0: PR_DestroyCondVar_stub(PRCondVar *cvar) michael@0: { michael@0: STUB_SAFE_CALL1(PR_DestroyCondVar, cvar); michael@0: abort(); michael@0: return; michael@0: } michael@0: michael@0: /* michael@0: * NOTE: this presupposes GCC 4.1 michael@0: */ michael@0: extern PRStatus michael@0: PR_CallOnce_stub(PRCallOnceType *once, PRCallOnceFN func) michael@0: { michael@0: STUB_SAFE_CALL2(PR_CallOnce, once, func); michael@0: abort(); michael@0: return PR_FAILURE; michael@0: } michael@0: michael@0: michael@0: /* michael@0: * SECITEMS implement Item Utilities michael@0: */ michael@0: extern void michael@0: SECITEM_FreeItem_stub(SECItem *zap, PRBool freeit) michael@0: { michael@0: STUB_SAFE_CALL2(SECITEM_FreeItem_Util, zap, freeit); michael@0: abort(); michael@0: } michael@0: michael@0: extern SECItem * michael@0: SECITEM_AllocItem_stub(PLArenaPool *arena, SECItem *item, unsigned int len) michael@0: { michael@0: STUB_SAFE_CALL3(SECITEM_AllocItem_Util, arena, item, len); michael@0: abort(); michael@0: return NULL; michael@0: } michael@0: michael@0: extern SECComparison michael@0: SECITEM_CompareItem_stub(const SECItem *a, const SECItem *b) michael@0: { michael@0: STUB_SAFE_CALL2(SECITEM_CompareItem_Util, a, b); michael@0: abort(); michael@0: return SECEqual; michael@0: } michael@0: michael@0: extern SECStatus michael@0: SECITEM_CopyItem_stub(PLArenaPool *arena, SECItem *to, const SECItem *from) michael@0: { michael@0: STUB_SAFE_CALL3(SECITEM_CopyItem_Util, arena, to, from); michael@0: abort(); michael@0: return SECFailure; michael@0: } michael@0: michael@0: extern SECOidTag michael@0: SECOID_FindOIDTag_stub(const SECItem *oid) michael@0: { michael@0: STUB_SAFE_CALL1(SECOID_FindOIDTag_Util, oid); michael@0: abort(); michael@0: return SEC_OID_UNKNOWN; michael@0: } michael@0: michael@0: extern void michael@0: SECITEM_ZfreeItem_stub(SECItem *zap, PRBool freeit) michael@0: { michael@0: STUB_SAFE_CALL2(SECITEM_ZfreeItem_Util, zap, freeit); michael@0: abort(); michael@0: } michael@0: michael@0: extern int michael@0: NSS_SecureMemcmp_stub(const void *a, const void *b, size_t n) michael@0: { michael@0: STUB_SAFE_CALL3(NSS_SecureMemcmp, a, b, n); michael@0: abort(); michael@0: } michael@0: michael@0: #ifdef FREEBL_NO_WEAK michael@0: michael@0: static const char *nsprLibName = SHLIB_PREFIX"nspr4."SHLIB_SUFFIX; michael@0: static const char *nssutilLibName = SHLIB_PREFIX"nssutil3."SHLIB_SUFFIX; michael@0: michael@0: static SECStatus michael@0: freebl_InitNSPR(void *lib) michael@0: { michael@0: STUB_FETCH_FUNCTION(PR_Free); michael@0: STUB_FETCH_FUNCTION(PR_Open); michael@0: STUB_FETCH_FUNCTION(PR_ImportPipe); michael@0: STUB_FETCH_FUNCTION(PR_Close); michael@0: STUB_FETCH_FUNCTION(PR_Read); michael@0: STUB_FETCH_FUNCTION(PR_Seek); michael@0: STUB_FETCH_FUNCTION(PR_GetLibraryFilePathname); michael@0: STUB_FETCH_FUNCTION(PR_Assert); michael@0: STUB_FETCH_FUNCTION(PR_Sleep); michael@0: STUB_FETCH_FUNCTION(PR_CallOnce); michael@0: STUB_FETCH_FUNCTION(PR_NewCondVar); michael@0: STUB_FETCH_FUNCTION(PR_NotifyCondVar); michael@0: STUB_FETCH_FUNCTION(PR_NotifyAllCondVar); michael@0: STUB_FETCH_FUNCTION(PR_WaitCondVar); michael@0: STUB_FETCH_FUNCTION(PR_DestroyCondVar); michael@0: STUB_FETCH_FUNCTION(PR_NewLock); michael@0: STUB_FETCH_FUNCTION(PR_Unlock); michael@0: STUB_FETCH_FUNCTION(PR_Lock); michael@0: STUB_FETCH_FUNCTION(PR_DestroyLock); michael@0: return SECSuccess; michael@0: } michael@0: michael@0: static SECStatus michael@0: freebl_InitNSSUtil(void *lib) michael@0: { michael@0: STUB_FETCH_FUNCTION(PORT_Alloc_Util); michael@0: STUB_FETCH_FUNCTION(PORT_Free_Util); michael@0: STUB_FETCH_FUNCTION(PORT_ZAlloc_Util); michael@0: STUB_FETCH_FUNCTION(PORT_ZFree_Util); michael@0: STUB_FETCH_FUNCTION(PORT_NewArena_Util); michael@0: STUB_FETCH_FUNCTION(PORT_ArenaAlloc_Util); michael@0: STUB_FETCH_FUNCTION(PORT_ArenaZAlloc_Util); michael@0: STUB_FETCH_FUNCTION(PORT_FreeArena_Util); michael@0: STUB_FETCH_FUNCTION(PORT_GetError_Util); michael@0: STUB_FETCH_FUNCTION(PORT_SetError_Util); michael@0: STUB_FETCH_FUNCTION(SECITEM_FreeItem_Util); michael@0: STUB_FETCH_FUNCTION(SECITEM_AllocItem_Util); michael@0: STUB_FETCH_FUNCTION(SECITEM_CompareItem_Util); michael@0: STUB_FETCH_FUNCTION(SECITEM_CopyItem_Util); michael@0: STUB_FETCH_FUNCTION(SECITEM_ZfreeItem_Util); michael@0: STUB_FETCH_FUNCTION(SECOID_FindOIDTag_Util); michael@0: STUB_FETCH_FUNCTION(NSS_SecureMemcmp); michael@0: return SECSuccess; michael@0: } michael@0: michael@0: /* michael@0: * fetch the library if it's loaded. For NSS it should already be loaded michael@0: */ michael@0: #define freebl_getLibrary(libName) \ michael@0: dlopen (libName, RTLD_LAZY|RTLD_NOLOAD) michael@0: michael@0: #define freebl_releaseLibrary(lib) \ michael@0: if (lib) dlclose(lib) michael@0: michael@0: static void * FREEBLnsprGlobalLib = NULL; michael@0: static void * FREEBLnssutilGlobalLib = NULL; michael@0: michael@0: void __attribute ((destructor)) FREEBL_unload() michael@0: { michael@0: freebl_releaseLibrary(FREEBLnsprGlobalLib); michael@0: freebl_releaseLibrary(FREEBLnssutilGlobalLib); michael@0: } michael@0: #endif michael@0: michael@0: /* michael@0: * load the symbols from the real libraries if available. michael@0: * michael@0: * if force is set, explicitly load the libraries if they are not already michael@0: * loaded. If we could not use the real libraries, return failure. michael@0: */ michael@0: extern SECStatus michael@0: FREEBL_InitStubs() michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: #ifdef FREEBL_NO_WEAK michael@0: void *nspr = NULL; michael@0: void *nssutil = NULL; michael@0: michael@0: /* NSPR should be first */ michael@0: if (!FREEBLnsprGlobalLib) { michael@0: nspr = freebl_getLibrary(nsprLibName); michael@0: if (!nspr) { michael@0: return SECFailure; michael@0: } michael@0: rv = freebl_InitNSPR(nspr); michael@0: if (rv != SECSuccess) { michael@0: freebl_releaseLibrary(nspr); michael@0: return rv; michael@0: } michael@0: FREEBLnsprGlobalLib = nspr; /* adopt */ michael@0: } michael@0: /* now load NSSUTIL */ michael@0: if (!FREEBLnssutilGlobalLib) { michael@0: nssutil= freebl_getLibrary(nssutilLibName); michael@0: if (!nssutil) { michael@0: return SECFailure; michael@0: } michael@0: rv = freebl_InitNSSUtil(nssutil); michael@0: if (rv != SECSuccess) { michael@0: freebl_releaseLibrary(nssutil); michael@0: return rv; michael@0: } michael@0: FREEBLnssutilGlobalLib = nssutil; /* adopt */ michael@0: } michael@0: #endif michael@0: michael@0: return rv; michael@0: }