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>
45 #include <osl/detail/android-bootstrap.h>
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?
57 char *buf
, *filename
=NULL
;
60 if ((buf
= malloc(size
)) == NULL
)
63 while(loadquery(L_GETINFO
, buf
, size
) == -1 && errno
== ENOMEM
)
66 if ((buf
= malloc(size
)) == NULL
)
70 lp
= (struct ld_info
*) buf
;
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
;
82 lp
= (struct ld_info
*) ((char *) lp
+ lp
->ldinfo_next
);
87 rtl_string_newFromStr(path
, filename
);
100 result
= lo_dladdr(address
, &dl_info
);
102 result
= dladdr(address
, &dl_info
);
107 rtl_string_newFromStr(path
, dl_info
.dli_fname
);
109 free((void *) dl_info
.dli_fname
);
121 /*****************************************************************************/
123 /*****************************************************************************/
125 oslModule SAL_CALL
osl_loadModule(rtl_uString
*ustrModuleName
, sal_Int32 nRtldMode
)
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
);
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
);
148 /*****************************************************************************/
149 /* osl_loadModuleAscii */
150 /*****************************************************************************/
152 oslModule SAL_CALL
osl_loadModuleAscii(const sal_Char
*pModuleName
, sal_Int32 nRtldMode
)
155 ((nRtldMode
& SAL_LOADMODULE_LAZY
) != 0
156 && (nRtldMode
& SAL_LOADMODULE_NOW
) != 0),
157 "sal.osl", "only either LAZY or NOW");
160 #ifndef DISABLE_DYNLOADING
163 void *pLib
= lo_dlopen(pModuleName
);
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
);
171 pLib
== 0, "sal.osl",
172 "dlopen(" << pModuleName
<< ", " << rtld_mode
<< "): "
175 return ((oslModule
)(pLib
));
177 #else /* DISABLE_DYNLOADING */
179 fprintf(stderr
, "No DL Functions, osl_loadModuleAscii(%s) does nothing\n", pModuleName
);
180 #endif /* DISABLE_DYNLOADING */
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
);
192 rtl_String
* path
= NULL
;
193 rtl_String
* suffix
= NULL
;
195 if (!getModulePathFromAddress(
196 reinterpret_cast< void * >(baseModule
), &path
))
200 rtl_string_newFromStr_WithLength(
202 (rtl_str_lastIndexOfChar_WithLength(path
->buffer
, path
->length
, '/')
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
);
215 /*****************************************************************************/
216 /* osl_getModuleHandle */
217 /*****************************************************************************/
220 osl_getModuleHandle(rtl_uString
*, oslModule
*pResult
)
222 #if !defined(DISABLE_DYNLOADING) || defined(IOS)
223 *pResult
= (oslModule
) RTLD_DEFAULT
;
230 /*****************************************************************************/
231 /* osl_unloadModule */
232 /*****************************************************************************/
233 void SAL_CALL
osl_unloadModule(oslModule hModule
)
237 #ifndef DISABLE_DYNLOADING
239 int nRet
= lo_dlclose(hModule
);
241 int nRet
= dlclose(hModule
);
244 nRet
!= 0, "sal.osl", "dlclose(" << hModule
<< "): " << dlerror());
245 #endif /* ifndef DISABLE_DYNLOADING */
249 /*****************************************************************************/
251 /*****************************************************************************/
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.
271 fcnAddr
= dlsym(Module
, pSymbol
);
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
);
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
);
322 "sal.osl", "osl_getModuleURLFromAddress: " << path
->buffer
);
323 rtl_string2UString(ppLibraryUrl
,
326 osl_getThreadTextEncoding(),
327 OSTRING_TO_OUSTRING_CVTFLAGS
);
330 *ppLibraryUrl
== 0, "sal.osl", "rtl_string2UString failed");
331 osl_getFileURLFromSystemPath(*ppLibraryUrl
, ppLibraryUrl
);
332 osl_getAbsoluteFileURL(workDir
, *ppLibraryUrl
, ppLibraryUrl
);
334 rtl_uString_release(workDir
);
341 rtl_string_release(path
);
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: */