зеркало из https://github.com/mozilla/pjs.git
Bug 298044 - Dynamically load XPCOM dependent libs as part of the XPCOM standalone glue bootstrap process, r=darin a=asa
This commit is contained in:
Родитель
d2018c5ee2
Коммит
28689c6ab0
|
@ -649,34 +649,6 @@ endif # IS_COMPONENT
|
||||||
endif # EXPORT_LIBRARY
|
endif # EXPORT_LIBRARY
|
||||||
endif # LIBRARY_NAME
|
endif # LIBRARY_NAME
|
||||||
|
|
||||||
# Dependent libs
|
|
||||||
ifdef USE_DEPENDENT_LIBS
|
|
||||||
ifdef IS_COMPONENT
|
|
||||||
|
|
||||||
ifeq (,$(filter-out OS2 WINNT,$(OS_ARCH))$(GNU_CXX))
|
|
||||||
DEPENDENT_LIBS = $(filter-out %_s$(DLL_SUFFIX), $(patsubst %.$(IMPORT_LIB_SUFFIX),$(LIB_PREFIX)%$(DLL_SUFFIX),$(notdir $(filter %.$(IMPORT_LIB_SUFFIX), $(EXTRA_DSO_LDOPTS)))))
|
|
||||||
else
|
|
||||||
DEPENDENT_LIBS = $(filter-out %_s$(DLL_SUFFIX), $(patsubst -l%,$(DLL_PREFIX)%$(DLL_SUFFIX),$(filter -l%, $(EXTRA_DSO_LDOPTS))))
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq (,$(strip $(DEPENDENT_LIBS)))
|
|
||||||
DEFINES += -DHAVE_DEPENDENT_LIBS
|
|
||||||
INCLUDES += -I.
|
|
||||||
# This must match value in nsIGenericFactory.h
|
|
||||||
DEPENDENT_LIBS_H = dependentLibs.h
|
|
||||||
GARBAGE += $(DEPENDENT_LIBS_H)
|
|
||||||
|
|
||||||
export:: $(DEPENDENT_LIBS_H)
|
|
||||||
|
|
||||||
$(DEPENDENT_LIBS_H): Makefile Makefile.in
|
|
||||||
@rm -f $@
|
|
||||||
echo "#define DEPENDENT_LIBS $(foreach f,$(DEPENDENT_LIBS),\"${f}\",) " > $@
|
|
||||||
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
# Create dependencies on static libraries
|
# Create dependencies on static libraries
|
||||||
LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
|
LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
|
||||||
HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
|
HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
|
||||||
|
|
|
@ -77,7 +77,6 @@ XPIDLSRCS = \
|
||||||
nsIComponentLoader.idl \
|
nsIComponentLoader.idl \
|
||||||
nsIComponentLoaderManager.idl \
|
nsIComponentLoaderManager.idl \
|
||||||
nsIComponentManagerObsolete.idl \
|
nsIComponentManagerObsolete.idl \
|
||||||
nsINativeComponentLoader.idl \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
SDK_XPIDLSRCS = \
|
SDK_XPIDLSRCS = \
|
||||||
|
|
|
@ -952,14 +952,6 @@ NS_IMPL_THREADSAFE_ISUPPORTS8(nsComponentManagerImpl,
|
||||||
nsresult
|
nsresult
|
||||||
nsComponentManagerImpl::GetInterface(const nsIID & uuid, void **result)
|
nsComponentManagerImpl::GetInterface(const nsIID & uuid, void **result)
|
||||||
{
|
{
|
||||||
if (uuid.Equals(NS_GET_IID(nsINativeComponentLoader)))
|
|
||||||
{
|
|
||||||
if (!mNativeComponentLoader)
|
|
||||||
return NS_ERROR_NOT_INITIALIZED;
|
|
||||||
|
|
||||||
return mNativeComponentLoader->QueryInterface(uuid, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_WARNING("This isn't supported");
|
NS_WARNING("This isn't supported");
|
||||||
// fall through to QI as anything QIable is a superset of what can be
|
// fall through to QI as anything QIable is a superset of what can be
|
||||||
// got via the GetInterface()
|
// got via the GetInterface()
|
||||||
|
|
|
@ -79,15 +79,13 @@ DLLStore_Destroy(nsHashKey *aKey, void *aData, void* closure)
|
||||||
|
|
||||||
nsNativeComponentLoader::nsNativeComponentLoader() :
|
nsNativeComponentLoader::nsNativeComponentLoader() :
|
||||||
mCompMgr(nsnull),
|
mCompMgr(nsnull),
|
||||||
mLoadedDependentLibs(16, PR_TRUE),
|
|
||||||
mDllStore(nsnull, nsnull, DLLStore_Destroy,
|
mDllStore(nsnull, nsnull, DLLStore_Destroy,
|
||||||
nsnull, 256, PR_TRUE)
|
nsnull, 256, PR_TRUE)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNativeComponentLoader,
|
NS_IMPL_THREADSAFE_ISUPPORTS1(nsNativeComponentLoader,
|
||||||
nsIComponentLoader,
|
nsIComponentLoader)
|
||||||
nsINativeComponentLoader)
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsNativeComponentLoader::GetFactory(const nsIID & aCID,
|
nsNativeComponentLoader::GetFactory(const nsIID & aCID,
|
||||||
|
@ -419,10 +417,6 @@ nsNativeComponentLoader::SelfRegisterDll(nsDll *dll,
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
nsresult res2 = dll->GetDllSpec(getter_AddRefs(fs)); // don't change 'res2' -- see warning, above
|
nsresult res2 = dll->GetDllSpec(getter_AddRefs(fs)); // don't change 'res2' -- see warning, above
|
||||||
if (NS_SUCCEEDED(res2)) {
|
if (NS_SUCCEEDED(res2)) {
|
||||||
// in the case of re-registering a component, we want to remove
|
|
||||||
// any optional data that this file may have had.
|
|
||||||
AddDependentLibrary(fs, nsnull);
|
|
||||||
|
|
||||||
res = mobj->RegisterSelf(mCompMgr, fs, registryLocation,
|
res = mobj->RegisterSelf(mCompMgr, fs, registryLocation,
|
||||||
nativeComponentType);
|
nativeComponentType);
|
||||||
}
|
}
|
||||||
|
@ -1063,36 +1057,3 @@ nsNativeComponentLoader::GetFactoryFromModule(nsDll *aDll, const nsCID &aCID,
|
||||||
return module->GetClassObject(mCompMgr, aCID, NS_GET_IID(nsIFactory),
|
return module->GetClassObject(mCompMgr, aCID, NS_GET_IID(nsIFactory),
|
||||||
(void **)aFactory);
|
(void **)aFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNativeComponentLoader::AddDependentLibrary(nsIFile* aFile, const char* libName)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIComponentLoaderManager> manager = do_QueryInterface(mCompMgr);
|
|
||||||
if (!manager)
|
|
||||||
{
|
|
||||||
NS_WARNING("Something is terribly wrong");
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the native component loader uses the optional data
|
|
||||||
// to store a space delimited list of dependent library
|
|
||||||
// names
|
|
||||||
|
|
||||||
if (!libName)
|
|
||||||
{
|
|
||||||
manager->SetOptionalData(aFile, nsnull, nsnull);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsXPIDLCString data;
|
|
||||||
manager->GetOptionalData(aFile, nsnull, getter_Copies(data));
|
|
||||||
|
|
||||||
if (!data.IsEmpty())
|
|
||||||
data.AppendLiteral(" ");
|
|
||||||
|
|
||||||
data.Append(nsDependentCString(libName));
|
|
||||||
|
|
||||||
manager->SetOptionalData(aFile, nsnull, data);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
|
@ -43,22 +43,20 @@
|
||||||
#include "nsHashtable.h"
|
#include "nsHashtable.h"
|
||||||
#include "nsVoidArray.h"
|
#include "nsVoidArray.h"
|
||||||
#include "xcDll.h"
|
#include "xcDll.h"
|
||||||
#include "nsINativeComponentLoader.h"
|
|
||||||
|
|
||||||
#ifndef nsNativeComponentLoader_h__
|
#ifndef nsNativeComponentLoader_h__
|
||||||
#define nsNativeComponentLoader_h__
|
#define nsNativeComponentLoader_h__
|
||||||
|
|
||||||
class nsNativeComponentLoader : public nsIComponentLoader, public nsINativeComponentLoader {
|
class nsNativeComponentLoader : public nsIComponentLoader
|
||||||
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSICOMPONENTLOADER
|
NS_DECL_NSICOMPONENTLOADER
|
||||||
NS_DECL_NSINATIVECOMPONENTLOADER
|
|
||||||
|
|
||||||
nsNativeComponentLoader();
|
nsNativeComponentLoader();
|
||||||
|
|
||||||
nsIComponentManager* mCompMgr; // weak reference -- backpointer
|
nsIComponentManager* mCompMgr; // weak reference -- backpointer
|
||||||
nsHashtable mLoadedDependentLibs;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsObjectHashtable mDllStore;
|
nsObjectHashtable mDllStore;
|
||||||
|
|
|
@ -1,446 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
/* ***** BEGIN LICENSE BLOCK *****
|
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Mozilla Public License Version
|
|
||||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
* http://www.mozilla.org/MPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing rights and limitations under the
|
|
||||||
* License.
|
|
||||||
*
|
|
||||||
* The Original Code is mozilla.org code.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* Netscape Communications Corporation.
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
*
|
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
|
||||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
||||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
||||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
||||||
* of those above. If you wish to allow use of your version of this file only
|
|
||||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
||||||
* use your version of this file under the terms of the MPL, indicate your
|
|
||||||
* decision by deleting the provisions above and replace them with the notice
|
|
||||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
||||||
* the provisions above, a recipient may use your version of this file under
|
|
||||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
||||||
*
|
|
||||||
* ***** END LICENSE BLOCK ***** */
|
|
||||||
|
|
||||||
/* nsDll
|
|
||||||
*
|
|
||||||
* Abstraction of a Dll. Stores modifiedTime and size for easy detection of
|
|
||||||
* change in dll.
|
|
||||||
*
|
|
||||||
* dp Suresh <dp@netscape.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "xcDll.h"
|
|
||||||
#include "nsDebug.h"
|
|
||||||
#include "nsIComponentManager.h"
|
|
||||||
#include "nsIComponentLoaderManager.h"
|
|
||||||
#include "nsIModule.h"
|
|
||||||
#include "nsILocalFile.h"
|
|
||||||
#include "nsDirectoryServiceDefs.h"
|
|
||||||
#include "nsDirectoryServiceUtils.h"
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
#include "nsCRT.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsITimelineService.h"
|
|
||||||
#include "nsModule.h"
|
|
||||||
#ifdef DEBUG
|
|
||||||
#if defined(VMS)
|
|
||||||
#include <lib$routines.h>
|
|
||||||
#include <ssdef.h>
|
|
||||||
#elif defined(XP_MACOSX)
|
|
||||||
#include <signal.h>
|
|
||||||
#endif
|
|
||||||
#endif /* defined(DEBUG) */
|
|
||||||
|
|
||||||
#include "nsTraceRefcntImpl.h"
|
|
||||||
|
|
||||||
#define UNLOAD_DEPENDENT_LIBS
|
|
||||||
#ifdef HPUX
|
|
||||||
#undef UNLOAD_DEPENDENT_LIBS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsNativeComponentLoader.h"
|
|
||||||
|
|
||||||
nsDll::nsDll(nsIFile *dllSpec, nsNativeComponentLoader *loader)
|
|
||||||
: m_dllSpec(do_QueryInterface(dllSpec)),
|
|
||||||
m_instance(NULL),
|
|
||||||
m_moduleObject(NULL),
|
|
||||||
m_loader(loader),
|
|
||||||
m_markForUnload(PR_FALSE)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(loader, "Null loader when creating a nsDLL");
|
|
||||||
}
|
|
||||||
|
|
||||||
nsDll::~nsDll(void)
|
|
||||||
{
|
|
||||||
//#if DEBUG_dougt
|
|
||||||
// The dll gets deleted when the dllStore is destroyed. This happens on
|
|
||||||
// app shutdown. At that point, unloading dlls can cause crashes if we have
|
|
||||||
// - dll dependencies
|
|
||||||
// - callbacks
|
|
||||||
// - static dtors
|
|
||||||
// Hence turn it back on after all the above have been removed.
|
|
||||||
//Unload();
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsDll::GetDisplayPath(nsACString& aLeafName)
|
|
||||||
{
|
|
||||||
m_dllSpec->GetNativeLeafName(aLeafName);
|
|
||||||
|
|
||||||
if (aLeafName.IsEmpty())
|
|
||||||
aLeafName.AssignLiteral("unknown!");
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsDll::HasChanged()
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIComponentLoaderManager> manager = do_QueryInterface(m_loader->mCompMgr);
|
|
||||||
if (!manager)
|
|
||||||
return PR_TRUE;
|
|
||||||
|
|
||||||
// If mod date has changed, then dll has changed
|
|
||||||
PRInt64 currentDate;
|
|
||||||
nsresult rv = m_dllSpec->GetLastModifiedTime(¤tDate);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return PR_TRUE;
|
|
||||||
PRBool changed = PR_TRUE;
|
|
||||||
manager->HasFileChanged(m_dllSpec, nsnull, currentDate, &changed);
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool nsDll::Load(void)
|
|
||||||
{
|
|
||||||
if (m_instance != NULL)
|
|
||||||
{
|
|
||||||
// Already loaded
|
|
||||||
return (PR_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_dllSpec)
|
|
||||||
{
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
nsTraceRefcntImpl::SetActivityIsLegal(PR_FALSE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Load any library dependencies
|
|
||||||
// The Component Loader Manager may hold onto some extra data
|
|
||||||
// set by either the native component loader or the native
|
|
||||||
// component. We assume that this data is a space delimited
|
|
||||||
// listing of dependent libraries which are required to be
|
|
||||||
// loaded prior to us loading the given component. Once, the
|
|
||||||
// component is loaded into memory, we can release our hold
|
|
||||||
// on the dependent libraries with the assumption that the
|
|
||||||
// component library holds a reference via the OS so loader.
|
|
||||||
|
|
||||||
#if defined(XP_UNIX)
|
|
||||||
nsCOMPtr<nsIComponentLoaderManager> manager = do_QueryInterface(m_loader->mCompMgr);
|
|
||||||
if (!manager)
|
|
||||||
return PR_TRUE;
|
|
||||||
|
|
||||||
nsXPIDLCString extraData;
|
|
||||||
manager->GetOptionalData(m_dllSpec, nsnull, getter_Copies(extraData));
|
|
||||||
|
|
||||||
#ifdef UNLOAD_DEPENDENT_LIBS
|
|
||||||
nsVoidArray dependentLibArray;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// if there was any extra data, treat it as a listing of dependent libs
|
|
||||||
if (extraData != nsnull)
|
|
||||||
{
|
|
||||||
// all dependent libraries are suppose to be in the "gre" directory.
|
|
||||||
// note that the gre directory is the same as the "bin" directory,
|
|
||||||
// when there isn't a real "gre" found.
|
|
||||||
|
|
||||||
nsXPIDLCString path;
|
|
||||||
nsCOMPtr<nsIFile> file;
|
|
||||||
NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(file));
|
|
||||||
|
|
||||||
if (!file)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
// we are talking about a file in the GRE dir. Lets append something
|
|
||||||
// stupid right now, so that later we can just set the leaf name.
|
|
||||||
file->AppendNative(NS_LITERAL_CSTRING("dummy"));
|
|
||||||
|
|
||||||
char *buffer = strdup(extraData);
|
|
||||||
if (!buffer)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
char* newStr;
|
|
||||||
char *token = nsCRT::strtok(buffer, " ", &newStr);
|
|
||||||
while (token!=nsnull)
|
|
||||||
{
|
|
||||||
nsCStringKey key(token);
|
|
||||||
if (m_loader->mLoadedDependentLibs.Get(&key)) {
|
|
||||||
token = nsCRT::strtok(newStr, " ", &newStr);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_loader->mLoadedDependentLibs.Put(&key, (void*)1);
|
|
||||||
|
|
||||||
nsXPIDLCString libpath;
|
|
||||||
file->SetNativeLeafName(nsDependentCString(token));
|
|
||||||
file->GetNativePath(path);
|
|
||||||
if (!path)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
// Load this dependent library with the global flag and stash
|
|
||||||
// the result for later so that we can unload it.
|
|
||||||
PRLibSpec libSpec;
|
|
||||||
libSpec.type = PR_LibSpec_Pathname;
|
|
||||||
|
|
||||||
// if the depend library path starts with a / we are
|
|
||||||
// going to assume that it is a full path and should
|
|
||||||
// be loaded without prepending the gre diretory
|
|
||||||
// location. We could have short circuited the
|
|
||||||
// SetNativeLeafName above, but this is clearer and
|
|
||||||
// the common case is a relative path.
|
|
||||||
|
|
||||||
if (token[0] == '/')
|
|
||||||
libSpec.value.pathname = token;
|
|
||||||
else
|
|
||||||
libSpec.value.pathname = path;
|
|
||||||
|
|
||||||
PRLibrary* lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_LAZY|PR_LD_GLOBAL);
|
|
||||||
// if we couldn't load the dependent library. We did the best we
|
|
||||||
// can. Now just let us fail later if this really was a required
|
|
||||||
// dependency.
|
|
||||||
#ifdef UNLOAD_DEPENDENT_LIBS
|
|
||||||
if (lib)
|
|
||||||
dependentLibArray.AppendElement((void*)lib);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
token = nsCRT::strtok(newStr, " ", &newStr);
|
|
||||||
}
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// load the component
|
|
||||||
nsCOMPtr<nsILocalFile> lf(do_QueryInterface(m_dllSpec));
|
|
||||||
NS_ASSERTION(lf, "nsIFile here must implement a nsILocalFile");
|
|
||||||
lf->Load(&m_instance);
|
|
||||||
|
|
||||||
#if defined(XP_UNIX)
|
|
||||||
// Unload any of library dependencies we loaded earlier. The assumption
|
|
||||||
// here is that the component will have a "internal" reference count to
|
|
||||||
// the dependency library we just loaded.
|
|
||||||
// XXX should we unload later - or even at all?
|
|
||||||
|
|
||||||
#ifdef UNLOAD_DEPENDENT_LIBS
|
|
||||||
if (extraData != nsnull)
|
|
||||||
{
|
|
||||||
PRInt32 arrayCount = dependentLibArray.Count();
|
|
||||||
for (PRInt32 index = 0; index < arrayCount; index++)
|
|
||||||
PR_UnloadLibrary((PRLibrary*)dependentLibArray.ElementAt(index));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
nsTraceRefcntImpl::SetActivityIsLegal(PR_TRUE);
|
|
||||||
if (m_instance) {
|
|
||||||
// Inform refcnt tracer of new library so that calls through the
|
|
||||||
// new library can be traced.
|
|
||||||
nsXPIDLCString displayPath;
|
|
||||||
GetDisplayPath(displayPath);
|
|
||||||
nsTraceRefcntImpl::LoadLibrarySymbols(displayPath.get(), m_instance);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SHOULD_IMPLEMENT_BREAKAFTERLOAD
|
|
||||||
// Debugging help for components. Component dlls need to have their
|
|
||||||
// symbols loaded before we can put a breakpoint in the debugger.
|
|
||||||
// This will help figureing out the point when the dll was loaded.
|
|
||||||
nsXPIDLCString displayPath;
|
|
||||||
GetDisplayPath(displayPath);
|
|
||||||
BreakAfterLoad(displayPath.get());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ((m_instance == NULL) ? PR_FALSE : PR_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool nsDll::Unload(void)
|
|
||||||
{
|
|
||||||
if (m_instance == NULL)
|
|
||||||
return (PR_FALSE);
|
|
||||||
|
|
||||||
// Shutdown the dll
|
|
||||||
Shutdown();
|
|
||||||
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
nsTraceRefcntImpl::SetActivityIsLegal(PR_FALSE);
|
|
||||||
#endif
|
|
||||||
PRStatus ret = PR_UnloadLibrary(m_instance);
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
nsTraceRefcntImpl::SetActivityIsLegal(PR_TRUE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ret == PR_SUCCESS)
|
|
||||||
{
|
|
||||||
m_instance = NULL;
|
|
||||||
return (PR_TRUE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return (PR_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void * nsDll::FindSymbol(const char *symbol)
|
|
||||||
{
|
|
||||||
if (symbol == NULL)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
// If not already loaded, load it now.
|
|
||||||
if (Load() != PR_TRUE)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
return(PR_FindSymbol(m_instance, symbol));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Component dll specific functions
|
|
||||||
nsresult nsDll::GetDllSpec(nsIFile **fsobj)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(m_dllSpec, "m_dllSpec NULL");
|
|
||||||
NS_ASSERTION(fsobj, "xcDll::GetModule : Null argument" );
|
|
||||||
|
|
||||||
*fsobj = m_dllSpec;
|
|
||||||
NS_ADDREF(*fsobj);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult nsDll::GetModule(nsISupports *servMgr, nsIModule **cobj)
|
|
||||||
{
|
|
||||||
// using the backpointer of the loader.
|
|
||||||
nsIComponentManager* compMgr = m_loader->mCompMgr;
|
|
||||||
NS_ASSERTION(compMgr, "Global Component Manager is null" );
|
|
||||||
if (!compMgr) return NS_ERROR_UNEXPECTED;
|
|
||||||
|
|
||||||
NS_ASSERTION(cobj, "xcDll::GetModule : Null argument" );
|
|
||||||
|
|
||||||
if (m_moduleObject)
|
|
||||||
{
|
|
||||||
NS_ADDREF(m_moduleObject);
|
|
||||||
*cobj = m_moduleObject;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not already loaded, load it now.
|
|
||||||
if (Load() != PR_TRUE) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
// We need a nsIFile for location
|
|
||||||
if (!m_dllSpec)
|
|
||||||
{
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsGetModuleProc proc =
|
|
||||||
(nsGetModuleProc) FindSymbol(NS_GET_MODULE_SYMBOL);
|
|
||||||
|
|
||||||
if (proc == NULL)
|
|
||||||
return NS_ERROR_FACTORY_NOT_LOADED;
|
|
||||||
|
|
||||||
nsresult rv = (*proc) (compMgr, m_dllSpec, &m_moduleObject);
|
|
||||||
if (NS_SUCCEEDED(rv))
|
|
||||||
{
|
|
||||||
NS_ADDREF(m_moduleObject);
|
|
||||||
*cobj = m_moduleObject;
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// These are used by BreakAfterLoad, below.
|
|
||||||
#ifdef SHOULD_IMPLEMENT_BREAKAFTERLOAD
|
|
||||||
static nsCString *sBreakList[16];
|
|
||||||
static int sBreakListCount = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsresult nsDll::Shutdown(void)
|
|
||||||
{
|
|
||||||
// Release the module object if we got one
|
|
||||||
nsrefcnt refcnt;
|
|
||||||
if (m_moduleObject)
|
|
||||||
{
|
|
||||||
NS_RELEASE2(m_moduleObject, refcnt);
|
|
||||||
NS_ASSERTION(refcnt == 0, "Dll moduleObject refcount non zero");
|
|
||||||
}
|
|
||||||
#ifdef SHOULD_IMPLEMENT_BREAKAFTERLOAD
|
|
||||||
for (int i = 0; i < sBreakListCount; i++)
|
|
||||||
{
|
|
||||||
delete sBreakList[i];
|
|
||||||
sBreakList[i] = nsnull;
|
|
||||||
}
|
|
||||||
sBreakListCount = 0;
|
|
||||||
#endif
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
}
|
|
||||||
#ifdef SHOULD_IMPLEMENT_BREAKAFTERLOAD
|
|
||||||
void nsDll::BreakAfterLoad(const char *nsprPath)
|
|
||||||
{
|
|
||||||
static PRBool firstTime = PR_TRUE;
|
|
||||||
|
|
||||||
// return if invalid input
|
|
||||||
if (!nsprPath || !*nsprPath) return;
|
|
||||||
|
|
||||||
// return if nothing to break on
|
|
||||||
if (!firstTime && sBreakListCount == 0) return;
|
|
||||||
|
|
||||||
if (firstTime)
|
|
||||||
{
|
|
||||||
firstTime = PR_FALSE;
|
|
||||||
// Form the list of dlls to break on load
|
|
||||||
nsCAutoString envList(getenv("XPCOM_BREAK_ON_LOAD"));
|
|
||||||
if (envList.IsEmpty()) return;
|
|
||||||
PRInt32 ofset = 0;
|
|
||||||
PRInt32 start = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
ofset = envList.FindChar(':', start);
|
|
||||||
sBreakList[sBreakListCount] = new nsCString();
|
|
||||||
envList.Mid(*(sBreakList[sBreakListCount]), start, ofset);
|
|
||||||
sBreakListCount++;
|
|
||||||
start = ofset + 1;
|
|
||||||
}
|
|
||||||
while (ofset != -1 && 16 > sBreakListCount); // avoiding vc6.0 compiler issue. count < thinks it is starting a template
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the dllname part of the string
|
|
||||||
nsCString currentPath(nsprPath);
|
|
||||||
PRInt32 lastSep = currentPath.RFindCharInSet(":\\/");
|
|
||||||
|
|
||||||
for (int i=0; i<sBreakListCount; i++)
|
|
||||||
if (currentPath.Find(*(sBreakList[i]), PR_TRUE, lastSep) > 0)
|
|
||||||
{
|
|
||||||
// Loading a dll that we want to break on
|
|
||||||
// Put your breakpoint here
|
|
||||||
fprintf(stderr, "...Loading module %s\n", nsprPath);
|
|
||||||
// Break in the debugger here.
|
|
||||||
#if defined(__i386) && defined(__GNUC__)
|
|
||||||
asm("int $3");
|
|
||||||
#elif defined(VMS)
|
|
||||||
lib$signal(SS$_DEBUG);
|
|
||||||
#elif defined(XP_MACOSX)
|
|
||||||
raise(SIGTRAP);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* SHOULD_IMPLEMENT_BREAKAFTERLOAD */
|
|
|
@ -48,9 +48,6 @@
|
||||||
#ifdef XPCOM_GLUE
|
#ifdef XPCOM_GLUE
|
||||||
#include "nsXPCOMGlue.h"
|
#include "nsXPCOMGlue.h"
|
||||||
#include "nsXPCOMPrivate.h"
|
#include "nsXPCOMPrivate.h"
|
||||||
#else
|
|
||||||
#include "nsIInterfaceRequestorUtils.h"
|
|
||||||
#include "nsINativeComponentLoader.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsGenericFactory::nsGenericFactory(const nsModuleComponentInfo *info)
|
nsGenericFactory::nsGenericFactory(const nsModuleComponentInfo *info)
|
||||||
|
@ -223,16 +220,14 @@ NS_NewGenericFactory(nsIGenericFactory* *result,
|
||||||
nsGenericModule::nsGenericModule(const char* moduleName, PRUint32 componentCount,
|
nsGenericModule::nsGenericModule(const char* moduleName, PRUint32 componentCount,
|
||||||
const nsModuleComponentInfo* components,
|
const nsModuleComponentInfo* components,
|
||||||
nsModuleConstructorProc ctor,
|
nsModuleConstructorProc ctor,
|
||||||
nsModuleDestructorProc dtor,
|
nsModuleDestructorProc dtor)
|
||||||
const char** aLibDepends)
|
|
||||||
: mInitialized(PR_FALSE),
|
: mInitialized(PR_FALSE),
|
||||||
mModuleName(moduleName),
|
mModuleName(moduleName),
|
||||||
mComponentCount(componentCount),
|
mComponentCount(componentCount),
|
||||||
mComponents(components),
|
mComponents(components),
|
||||||
mFactoriesNotToBeRegistered(nsnull),
|
mFactoriesNotToBeRegistered(nsnull),
|
||||||
mCtor(ctor),
|
mCtor(ctor),
|
||||||
mDtor(dtor),
|
mDtor(dtor)
|
||||||
mLibraryDependencies(aLibDepends)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,25 +428,6 @@ nsGenericModule::RegisterSelf(nsIComponentManager *aCompMgr,
|
||||||
cp++;
|
cp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef XPCOM_GLUE
|
|
||||||
// We want to tell the component loader of any dependencies
|
|
||||||
// we have so that the loader can resolve them for us.
|
|
||||||
|
|
||||||
nsCOMPtr<nsINativeComponentLoader> loader = do_GetInterface(aCompMgr);
|
|
||||||
if (loader && mLibraryDependencies)
|
|
||||||
{
|
|
||||||
for(int i=0; mLibraryDependencies[i] != nsnull &&
|
|
||||||
mLibraryDependencies[i][0] != '\0'; i++)
|
|
||||||
{
|
|
||||||
loader->AddDependentLibrary(aPath,
|
|
||||||
mLibraryDependencies[i]);
|
|
||||||
}
|
|
||||||
loader = nsnull;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,7 +482,7 @@ NS_NewGenericModule2(nsModuleInfo* info, nsIModule* *result)
|
||||||
// Create and initialize the module instance
|
// Create and initialize the module instance
|
||||||
nsGenericModule *m =
|
nsGenericModule *m =
|
||||||
new nsGenericModule(info->mModuleName, info->mCount, info->mComponents,
|
new nsGenericModule(info->mModuleName, info->mCount, info->mComponents,
|
||||||
info->mCtor, info->mDtor, info->mLibraryDependencies);
|
info->mCtor, info->mDtor);
|
||||||
|
|
||||||
if (!m)
|
if (!m)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
@ -531,7 +507,6 @@ NS_NewGenericModule(const char* moduleName,
|
||||||
info.mComponents = components;
|
info.mComponents = components;
|
||||||
info.mCount = componentCount;
|
info.mCount = componentCount;
|
||||||
info.mDtor = dtor;
|
info.mDtor = dtor;
|
||||||
info.mLibraryDependencies = nsnull;
|
|
||||||
|
|
||||||
return NS_NewGenericModule2(&info, result);
|
return NS_NewGenericModule2(&info, result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,8 +82,7 @@ public:
|
||||||
PRUint32 componentCount,
|
PRUint32 componentCount,
|
||||||
const nsModuleComponentInfo* components,
|
const nsModuleComponentInfo* components,
|
||||||
nsModuleConstructorProc ctor,
|
nsModuleConstructorProc ctor,
|
||||||
nsModuleDestructorProc dtor,
|
nsModuleDestructorProc dtor);
|
||||||
const char** alibDepends);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~nsGenericModule();
|
~nsGenericModule();
|
||||||
|
@ -122,7 +121,6 @@ protected:
|
||||||
FactoryNode* mFactoriesNotToBeRegistered;
|
FactoryNode* mFactoriesNotToBeRegistered;
|
||||||
nsModuleConstructorProc mCtor;
|
nsModuleConstructorProc mCtor;
|
||||||
nsModuleDestructorProc mDtor;
|
nsModuleDestructorProc mDtor;
|
||||||
const char** mLibraryDependencies;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsGenericFactory_h___ */
|
#endif /* nsGenericFactory_h___ */
|
||||||
|
|
|
@ -41,9 +41,6 @@
|
||||||
#include "nsIFactory.h"
|
#include "nsIFactory.h"
|
||||||
#include "nsIModule.h"
|
#include "nsIModule.h"
|
||||||
#include "nsIClassInfo.h"
|
#include "nsIClassInfo.h"
|
||||||
#ifdef HAVE_DEPENDENT_LIBS
|
|
||||||
#include "dependentLibs.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// {3bc97f01-ccdf-11d2-bab8-b548654461fc}
|
// {3bc97f01-ccdf-11d2-bab8-b548654461fc}
|
||||||
#define NS_GENERICFACTORY_CID \
|
#define NS_GENERICFACTORY_CID \
|
||||||
|
@ -280,8 +277,6 @@ typedef void (PR_CALLBACK *nsModuleDestructorProc) (nsIModule *self);
|
||||||
* @param mCount : Count of mComponents
|
* @param mCount : Count of mComponents
|
||||||
* @param mCtor : Module user defined constructor
|
* @param mCtor : Module user defined constructor
|
||||||
* @param mDtor : Module user defined destructor
|
* @param mDtor : Module user defined destructor
|
||||||
* @param mLibraryDependencies : array of library which this module is
|
|
||||||
* dependent on.
|
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
@ -292,7 +287,6 @@ struct nsModuleInfo {
|
||||||
PRUint32 mCount;
|
PRUint32 mCount;
|
||||||
nsModuleConstructorProc mCtor;
|
nsModuleConstructorProc mCtor;
|
||||||
nsModuleDestructorProc mDtor;
|
nsModuleDestructorProc mDtor;
|
||||||
const char** mLibraryDependencies;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -323,13 +317,9 @@ NS_NewGenericModule(const char* moduleName,
|
||||||
# define NS_MODULEINFO nsModuleInfo
|
# define NS_MODULEINFO nsModuleInfo
|
||||||
# define NSMODULEINFO(_name) _name##_gModuleInfo
|
# define NSMODULEINFO(_name) _name##_gModuleInfo
|
||||||
# define NSGETMODULE_ENTRY_POINT(_info)
|
# define NSGETMODULE_ENTRY_POINT(_info)
|
||||||
# define NSDEPENDENT_LIBS(_name) const char* _name##_gDependlibs[]={DEPENDENT_LIBS "\0"};
|
|
||||||
# define NSDEPENDENT_LIBS_NAME(_name) _name##_gDependlibs
|
|
||||||
#else
|
#else
|
||||||
# define NS_MODULEINFO static nsModuleInfo
|
# define NS_MODULEINFO static nsModuleInfo
|
||||||
# define NSMODULEINFO(_name) gModuleInfo
|
# define NSMODULEINFO(_name) gModuleInfo
|
||||||
# define NSDEPENDENT_LIBS(_name) static const char* gDependlibs[]={DEPENDENT_LIBS "\0"};
|
|
||||||
# define NSDEPENDENT_LIBS_NAME(_name) gDependlibs
|
|
||||||
# define NSGETMODULE_ENTRY_POINT(_info) \
|
# define NSGETMODULE_ENTRY_POINT(_info) \
|
||||||
extern "C" NS_EXPORT nsresult \
|
extern "C" NS_EXPORT nsresult \
|
||||||
NSGetModule(nsIComponentManager *servMgr, \
|
NSGetModule(nsIComponentManager *servMgr, \
|
||||||
|
@ -355,8 +345,6 @@ NSGetModule(nsIComponentManager *servMgr, \
|
||||||
#define NS_IMPL_NSGETMODULE_WITH_DTOR(_name, _components, _dtor) \
|
#define NS_IMPL_NSGETMODULE_WITH_DTOR(_name, _components, _dtor) \
|
||||||
NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(_name, _components, nsnull, _dtor)
|
NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(_name, _components, nsnull, _dtor)
|
||||||
|
|
||||||
#ifndef DEPENDENT_LIBS
|
|
||||||
|
|
||||||
#define NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(_name, _components, _ctor, _dtor) \
|
#define NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(_name, _components, _ctor, _dtor) \
|
||||||
NS_MODULEINFO NSMODULEINFO(_name) = { \
|
NS_MODULEINFO NSMODULEINFO(_name) = { \
|
||||||
NS_MODULEINFO_VERSION, \
|
NS_MODULEINFO_VERSION, \
|
||||||
|
@ -364,28 +352,10 @@ NS_MODULEINFO NSMODULEINFO(_name) = { \
|
||||||
(_components), \
|
(_components), \
|
||||||
(sizeof(_components) / sizeof(_components[0])), \
|
(sizeof(_components) / sizeof(_components[0])), \
|
||||||
(_ctor), \
|
(_ctor), \
|
||||||
(_dtor), \
|
(_dtor) \
|
||||||
(nsnull) \
|
|
||||||
}; \
|
}; \
|
||||||
NSGETMODULE_ENTRY_POINT(NSMODULEINFO(_name))
|
NSGETMODULE_ENTRY_POINT(NSMODULEINFO(_name))
|
||||||
|
|
||||||
#else // DEPENDENT_LIBS
|
|
||||||
|
|
||||||
#define NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(_name, _components, _ctor, _dtor) \
|
|
||||||
NSDEPENDENT_LIBS(_name) \
|
|
||||||
NS_MODULEINFO NSMODULEINFO(_name) = { \
|
|
||||||
NS_MODULEINFO_VERSION, \
|
|
||||||
(#_name), \
|
|
||||||
(_components), \
|
|
||||||
(sizeof(_components) / sizeof(_components[0])), \
|
|
||||||
(_ctor), \
|
|
||||||
(_dtor), \
|
|
||||||
(NSDEPENDENT_LIBS_NAME(_name)) \
|
|
||||||
}; \
|
|
||||||
NSGETMODULE_ENTRY_POINT(NSMODULEINFO(_name))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define NS_GENERIC_FACTORY_CONSTRUCTOR(_InstanceClass) \
|
#define NS_GENERIC_FACTORY_CONSTRUCTOR(_InstanceClass) \
|
||||||
|
|
|
@ -53,10 +53,29 @@ LOCAL_INCLUDES = \
|
||||||
-I$(srcdir)/../../build \
|
-I$(srcdir)/../../build \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
ifeq (Darwin,$(OS_ARCH))
|
||||||
|
LINKSRC = nsGlueLinkingOSX.cpp
|
||||||
|
endif
|
||||||
|
ifeq (WINNT,$(OS_ARCH))
|
||||||
|
LINKSRC = nsGlueLinkingWin.cpp
|
||||||
|
endif
|
||||||
|
ifneq (,$(filter Linux,$(OS_ARCH)))
|
||||||
|
LINKSRC = nsGlueLinkingDlopen.cpp
|
||||||
|
endif
|
||||||
|
ifeq (OS2,$(OS_ARCH))
|
||||||
|
LINKSRC = nsGlueLinkingOS2.cpp
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef LINKSRC
|
||||||
|
LINKSRC = nsGlueLinkingNull.cpp
|
||||||
|
$(warning TinderboxPrint:<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=298044">Error: XPCOM Glue</a>)
|
||||||
|
endif
|
||||||
|
|
||||||
CPPSRCS = \
|
CPPSRCS = \
|
||||||
$(XPCOM_GLUE_SRC_LCSRCS) \
|
$(XPCOM_GLUE_SRC_LCSRCS) \
|
||||||
nsXPCOMGlue.cpp \
|
nsXPCOMGlue.cpp \
|
||||||
nsGREDirServiceProvider.cpp \
|
nsGREDirServiceProvider.cpp \
|
||||||
|
$(LINKSRC) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
SDK_HEADERS = \
|
SDK_HEADERS = \
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla XPCOM.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||||
|
*
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef nsGlueLinking_h__
|
||||||
|
#define nsGlueLinking_h__
|
||||||
|
|
||||||
|
#include "nsXPCOMPrivate.h"
|
||||||
|
|
||||||
|
#define XPCOM_DEPENDENT_LIBS_LIST "dependentlibs.list"
|
||||||
|
|
||||||
|
NS_HIDDEN_(GetFrozenFunctionsFunc)
|
||||||
|
XPCOMGlueLoad(const char *xpcomFile);
|
||||||
|
|
||||||
|
NS_HIDDEN_(void)
|
||||||
|
XPCOMGlueUnload();
|
||||||
|
|
||||||
|
typedef void (*DependentLibsCallback)(const char *aDependentLib);
|
||||||
|
|
||||||
|
NS_HIDDEN_(void)
|
||||||
|
XPCOMGlueLoadDependentLibs(const char *xpcomDir, DependentLibsCallback cb);
|
||||||
|
|
||||||
|
#endif // nsGlueLinking_h__
|
|
@ -0,0 +1,129 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 6; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla XPCOM.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||||
|
*
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsGlueLinking.h"
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(SUNOS4) || defined(NEXTSTEP) || \
|
||||||
|
(defined(OPENBSD) || defined(NETBSD)) && !defined(__ELF__)
|
||||||
|
#define LEADING_UNDERSCORE "_"
|
||||||
|
#else
|
||||||
|
#define LEADING_UNDERSCORE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct DependentLib
|
||||||
|
{
|
||||||
|
void *libHandle;
|
||||||
|
DependentLib *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static DependentLib *sTop;
|
||||||
|
|
||||||
|
static void
|
||||||
|
AppendDependentLib(void *libHandle)
|
||||||
|
{
|
||||||
|
DependentLib *d = new DependentLib;
|
||||||
|
if (!d)
|
||||||
|
return;
|
||||||
|
|
||||||
|
d->next = sTop;
|
||||||
|
d->libHandle = libHandle;
|
||||||
|
|
||||||
|
sTop = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ReadDependentCB(const char *aDependentLib)
|
||||||
|
{
|
||||||
|
void *libHandle = dlopen(aDependentLib, RTLD_GLOBAL | RTLD_LAZY);
|
||||||
|
if (!libHandle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AppendDependentLib(libHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetFrozenFunctionsFunc
|
||||||
|
XPCOMGlueLoad(const char *xpcomFile)
|
||||||
|
{
|
||||||
|
char xpcomDir[MAXPATHLEN];
|
||||||
|
if (realpath(xpcomFile, xpcomDir)) {
|
||||||
|
char *lastSlash = strrchr(xpcomDir, '/');
|
||||||
|
if (lastSlash) {
|
||||||
|
*lastSlash = '\0';
|
||||||
|
|
||||||
|
XPCOMGlueLoadDependentLibs(xpcomDir, ReadDependentCB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *libHandle = RTLD_DEFAULT;
|
||||||
|
|
||||||
|
if (xpcomFile[0] != '.' || xpcomFile[1] != '\0') {
|
||||||
|
libHandle = dlopen(xpcomFile, RTLD_GLOBAL | RTLD_LAZY);
|
||||||
|
if (libHandle) {
|
||||||
|
AppendDependentLib(libHandle);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
libHandle = RTLD_DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetFrozenFunctionsFunc sym =
|
||||||
|
(GetFrozenFunctionsFunc) dlsym(libHandle,
|
||||||
|
LEADING_UNDERSCORE "NS_GetFrozenFunctions");
|
||||||
|
|
||||||
|
if (!sym)
|
||||||
|
XPCOMGlueUnload();
|
||||||
|
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XPCOMGlueUnload()
|
||||||
|
{
|
||||||
|
while (sTop) {
|
||||||
|
dlclose(sTop->libHandle);
|
||||||
|
|
||||||
|
DependentLib *temp = sTop;
|
||||||
|
sTop = sTop->next;
|
||||||
|
|
||||||
|
delete temp;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 6; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla XPCOM.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||||
|
*
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsGlueLinking.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
GetFrozenFunctionsFunc
|
||||||
|
XPCOMGlueLoad(const char *xpcomFile)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "XPCOM glue dynamic linking is not implemented on this platform!");
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XPCOMGlueUnload()
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 6; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla XPCOM.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||||
|
*
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsGlueLinking.h"
|
||||||
|
|
||||||
|
#define INCL_DOS
|
||||||
|
#define INCL_DOSERRORS
|
||||||
|
#include <os2.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct DependentLib
|
||||||
|
{
|
||||||
|
HMODULE libHandle;
|
||||||
|
DependentLib *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static DependentLib *sTop;
|
||||||
|
|
||||||
|
static void
|
||||||
|
AppendDependentLib(HMODULE libHandle)
|
||||||
|
{
|
||||||
|
DependentLib *d = new DependentLib;
|
||||||
|
if (!d)
|
||||||
|
return;
|
||||||
|
|
||||||
|
d->next = sTop;
|
||||||
|
d->libHandle = libHandle;
|
||||||
|
|
||||||
|
sTop = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ReadDependentCB(const char *aDependentLib)
|
||||||
|
{
|
||||||
|
CHAR pszError[_MAX_PATH];
|
||||||
|
ULONG ulRc = NO_ERROR;
|
||||||
|
HMODULE h;
|
||||||
|
|
||||||
|
ulRc = DosLoadModule(pszError, _MAX_PATH, aDependentLib, &h);
|
||||||
|
|
||||||
|
if (ulRc != NO_ERROR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AppendDependentLib(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
// like strpbrk but finds the *last* char, not the first
|
||||||
|
static char*
|
||||||
|
ns_strrpbrk(char *string, const char *strCharSet)
|
||||||
|
{
|
||||||
|
char *found = NULL;
|
||||||
|
for (; *string; ++string) {
|
||||||
|
for(const char *search = strCharSet; *search; ++search) {
|
||||||
|
if (*search == *string) {
|
||||||
|
found = string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetFrozenFunctionsFunc
|
||||||
|
XPCOMGlueLoad(const char *xpcomFile)
|
||||||
|
{
|
||||||
|
if (xpcomFile[0] == '.' && xpcomFile[1] == '\0') {
|
||||||
|
xpcomFile = XPCOM_DLL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char xpcomDir[MAXPATHLEN];
|
||||||
|
|
||||||
|
_fullpath(xpcomDir, xpcomFile, sizeof(xpcomDir));
|
||||||
|
char *lastSlash = ns_strrpbrk(xpcomDir, "/\\");
|
||||||
|
if (lastSlash) {
|
||||||
|
*lastSlash = '\0';
|
||||||
|
|
||||||
|
XPCOMGlueLoadDependentLibs(xpcomDir, ReadDependentCB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHAR pszError[_MAX_PATH];
|
||||||
|
ULONG ulRc = NO_ERROR;
|
||||||
|
HMODULE h;
|
||||||
|
|
||||||
|
ulRc = DosLoadModule(pszError, _MAX_PATH, xpcomFile, &h);
|
||||||
|
|
||||||
|
if (ulRc != NO_ERROR)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
AppendDependentLib(h);
|
||||||
|
|
||||||
|
ULONG ulrc = NO_ERROR;
|
||||||
|
|
||||||
|
GetFrozenFunctionsFunc sym;
|
||||||
|
|
||||||
|
ulrc = DosQueryProcAddr(h, 0, "NS_GetFrozenFunctions", &sym);
|
||||||
|
|
||||||
|
if (ulrc != NO_ERROR)
|
||||||
|
XPCOMGlueUnload();
|
||||||
|
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XPCOMGlueUnload()
|
||||||
|
{
|
||||||
|
while (sTop) {
|
||||||
|
DosFreeModule(sTop->libHandle);
|
||||||
|
|
||||||
|
DependentLib *temp = sTop;
|
||||||
|
sTop = sTop->next;
|
||||||
|
|
||||||
|
delete temp;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 6; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla XPCOM.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||||
|
*
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsGlueLinking.h"
|
||||||
|
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
ReadDependentCB(const char *aDependentLib)
|
||||||
|
{
|
||||||
|
(void) NSAddImage(aDependentLib,
|
||||||
|
NSADDIMAGE_OPTION_RETURN_ON_ERROR |
|
||||||
|
NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetFrozenFunctionsFunc
|
||||||
|
XPCOMGlueLoad(const char *xpcomFile)
|
||||||
|
{
|
||||||
|
if (xpcomFile[0] != '.' || xpcomFile[1] != '\0') {
|
||||||
|
char xpcomDir[PATH_MAX];
|
||||||
|
if (realpath(xpcomFile, xpcomDir)) {
|
||||||
|
char *lastSlash = strrchr(xpcomDir, '/');
|
||||||
|
if (lastSlash) {
|
||||||
|
*lastSlash = '\0';
|
||||||
|
|
||||||
|
XPCOMGlueLoadDependentLibs(xpcomDir, ReadDependentCB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) NSAddImage(xpcomFile,
|
||||||
|
NSADDIMAGE_OPTION_RETURN_ON_ERROR |
|
||||||
|
NSADDIMAGE_OPTION_WITH_SEARCHING |
|
||||||
|
NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME);
|
||||||
|
// We don't really care if this fails, as long as we can get
|
||||||
|
// NS_GetFrozenFunctions below.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NSIsSymbolNameDefined("_NS_GetFrozenFunctions"))
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
NSSymbol sym = NSLookupAndBindSymbol("_NS_GetFrozenFunctions");
|
||||||
|
return (GetFrozenFunctionsFunc) NSAddressOfSymbol(sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XPCOMGlueUnload()
|
||||||
|
{
|
||||||
|
// nothing to do, since we cannot unload dylibs on OS X
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 6; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla XPCOM.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||||
|
*
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsGlueLinking.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct DependentLib
|
||||||
|
{
|
||||||
|
HINSTANCE libHandle;
|
||||||
|
DependentLib *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static DependentLib *sTop;
|
||||||
|
|
||||||
|
static void
|
||||||
|
AppendDependentLib(HINSTANCE libHandle)
|
||||||
|
{
|
||||||
|
DependentLib *d = new DependentLib;
|
||||||
|
if (!d)
|
||||||
|
return;
|
||||||
|
|
||||||
|
d->next = sTop;
|
||||||
|
d->libHandle = libHandle;
|
||||||
|
|
||||||
|
sTop = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ReadDependentCB(const char *aDependentLib)
|
||||||
|
{
|
||||||
|
HINSTANCE h =
|
||||||
|
LoadLibraryEx(aDependentLib, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||||
|
if (!h)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AppendDependentLib(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
// like strpbrk but finds the *last* char, not the first
|
||||||
|
static char*
|
||||||
|
ns_strrpbrk(char *string, const char *strCharSet)
|
||||||
|
{
|
||||||
|
char *found = NULL;
|
||||||
|
for (; *string; ++string) {
|
||||||
|
for (const char *search = strCharSet; *search; ++search) {
|
||||||
|
if (*search == *string) {
|
||||||
|
found = string;
|
||||||
|
// Since we're looking for the last char, we save "found"
|
||||||
|
// until we're at the end of the string.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetFrozenFunctionsFunc
|
||||||
|
XPCOMGlueLoad(const char *xpcomFile)
|
||||||
|
{
|
||||||
|
if (xpcomFile[0] == '.' && xpcomFile[1] == '\0') {
|
||||||
|
xpcomFile = XPCOM_DLL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char xpcomDir[MAXPATHLEN];
|
||||||
|
|
||||||
|
_fullpath(xpcomDir, xpcomFile, sizeof(xpcomDir));
|
||||||
|
char *lastSlash = ns_strrpbrk(xpcomDir, "/\\");
|
||||||
|
if (lastSlash) {
|
||||||
|
*lastSlash = '\0';
|
||||||
|
|
||||||
|
XPCOMGlueLoadDependentLibs(xpcomDir, ReadDependentCB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HINSTANCE h =
|
||||||
|
LoadLibraryEx(xpcomFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||||
|
|
||||||
|
if (!h)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
AppendDependentLib(h);
|
||||||
|
|
||||||
|
GetFrozenFunctionsFunc sym =
|
||||||
|
(GetFrozenFunctionsFunc) GetProcAddress(h, "NS_GetFrozenFunctions");
|
||||||
|
|
||||||
|
if (!sym)
|
||||||
|
XPCOMGlueUnload();
|
||||||
|
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XPCOMGlueUnload()
|
||||||
|
{
|
||||||
|
while (sTop) {
|
||||||
|
FreeLibrary(sTop->libHandle);
|
||||||
|
|
||||||
|
DependentLib *temp = sTop;
|
||||||
|
sTop = sTop->next;
|
||||||
|
|
||||||
|
delete temp;
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,10 @@ include $(DEPTH)/config/autoconf.mk
|
||||||
MODULE = xpcom
|
MODULE = xpcom
|
||||||
LIBRARY_NAME = xpcom
|
LIBRARY_NAME = xpcom
|
||||||
|
|
||||||
|
# The XPCOM glue uses realpath() on libxpcom.so to resolve any symlinks. We
|
||||||
|
# want it to find dist/bin and not xpcom/stub so we copy instead of symlinking.
|
||||||
|
NSDISTMODE = copy
|
||||||
|
|
||||||
PACKAGE_FILE = xpcom.pkg
|
PACKAGE_FILE = xpcom.pkg
|
||||||
PACKAGE_VARS += USE_SHORT_LIBNAME
|
PACKAGE_VARS += USE_SHORT_LIBNAME
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче