[Libreoffice-commits] .: sal/inc sal/osl sal/textenc

Stephan Bergmann sbergmann at kemper.freedesktop.org
Tue Sep 27 01:11:15 PDT 2011


 sal/inc/osl/module.h    |   24 ++++++
 sal/inc/osl/module.hxx  |   15 ++++
 sal/osl/unx/module.c    |  168 +++++++++++++++++++++++++++---------------------
 sal/osl/w32/module.cxx  |    6 +
 sal/textenc/textenc.cxx |   12 ---
 5 files changed, 144 insertions(+), 81 deletions(-)

New commits:
commit 193715bbf0e59256fd8da7ebd8dc5eb937615281
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Tue Sep 27 10:06:54 2011 +0200

    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.

diff --git a/sal/inc/osl/module.h b/sal/inc/osl/module.h
index c103e41..6784232 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 cfc1c5e..3ece623 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 63fbc20..7db8011 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 b9841ad..07f750e 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 7c71284..c3f3bdc 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"


More information about the Libreoffice-commits mailing list