зеркало из 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 # 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
|
||||
LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
|
||||
HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
|
||||
|
|
|
@ -77,7 +77,6 @@ XPIDLSRCS = \
|
|||
nsIComponentLoader.idl \
|
||||
nsIComponentLoaderManager.idl \
|
||||
nsIComponentManagerObsolete.idl \
|
||||
nsINativeComponentLoader.idl \
|
||||
$(NULL)
|
||||
|
||||
SDK_XPIDLSRCS = \
|
||||
|
|
|
@ -952,14 +952,6 @@ NS_IMPL_THREADSAFE_ISUPPORTS8(nsComponentManagerImpl,
|
|||
nsresult
|
||||
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");
|
||||
// fall through to QI as anything QIable is a superset of what can be
|
||||
// got via the GetInterface()
|
||||
|
|
|
@ -79,15 +79,13 @@ DLLStore_Destroy(nsHashKey *aKey, void *aData, void* closure)
|
|||
|
||||
nsNativeComponentLoader::nsNativeComponentLoader() :
|
||||
mCompMgr(nsnull),
|
||||
mLoadedDependentLibs(16, PR_TRUE),
|
||||
mDllStore(nsnull, nsnull, DLLStore_Destroy,
|
||||
nsnull, 256, PR_TRUE)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNativeComponentLoader,
|
||||
nsIComponentLoader,
|
||||
nsINativeComponentLoader)
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsNativeComponentLoader,
|
||||
nsIComponentLoader)
|
||||
|
||||
NS_IMETHODIMP
|
||||
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
|
||||
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,
|
||||
nativeComponentType);
|
||||
}
|
||||
|
@ -1063,36 +1057,3 @@ nsNativeComponentLoader::GetFactoryFromModule(nsDll *aDll, const nsCID &aCID,
|
|||
return module->GetClassObject(mCompMgr, aCID, NS_GET_IID(nsIFactory),
|
||||
(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 "nsVoidArray.h"
|
||||
#include "xcDll.h"
|
||||
#include "nsINativeComponentLoader.h"
|
||||
|
||||
#ifndef nsNativeComponentLoader_h__
|
||||
#define nsNativeComponentLoader_h__
|
||||
|
||||
class nsNativeComponentLoader : public nsIComponentLoader, public nsINativeComponentLoader {
|
||||
class nsNativeComponentLoader : public nsIComponentLoader
|
||||
{
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICOMPONENTLOADER
|
||||
NS_DECL_NSINATIVECOMPONENTLOADER
|
||||
|
||||
nsNativeComponentLoader();
|
||||
|
||||
nsIComponentManager* mCompMgr; // weak reference -- backpointer
|
||||
nsHashtable mLoadedDependentLibs;
|
||||
|
||||
private:
|
||||
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
|
||||
#include "nsXPCOMGlue.h"
|
||||
#include "nsXPCOMPrivate.h"
|
||||
#else
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsINativeComponentLoader.h"
|
||||
#endif
|
||||
|
||||
nsGenericFactory::nsGenericFactory(const nsModuleComponentInfo *info)
|
||||
|
@ -223,16 +220,14 @@ NS_NewGenericFactory(nsIGenericFactory* *result,
|
|||
nsGenericModule::nsGenericModule(const char* moduleName, PRUint32 componentCount,
|
||||
const nsModuleComponentInfo* components,
|
||||
nsModuleConstructorProc ctor,
|
||||
nsModuleDestructorProc dtor,
|
||||
const char** aLibDepends)
|
||||
nsModuleDestructorProc dtor)
|
||||
: mInitialized(PR_FALSE),
|
||||
mModuleName(moduleName),
|
||||
mComponentCount(componentCount),
|
||||
mComponents(components),
|
||||
mFactoriesNotToBeRegistered(nsnull),
|
||||
mCtor(ctor),
|
||||
mDtor(dtor),
|
||||
mLibraryDependencies(aLibDepends)
|
||||
mDtor(dtor)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -433,25 +428,6 @@ nsGenericModule::RegisterSelf(nsIComponentManager *aCompMgr,
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -506,7 +482,7 @@ NS_NewGenericModule2(nsModuleInfo* info, nsIModule* *result)
|
|||
// Create and initialize the module instance
|
||||
nsGenericModule *m =
|
||||
new nsGenericModule(info->mModuleName, info->mCount, info->mComponents,
|
||||
info->mCtor, info->mDtor, info->mLibraryDependencies);
|
||||
info->mCtor, info->mDtor);
|
||||
|
||||
if (!m)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -531,7 +507,6 @@ NS_NewGenericModule(const char* moduleName,
|
|||
info.mComponents = components;
|
||||
info.mCount = componentCount;
|
||||
info.mDtor = dtor;
|
||||
info.mLibraryDependencies = nsnull;
|
||||
|
||||
return NS_NewGenericModule2(&info, result);
|
||||
}
|
||||
|
|
|
@ -82,8 +82,7 @@ public:
|
|||
PRUint32 componentCount,
|
||||
const nsModuleComponentInfo* components,
|
||||
nsModuleConstructorProc ctor,
|
||||
nsModuleDestructorProc dtor,
|
||||
const char** alibDepends);
|
||||
nsModuleDestructorProc dtor);
|
||||
|
||||
private:
|
||||
~nsGenericModule();
|
||||
|
@ -122,7 +121,6 @@ protected:
|
|||
FactoryNode* mFactoriesNotToBeRegistered;
|
||||
nsModuleConstructorProc mCtor;
|
||||
nsModuleDestructorProc mDtor;
|
||||
const char** mLibraryDependencies;
|
||||
};
|
||||
|
||||
#endif /* nsGenericFactory_h___ */
|
||||
|
|
|
@ -41,9 +41,6 @@
|
|||
#include "nsIFactory.h"
|
||||
#include "nsIModule.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#ifdef HAVE_DEPENDENT_LIBS
|
||||
#include "dependentLibs.h"
|
||||
#endif
|
||||
|
||||
// {3bc97f01-ccdf-11d2-bab8-b548654461fc}
|
||||
#define NS_GENERICFACTORY_CID \
|
||||
|
@ -280,8 +277,6 @@ typedef void (PR_CALLBACK *nsModuleDestructorProc) (nsIModule *self);
|
|||
* @param mCount : Count of mComponents
|
||||
* @param mCtor : Module user defined constructor
|
||||
* @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;
|
||||
nsModuleConstructorProc mCtor;
|
||||
nsModuleDestructorProc mDtor;
|
||||
const char** mLibraryDependencies;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -323,13 +317,9 @@ NS_NewGenericModule(const char* moduleName,
|
|||
# define NS_MODULEINFO nsModuleInfo
|
||||
# define NSMODULEINFO(_name) _name##_gModuleInfo
|
||||
# define NSGETMODULE_ENTRY_POINT(_info)
|
||||
# define NSDEPENDENT_LIBS(_name) const char* _name##_gDependlibs[]={DEPENDENT_LIBS "\0"};
|
||||
# define NSDEPENDENT_LIBS_NAME(_name) _name##_gDependlibs
|
||||
#else
|
||||
# define NS_MODULEINFO static nsModuleInfo
|
||||
# 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) \
|
||||
extern "C" NS_EXPORT nsresult \
|
||||
NSGetModule(nsIComponentManager *servMgr, \
|
||||
|
@ -355,8 +345,6 @@ NSGetModule(nsIComponentManager *servMgr, \
|
|||
#define NS_IMPL_NSGETMODULE_WITH_DTOR(_name, _components, _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) \
|
||||
NS_MODULEINFO NSMODULEINFO(_name) = { \
|
||||
NS_MODULEINFO_VERSION, \
|
||||
|
@ -364,28 +352,10 @@ NS_MODULEINFO NSMODULEINFO(_name) = { \
|
|||
(_components), \
|
||||
(sizeof(_components) / sizeof(_components[0])), \
|
||||
(_ctor), \
|
||||
(_dtor), \
|
||||
(nsnull) \
|
||||
(_dtor) \
|
||||
}; \
|
||||
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) \
|
||||
|
|
|
@ -53,10 +53,29 @@ LOCAL_INCLUDES = \
|
|||
-I$(srcdir)/../../build \
|
||||
$(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 = \
|
||||
$(XPCOM_GLUE_SRC_LCSRCS) \
|
||||
nsXPCOMGlue.cpp \
|
||||
nsGREDirServiceProvider.cpp \
|
||||
$(LINKSRC) \
|
||||
$(NULL)
|
||||
|
||||
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
|
||||
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_VARS += USE_SHORT_LIBNAME
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче