diff options
Diffstat (limited to 'sal/osl/unx/module.c')
-rw-r--r-- | sal/osl/unx/module.c | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/sal/osl/unx/module.c b/sal/osl/unx/module.c new file mode 100644 index 000000000000..8f8f76a8656c --- /dev/null +++ b/sal/osl/unx/module.c @@ -0,0 +1,242 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <sal/types.h> +#include <osl/diagnose.h> +#include <osl/module.h> +#include <osl/thread.h> +#include <osl/process.h> +#include <osl/file.h> + +#include "system.h" + +#if OSL_DEBUG_LEVEL > 1 +#include <stdio.h> +#endif + +/* implemented in file.c */ +extern int UnicodeToText(char *, size_t, const sal_Unicode *, sal_Int32); + +oslModule SAL_CALL osl_psz_loadModule(const sal_Char *pszModuleName, sal_Int32 nRtldMode); + +/*****************************************************************************/ +/* osl_loadModule */ +/*****************************************************************************/ + +oslModule SAL_CALL osl_loadModule(rtl_uString *ustrModuleName, sal_Int32 nRtldMode) +{ + oslModule pModule=0; + rtl_uString* ustrTmp = NULL; + + OSL_ENSURE(ustrModuleName,"osl_loadModule : string is not valid"); + + /* ensure ustrTmp hold valid string */ + if (osl_File_E_None != osl_getSystemPathFromFileURL(ustrModuleName, &ustrTmp)) + rtl_uString_assign(&ustrTmp, ustrModuleName); + + if (ustrTmp) + { + char buffer[PATH_MAX]; + + if (UnicodeToText(buffer, PATH_MAX, ustrTmp->buffer, ustrTmp->length)) + pModule = osl_psz_loadModule(buffer, nRtldMode); + rtl_uString_release(ustrTmp); + } + + return pModule; +} + +/*****************************************************************************/ +/* osl_psz_loadModule */ +/*****************************************************************************/ + +oslModule SAL_CALL osl_psz_loadModule(const sal_Char *pszModuleName, sal_Int32 nRtldMode) +{ + OSL_ASSERT( + (nRtldMode & SAL_LOADMODULE_LAZY) == 0 || + (nRtldMode & SAL_LOADMODULE_NOW) == 0); /* only either LAZY or NOW */ + if (pszModuleName) + { +#ifndef NO_DL_FUNCTIONS + int rtld_mode = + ((nRtldMode & SAL_LOADMODULE_NOW) ? RTLD_NOW : RTLD_LAZY) | + ((nRtldMode & SAL_LOADMODULE_GLOBAL) ? RTLD_GLOBAL : RTLD_LOCAL); + void* pLib = dlopen(pszModuleName, rtld_mode); + +#if OSL_DEBUG_LEVEL > 1 + if (pLib == 0) + OSL_TRACE("Error osl_loadModule: %s\n", dlerror()); +#endif /* OSL_DEBUG_LEVEL */ + + return ((oslModule)(pLib)); + +#else /* NO_DL_FUNCTIONS */ + printf("No DL Functions\n"); +#endif /* NO_DL_FUNCTIONS */ + } + return NULL; +} + +/*****************************************************************************/ +/* osl_getModuleHandle */ +/*****************************************************************************/ + +sal_Bool SAL_CALL +osl_getModuleHandle(rtl_uString *pModuleName, oslModule *pResult) +{ + (void) pModuleName; /* avoid warning about unused parameter */ + *pResult = (oslModule) RTLD_DEFAULT; + return sal_True; +} + +/*****************************************************************************/ +/* osl_unloadModule */ +/*****************************************************************************/ +void SAL_CALL osl_unloadModule(oslModule hModule) +{ + if (hModule) + { +#ifndef NO_DL_FUNCTIONS + int nRet = dlclose(hModule); + +#if OSL_DEBUG_LEVEL > 1 + if (nRet != 0) + { + fprintf(stderr, "Error osl_unloadModule: %s\n", dlerror()); + } +#else + (void) nRet; +#endif /* if OSL_DEBUG_LEVEL */ + +#endif /* ifndef NO_DL_FUNCTIONS */ + } +} + +/*****************************************************************************/ +/* osl_getSymbol */ +/*****************************************************************************/ +void* SAL_CALL +osl_getSymbol(oslModule Module, rtl_uString* pSymbolName) +{ + return (void *) osl_getFunctionSymbol(Module, pSymbolName); +} + + +/*****************************************************************************/ +/* osl_getAsciiFunctionSymbol */ +/*****************************************************************************/ +oslGenericFunction SAL_CALL +osl_getAsciiFunctionSymbol(oslModule Module, const sal_Char *pSymbol) +{ + void *fcnAddr = NULL; + +#ifndef NO_DL_FUNCTIONS + if (pSymbol) + { + fcnAddr = dlsym(Module, pSymbol); + + if (!fcnAddr) + OSL_TRACE("Error osl_getAsciiFunctionSymbol: %s\n", dlerror()); + } +#endif + + return (oslGenericFunction) fcnAddr; +} + +/*****************************************************************************/ +/* osl_getFunctionSymbol */ +/*****************************************************************************/ +oslGenericFunction SAL_CALL +osl_getFunctionSymbol(oslModule module, rtl_uString *puFunctionSymbolName) +{ + oslGenericFunction pSymbol = NULL; + + if( puFunctionSymbolName ) + { + rtl_String* pSymbolName = NULL; + + rtl_uString2String( &pSymbolName, + rtl_uString_getStr(puFunctionSymbolName), + rtl_uString_getLength(puFunctionSymbolName), + RTL_TEXTENCODING_UTF8, + OUSTRING_TO_OSTRING_CVTFLAGS ); + + if( pSymbolName != NULL ) + { + pSymbol = osl_getAsciiFunctionSymbol(module, rtl_string_getStr(pSymbolName)); + rtl_string_release(pSymbolName); + } + } + + return pSymbol; +} + +/*****************************************************************************/ +/* osl_getModuleURLFromAddress */ +/*****************************************************************************/ +sal_Bool SAL_CALL osl_getModuleURLFromAddress(void * addr, rtl_uString ** ppLibraryUrl) +{ + sal_Bool result = sal_False; + Dl_info dl_info; + + if ((result = dladdr(addr, &dl_info)) != 0) + { + rtl_uString * workDir = NULL; + osl_getProcessWorkingDir(&workDir); + if (workDir) + { +#if OSL_DEBUG_LEVEL > 1 + OSL_TRACE("module.c::osl_getModuleURLFromAddress - %s\n", dl_info.dli_fname); +#endif + rtl_string2UString(ppLibraryUrl, + dl_info.dli_fname, + strlen(dl_info.dli_fname), + osl_getThreadTextEncoding(), + OSTRING_TO_OUSTRING_CVTFLAGS); + + OSL_ASSERT(*ppLibraryUrl != NULL); + osl_getFileURLFromSystemPath(*ppLibraryUrl, ppLibraryUrl); + osl_getAbsoluteFileURL(workDir, *ppLibraryUrl, ppLibraryUrl); + + rtl_uString_release(workDir); + result = sal_True; + } + else + { + result = sal_False; + } + } + return result; +} + +/*****************************************************************************/ +/* osl_getModuleURLFromFunctionAddress */ +/*****************************************************************************/ +sal_Bool SAL_CALL osl_getModuleURLFromFunctionAddress(oslGenericFunction addr, rtl_uString ** ppLibraryUrl) +{ + return osl_getModuleURLFromAddress((void*)addr, ppLibraryUrl); +} |