1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
22 #include <sal/log.hxx>
23 #include <sal/types.h>
24 #include <osl/module.h>
25 #include <osl/thread.h>
26 #include <osl/process.h>
36 #include <osl/detail/android-bootstrap.h>
39 /* implemented in file.c */
40 extern "C" int UnicodeToText(char *, size_t, const sal_Unicode
*, sal_Int32
);
42 static bool getModulePathFromAddress(void * address
, rtl_String
** path
) {
44 // We do want to have this functionality also in the
45 // DISABLE_DYNLOADING case, I think?
48 char *buf
, *filename
=NULL
;
51 if ((buf
= (char*)malloc(size
)) == NULL
)
54 //figure out how big a buffer we need
55 while (loadquery(L_GETINFO
, buf
, size
) == -1 && errno
== ENOMEM
)
59 if ((buf
= (char*)malloc(size
)) == NULL
)
63 lp
= (struct ld_info
*) buf
;
66 unsigned long start
= (unsigned long)lp
->ldinfo_dataorg
;
67 unsigned long end
= start
+ lp
->ldinfo_datasize
;
68 if (start
<= (unsigned long)address
&& end
> (unsigned long)address
)
70 filename
= lp
->ldinfo_filename
;
75 lp
= (struct ld_info
*) ((char *) lp
+ lp
->ldinfo_next
);
80 rtl_string_newFromStr(path
, filename
);
92 #if defined(ANDROID) && !defined(DISABLE_DYNLOADING)
93 result
= lo_dladdr(address
, &dl_info
) != 0;
95 result
= dladdr(address
, &dl_info
) != 0;
100 rtl_string_newFromStr(path
, dl_info
.dli_fname
);
101 #if defined(ANDROID) && !defined(DISABLE_DYNLOADING)
102 free((void *) dl_info
.dli_fname
);
109 #ifndef DISABLE_DYNLOADING
111 /*****************************************************************************/
113 /*****************************************************************************/
115 oslModule SAL_CALL
osl_loadModule(rtl_uString
*ustrModuleName
, sal_Int32 nRtldMode
)
118 rtl_uString
* ustrTmp
= NULL
;
120 SAL_WARN_IF(ustrModuleName
== 0, "sal.osl", "string is not valid");
122 /* ensure ustrTmp hold valid string */
123 if (osl_File_E_None
!= osl_getSystemPathFromFileURL(ustrModuleName
, &ustrTmp
))
124 rtl_uString_assign(&ustrTmp
, ustrModuleName
);
128 char buffer
[PATH_MAX
];
130 if (UnicodeToText(buffer
, PATH_MAX
, ustrTmp
->buffer
, ustrTmp
->length
))
131 pModule
= osl_loadModuleAscii(buffer
, nRtldMode
);
132 rtl_uString_release(ustrTmp
);
138 /*****************************************************************************/
139 /* osl_loadModuleAscii */
140 /*****************************************************************************/
142 oslModule SAL_CALL
osl_loadModuleAscii(const sal_Char
*pModuleName
, sal_Int32 nRtldMode
)
145 ((nRtldMode
& SAL_LOADMODULE_LAZY
) != 0
146 && (nRtldMode
& SAL_LOADMODULE_NOW
) != 0),
147 "sal.osl", "only either LAZY or NOW");
152 void *pLib
= lo_dlopen(pModuleName
);
155 ((nRtldMode
& SAL_LOADMODULE_NOW
) ? RTLD_NOW
: RTLD_LAZY
) |
156 ((nRtldMode
& SAL_LOADMODULE_GLOBAL
) ? RTLD_GLOBAL
: RTLD_LOCAL
);
157 void* pLib
= dlopen(pModuleName
, rtld_mode
);
160 pLib
== 0, "sal.osl",
161 "dlopen(" << pModuleName
<< ", " << rtld_mode
<< "): "
164 return ((oslModule
)(pLib
));
169 oslModule
osl_loadModuleRelativeAscii(
170 oslGenericFunction baseModule
, char const * relativePath
, sal_Int32 mode
)
172 SAL_WARN_IF(relativePath
== 0, "sal.osl", "illegal argument");
173 if (relativePath
[0] == '/') {
174 return osl_loadModuleAscii(relativePath
, mode
);
176 rtl_String
* path
= NULL
;
177 rtl_String
* suffix
= NULL
;
179 if (!getModulePathFromAddress(
180 reinterpret_cast< void * >(baseModule
), &path
))
184 rtl_string_newFromStr_WithLength(
186 (rtl_str_lastIndexOfChar_WithLength(path
->buffer
, path
->length
, '/')
188 /* cut off everything after the last slash; should the original path
189 contain no slash, the resulting path is the empty string */
190 rtl_string_newFromStr(&suffix
, relativePath
);
191 rtl_string_newConcat(&path
, path
, suffix
);
192 rtl_string_release(suffix
);
193 module
= osl_loadModuleAscii(path
->buffer
, mode
);
194 rtl_string_release(path
);
199 #endif // !DISABLE_DYNLOADING
201 /*****************************************************************************/
202 /* osl_getModuleHandle */
203 /*****************************************************************************/
206 osl_getModuleHandle(rtl_uString
*, oslModule
*pResult
)
208 #if !defined(DISABLE_DYNLOADING) || defined(IOS)
209 *pResult
= (oslModule
) RTLD_DEFAULT
;
216 #ifndef DISABLE_DYNLOADING
218 /*****************************************************************************/
219 /* osl_unloadModule */
220 /*****************************************************************************/
221 void SAL_CALL
osl_unloadModule(oslModule hModule
)
226 int nRet
= lo_dlclose(hModule
);
228 int nRet
= dlclose(hModule
);
231 nRet
!= 0, "sal.osl", "dlclose(" << hModule
<< "): " << dlerror());
235 #endif // !DISABLE_DYNLOADING
237 /*****************************************************************************/
239 /*****************************************************************************/
241 osl_getSymbol(oslModule Module
, rtl_uString
* pSymbolName
)
243 return (void *) osl_getFunctionSymbol(Module
, pSymbolName
);
246 /*****************************************************************************/
247 /* osl_getAsciiFunctionSymbol */
248 /*****************************************************************************/
249 oslGenericFunction SAL_CALL
250 osl_getAsciiFunctionSymbol(oslModule Module
, const sal_Char
*pSymbol
)
252 void *fcnAddr
= NULL
;
254 // We do want to use dlsym() also in the DISABLE_DYNLOADING case
255 // just to look up symbols in the static executable, I think.
258 fcnAddr
= dlsym(Module
, pSymbol
);
260 fcnAddr
== 0, "sal.osl",
261 "dlsym(" << Module
<< ", " << pSymbol
<< "): " << dlerror());
264 return (oslGenericFunction
) fcnAddr
;
267 /*****************************************************************************/
268 /* osl_getFunctionSymbol */
269 /*****************************************************************************/
270 oslGenericFunction SAL_CALL
271 osl_getFunctionSymbol(oslModule module
, rtl_uString
*puFunctionSymbolName
)
273 oslGenericFunction pSymbol
= NULL
;
275 if( puFunctionSymbolName
)
277 rtl_String
* pSymbolName
= NULL
;
279 rtl_uString2String( &pSymbolName
,
280 rtl_uString_getStr(puFunctionSymbolName
),
281 rtl_uString_getLength(puFunctionSymbolName
),
282 RTL_TEXTENCODING_UTF8
,
283 OUSTRING_TO_OSTRING_CVTFLAGS
);
285 if( pSymbolName
!= NULL
)
287 pSymbol
= osl_getAsciiFunctionSymbol(module
, rtl_string_getStr(pSymbolName
));
288 rtl_string_release(pSymbolName
);
295 /*****************************************************************************/
296 /* osl_getModuleURLFromAddress */
297 /*****************************************************************************/
298 sal_Bool SAL_CALL
osl_getModuleURLFromAddress(void * addr
, rtl_uString
** ppLibraryUrl
)
301 rtl_String
* path
= NULL
;
302 if (getModulePathFromAddress(addr
, &path
))
304 rtl_uString
* workDir
= NULL
;
305 osl_getProcessWorkingDir(&workDir
);
309 "sal.osl", "osl_getModuleURLFromAddress: " << path
->buffer
);
310 rtl_string2UString(ppLibraryUrl
,
313 osl_getThreadTextEncoding(),
314 OSTRING_TO_OUSTRING_CVTFLAGS
);
317 *ppLibraryUrl
== 0, "sal.osl", "rtl_string2UString failed");
318 osl_getFileURLFromSystemPath(*ppLibraryUrl
, ppLibraryUrl
);
319 osl_getAbsoluteFileURL(workDir
, *ppLibraryUrl
, ppLibraryUrl
);
321 rtl_uString_release(workDir
);
328 rtl_string_release(path
);
333 /*****************************************************************************/
334 /* osl_getModuleURLFromFunctionAddress */
335 /*****************************************************************************/
336 sal_Bool SAL_CALL
osl_getModuleURLFromFunctionAddress(oslGenericFunction addr
, rtl_uString
** ppLibraryUrl
)
338 return osl_getModuleURLFromAddress((void*)addr
, ppLibraryUrl
);
341 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */