Bump for 3.6-28
[LibreOffice.git] / sal / osl / unx / module.cxx
bloba68a105e7fb7a4cb3fbc0edb8e7f0c1e1e365ee9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "sal/config.h"
31 #include <sal/log.hxx>
32 #include <sal/types.h>
33 #include <osl/module.h>
34 #include <osl/thread.h>
35 #include <osl/process.h>
36 #include <osl/file.h>
38 #include "system.h"
40 #ifdef AIX
41 #include <sys/ldr.h>
42 #endif
44 #ifdef ANDROID
45 #include <osl/detail/android-bootstrap.h>
46 #endif
48 /* implemented in file.c */
49 extern "C" int UnicodeToText(char *, size_t, const sal_Unicode *, sal_Int32);
51 static sal_Bool getModulePathFromAddress(void * address, rtl_String ** path) {
52 sal_Bool result = sal_False;
53 // We do want to have this functionality also in the
54 // DISABLE_DYNLOADING case, I think?
55 #if defined(AIX)
56 int size = 4 * 1024;
57 char *buf, *filename=NULL;
58 struct ld_info *lp;
60 if ((buf = malloc(size)) == NULL)
61 return result;
63 while(loadquery(L_GETINFO, buf, size) == -1 && errno == ENOMEM)
65 size += 4 * 1024;
66 if ((buf = malloc(size)) == NULL)
67 break;
70 lp = (struct ld_info*) buf;
71 while (lp)
73 unsigned long start = (unsigned long)lp->ldinfo_dataorg;
74 unsigned long end = start + lp->ldinfo_datasize;
75 if (start <= (unsigned long)address && end > (unsigned long)address)
77 filename = lp->ldinfo_filename;
78 break;
80 if (!lp->ldinfo_next)
81 break;
82 lp = (struct ld_info*) ((char *) lp + lp->ldinfo_next);
85 if (filename)
87 rtl_string_newFromStr(path, filename);
88 result = sal_True;
90 else
92 result = sal_False;
95 free(buf);
96 #else
97 Dl_info dl_info;
99 #ifdef ANDROID
100 result = lo_dladdr(address, &dl_info);
101 #else
102 result = dladdr(address, &dl_info);
103 #endif
105 if (result != 0)
107 rtl_string_newFromStr(path, dl_info.dli_fname);
108 #ifdef ANDROID
109 free((void *) dl_info.dli_fname);
110 #endif
111 result = sal_True;
113 else
115 result = sal_False;
117 #endif
118 return result;
121 /*****************************************************************************/
122 /* osl_loadModule */
123 /*****************************************************************************/
125 oslModule SAL_CALL osl_loadModule(rtl_uString *ustrModuleName, sal_Int32 nRtldMode)
127 oslModule pModule=0;
128 rtl_uString* ustrTmp = NULL;
130 SAL_WARN_IF(ustrModuleName == 0, "sal.osl", "string is not valid");
132 /* ensure ustrTmp hold valid string */
133 if (osl_File_E_None != osl_getSystemPathFromFileURL(ustrModuleName, &ustrTmp))
134 rtl_uString_assign(&ustrTmp, ustrModuleName);
136 if (ustrTmp)
138 char buffer[PATH_MAX];
140 if (UnicodeToText(buffer, PATH_MAX, ustrTmp->buffer, ustrTmp->length))
141 pModule = osl_loadModuleAscii(buffer, nRtldMode);
142 rtl_uString_release(ustrTmp);
145 return pModule;
148 /*****************************************************************************/
149 /* osl_loadModuleAscii */
150 /*****************************************************************************/
152 oslModule SAL_CALL osl_loadModuleAscii(const sal_Char *pModuleName, sal_Int32 nRtldMode)
154 SAL_WARN_IF(
155 ((nRtldMode & SAL_LOADMODULE_LAZY) != 0
156 && (nRtldMode & SAL_LOADMODULE_NOW) != 0),
157 "sal.osl", "only either LAZY or NOW");
158 if (pModuleName)
160 #ifndef DISABLE_DYNLOADING
161 #ifdef ANDROID
162 (void) nRtldMode;
163 void *pLib = lo_dlopen(pModuleName);
164 #else
165 int rtld_mode =
166 ((nRtldMode & SAL_LOADMODULE_NOW) ? RTLD_NOW : RTLD_LAZY) |
167 ((nRtldMode & SAL_LOADMODULE_GLOBAL) ? RTLD_GLOBAL : RTLD_LOCAL);
168 void* pLib = dlopen(pModuleName, rtld_mode);
170 SAL_INFO_IF(
171 pLib == 0, "sal.osl",
172 "dlopen(" << pModuleName << ", " << rtld_mode << "): "
173 << dlerror());
174 #endif
175 return ((oslModule)(pLib));
177 #else /* DISABLE_DYNLOADING */
178 (void) nRtldMode;
179 fprintf(stderr, "No DL Functions, osl_loadModuleAscii(%s) does nothing\n", pModuleName);
180 #endif /* DISABLE_DYNLOADING */
182 return NULL;
185 oslModule osl_loadModuleRelativeAscii(
186 oslGenericFunction baseModule, char const * relativePath, sal_Int32 mode)
188 SAL_WARN_IF(relativePath == 0, "sal.osl", "illegal argument");
189 if (relativePath[0] == '/') {
190 return osl_loadModuleAscii(relativePath, mode);
191 } else {
192 rtl_String * path = NULL;
193 rtl_String * suffix = NULL;
194 oslModule module;
195 if (!getModulePathFromAddress(
196 reinterpret_cast< void * >(baseModule), &path))
198 return NULL;
200 rtl_string_newFromStr_WithLength(
201 &path, path->buffer,
202 (rtl_str_lastIndexOfChar_WithLength(path->buffer, path->length, '/')
203 + 1));
204 /* cut off everything after the last slash; should the original path
205 contain no slash, the resulting path is the empty string */
206 rtl_string_newFromStr(&suffix, relativePath);
207 rtl_string_newConcat(&path, path, suffix);
208 rtl_string_release(suffix);
209 module = osl_loadModuleAscii(path->buffer, mode);
210 rtl_string_release(path);
211 return module;
215 /*****************************************************************************/
216 /* osl_getModuleHandle */
217 /*****************************************************************************/
219 sal_Bool SAL_CALL
220 osl_getModuleHandle(rtl_uString *, oslModule *pResult)
222 #if !defined(DISABLE_DYNLOADING) || defined(IOS)
223 *pResult = (oslModule) RTLD_DEFAULT;
224 #else
225 *pResult = NULL;
226 #endif
227 return sal_True;
230 /*****************************************************************************/
231 /* osl_unloadModule */
232 /*****************************************************************************/
233 void SAL_CALL osl_unloadModule(oslModule hModule)
235 if (hModule)
237 #ifndef DISABLE_DYNLOADING
238 #ifdef ANDROID
239 int nRet = lo_dlclose(hModule);
240 #else
241 int nRet = dlclose(hModule);
242 #endif
243 SAL_INFO_IF(
244 nRet != 0, "sal.osl", "dlclose(" << hModule << "): " << dlerror());
245 #endif /* ifndef DISABLE_DYNLOADING */
249 /*****************************************************************************/
250 /* osl_getSymbol */
251 /*****************************************************************************/
252 void* SAL_CALL
253 osl_getSymbol(oslModule Module, rtl_uString* pSymbolName)
255 return (void *) osl_getFunctionSymbol(Module, pSymbolName);
259 /*****************************************************************************/
260 /* osl_getAsciiFunctionSymbol */
261 /*****************************************************************************/
262 oslGenericFunction SAL_CALL
263 osl_getAsciiFunctionSymbol(oslModule Module, const sal_Char *pSymbol)
265 void *fcnAddr = NULL;
267 // We do want to use dlsym() also in the DISABLE_DYNLOADING case
268 // just to look up symbols in the static executable, I think.
269 if (pSymbol)
271 fcnAddr = dlsym(Module, pSymbol);
272 SAL_INFO_IF(
273 fcnAddr == 0, "sal.osl",
274 "dlsym(" << Module << ", " << pSymbol << "): " << dlerror());
277 return (oslGenericFunction) fcnAddr;
280 /*****************************************************************************/
281 /* osl_getFunctionSymbol */
282 /*****************************************************************************/
283 oslGenericFunction SAL_CALL
284 osl_getFunctionSymbol(oslModule module, rtl_uString *puFunctionSymbolName)
286 oslGenericFunction pSymbol = NULL;
288 if( puFunctionSymbolName )
290 rtl_String* pSymbolName = NULL;
292 rtl_uString2String( &pSymbolName,
293 rtl_uString_getStr(puFunctionSymbolName),
294 rtl_uString_getLength(puFunctionSymbolName),
295 RTL_TEXTENCODING_UTF8,
296 OUSTRING_TO_OSTRING_CVTFLAGS );
298 if( pSymbolName != NULL )
300 pSymbol = osl_getAsciiFunctionSymbol(module, rtl_string_getStr(pSymbolName));
301 rtl_string_release(pSymbolName);
305 return pSymbol;
308 /*****************************************************************************/
309 /* osl_getModuleURLFromAddress */
310 /*****************************************************************************/
311 sal_Bool SAL_CALL osl_getModuleURLFromAddress(void * addr, rtl_uString ** ppLibraryUrl)
313 sal_Bool result = sal_False;
314 rtl_String * path = NULL;
315 if (getModulePathFromAddress(addr, &path))
317 rtl_uString * workDir = NULL;
318 osl_getProcessWorkingDir(&workDir);
319 if (workDir)
321 SAL_INFO(
322 "sal.osl", "osl_getModuleURLFromAddress: " << path->buffer);
323 rtl_string2UString(ppLibraryUrl,
324 path->buffer,
325 path->length,
326 osl_getThreadTextEncoding(),
327 OSTRING_TO_OUSTRING_CVTFLAGS);
329 SAL_WARN_IF(
330 *ppLibraryUrl == 0, "sal.osl", "rtl_string2UString failed");
331 osl_getFileURLFromSystemPath(*ppLibraryUrl, ppLibraryUrl);
332 osl_getAbsoluteFileURL(workDir, *ppLibraryUrl, ppLibraryUrl);
334 rtl_uString_release(workDir);
335 result = sal_True;
337 else
339 result = sal_False;
341 rtl_string_release(path);
343 return result;
346 /*****************************************************************************/
347 /* osl_getModuleURLFromFunctionAddress */
348 /*****************************************************************************/
349 sal_Bool SAL_CALL osl_getModuleURLFromFunctionAddress(oslGenericFunction addr, rtl_uString ** ppLibraryUrl)
351 return osl_getModuleURLFromAddress((void*)addr, ppLibraryUrl);
354 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */