/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * Allow freebl and softoken to be loaded without util or NSPR.
 *
 * These symbols are overridden once real NSPR, and libutil are attached.
 */
#define _GNU_SOURCE 1
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <dlfcn.h>
#include <prio.h>
#include <prlink.h>
#include <prlog.h>
#include <prthread.h>
#include <plstr.h>
#include <prinit.h>
#include <prlock.h>
#include <prmem.h>
#include <prerror.h>
#include <prmon.h>
#include <pratom.h>
#include <prsystem.h>
#include <prinrval.h>
#include <prtime.h>
#include <prcvar.h>
#include <secasn1.h>
#include <secdig.h>
#include <secport.h>
#include <secitem.h>
#include <blapi.h>
#include <assert.h>
#include <private/pprio.h>

/* Android API < 21 doesn't define RTLD_NOLOAD */
#ifndef RTLD_NOLOAD
#define RTLD_NOLOAD 0
#endif

#define FREEBL_NO_WEAK 1

#define WEAK __attribute__((weak))

#ifdef FREEBL_NO_WEAK

/*
 * This uses function pointers.
 *
 * CONS:  A separate function is needed to
 * fill in the function pointers.
 *
 * PROS: it works on all platforms.
 *  it allows for dynamically finding nspr and libutil, even once
 *  softoken is loaded and running. (NOTE: this may be a problem if
 *  we switch between the stubs and real NSPR on the fly. NSPR will
 *  do bad things if passed an _FakeArena to free or allocate from).
 */
