summaryrefslogtreecommitdiff
path: root/sal
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2011-09-27 10:06:54 +0200
committerStephan Bergmann <sbergman@redhat.com>2011-09-27 10:10:55 +0200
commit193715bbf0e59256fd8da7ebd8dc5eb937615281 (patch)
treee268a2f2623b7ebd1ac03e71d763d9ab84952167 /sal
parent04b8b4fbbb4b7f72f33d0b76b86945cb98c4ecd9 (diff)
FullTextEncodingDataSingleton must not call itself recursively.
Happened on non-standard locales (like hu_HU on Linux) when osl_loadModuleRelative wanted to access non-standard text encodings. For Windows, the fix is still only a "TODO: FIXME" dummy.
Diffstat (limited to 'sal')
-rw-r--r--sal/inc/osl/module.h24
-rw-r--r--sal/inc/osl/module.hxx15
-rw-r--r--sal/osl/unx/module.c168
-rw-r--r--sal/osl/w32/module.cxx6
-rw-r--r--sal/textenc/textenc.cxx12
5 files changed, 144 insertions, 81 deletions
diff --git a/sal/inc/osl/module.h b/sal/inc/osl/module.h
index c103e41af7eb..67842325eb62 100644
--- a/sal/inc/osl/module.h
+++ b/sal/inc/osl/module.h
@@ -102,6 +102,30 @@ oslModule SAL_CALL osl_loadModuleAscii(const sal_Char *pModuleName, sal_Int32 nR
oslModule SAL_CALL osl_loadModuleRelative(
oslGenericFunction baseModule, rtl_uString * relativePath, sal_Int32 mode);
+/** Load a module located relative to some other module.
+
+ @param baseModule
+ must point to a function that is part of the code of some loaded module;
+ must not be NULL.
+
+ @param relativePath
+ a relative URL containing only ASCII (0x01--7F) characters; must not be
+ NULL.
+
+ @param mode
+ the SAL_LOADMODULE_xxx flags.
+
+ @return
+ a non-NULL handle to the loaded module, or NULL if an error occurred.
+
+ @since LibreOffice 3.5
+*/
+oslModule SAL_CALL osl_loadModuleRelativeAscii(
+ oslGenericFunction baseModule, char const * relativePath, sal_Int32 mode);
+ /* This function is guaranteed not to call into
+ FullTextEncodingDataSingleton in sal/textenc/textenc.cxx, so can be used
+ in its implementation without running into circles. */
+
/** Retrieve the handle of an already loaded module.
This function can be used to search for a function symbol in the process address space.
diff --git a/sal/inc/osl/module.hxx b/sal/inc/osl/module.hxx
index cfc1c5e02fc1..3ece623d1aa9 100644
--- a/sal/inc/osl/module.hxx
+++ b/sal/inc/osl/module.hxx
@@ -102,6 +102,16 @@ public:
return is();
}
+ /// @since LibreOffice 3.5
+ sal_Bool SAL_CALL loadRelative(
+ oslGenericFunction baseModule, char const * relativePath,
+ sal_Int32 mode = SAL_LOADMODULE_DEFAULT)
+ {
+ unload();
+ m_Module = osl_loadModuleRelativeAscii(baseModule, relativePath, mode);
+ return is();
+ }
+
void SAL_CALL unload()
{
if (m_Module)
@@ -144,6 +154,11 @@ public:
return ( osl_getFunctionSymbol( m_Module, ustrFunctionSymbolName.pData ) );
}
+ /// @since LibreOffice 3.5
+ oslGenericFunction SAL_CALL getFunctionSymbol(char const * name) const {
+ return osl_getAsciiFunctionSymbol(m_Module, name);
+ }
+
operator oslModule() const
{
return m_Module;
diff --git a/sal/osl/unx/module.c b/sal/osl/unx/module.c
index 63fbc20b68b2..7db80117604a 100644
--- a/sal/osl/unx/module.c
+++ b/sal/osl/unx/module.c
@@ -46,6 +46,69 @@
/* implemented in file.c */
extern int UnicodeToText(char *, size_t, const sal_Unicode *, sal_Int32);
+static sal_Bool getModulePathFromAddress(void * address, rtl_String ** path) {
+ sal_Bool result = sal_False;
+/* Bah, we do want to use dladdr here also on iOS, I think? */
+#if !defined(NO_DL_FUNCTIONS) || defined(IOS)
+#if defined(AIX)
+ int i;
+ int size = 4 * 1024;
+ char *buf, *filename=NULL;
+ struct ld_info *lp;
+
+ if ((buf = malloc(size)) == NULL)
+ return result;
+
+ while((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM)
+ {
+ size += 4 * 1024;
+ if ((buf = malloc(size)) == NULL)
+ break;
+ }
+
+ lp = (struct ld_info*) buf;
+ while (lp)
+ {
+ unsigned long start = (unsigned long)lp->ldinfo_dataorg;
+ unsigned long end = start + lp->ldinfo_datasize;
+ if (start <= (unsigned long)address && end > (unsigned long)address)
+ {
+ filename = lp->ldinfo_filename;
+ break;
+ }
+ if (!lp->ldinfo_next)
+ break;
+ lp = (struct ld_info*) ((char *) lp + lp->ldinfo_next);
+ }
+
+ if (filename)
+ {
+ rtl_string_newFromStr(path, filename);
+ result = sal_True;
+ }
+ else
+ {
+ result = sal_False;
+ }
+
+ free(buf);
+#else
+ Dl_info dl_info;
+
+ if ((result = dladdr(address, &dl_info)) != 0)
+ {
+ rtl_string_newFromStr(path, dl_info.dli_fname);
+ result = sal_True;
+ }
+ else
+ {
+ result = sal_False;
+ }
+#endif
+#endif
+ return result;
+}
+
/*****************************************************************************/
/* osl_loadModule */
/*****************************************************************************/
@@ -104,6 +167,34 @@ oslModule SAL_CALL osl_loadModuleAscii(const sal_Char *pModuleName, sal_Int32 nR
return NULL;
}
+oslModule osl_loadModuleRelativeAscii(
+ oslGenericFunction baseModule, char const * relativePath, sal_Int32 mode)
+{
+ OSL_ASSERT(relativePath != NULL);
+ if (relativePath[0] == '/') {
+ return osl_loadModuleAscii(relativePath, mode);
+ } else {
+ rtl_String * path = NULL;
+ rtl_String * suffix = NULL;
+ oslModule module;
+ if (!getModulePathFromAddress(baseModule, &path)) {
+ return NULL;
+ }
+ rtl_string_newFromStr_WithLength(
+ &path, path->buffer,
+ (rtl_str_lastIndexOfChar_WithLength(path->buffer, path->length, '/')
+ + 1));
+ /* cut off everything after the last slash; should the original path
+ contain no slash, the resulting path is the empty string */
+ rtl_string_newFromStr(&suffix, relativePath);
+ rtl_string_newConcat(&path, path, suffix);
+ rtl_string_release(suffix);
+ module = osl_loadModuleAscii(path->buffer, mode);
+ rtl_string_release(path);
+ return module;
+ }
+}
+
/*****************************************************************************/
/* osl_getModuleHandle */
/*****************************************************************************/
@@ -209,51 +300,19 @@ osl_getFunctionSymbol(oslModule module, rtl_uString *puFunctionSymbolName)
sal_Bool SAL_CALL osl_getModuleURLFromAddress(void * addr, rtl_uString ** ppLibraryUrl)
{
sal_Bool result = sal_False;
-/* Bah, we do want to use dladdr here also on iOS, I think? */
-#if !defined(NO_DL_FUNCTIONS) || defined(IOS)
-#if defined(AIX)
- int i;
- int size = 4 * 1024;
- char *buf, *filename=NULL;
- struct ld_info *lp;
-
- if ((buf = malloc(size)) == NULL)
- return result;
-
- while((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM)
- {
- size += 4 * 1024;
- if ((buf = malloc(size)) == NULL)
- break;
- }
-
- lp = (struct ld_info*) buf;
- while (lp)
- {
- unsigned long start = (unsigned long)lp->ldinfo_dataorg;
- unsigned long end = start + lp->ldinfo_datasize;
- if (start <= (unsigned long)addr && end > (unsigned long)addr)
- {
- filename = lp->ldinfo_filename;
- break;
- }
- if (!lp->ldinfo_next)
- break;
- lp = (struct ld_info*) ((char *) lp + lp->ldinfo_next);
- }
-
- if (filename)
+ rtl_String * path = NULL;
+ if (getModulePathFromAddress(addr, &path))
{
rtl_uString * workDir = NULL;
osl_getProcessWorkingDir(&workDir);
if (workDir)
{
#if OSL_DEBUG_LEVEL > 1
- OSL_TRACE("module.c::osl_getModuleURLFromAddress - %s", filename);
+ OSL_TRACE("module.c::osl_getModuleURLFromAddress - %s", path->buffer);
#endif
rtl_string2UString(ppLibraryUrl,
- filename,
- strlen(filename),
+ path->buffer,
+ path->length,
osl_getThreadTextEncoding(),
OSTRING_TO_OUSTRING_CVTFLAGS);
@@ -268,41 +327,8 @@ sal_Bool SAL_CALL osl_getModuleURLFromAddress(void * addr, rtl_uString ** ppLibr
{
result = sal_False;
}
+ rtl_string_release(path);
}
-
- free(buf);
-#else
- 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", 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;
- }
- }
-#endif
-#endif
return result;
}
diff --git a/sal/osl/w32/module.cxx b/sal/osl/w32/module.cxx
index b9841ad1e4bd..07f750e49724 100644
--- a/sal/osl/w32/module.cxx
+++ b/sal/osl/w32/module.cxx
@@ -138,6 +138,12 @@ oslModule SAL_CALL osl_loadModuleAscii(const sal_Char *pModuleName, sal_Int32 nR
return ret;
}
+oslModule osl_loadModuleRelativeAscii(
+ oslGenericFunction, char const * relativePath, sal_Int32 mode)
+{
+ return osl_loadModuleAscii(relativePath, mode); //TODO: FIXME
+}
+
/*****************************************************************************/
/* osl_getModuleHandle */
/*****************************************************************************/
diff --git a/sal/textenc/textenc.cxx b/sal/textenc/textenc.cxx
index 7c71284f3f64..c3f3bdc00768 100644
--- a/sal/textenc/textenc.cxx
+++ b/sal/textenc/textenc.cxx
@@ -129,20 +129,12 @@ void SAL_CALL thisModule() {}
class FullTextEncodingData: private boost::noncopyable {
public:
FullTextEncodingData() {
- if (!module_.loadRelative(
- &thisModule,
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM(
- SAL_MODULENAME("sal_textenc")))))
- {
+ if (!module_.loadRelative(&thisModule, SAL_MODULENAME("sal_textenc"))) {
OSL_TRACE("Loading sal_textenc library failed");
std::abort();
}
function_ = reinterpret_cast< TextEncodingFunction * >(
- module_.getFunctionSymbol(
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM(
- "sal_getFullTextEncodingData"))));
+ module_.getFunctionSymbol("sal_getFullTextEncodingData"));
if (function_ == 0) {
OSL_TRACE(
"Obtaining sal_getFullTextEncodingData fuction from sal_textenc"