VirtualBox

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

Last change on this file since 49329 was 49044, checked in by vboxsync, 11 years ago

Darwin guest OS digger hacking in progress. Adding symbol cache util to iprt and started on the Mach-O code that'll make use of it (RTDbgModCreateFromMachOImage++). Updates kStuff from 53 to 55 for UUID query and 64-bit kext loading.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 9.4 KB
Line 
1/* $Id: ldrNative.cpp 49044 2013-10-11 01:06:28Z 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 42
86};
87
88
89
90/**
91 * Loads a dynamic load library (/shared object) image file using native
92 * OS facilities.
93 *
94 * The filename will be appended the default DLL/SO extension of
95 * the platform if it have been omitted. This means that it's not
96 * possible to load DLLs/SOs with no extension using this interface,
97 * but that's not a bad tradeoff.
98 *
99 * If no path is specified in the filename, the OS will usually search it's library
100 * path to find the image file.
101 *
102 * @returns iprt status code.
103 * @param pszFilename Image filename.
104 * @param phLdrMod Where to store the handle to the loaded module.
105 */
106RTDECL(int) RTLdrLoad(const char *pszFilename, PRTLDRMOD phLdrMod)
107{
108 return RTLdrLoadEx(pszFilename, phLdrMod, RTLDRLOAD_FLAGS_LOCAL, NULL);
109}
110RT_EXPORT_SYMBOL(RTLdrLoad);
111
112
113RTDECL(int) RTLdrLoadEx(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo)
114{
115 LogFlow(("RTLdrLoadEx: pszFilename=%p:{%s} phLdrMod=%p fFlags=%#x pErrInfo=%p\n", pszFilename, pszFilename, phLdrMod, fFlags, pErrInfo));
116
117 /*
118 * Validate and massage the input.
119 */
120 RTErrInfoClear(pErrInfo);
121 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
122 AssertPtrReturn(phLdrMod, VERR_INVALID_POINTER);
123 AssertReturn(!(fFlags & ~RTLDRLOAD_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
124
125 /*
126 * Allocate and initialize module structure.
127 */
128 int rc = VERR_NO_MEMORY;
129 PRTLDRMODNATIVE pMod = (PRTLDRMODNATIVE)RTMemAlloc(sizeof(*pMod));
130 if (pMod)
131 {
132 pMod->Core.u32Magic = RTLDRMOD_MAGIC;
133 pMod->Core.eState = LDR_STATE_LOADED;
134 pMod->Core.pOps = &g_rtldrNativeOps;
135 pMod->Core.pReader = NULL;
136 pMod->Core.enmFormat = RTLDRFMT_NATIVE;
137 pMod->Core.enmType = RTLDRTYPE_SHARED_LIBRARY_RELOCATABLE; /* approx */
138#ifdef RT_BIG_ENDIAN
139 pMod->Core.enmEndian = RTLDRENDIAN_BIG;
140#else
141 pMod->Core.enmEndian = RTLDRENDIAN_LITTLE;
142#endif
143#ifdef RT_ARCH_AMD64
144 pMod->Core.enmArch = RTLDRARCH_AMD64;
145#elif defined(RT_ARCH_X86)
146 pMod->Core.enmArch = RTLDRARCH_X86_32;
147#else
148 pMod->Core.enmArch = RTLDRARCH_HOST;
149#endif
150 pMod->hNative = ~(uintptr_t)0;
151 pMod->fFlags = fFlags;
152
153 /*
154 * Attempt to open the module.
155 */
156 rc = rtldrNativeLoad(pszFilename, &pMod->hNative, fFlags, pErrInfo);
157 if (RT_SUCCESS(rc))
158 {
159 *phLdrMod = &pMod->Core;
160 LogFlow(("RTLdrLoad: returns %Rrc *phLdrMod=%RTldrm\n", rc, *phLdrMod));
161 return rc;
162 }
163
164 RTMemFree(pMod);
165 }
166 else
167 RTErrInfoSetF(pErrInfo, rc, "Failed to allocate %zu bytes for the module handle", sizeof(*pMod));
168 *phLdrMod = NIL_RTLDRMOD;
169 LogFlow(("RTLdrLoad: returns %Rrc\n", rc));
170 return rc;
171}
172RT_EXPORT_SYMBOL(RTLdrLoadEx);
173
174
175RTDECL(int) RTLdrLoadSystem(const char *pszFilename, bool fNoUnload, PRTLDRMOD phLdrMod)
176{
177 LogFlow(("RTLdrLoadSystem: pszFilename=%p:{%s} fNoUnload=%RTbool phLdrMod=%p\n",
178 pszFilename, pszFilename, fNoUnload, phLdrMod));
179
180 /*
181 * Validate input.
182 */
183 AssertPtrReturn(phLdrMod, VERR_INVALID_PARAMETER);
184 *phLdrMod = NIL_RTLDRMOD;
185 AssertPtrReturn(pszFilename, VERR_INVALID_PARAMETER);
186 AssertMsgReturn(!RTPathHasPath(pszFilename), ("%s\n", pszFilename), VERR_INVALID_PARAMETER);
187
188 /*
189 * Check the filename.
190 */
191 size_t cchFilename = strlen(pszFilename);
192 AssertMsgReturn(cchFilename < (RTPATH_MAX / 4) * 3, ("%zu\n", cchFilename), VERR_INVALID_PARAMETER);
193
194 const char *pszSuffix = "";
195 if (!RTPathHasSuffix(pszFilename))
196 pszSuffix = RTLdrGetSuff();
197
198 /*
199 * Let the platform specific code do the rest.
200 */
201 int rc = rtldrNativeLoadSystem(pszFilename, pszSuffix, fNoUnload ? RTLDRLOAD_FLAGS_NO_UNLOAD : 0, phLdrMod);
202 LogFlow(("RTLdrLoadSystem: returns %Rrc\n", rc));
203 return rc;
204}
205
206
207RTDECL(void *) RTLdrGetSystemSymbol(const char *pszFilename, const char *pszSymbol)
208{
209 void *pvRet = NULL;
210 RTLDRMOD hLdrMod;
211 int rc = RTLdrLoadSystem(pszFilename, true /*fNoUnload*/, &hLdrMod);
212 if (RT_SUCCESS(rc))
213 {
214 rc = RTLdrGetSymbol(hLdrMod, pszSymbol, &pvRet);
215 if (RT_FAILURE(rc))
216 pvRet = NULL; /* paranoia */
217 RTLdrClose(hLdrMod);
218 }
219 return pvRet;
220}
221
222
223/**
224 * Loads a dynamic load library (/shared object) image file residing in the
225 * RTPathAppPrivateArch() directory.
226 *
227 * Suffix is not required.
228 *
229 * @returns iprt status code.
230 * @param pszFilename Image filename. No path.
231 * @param phLdrMod Where to store the handle to the loaded module.
232 */
233RTDECL(int) RTLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod)
234{
235 LogFlow(("RTLdrLoadAppPriv: pszFilename=%p:{%s} phLdrMod=%p\n", pszFilename, pszFilename, phLdrMod));
236
237 /*
238 * Validate input.
239 */
240 AssertPtrReturn(phLdrMod, VERR_INVALID_PARAMETER);
241 *phLdrMod = NIL_RTLDRMOD;
242 AssertPtrReturn(pszFilename, VERR_INVALID_PARAMETER);
243 AssertMsgReturn(!RTPathHasPath(pszFilename), ("%s\n", pszFilename), VERR_INVALID_PARAMETER);
244
245 /*
246 * Check the filename.
247 */
248 size_t cchFilename = strlen(pszFilename);
249 AssertMsgReturn(cchFilename < (RTPATH_MAX / 4) * 3, ("%zu\n", cchFilename), VERR_INVALID_PARAMETER);
250
251 const char *pszSuffix = "";
252 size_t cchSuffix = 0;
253 if (!RTPathHasSuffix(pszFilename))
254 {
255 pszSuffix = RTLdrGetSuff();
256 cchSuffix = strlen(pszSuffix);
257 }
258
259 /*
260 * Construct the private arch path and check if the file exists.
261 */
262 char szPath[RTPATH_MAX];
263 int rc = RTPathAppPrivateArch(szPath, sizeof(szPath) - 1 - cchSuffix - cchFilename);
264 AssertRCReturn(rc, rc);
265
266 char *psz = strchr(szPath, '\0');
267 *psz++ = RTPATH_SLASH;
268 memcpy(psz, pszFilename, cchFilename);
269 psz += cchFilename;
270 memcpy(psz, pszSuffix, cchSuffix + 1);
271
272 if (!RTPathExists(szPath))
273 {
274 LogRel(("RTLdrLoadAppPriv: \"%s\" not found\n", szPath));
275 return VERR_FILE_NOT_FOUND;
276 }
277
278 /*
279 * Pass it on to RTLdrLoad.
280 */
281 rc = RTLdrLoad(szPath, phLdrMod);
282
283 LogFlow(("RTLdrLoadAppPriv: returns %Rrc\n", rc));
284 return rc;
285}
286RT_EXPORT_SYMBOL(RTLdrLoadAppPriv);
287
288
289/**
290 * Gets the default file suffix for DLL/SO/DYLIB/whatever.
291 *
292 * @returns The stuff (readonly).
293 */
294RTDECL(const char *) RTLdrGetSuff(void)
295{
296#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
297 static const char s_szSuff[] = ".DLL";
298#elif defined(RT_OS_L4)
299 static const char s_szSuff[] = ".s.so";
300#elif defined(RT_OS_DARWIN)
301 static const char s_szSuff[] = ".dylib";
302#else
303 static const char s_szSuff[] = ".so";
304#endif
305
306 return s_szSuff;
307}
308RT_EXPORT_SYMBOL(RTLdrGetSuff);
309
310
311RTDECL(uintptr_t) RTLdrGetNativeHandle(RTLDRMOD hLdrMod)
312{
313 PRTLDRMODNATIVE pThis = (PRTLDRMODNATIVE)hLdrMod;
314 AssertPtrReturn(pThis, ~(uintptr_t)0);
315 AssertReturn(pThis->Core.u32Magic == RTLDRMOD_MAGIC, ~(uintptr_t)0);
316 AssertReturn(pThis->Core.pOps == &g_rtldrNativeOps, ~(uintptr_t)0);
317 return pThis->hNative;
318}
319RT_EXPORT_SYMBOL(RTLdrGetNativeHandle);
320
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