#define STUB_DECLARE(ret, fn, args) \
    typedef ret(*type_##fn) args;   \
    static type_##fn ptr_##fn = NULL

#define STUB_SAFE_CALL0(fn) \
    if (ptr_##fn) {         \
        return ptr_##fn();  \
    }
#define STUB_SAFE_CALL1(fn, a1) \
    if (ptr_##fn) {             \
        return ptr_##fn(a1);    \
    }
#define STUB_SAFE_CALL2(fn, a1, a2) \
    if (ptr_##fn) {                 \
        return ptr_##fn(a1, a2);    \
    }
#define STUB_SAFE_CALL3(fn, a1, a2, a3) \
    if (ptr_##fn) {                     \
        return ptr_##fn(a1, a2, a3);    \
    }
#define STUB_SAFE_CALL4(fn, a1, a2, a3, a4) \
    if (ptr_##fn) {                         \
        return ptr_##fn(a1, a2, a3, a4);    \
    }
#define STUB_SAFE_CALL6(fn, a1, a2, a3, a4, a5, a6) \
    if (ptr_##fn) {                                 \
        return ptr_##fn(a1, a2, a3, a4, a5, a6);    \
    }

#define STUB_FETCH_FUNCTION(fn)            \
    ptr_##fn = (type_##fn)dlsym(lib, #fn); \
    if (ptr_##fn == NULL) {                \
        return SECFailure;                 \
    }

#else
/*
 * this uses the loader weak attribute. it works automatically, but once
 * freebl is loaded, the symbols are 'fixed' (later loading of NSPR or
 * libutil will not resolve these symbols).
 */

#define STUB_DECLARE(ret, fn, args) \
    WEAK extern ret fn args

#define STUB_SAFE_CALL0(fn) \
    if (fn) {               \
        return fn();        \
    }
#define STUB_SAFE_CALL1(fn, a1) \
    if (fn) {                   \
        return fn(a1);          \
    }
#define STUB_SAFE_CALL2(fn, a1, a2) \
    if (fn) {                       \
        return fn(a1, a2);          \
    }
#define STUB_SAFE_CALL3(fn, a1, a2, a3) \
    if (fn) {                           \
        return fn(a1, a2, a3);          \
    }
#define STUB_SAFE_CALL4(fn, a1, a2, a3, a4) \
    if (fn) {                               \
        return fn(a1, a2, a3, a4);          \
    }
#define STUB_SAFE_CALL6(fn, a1, a2, a3, a4, a5, a6) \
    if (fn) {                                       \
        return fn(a1, a2, a3, a4, a5, a6);          \
    }
#endif

STUB_DECLARE(void *, PORT_Alloc_Util, (size_t len));
STUB_DECLARE(void *, PORT_ArenaAlloc_Util, (PLArenaPool * arena, size_t size));
STUB_DECLARE(void *, PORT_ArenaZAlloc_Util, (PLArenaPool * arena, size_t size));
STUB_DECLARE(void, PORT_Free_Util, (void *ptr));
STUB_DECLARE(void, PORT_FreeArena_Util, (PLArenaPool * arena, PRBool zero));
STUB_DECLARE(int, PORT_GetError_Util, (void));
STUB_DECLARE(PLArenaPool *, PORT_NewArena_Util, (unsigned long chunksize));
STUB_DECLARE(void, PORT_SetError_Util, (int value));
STUB_DECLARE(void *, PORT_ZAlloc_Util, (size_t len));
STUB_DECLARE(void *, PORT_ZAllocAligned_Util, (size_t bytes, size_t alignment,
                                               void **mem));
STUB_DECLARE(void *, PORT_ZAllocAlignedOffset_Util, (size_t bytes,
                                                     size_t alignment,
                                                     size_t offset));
STUB_DECLARE(void, PORT_ZFree_Util, (void *ptr, size_t len));

STUB_DECLARE(void, PR_Assert, (const char *s, const char *file, PRIntn ln));
STUB_DECLARE(PRStatus, PR_Access, (const char *name, PRAccessHow how));
STUB_DECLARE(PRStatus, PR_CallOnce, (PRCallOnceType * once, PRCallOnceFN func));
STUB_DECLARE(PRStatus, PR_Close, (PRFileDesc * fd));
STUB_DECLARE(void, PR_DestroyLock, (PRLock * lock));
STUB_DECLARE(void, PR_DestroyCondVar, (PRCondVar * cvar));
STUB_DECLARE(void, PR_Free, (void *ptr));
STUB_DECLARE(char *, PR_GetLibraryFilePathname, (const char *name,
                                                 PRFuncPtr addr));
STUB_DECLARE(PRFileDesc *, PR_ImportPipe, (PROsfd osfd));
STUB_DECLARE(void, PR_Lock, (PRLock * lock));
STUB_DECLARE(PRCondVar *, PR_NewCondVar, (PRLock * lock));
STUB_DECLARE(PRLock *, PR_NewLock, (void));
STUB_DECLARE(PRStatus, PR_NotifyCondVar, (PRCondVar * cvar));
STUB_DECLARE(PRStatus, PR_NotifyAllCondVar, (PRCondVar * cvar));
STUB_DECLARE(PRFileDesc *, PR_Open, (const char *name, PRIntn flags,
                                     PRIntn mode));
STUB_DECLARE(PRInt32, PR_Read, (PRFileDesc * fd, void *buf, PRInt32 amount));
STUB_DECLARE(PROffset32, PR_Seek, (PRFileDesc * fd, PROffset32 offset,
                                   PRSeekWhence whence));
STUB_DECLARE(PRStatus, PR_Sleep, (PRIntervalTime ticks));
STUB_DECLARE(PRStatus, PR_Unlock, (PRLock * lock));
STUB_DECLARE(PRStatus, PR_WaitCondVar, (PRCondVar * cvar,
                                        PRIntervalTime timeout));
STUB_DECLARE(char *, PR_GetEnvSecure, (const char *));

STUB_DECLARE(SECItem *, SECITEM_AllocItem_Util, (PLArenaPool * arena,
                                                 SECItem *item, unsigned int len));
STUB_DECLARE(SECComparison, SECITEM_CompareItem_Util, (const SECItem *a,
                                                       const SECItem *b));
STUB_DECLARE(SECStatus, SECITEM_CopyItem_Util, (PLArenaPool * arena,
                                                SECItem *to, const SECItem *from));
STUB_DECLARE(void, SECITEM_FreeItem_Util, (SECItem * zap, PRBool freeit));
STUB_DECLARE(void, SECITEM_ZfreeItem_Util, (SECItem * zap, PRBool freeit));
STUB_DECLARE(SECOidTag, SECOID_FindOIDTag_Util, (const SECItem *oid));
STUB_DECLARE(int, NSS_SecureMemcmp, (const void *a, const void *b, size_t n));
STUB_DECLARE(unsigned int, NSS_SecureMemcmpZero, (const void *mem, size_t n));

#define PORT_ZNew_stub(type) (type *)PORT_ZAlloc_stub(sizeof(type))
#define PORT_New_stub(type) (type *)PORT_Alloc_stub(sizeof(type))
#define PORT_ZNewArray_stub(type, num) \
    (type *)PORT_ZAlloc_stub(sizeof(type) * (num))
#define PORT_ZNewAligned_stub(type, alignment, mem) \
    (type *)PORT_ZAllocAlignedOffset_stub(sizeof(type), alignment, offsetof(type, mem))

/*
 * NOTE: in order to support hashing only the memory allocation stubs,
 * the get library name stubs, and the file io stubs are needed (the latter
 * two are for the library verification). The remaining stubs are simply to
 * compile. Attempts to use the library for other operations without NSPR
 * will most likely fail.
 */

/* memory */
extern void *
PORT_Alloc_stub(size_t len)
{
    STUB_SAFE_CALL1(PORT_Alloc_Util, len);
    return malloc(len);
}

extern void
PORT_Free_stub(void *ptr)
{
    STUB_SAFE_CALL1(PORT_Free_Util, ptr);
    return free(ptr);
}

extern void *
PORT_ZAlloc_stub(size_t len)
{
    STUB_SAFE_CALL1(PORT_ZAlloc_Util, len);
    void *ptr = malloc(len);
    if (ptr) {
        memset(ptr, 0, len);
    }
    return ptr;
}

/* aligned_alloc is C11. This is an alternative to get aligned memory. */
extern void *
PORT_ZAllocAligned_stub(size_t bytes, size_t alignment, void **mem)
{
    STUB_SAFE_CALL3(PORT_ZAllocAligned_Util, bytes, alignment, mem);

    /* This only works if alignement is a power of 2. */
    if ((alignment == 0) || (alignment & (alignment - 1))) {
        return NULL;
    }

    size_t x = alignment - 1;
    size_t len = (bytes ? bytes : 1) + x;

    if (!mem) {
        return NULL;
    }

    /* Always allocate a non-zero amount of bytes */
    *mem = malloc(len);
    if (!*mem) {
        return NULL;
    }

    memset(*mem, 0, len);

    /* We're pretty sure this is non-zero, but let's assure scan-build too. */
    void *ret = (void *)(((uintptr_t)*mem + x) & ~(uintptr_t)x);
    assert(ret);

    return ret;
}

extern void *
PORT_ZAllocAlignedOffset_stub(size_t size, size_t alignment, size_t offset)
{
    STUB_SAFE_CALL3(PORT_ZAllocAlignedOffset_Util, size, alignment, offset);
    if (offset > size) {
        return NULL;
    }

    void *mem = NULL;
    void *v = PORT_ZAllocAligned_stub(size, alignment, &mem);
    if (!v) {
        return NULL;
    }

    *((void **)((uintptr_t)v + offset)) = mem;
    return v;
}

extern void
PORT_ZFree_stub(void *ptr, size_t len)
{
    STUB_SAFE_CALL2(PORT_ZFree_Util, ptr, len);
    memset(ptr, 0, len);
    return free(ptr);
}

extern void
PR_Free_stub(void *ptr)
{
    STUB_SAFE_CALL1(PR_Free, ptr);
    return free(ptr);
}

/*
 * arenas
 *
 */
extern PLArenaPool *
PORT_NewArena_stub(unsigned long chunksize)
{
    STUB_SAFE_CALL1(PORT_NewArena_Util, chunksize);
    abort();
    return NULL;
}

extern void *
PORT_ArenaAlloc_stub(PLArenaPool *arena, size_t size)
{

    STUB_SAFE_CALL2(PORT_ArenaZAlloc_Util, arena, size);
    abort();
    return NULL;
}

extern void *
PORT_ArenaZAlloc_stub(PLArenaPool *arena, size_t size)
{

    STUB_SAFE_CALL2(PORT_ArenaZAlloc_Util, arena, size);
    abort();
    return NULL;
}

extern void
PORT_FreeArena_stub(PLArenaPool *arena, PRBool zero)
{

    STUB_SAFE_CALL2(PORT_FreeArena_Util, arena, zero);
    abort();
}

/* io */
extern PRFileDesc *
PR_Open_stub(const char *name, PRIntn flags, PRIntn mode)
{
    int *lfd = NULL;
    int fd;
    int lflags = 0;

    STUB_SAFE_CALL3(PR_Open, name, flags, mode);

    if (flags & PR_RDWR) {
        lflags = O_RDWR;
    } else if (flags & PR_WRONLY) {
        lflags = O_WRONLY;
    } else {
        lflags = O_RDONLY;
    }

    if (flags & PR_EXCL)
        lflags |= O_EXCL;
    if (flags & PR_APPEND)
        lflags |= O_APPEND;
    if (flags & PR_TRUNCATE)
        lflags |= O_TRUNC;

    fd = open(name, lflags, mode);
    if (fd >= 0) {
        lfd = PORT_New_stub(int);
        if (lfd != NULL) {
            *lfd = fd;
        } else {
            close(fd);
        }
    }
    return (PRFileDesc *)lfd;
}

extern PRFileDesc *
PR_ImportPipe_stub(PROsfd fd)
{
    int *lfd = NULL;

    STUB_SAFE_CALL1(PR_ImportPipe, fd);

    lfd = PORT_New_stub(int);
    if (lfd != NULL) {
        *lfd = fd;
    }
    return (PRFileDesc *)lfd;
}

extern PRStatus
PR_Close_stub(PRFileDesc *fd)
{
    int *lfd;
    STUB_SAFE_CALL1(PR_Close, fd);

    lfd = (int *)fd;
    close(*lfd);
    PORT_Free_stub(lfd);

    return PR_SUCCESS;
}

extern PRInt32
PR_Read_stub(PRFileDesc *fd, void *buf, PRInt32 amount)
{
    int *lfd;
    STUB_SAFE_CALL3(PR_Read, fd, buf, amount);

    lfd = (int *)fd;
    return read(*lfd, buf, amount);
}

extern PROffset32
PR_Seek_stub(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
{
    int *lfd;
    int lwhence = SEEK_SET;
    STUB_SAFE_CALL3(PR_Seek, fd, offset, whence);
    lfd = (int *)fd;
    switch (whence) {
        case PR_SEEK_CUR:
            lwhence = SEEK_CUR;
            break;
        case PR_SEEK_END:
            lwhence = SEEK_END;
            break;
        case PR_SEEK_SET:
            break;
    }

    return lseek(*lfd, offset, lwhence);
}

PRStatus
PR_Access_stub(const char *name, PRAccessHow how)
{
    int mode = F_OK;
    int rv;
    STUB_SAFE_CALL2(PR_Access, name, how);
    switch (how) {
        case PR_ACCESS_WRITE_OK:
            mode = W_OK;
            break;
        case PR_ACCESS_READ_OK:
            mode = R_OK;
            break;
        /* assume F_OK for all others */
        default:
            break;
    }
    rv = access(name, mode);
    if (rv == 0) {
        return PR_SUCCESS;
    }
    return PR_FAILURE;
}

/*
 * library
 */
extern char *
PR_GetLibraryFilePathname_stub(const char *name, PRFuncPtr addr)
{
    Dl_info dli;
    char *result;

    STUB_SAFE_CALL2(PR_GetLibraryFilePathname, name, addr);

    if (dladdr((void *)addr, &dli) == 0) {
        return NULL;
    }
    result = PORT_Alloc_stub(strlen(dli.dli_fname) + 1);
    if (result != NULL) {
        strcpy(result, dli.dli_fname);
    }
    return result;
}

#include <errno.h>

/* errors */
extern int
PORT_GetError_stub(void)
{
    STUB_SAFE_CALL0(PORT_GetError_Util);
    return errno;
}

extern void
PORT_SetError_stub(int value)
{
    STUB_SAFE_CALL1(PORT_SetError_Util, value);
    errno = value;
}

/* misc */
extern void
PR_Assert_stub(const char *s, const char *file, PRIntn ln)
{
    STUB_SAFE_CALL3(PR_Assert, s, file, ln);
    fprintf(stderr, "%s line %d: %s\n", file, ln, s);
    abort();
}

/* time */
extern PRStatus
PR_Sleep_stub(PRIntervalTime ticks)
{
    STUB_SAFE_CALL1(PR_Sleep, ticks);
    usleep(ticks * 1000);
    return PR_SUCCESS;
}

/* locking */
extern PRLock *
PR_NewLock_stub(void)
{
    STUB_SAFE_CALL0(PR_NewLock);
    abort();
    return NULL;
}

extern PRStatus
PR_Unlock_stub(PRLock *lock)
{
    STUB_SAFE_CALL1(PR_Unlock, lock);
    abort();
    return PR_FAILURE;
}

extern void
PR_Lock_stub(PRLock *lock)
{
    STUB_SAFE_CALL1(PR_Lock, lock);
    abort();
    return;
}

extern void
PR_DestroyLock_stub(PRLock *lock)
{
    STUB_SAFE_CALL1(PR_DestroyLock, lock);
    abort();
    return;
}

extern PRCondVar *
PR_NewCondVar_stub(PRLock *lock)
{
    STUB_SAFE_CALL1(PR_NewCondVar, lock);
    abort();
    return NULL;
}

extern PRStatus
PR_NotifyCondVar_stub(PRCondVar *cvar)
{
    STUB_SAFE_CALL1(PR_NotifyCondVar, cvar);
    abort();
    return PR_FAILURE;
}

extern PRStatus
PR_NotifyAllCondVar_stub(PRCondVar *cvar)
{
    STUB_SAFE_CALL1(PR_NotifyAllCondVar, cvar);
    abort();
    return PR_FAILURE;
}

extern PRStatus
PR_WaitCondVar_stub(PRCondVar *cvar, PRIntervalTime timeout)
{
    STUB_SAFE_CALL2(PR_WaitCondVar, cvar, timeout);
    abort();
    return PR_FAILURE;
}

extern char *
PR_GetEnvSecure_stub(const char *var)
{
    STUB_SAFE_CALL1(PR_GetEnvSecure, var);
    abort();
    return NULL;
}

extern void
PR_DestroyCondVar_stub(PRCondVar *cvar)
{
    STUB_SAFE_CALL1(PR_DestroyCondVar, cvar);
    abort();
    return;
}

/*
 * NOTE: this presupposes GCC 4.1
 */
extern PRStatus
PR_CallOnce_stub(PRCallOnceType *once, PRCallOnceFN func)
{
    STUB_SAFE_CALL2(PR_CallOnce, once, func);
    abort();
    return PR_FAILURE;
}

/*
 * SECITEMS implement Item Utilities
 */
extern void
SECITEM_FreeItem_stub(SECItem *zap, PRBool freeit)
{
    STUB_SAFE_CALL2(SECITEM_FreeItem_Util, zap, freeit);
    abort();
}

extern SECItem *
SECITEM_AllocItem_stub(PLArenaPool *arena, SECItem *item, unsigned int len)
{
    STUB_SAFE_CALL3(SECITEM_AllocItem_Util, arena, item, len);
    abort();
    return NULL;
}

extern SECComparison
SECITEM_CompareItem_stub(const SECItem *a, const SECItem *b)
{
    STUB_SAFE_CALL2(SECITEM_CompareItem_Util, a, b);
    abort();
    return SECEqual;
}

extern SECStatus
SECITEM_CopyItem_stub(PLArenaPool *arena, SECItem *to, const SECItem *from)
{
    STUB_SAFE_CALL3(SECITEM_CopyItem_Util, arena, to, from);
    abort();
    return SECFailure;
}

extern SECOidTag
SECOID_FindOIDTag_stub(const SECItem *oid)
{
    STUB_SAFE_CALL1(SECOID_FindOIDTag_Util, oid);
    abort();
    return SEC_OID_UNKNOWN;
}

extern void
SECITEM_ZfreeItem_stub(SECItem *zap, PRBool freeit)
{
    STUB_SAFE_CALL2(SECITEM_ZfreeItem_Util, zap, freeit);
    abort();
}

extern int
NSS_SecureMemcmp_stub(const void *a, const void *b, size_t n)
{
    STUB_SAFE_CALL3(NSS_SecureMemcmp, a, b, n);
    abort();
}

extern unsigned int
NSS_SecureMemcmpZero_stub(const void *mem, size_t n)
{
    STUB_SAFE_CALL2(NSS_SecureMemcmpZero, mem, n);
    abort();
}

#ifdef FREEBL_NO_WEAK

static const char *nsprLibName = SHLIB_PREFIX "nspr4." SHLIB_SUFFIX;
static const char *nssutilLibName = SHLIB_PREFIX "nssutil3." SHLIB_SUFFIX;

static SECStatus
freebl_InitNSPR(void *lib)
{
    STUB_FETCH_FUNCTION(PR_Free);
    STUB_FETCH_FUNCTION(PR_Open);
    STUB_FETCH_FUNCTION(PR_ImportPipe);
    STUB_FETCH_FUNCTION(PR_Close);
    STUB_FETCH_FUNCTION(PR_Read);
    STUB_FETCH_FUNCTION(PR_Seek);
    STUB_FETCH_FUNCTION(PR_GetLibraryFilePathname);
    STUB_FETCH_FUNCTION(PR_Assert);
    STUB_FETCH_FUNCTION(PR_Access);
    STUB_FETCH_FUNCTION(PR_Sleep);
    STUB_FETCH_FUNCTION(PR_CallOnce);
    STUB_FETCH_FUNCTION(PR_NewCondVar);
    STUB_FETCH_FUNCTION(PR_NotifyCondVar);
    STUB_FETCH_FUNCTION(PR_NotifyAllCondVar);
    STUB_FETCH_FUNCTION(PR_WaitCondVar);
    STUB_FETCH_FUNCTION(PR_DestroyCondVar);
    STUB_FETCH_FUNCTION(PR_NewLock);
    STUB_FETCH_FUNCTION(PR_Unlock);
    STUB_FETCH_FUNCTION(PR_Lock);
    STUB_FETCH_FUNCTION(PR_DestroyLock);
    STUB_FETCH_FUNCTION(PR_GetEnvSecure);
    return SECSuccess;
}

static SECStatus
freebl_InitNSSUtil(void *lib)
{
    STUB_FETCH_FUNCTION(PORT_Alloc_Util);
    STUB_FETCH_FUNCTION(PORT_Free_Util);
    STUB_FETCH_FUNCTION(PORT_ZAlloc_Util);
    STUB_FETCH_FUNCTION(PORT_ZFree_Util);
    STUB_FETCH_FUNCTION(PORT_NewArena_Util);
    STUB_FETCH_FUNCTION(PORT_ArenaAlloc_Util);
    STUB_FETCH_FUNCTION(PORT_ArenaZAlloc_Util);
    STUB_FETCH_FUNCTION(PORT_FreeArena_Util);
    STUB_FETCH_FUNCTION(PORT_GetError_Util);
    STUB_FETCH_FUNCTION(PORT_SetError_Util);
    STUB_FETCH_FUNCTION(SECITEM_FreeItem_Util);
    STUB_FETCH_FUNCTION(SECITEM_AllocItem_Util);
    STUB_FETCH_FUNCTION(SECITEM_CompareItem_Util);
    STUB_FETCH_FUNCTION(SECITEM_CopyItem_Util);
    STUB_FETCH_FUNCTION(SECITEM_ZfreeItem_Util);
    STUB_FETCH_FUNCTION(SECOID_FindOIDTag_Util);
    STUB_FETCH_FUNCTION(NSS_SecureMemcmp);
    STUB_FETCH_FUNCTION(NSS_SecureMemcmpZero);
    return SECSuccess;
}

/*
 * fetch the library if it's loaded. For NSS it should already be loaded
 */
#define freebl_getLibrary(libName) \
    dlopen(libName, RTLD_LAZY | RTLD_NOLOAD)

#define freebl_releaseLibrary(lib) \
    if (lib)                       \
    dlclose(lib)

static void *FREEBLnsprGlobalLib = NULL;
static void *FREEBLnssutilGlobalLib = NULL;

void __attribute((destructor)) FREEBL_unload()
{
    freebl_releaseLibrary(FREEBLnsprGlobalLib);
    freebl_releaseLibrary(FREEBLnssutilGlobalLib);
}
#endif

/*
 * load the symbols from the real libraries if available.
 *
 * if force is set, explicitly load the libraries if they are not already
 * loaded. If we could not use the real libraries, return failure.
 */
extern SECStatus
FREEBL_InitStubs()
{
    SECStatus rv = SECSuccess;
#ifdef FREEBL_NO_WEAK
    void *nspr = NULL;
    void *nssutil = NULL;

    /* NSPR should be first */
    if (!FREEBLnsprGlobalLib) {
        nspr = freebl_getLibrary(nsprLibName);
        if (!nspr) {
            return SECFailure;
        }
        rv = freebl_InitNSPR(nspr);
        if (rv != SECSuccess) {
            freebl_releaseLibrary(nspr);
            return rv;
        }
        FREEBLnsprGlobalLib = nspr; /* adopt */
    }
    /* now load NSSUTIL */
    if (!FREEBLnssutilGlobalLib) {
        nssutil = freebl_getLibrary(nssutilLibName);
        if (!nssutil) {
            return SECFailure;
        }
        rv = freebl_InitNSSUtil(nssutil);
        if (rv != SECSuccess) {
            freebl_releaseLibrary(nssutil);
            return rv;
        }
        FREEBLnssutilGlobalLib = nssutil; /* adopt */
    }
#endif

    return rv;
}
