Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "sal/config.h"
30 : :
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>
37 : :
38 : : #include "system.h"
39 : :
40 : : #ifdef AIX
41 : : #include <sys/ldr.h>
42 : : #endif
43 : :
44 : : #ifdef ANDROID
45 : : #include <osl/detail/android-bootstrap.h>
46 : : #endif
47 : :
48 : : /* implemented in file.c */
49 : : extern "C" int UnicodeToText(char *, size_t, const sal_Unicode *, sal_Int32);
50 : :
51 : 40721 : static sal_Bool getModulePathFromAddress(void * address, rtl_String ** path) {
52 : 40721 : 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;
59 : :
60 : : if ((buf = malloc(size)) == NULL)
61 : : return result;
62 : :
63 : : while(loadquery(L_GETINFO, buf, size) == -1 && errno == ENOMEM)
64 : : {
65 : : size += 4 * 1024;
66 : : if ((buf = malloc(size)) == NULL)
67 : : break;
68 : : }
69 : :
70 : : lp = (struct ld_info*) buf;
71 : : while (lp)
72 : : {
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)
76 : : {
77 : : filename = lp->ldinfo_filename;
78 : : break;
79 : : }
80 : : if (!lp->ldinfo_next)
81 : : break;
82 : : lp = (struct ld_info*) ((char *) lp + lp->ldinfo_next);
83 : : }
84 : :
85 : : if (filename)
86 : : {
87 : : rtl_string_newFromStr(path, filename);
88 : : result = sal_True;
89 : : }
90 : : else
91 : : {
92 : : result = sal_False;
93 : : }
94 : :
95 : : free(buf);
96 : : #else
97 : : Dl_info dl_info;
98 : :
99 : : #ifdef ANDROID
100 : : result = lo_dladdr(address, &dl_info);
101 : : #else
102 : 40721 : result = dladdr(address, &dl_info);
103 : : #endif
104 : :
105 [ + - ]: 40721 : if (result != 0)
106 : : {
107 : 40721 : rtl_string_newFromStr(path, dl_info.dli_fname);
108 : : #ifdef ANDROID
109 : : free((void *) dl_info.dli_fname);
110 : : #endif
111 : 40721 : result = sal_True;
112 : : }
113 : : else
114 : : {
115 : 0 : result = sal_False;
116 : : }
117 : : #endif
118 : 40721 : return result;
119 : : }
120 : :
121 : : /*****************************************************************************/
122 : : /* osl_loadModule */
123 : : /*****************************************************************************/
124 : :
125 : 69865 : oslModule SAL_CALL osl_loadModule(rtl_uString *ustrModuleName, sal_Int32 nRtldMode)
126 : : {
127 : 69865 : oslModule pModule=0;
128 : 69865 : rtl_uString* ustrTmp = NULL;
129 : :
130 : : SAL_WARN_IF(ustrModuleName == 0, "sal.osl", "string is not valid");
131 : :
132 : : /* ensure ustrTmp hold valid string */
133 [ + - ][ - + ]: 69865 : if (osl_File_E_None != osl_getSystemPathFromFileURL(ustrModuleName, &ustrTmp))
134 : 0 : rtl_uString_assign(&ustrTmp, ustrModuleName);
135 : :
136 [ + - ]: 69865 : if (ustrTmp)
137 : : {
138 : : char buffer[PATH_MAX];
139 : :
140 [ + - ][ + - ]: 69865 : if (UnicodeToText(buffer, PATH_MAX, ustrTmp->buffer, ustrTmp->length))
141 [ + - ]: 69865 : pModule = osl_loadModuleAscii(buffer, nRtldMode);
142 : 69865 : rtl_uString_release(ustrTmp);
143 : : }
144 : :
145 : 69865 : return pModule;
146 : : }
147 : :
148 : : /*****************************************************************************/
149 : : /* osl_loadModuleAscii */
150 : : /*****************************************************************************/
151 : :
152 : 69967 : oslModule SAL_CALL osl_loadModuleAscii(const sal_Char *pModuleName, sal_Int32 nRtldMode)
153 : : {
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 [ + - ]: 69967 : if (pModuleName)
159 : : {
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 [ + + ]: 69967 : ((nRtldMode & SAL_LOADMODULE_GLOBAL) ? RTLD_GLOBAL : RTLD_LOCAL);
168 : 69967 : void* pLib = dlopen(pModuleName, rtld_mode);
169 : :
170 : : SAL_INFO_IF(
171 : : pLib == 0, "sal.osl",
172 : : "dlopen(" << pModuleName << ", " << rtld_mode << "): "
173 : : << dlerror());
174 : : #endif
175 : 69967 : return ((oslModule)(pLib));
176 : :
177 : : #else /* DISABLE_DYNLOADING */
178 : : (void) nRtldMode;
179 : : fprintf(stderr, "No DL Functions, osl_loadModuleAscii(%s) does nothing\n", pModuleName);
180 : : #endif /* DISABLE_DYNLOADING */
181 : : }
182 : 69967 : return NULL;
183 : : }
184 : :
185 : 102 : oslModule osl_loadModuleRelativeAscii(
186 : : oslGenericFunction baseModule, char const * relativePath, sal_Int32 mode)
187 : : {
188 : : SAL_WARN_IF(relativePath == 0, "sal.osl", "illegal argument");
189 [ - + ]: 102 : if (relativePath[0] == '/') {
190 : 0 : return osl_loadModuleAscii(relativePath, mode);
191 : : } else {
192 : 102 : rtl_String * path = NULL;
193 : 102 : rtl_String * suffix = NULL;
194 : : oslModule module;
195 [ - + ]: 102 : if (!getModulePathFromAddress(
196 : 102 : reinterpret_cast< void * >(baseModule), &path))
197 : : {
198 : 0 : return NULL;
199 : : }
200 : : rtl_string_newFromStr_WithLength(
201 : : &path, path->buffer,
202 : 102 : (rtl_str_lastIndexOfChar_WithLength(path->buffer, path->length, '/')
203 : 102 : + 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 : 102 : rtl_string_newFromStr(&suffix, relativePath);
207 : 102 : rtl_string_newConcat(&path, path, suffix);
208 : 102 : rtl_string_release(suffix);
209 [ + - ]: 102 : module = osl_loadModuleAscii(path->buffer, mode);
210 : 102 : rtl_string_release(path);
211 : 102 : return module;
212 : : }
213 : : }
214 : :
215 : : /*****************************************************************************/
216 : : /* osl_getModuleHandle */
217 : : /*****************************************************************************/
218 : :
219 : : sal_Bool SAL_CALL
220 : 0 : osl_getModuleHandle(rtl_uString *, oslModule *pResult)
221 : : {
222 : : #if !defined(DISABLE_DYNLOADING) || defined(IOS)
223 : 0 : *pResult = (oslModule) RTLD_DEFAULT;
224 : : #else
225 : : *pResult = NULL;
226 : : #endif
227 : 0 : return sal_True;
228 : : }
229 : :
230 : : /*****************************************************************************/
231 : : /* osl_unloadModule */
232 : : /*****************************************************************************/
233 : 20488 : void SAL_CALL osl_unloadModule(oslModule hModule)
234 : : {
235 [ + + ]: 20488 : if (hModule)
236 : : {
237 : : #ifndef DISABLE_DYNLOADING
238 : : #ifdef ANDROID
239 : : int nRet = lo_dlclose(hModule);
240 : : #else
241 : 20334 : int nRet = dlclose(hModule);
242 : : #endif
243 : : SAL_INFO_IF(
244 : : nRet != 0, "sal.osl", "dlclose(" << hModule << "): " << dlerror());
245 : : #endif /* ifndef DISABLE_DYNLOADING */
246 : : }
247 : 20488 : }
248 : :
249 : : /*****************************************************************************/
250 : : /* osl_getSymbol */
251 : : /*****************************************************************************/
252 : : void* SAL_CALL
253 : 15 : osl_getSymbol(oslModule Module, rtl_uString* pSymbolName)
254 : : {
255 : 15 : return (void *) osl_getFunctionSymbol(Module, pSymbolName);
256 : : }
257 : :
258 : :
259 : : /*****************************************************************************/
260 : : /* osl_getAsciiFunctionSymbol */
261 : : /*****************************************************************************/
262 : : oslGenericFunction SAL_CALL
263 : 711801 : osl_getAsciiFunctionSymbol(oslModule Module, const sal_Char *pSymbol)
264 : : {
265 : 711801 : void *fcnAddr = NULL;
266 : :
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 [ + - ]: 711801 : if (pSymbol)
270 : : {
271 : 711801 : fcnAddr = dlsym(Module, pSymbol);
272 : : SAL_INFO_IF(
273 : : fcnAddr == 0, "sal.osl",
274 : : "dlsym(" << Module << ", " << pSymbol << "): " << dlerror());
275 : : }
276 : :
277 : 711801 : return (oslGenericFunction) fcnAddr;
278 : : }
279 : :
280 : : /*****************************************************************************/
281 : : /* osl_getFunctionSymbol */
282 : : /*****************************************************************************/
283 : : oslGenericFunction SAL_CALL
284 : 711140 : osl_getFunctionSymbol(oslModule module, rtl_uString *puFunctionSymbolName)
285 : : {
286 : 711140 : oslGenericFunction pSymbol = NULL;
287 : :
288 [ + - ]: 711140 : if( puFunctionSymbolName )
289 : : {
290 : 711140 : rtl_String* pSymbolName = NULL;
291 : :
292 : : rtl_uString2String( &pSymbolName,
293 : 711140 : rtl_uString_getStr(puFunctionSymbolName),
294 : : rtl_uString_getLength(puFunctionSymbolName),
295 : : RTL_TEXTENCODING_UTF8,
296 : 1422280 : OUSTRING_TO_OSTRING_CVTFLAGS );
297 : :
298 [ + - ]: 711140 : if( pSymbolName != NULL )
299 : : {
300 [ + - ]: 711140 : pSymbol = osl_getAsciiFunctionSymbol(module, rtl_string_getStr(pSymbolName));
301 : 711140 : rtl_string_release(pSymbolName);
302 : : }
303 : : }
304 : :
305 : 711140 : return pSymbol;
306 : : }
307 : :
308 : : /*****************************************************************************/
309 : : /* osl_getModuleURLFromAddress */
310 : : /*****************************************************************************/
311 : 40619 : sal_Bool SAL_CALL osl_getModuleURLFromAddress(void * addr, rtl_uString ** ppLibraryUrl)
312 : : {
313 : 40619 : sal_Bool result = sal_False;
314 : 40619 : rtl_String * path = NULL;
315 [ + - ]: 40619 : if (getModulePathFromAddress(addr, &path))
316 : : {
317 : 40619 : rtl_uString * workDir = NULL;
318 [ + - ]: 40619 : osl_getProcessWorkingDir(&workDir);
319 [ + - ]: 40619 : if (workDir)
320 : : {
321 : : SAL_INFO(
322 : : "sal.osl", "osl_getModuleURLFromAddress: " << path->buffer);
323 : : rtl_string2UString(ppLibraryUrl,
324 : : path->buffer,
325 : : path->length,
326 [ + - ]: 40619 : osl_getThreadTextEncoding(),
327 : 40619 : OSTRING_TO_OUSTRING_CVTFLAGS);
328 : :
329 : : SAL_WARN_IF(
330 : : *ppLibraryUrl == 0, "sal.osl", "rtl_string2UString failed");
331 [ + - ]: 40619 : osl_getFileURLFromSystemPath(*ppLibraryUrl, ppLibraryUrl);
332 [ + - ]: 40619 : osl_getAbsoluteFileURL(workDir, *ppLibraryUrl, ppLibraryUrl);
333 : :
334 : 40619 : rtl_uString_release(workDir);
335 : 40619 : result = sal_True;
336 : : }
337 : : else
338 : : {
339 : 0 : result = sal_False;
340 : : }
341 : 40619 : rtl_string_release(path);
342 : : }
343 : 40619 : return result;
344 : : }
345 : :
346 : : /*****************************************************************************/
347 : : /* osl_getModuleURLFromFunctionAddress */
348 : : /*****************************************************************************/
349 : 40522 : sal_Bool SAL_CALL osl_getModuleURLFromFunctionAddress(oslGenericFunction addr, rtl_uString ** ppLibraryUrl)
350 : : {
351 : 40522 : return osl_getModuleURLFromAddress((void*)addr, ppLibraryUrl);
352 : : }
353 : :
354 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|