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 sal_Bool
getModulePathFromAddress(void * address
, rtl_String
** path
) {
43 sal_Bool result
= sal_False
;
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
);
95 result
= dladdr(address
, &dl_info
);
100 rtl_string_newFromStr(path
, dl_info
.dli_fname
);
101 #if defined(ANDROID) && !defined(DISABLE_DYNLOADING)
102 free((void *) dl_info
.dli_fname
);
115 #ifndef DISABLE_DYNLOADING
117 /*****************************************************************************/
119 /*****************************************************************************/
121 oslModule SAL_CALL
osl_loadModule(rtl_uString
*ustrModuleName
, sal_Int32 nRtldMode
)
124 rtl_uString
* ustrTmp
= NULL
;
126 SAL_WARN_IF(ustrModuleName
== 0, "sal.osl", "string is not valid");
128 /* ensure ustrTmp hold valid string */
129 if (osl_File_E_None
!= osl_getSystemPathFromFileURL(ustrModuleName
, &ustrTmp
))
130 rtl_uString_assign(&ustrTmp
, ustrModuleName
);
134 char buffer
[PATH_MAX
];
136 if (UnicodeToText(buffer
, PATH_MAX
, ustrTmp
->buffer
, ustrTmp
->length
))
137 pModule
= osl_loadModuleAscii(buffer
, nRtldMode
);
138 rtl_uString_release(ustrTmp
);
144 /*****************************************************************************/
145 /* osl_loadModuleAscii */
146 /*****************************************************************************/
148 oslModule SAL_CALL
osl_loadModuleAscii(const sal_Char
*pModuleName
, sal_Int32 nRtldMode
)
151 ((nRtldMode
& SAL_LOADMODULE_LAZY
) != 0
152 && (nRtldMode
& SAL_LOADMODULE_NOW
) != 0),
153 "sal.osl", "only either LAZY or NOW");
158 void *pLib
= lo_dlopen(pModuleName
);
161 ((nRtldMode
& SAL_LOADMODULE_NOW
) ? RTLD_NOW
: RTLD_LAZY
) |
162 ((nRtldMode
& SAL_LOADMODULE_GLOBAL
) ? RTLD_GLOBAL
: RTLD_LOCAL
);
163 void* pLib
= dlopen(pModuleName
, rtld_mode
);
166 pLib
== 0, "sal.osl",
167 "dlopen(" << pModuleName
<< ", " << rtld_mode
<< "): "
170 return ((oslModule
)(pLib
));
175 oslModule
osl_loadModuleRelativeAscii(
176 oslGenericFunction baseModule
, char const * relativePath
, sal_Int32 mode
)
178 SAL_WARN_IF(relativePath
== 0, "sal.osl", "illegal argument");
179 if (relativePath
[0] == '/') {
180 return osl_loadModuleAscii(relativePath
, mode
);
182 rtl_String
* path
= NULL
;
183 rtl_String
* suffix
= NULL
;
185 if (!getModulePathFromAddress(
186 reinterpret_cast< void * >(baseModule
), &path
))
190 rtl_string_newFromStr_WithLength(
192 (rtl_str_lastIndexOfChar_WithLength(path
->buffer
, path
->length
, '/')
194 /* cut off everything after the last slash; should the original path
195 contain no slash, the resulting path is the empty string */
196 rtl_string_newFromStr(&suffix
, relativePath
);
197 rtl_string_newConcat(&path
, path
, suffix
);
198 rtl_string_release(suffix
);
199 module
= osl_loadModuleAscii(path
->buffer
, mode
);
200 rtl_string_release(path
);
205 #endif // !DISABLE_DYNLOADING
207 /*****************************************************************************/
208 /* osl_getModuleHandle */
209 /*****************************************************************************/
212 osl_getModuleHandle(rtl_uString
*, oslModule
*pResult
)
214 #if !defined(DISABLE_DYNLOADING) || defined(IOS)
215 *pResult
= (oslModule
) RTLD_DEFAULT
;
222 #ifndef DISABLE_DYNLOADING
224 /*****************************************************************************/
225 /* osl_unloadModule */
226 /*****************************************************************************/
227 void SAL_CALL
osl_unloadModule(oslModule hModule
)
232 int nRet
= lo_dlclose(hModule
);
234 int nRet
= dlclose(hModule
);
237 nRet
!= 0, "sal.osl", "dlclose(" << hModule
<< "): " << dlerror());
241 #endif // !DISABLE_DYNLOADING
243 /*****************************************************************************/
245 /*****************************************************************************/
247 osl_getSymbol(oslModule Module
, rtl_uString
* pSymbolName
)
249 return (void *) osl_getFunctionSymbol(Module
, pSymbolName
);
253 /*****************************************************************************/
254 /* osl_getAsciiFunctionSymbol */
255 /*****************************************************************************/
256 oslGenericFunction SAL_CALL
257 osl_getAsciiFunctionSymbol(oslModule Module
, const sal_Char
*pSymbol
)
259 void *fcnAddr
= NULL
;
261 // We do want to use dlsym() also in the DISABLE_DYNLOADING case
262 // just to look up symbols in the static executable, I think.
265 fcnAddr
= dlsym(Module
, pSymbol
);
267 fcnAddr
== 0, "sal.osl",
268 "dlsym(" << Module
<< ", " << pSymbol
<< "): " << dlerror());
271 return (oslGenericFunction
) fcnAddr
;
274 /*****************************************************************************/
275 /* osl_getFunctionSymbol */
276 /*****************************************************************************/
277 oslGenericFunction SAL_CALL
278 osl_getFunctionSymbol(oslModule module
, rtl_uString
*puFunctionSymbolName
)
280 oslGenericFunction pSymbol
= NULL
;
282 if( puFunctionSymbolName
)
284 rtl_String
* pSymbolName
= NULL
;
286 rtl_uString2String( &pSymbolName
,
287 rtl_uString_getStr(puFunctionSymbolName
),
288 rtl_uString_getLength(puFunctionSymbolName
),
289 RTL_TEXTENCODING_UTF8
,
290 OUSTRING_TO_OSTRING_CVTFLAGS
);
292 if( pSymbolName
!= NULL
)
294 pSymbol
= osl_getAsciiFunctionSymbol(module
, rtl_string_getStr(pSymbolName
));
295 rtl_string_release(pSymbolName
);
302 /*****************************************************************************/
303 /* osl_getModuleURLFromAddress */
304 /*****************************************************************************/
305 sal_Bool SAL_CALL
osl_getModuleURLFromAddress(void * addr
, rtl_uString
** ppLibraryUrl
)
307 sal_Bool result
= sal_False
;
308 rtl_String
* path
= NULL
;
309 if (getModulePathFromAddress(addr
, &path
))
311 rtl_uString
* workDir
= NULL
;
312 osl_getProcessWorkingDir(&workDir
);
316 "sal.osl", "osl_getModuleURLFromAddress: " << path
->buffer
);
317 rtl_string2UString(ppLibraryUrl
,
320 osl_getThreadTextEncoding(),
321 OSTRING_TO_OUSTRING_CVTFLAGS
);
324 *ppLibraryUrl
== 0, "sal.osl", "rtl_string2UString failed");
325 osl_getFileURLFromSystemPath(*ppLibraryUrl
, ppLibraryUrl
);
326 osl_getAbsoluteFileURL(workDir
, *ppLibraryUrl
, ppLibraryUrl
);
328 rtl_uString_release(workDir
);
335 rtl_string_release(path
);
340 /*****************************************************************************/
341 /* osl_getModuleURLFromFunctionAddress */
342 /*****************************************************************************/
343 sal_Bool SAL_CALL
osl_getModuleURLFromFunctionAddress(oslGenericFunction addr
, rtl_uString
** ppLibraryUrl
)
345 return osl_getModuleURLFromAddress((void*)addr
, ppLibraryUrl
);
348 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */