VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/ldr/ldrNative.cpp@ 51770

Last change on this file since 51770 was 51770, checked in by vboxsync, 10 years ago

Merged in iprt++ dev branch.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 9.7 KB
Line 
1/* $Id: ldrNative.cpp 51770 2014-07-01 18:14:02Z vboxsync $ */
2/** @file
3 * IPRT - Binary Image Loader, Native interface.
4 */
5
6/*
7 * Copyright (C) 2006-2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#define LOG_GROUP RTLOGGROUP_LDR
32#include <iprt/ldr.h>
33#include "internal/iprt.h"
34
35#include <iprt/alloc.h>
36#include <iprt/assert.h>
37#include <iprt/log.h>
38#include <iprt/param.h>
39#include <iprt/path.h>
40#include <iprt/string.h>
41#include <iprt/err.h>
42#include "internal/ldr.h"
43
44
45/** @copydoc RTLDROPS::pfnEnumSymbols */
46static DECLCALLBACK(int) rtldrNativeEnumSymbols(PRTLDRMODINTERNAL pMod, unsigned fFlags, const void *pvBits,
47 RTUINTPTR BaseAddress, PFNRTLDRENUMSYMS pfnCallback, void *pvUser)
48{
49 NOREF(pMod); NOREF(fFlags); NOREF(pvBits); NOREF(BaseAddress); NOREF(pfnCallback); NOREF(pvUser);
50 return VERR_NOT_SUPPORTED;
51}
52
53
54/** @copydoc RTLDROPS::pfnDone */
55static DECLCALLBACK(int) rtldrNativeDone(PRTLDRMODINTERNAL pMod)
56{
57 NOREF(pMod);
58 return VINF_SUCCESS;
59}
60
61
62/**
63 * Operations for a native module.
64 */
65static const RTLDROPS g_rtldrNativeOps =
66{
67 "native",
68 rtldrNativeClose,
69 rtldrNativeGetSymbol,
70 rtldrNativeDone,
71 rtldrNativeEnumSymbols,
72 /* ext: */
73 NULL,
74 NULL,
75 NULL,
76 NULL,
77 NULL,
78 NULL,
79 NULL,
80 NULL,
81 NULL,
82 NULL,
83 NULL,
84 NULL,
85 NULL,
86 NULL,
87 42
88};
89
90
91
92/**
93 * Loads a dynamic load library (/shared object) image file using native
94 * OS facilities.
95 *
96 * The filename will be appended the default DLL/SO extension of
97 * the platform if it have been omitted. This means that it's not
98 * possible to load DLLs/SOs with no extension using this interface,
99 * but that's not a bad tradeoff.
100 *
101 * If no path is specified in the filename, the OS will usually search it's library
102 * path to find the image file.
103 *
104 * @returns iprt status code.
105 * @param pszFilename Image filename.
106 * @param phLdrMod Where to store the handle to the loaded module.
107 */
108RTDECL(int) RTLdrLoad(const char *pszFilename, PRTLDRMOD phLdrMod)
109{
110 return RTLdrLoadEx(pszFilename, phLdrMod, RTLDRLOAD_FLAGS_LOCAL, NULL);
111}
112RT_EXPORT_SYMBOL(RTLdrLoad);
113
114
115RTDECL(int) RTLdrLoadEx(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo)
116{
117 LogFlow(("RTLdrLoadEx: pszFilename=%p:{%s} phLdrMod=%p fFlags=%#x pErrInfo=%p\n", pszFilename, pszFilename, phLdrMod, fFlags, pErrInfo));
118
119 /*
120 * Validate and massage the input.
121 */
122 RTErrInfoClear(pErrInfo);
123 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
124 AssertPtrReturn(phLdrMod, VERR_INVALID_POINTER);
125 AssertReturn(!(fFlags & ~RTLDRLOAD_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
126
127 /*
128 * Allocate and initialize module structure.
129 */
130 int rc = VERR_NO_MEMORY;
131 PRTLDRMODNATIVE pMod = (PRTLDRMODNATIVE)RTMemAlloc(sizeof(*pMod));
132 if (pMod)
133 {
134 pMod->Core.u32Magic = RTLDRMOD_MAGIC;
135 pMod->Core.eState = LDR_STATE_LOADED;
136 pMod->Core.pOps = &g_rtldrNativeOps;
137 pMod->Core.pReader = NULL;
138 pMod->Core.enmFormat = RTLDRFMT_NATIVE;
139 pMod->Core.enmType = RTLDRTYPE_SHARED_LIBRARY_RELOCATABLE; /* approx */
140#ifdef RT_BIG_ENDIAN
141 pMod->Core.enmEndian = RTLDRENDIAN_BIG;
142#else
143 pMod->Core.enmEndian = RTLDRENDIAN_LITTLE;
144#endif
145#ifdef RT_ARCH_AMD64
146 pMod->Core.enmArch = RTLDRARCH_AMD64;
147#elif defined(RT_ARCH_X86)
148 pMod->Core.enmArch = RTLDRARCH_X86_32;
149#else
150 pMod->Core.enmArch = RTLDRARCH_HOST;
151#endif
152 pMod->hNative = ~(uintptr_t)0;
153 pMod->fFlags = fFlags;
154
155 /*
156 * Attempt to open the module.
157 */
158 rc = rtldrNativeLoad(pszFilename, &pMod->hNative, fFlags, pErrInfo);
159 if (RT_SUCCESS(rc))
160 {
161 *phLdrMod = &pMod->Core;
162 LogFlow(("RTLdrLoad: returns %Rrc *phLdrMod=%RTldrm\n", rc, *phLdrMod));
163 return rc;
164 }
165
166 RTMemFree(pMod);
167 }
168 else
169 RTErrInfoSetF(pErrInfo, rc, "Failed to allocate %zu bytes for the module handle", sizeof(*pMod));
170 *phLdrMod = NIL_RTLDRMOD;
171 LogFlow(("RTLdrLoad: returns %Rrc\n", rc));
172 return rc;
173}
174RT_EXPORT_SYMBOL(RTLdrLoadEx);
175
176
177RTDECL(int) RTLdrLoadSystem(const char *pszFilename, bool fNoUnload, PRTLDRMOD phLdrMod)
178{
179 LogFlow(("RTLdrLoadSystem: pszFilename=%p:{%s} fNoUnload=%RTbool phLdrMod=%p\n",
180 pszFilename, pszFilename, fNoUnload, phLdrMod));
181
182 /*
183 * Validate input.
184 */
185 AssertPtrReturn(phLdrMod, VERR_INVALID_PARAMETER);
186 *phLdrMod = NIL_RTLDRMOD;
187 AssertPtrReturn(pszFilename, VERR_INVALID_PARAMETER);
188 AssertMsgReturn(!RTPathHasPath(pszFilename), ("%s\n", pszFilename), VERR_INVALID_PARAMETER);
189
190 /*
191 * Check the filename.
192 */
193 size_t cchFilename = strlen(pszFilename);
194 AssertMsgReturn(cchFilename < (RTPATH_MAX / 4) * 3, ("%zu\n", cchFilename), VERR_INVALID_PARAMETER);
195
196 const char *pszSuffix = "";
197 if (!RTPathHasSuffix(pszFilename))
198 pszSuffix = RTLdrGetSuff();
199
200 /*
201 * Let the platform specific code do the rest.
202 */
203 int rc = rtldrNativeLoadSystem(pszFilename, pszSuffix, fNoUnload ? RTLDRLOAD_FLAGS_NO_UNLOAD : 0, phLdrMod);
204 LogFlow(("RTLdrLoadSystem: returns %Rrc\n", rc));
205 return rc;
206}
207
208
209RTDECL(void *) RTLdrGetSystemSymbol(const char *pszFilename, const char *pszSymbol)
210{
211 void *pvRet = NULL;
212 RTLDRMOD hLdrMod;
213 int rc = RTLdrLoadSystem(pszFilename, true /*fNoUnload*/, &hLdrMod);
214 if (RT_SUCCESS(rc))
215 {
216 rc = RTLdrGetSymbol(hLdrMod, pszSymbol, &pvRet);
217 if (RT_FAILURE(rc))
218 pvRet = NULL; /* paranoia */
219 RTLdrClose(hLdrMod);
220 }
221 return pvRet;
222}
223
224
225/**
226 * Loads a dynamic load library (/shared object) image file residing in the
227 * RTPathAppPrivateArch() directory.
228 *
229 * Suffix is not required.
230 *
231 * @returns iprt status code.
232 * @param pszFilename Image filename. No path.
233 * @param phLdrMod Where to store the handle to the loaded module.
234 */
235RTDECL(int) RTLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod)
236{
237 LogFlow(("RTLdrLoadAppPriv: pszFilename=%p:{%s} phLdrMod=%p\n", pszFilename, pszFilename, phLdrMod));
238
239 /*
240 * Validate input.
241 */
242 AssertPtrReturn(phLdrMod, VERR_INVALID_PARAMETER);
243 *phLdrMod = NIL_RTLDRMOD;
244 AssertPtrReturn(pszFilename, VERR_INVALID_PARAMETER);
245 AssertMsgReturn(!RTPathHasPath(pszFilename), ("%s\n", pszFilename), VERR_INVALID_PARAMETER);
246
247 /*
248 * Check the filename.
249 */
250 size_t cchFilename = strlen(pszFilename);
251 AssertMsgReturn(cchFilename < (RTPATH_MAX / 4) * 3, ("%zu\n", cchFilename), VERR_INVALID_PARAMETER);
252
253 const char *pszSuffix = "";
254 size_t cchSuffix = 0;
255 if (!RTPathHasSuffix(pszFilename))
256 {
257 pszSuffix = RTLdrGetSuff();
258 cchSuffix = strlen(pszSuffix);
259 }
260
261 /*
262 * Construct the private arch path and check if the file exists.
263 */
264 char szPath[RTPATH_MAX];
265 int rc = RTPathAppPrivateArch(szPath, sizeof(szPath) - 1 - cchSuffix - cchFilename);
266 AssertRCReturn(rc, rc);
267
268 char *psz = strchr(szPath, '\0');
269 *psz++ = RTPATH_SLASH;
270 memcpy(psz, pszFilename, cchFilename);
271 psz += cchFilename;
272 memcpy(psz, pszSuffix, cchSuffix + 1);
273
274 if (!RTPathExists(szPath))
275 {
276 LogRel(("RTLdrLoadAppPriv: \"%s\" not found\n", szPath));
277 return VERR_FILE_NOT_FOUND;
278 }
279
280 /*
281 * Pass it on to RTLdrLoad.
282 */
283 rc = RTLdrLoad(szPath, phLdrMod);
284
285 LogFlow(("RTLdrLoadAppPriv: returns %Rrc\n", rc));
286 return rc;
287}
288RT_EXPORT_SYMBOL(RTLdrLoadAppPriv);
289
290
291/**
292 * Gets the default file suffix for DLL/SO/DYLIB/whatever.
293 *
294 * @returns The stuff (readonly).
295 */
296RTDECL(const char *) RTLdrGetSuff(void)
297{
298#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
299 static const char s_szSuff[] = ".DLL";
300#elif defined(RT_OS_L4)
301 static const char s_szSuff[] = ".s.so";
302#elif defined(RT_OS_DARWIN)
303 static const char s_szSuff[] = ".dylib";
304#else
305 static const char s_szSuff[] = ".so";
306#endif
307
308 return s_szSuff;
309}
310RT_EXPORT_SYMBOL(RTLdrGetSuff);
311
312
313RTDECL(uintptr_t) RTLdrGetNativeHandle(RTLDRMOD hLdrMod)
314{
315 PRTLDRMODNATIVE pThis = (PRTLDRMODNATIVE)hLdrMod;
316 AssertPtrReturn(pThis, ~(uintptr_t)0);
317 AssertReturn(pThis->Core.u32Magic == RTLDRMOD_MAGIC, ~(uintptr_t)0);
318 AssertReturn(pThis->Core.pOps == &g_rtldrNativeOps, ~(uintptr_t)0);
319 return pThis->hNative;
320}
321RT_EXPORT_SYMBOL(RTLdrGetNativeHandle);
322
323
324RTDECL(bool) RTLdrIsLoadable(const char *pszFilename)
325{
326 /*
327 * Try to load the library.
328 */
329 RTLDRMOD hLib;
330 int rc = RTLdrLoad(pszFilename, &hLib);
331 if (RT_SUCCESS(rc))
332 {
333 RTLdrClose(hLib);
334 return true;
335 }
336 return false;
337}
338RT_EXPORT_SYMBOL(RTLdrIsLoadable);
339
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette