VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/ldr/ldrkStuff.cpp@ 11523

Last change on this file since 11523 was 8245, checked in by vboxsync, 17 years ago

rebranding: IPRT files again.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 21.5 KB
Line 
1/* $Id: ldrkStuff.cpp 8245 2008-04-21 17:24:28Z vboxsync $ */
2/** @file
3 * IPRT - Binary Image Loader, kLdr Interface.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#define LOG_GROUP RTLOGGROUP_LDR
36#include <iprt/ldr.h>
37#include <iprt/file.h>
38#include <iprt/alloc.h>
39#include <iprt/alloca.h>
40#include <iprt/assert.h>
41#include <iprt/string.h>
42#include <iprt/path.h>
43#include <iprt/log.h>
44#include <iprt/param.h>
45#include <iprt/err.h>
46#include "internal/ldr.h"
47#define KLDR_ALREADY_INCLUDE_STD_TYPES
48#define KLDR_NO_KLDR_H_INCLUDES
49#include <k/kLdr.h>
50#include <k/kRdrAll.h>
51#include <k/kErrors.h>
52#include <k/kMagics.h>
53
54
55/*******************************************************************************
56* Structures and Typedefs *
57*******************************************************************************/
58/**
59 * kLdr file provider.
60 */
61typedef struct RTKLDRRDR
62{
63 /** The core. */
64 KRDR Core;
65 /** The IPRT bit reader. */
66 PRTLDRREADER pReader;
67} RTKLDRRDR, *PRTKLDRRDR;
68
69/**
70 * IPRT module.
71 */
72typedef struct RTLDRMODKLDR
73{
74 /** The Core module structure. */
75 RTLDRMODINTERNAL Core;
76 /** The kLdr module. */
77 PKLDRMOD pMod;
78} RTLDRMODKLDR, *PRTLDRMODKLDR;
79
80
81/**
82 * Arguments for a RTLDRMODKLDR callback wrapper.
83 */
84typedef struct RTLDRMODKLDRARGS
85{
86 union
87 {
88 PFNRT pfn;
89 PFNRTLDRENUMSYMS pfnEnumSyms;
90 PFNRTLDRIMPORT pfnGetImport;
91 } u;
92 void *pvUser;
93 const void *pvBits;
94 PRTLDRMODKLDR pMod;
95} RTLDRMODKLDRARGS, *PRTLDRMODKLDRARGS;
96
97
98/*******************************************************************************
99* Internal Functions *
100*******************************************************************************/
101static int rtkldrConvertError(int krc);
102static int rtkldrConvertErrorFromIPRT(int rc);
103
104
105static int rtkldrRdrCreate( PPKRDR ppRdr, const char *pszFilename);
106static int rtkldrRdrDestroy( PKRDR pRdr);
107static int rtkldrRdrRead( PKRDR pRdr, void *pvBuf, KSIZE cb, KFOFF off);
108static int rtkldrRdrAllMap( PKRDR pRdr, const void **ppvBits);
109static int rtkldrRdrAllUnmap(PKRDR pRdr, const void *pvBits);
110static KFOFF rtkldrRdrSize( PKRDR pRdr);
111static KFOFF rtkldrRdrTell( PKRDR pRdr);
112static const char * rtkldrRdrName(PKRDR pRdr);
113static KIPTR rtkldrRdrNativeFH(PKRDR pRdr);
114static KSIZE rtkldrRdrPageSize(PKRDR pRdr);
115static int rtkldrRdrMap( PKRDR pRdr, void **ppvBase, KU32 cSegments, PCKLDRSEG paSegments, KBOOL fFixed);
116static int rtkldrRdrRefresh( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments);
117static int rtkldrRdrProtect( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments, KBOOL fUnprotectOrProtect);
118static int rtkldrRdrUnmap( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments);
119static void rtkldrRdrDone( PKRDR pRdr);
120
121
122static DECLCALLBACK(int) rtkldrClose(PRTLDRMODINTERNAL pMod);
123static DECLCALLBACK(int) rtkldrDone(PRTLDRMODINTERNAL pMod);
124static DECLCALLBACK(int) rtkldrEnumSymbols(PRTLDRMODINTERNAL pMod, unsigned fFlags, const void *pvBits,
125 RTUINTPTR BaseAddress,PFNRTLDRENUMSYMS pfnCallback, void *pvUser);
126static int rtkldrEnumSymbolsWrapper(PKLDRMOD pMod, uint32_t iSymbol,
127 const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion,
128 KLDRADDR uValue, uint32_t fKind, void *pvUser);
129static DECLCALLBACK(size_t) rtkldrGetImageSize(PRTLDRMODINTERNAL pMod);
130static DECLCALLBACK(int) rtkldrGetBits(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR BaseAddress,
131 PFNRTLDRIMPORT pfnGetImport, void *pvUser);
132static DECLCALLBACK(int) rtkldrRelocate(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR NewBaseAddress,
133 RTUINTPTR OldBaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser);
134static int rtkldrGetImportWrapper(PKLDRMOD pMod, uint32_t iImport, uint32_t iSymbol, const char *pchSymbol, KSIZE cchSymbol,
135 const char *pszVersion, PKLDRADDR puValue, uint32_t *pfKind, void *pvUser);
136
137static DECLCALLBACK(int) rtkldrGetSymbolEx(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress,
138 const char *pszSymbol, RTUINTPTR *pValue);
139
140
141
142/**
143 * Converts a kLdr error code to an IPRT one.
144 */
145static int rtkldrConvertError(int krc)
146{
147 if (!krc)
148 return VINF_SUCCESS;
149 switch (krc)
150 {
151 case KERR_INVALID_PARAMETER: return VERR_INVALID_PARAMETER;
152 case KERR_INVALID_HANDLE: return VERR_INVALID_HANDLE;
153 case KERR_NO_MEMORY: return VERR_NO_MEMORY;
154
155
156 case KLDR_ERR_UNKNOWN_FORMAT:
157 case KLDR_ERR_MZ_NOT_SUPPORTED: return VERR_MZ_EXE_NOT_SUPPORTED;
158 case KLDR_ERR_NE_NOT_SUPPORTED: return VERR_NE_EXE_NOT_SUPPORTED;
159 case KLDR_ERR_LX_NOT_SUPPORTED: return VERR_LX_EXE_NOT_SUPPORTED;
160 case KLDR_ERR_LE_NOT_SUPPORTED: return VERR_LE_EXE_NOT_SUPPORTED;
161 case KLDR_ERR_PE_NOT_SUPPORTED: return VERR_PE_EXE_NOT_SUPPORTED;
162 case KLDR_ERR_ELF_NOT_SUPPORTED: return VERR_ELF_EXE_NOT_SUPPORTED;
163 case KLDR_ERR_MACHO_NOT_SUPPORTED: return VERR_INVALID_EXE_SIGNATURE;
164 case KLDR_ERR_AOUT_NOT_SUPPORTED: return VERR_AOUT_EXE_NOT_SUPPORTED;
165
166 case KLDR_ERR_MODULE_NOT_FOUND: return VERR_MODULE_NOT_FOUND;
167 case KLDR_ERR_PREREQUISITE_MODULE_NOT_FOUND: return VERR_MODULE_NOT_FOUND;
168 case KLDR_ERR_MAIN_STACK_ALLOC_FAILED: return VERR_NO_MEMORY;
169 case KERR_BUFFER_OVERFLOW: return VERR_BUFFER_OVERFLOW;
170 case KLDR_ERR_SYMBOL_NOT_FOUND: return VERR_SYMBOL_NOT_FOUND;
171 case KLDR_ERR_FORWARDER_SYMBOL: return VERR_BAD_EXE_FORMAT;
172 case KLDR_ERR_BAD_FIXUP: return VERR_BAD_EXE_FORMAT;
173 case KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS: return VERR_BAD_EXE_FORMAT;
174 case KLDR_ERR_NO_DEBUG_INFO: return VERR_FILE_NOT_FOUND;
175 case KLDR_ERR_ALREADY_MAPPED: return VERR_WRONG_ORDER;
176 case KLDR_ERR_NOT_MAPPED: return VERR_WRONG_ORDER;
177 case KLDR_ERR_ADDRESS_OVERFLOW: return VERR_NUMBER_TOO_BIG;
178
179 case KLDR_ERR_NOT_LOADED_DYNAMICALLY:
180 case KCPU_ERR_ARCH_CPU_NOT_COMPATIBLE:
181 case KLDR_ERR_TOO_LONG_FORWARDER_CHAIN:
182 case KLDR_ERR_MODULE_TERMINATING:
183 case KLDR_ERR_PREREQUISITE_MODULE_TERMINATING:
184 case KLDR_ERR_MODULE_INIT_FAILED:
185 case KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED:
186 case KLDR_ERR_MODULE_INIT_FAILED_ALREADY:
187 case KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED_ALREADY:
188 case KLDR_ERR_PREREQUISITE_RECURSED_TOO_DEEPLY:
189 case KLDR_ERR_THREAD_ATTACH_FAILED:
190 case KRDR_ERR_TOO_MANY_MAPPINGS:
191 case KLDR_ERR_NOT_DLL:
192 case KLDR_ERR_NOT_EXE:
193 return VERR_GENERAL_FAILURE;
194
195
196 case KLDR_ERR_PE_UNSUPPORTED_MACHINE:
197 case KLDR_ERR_PE_BAD_FILE_HEADER:
198 case KLDR_ERR_PE_BAD_OPTIONAL_HEADER:
199 case KLDR_ERR_PE_BAD_SECTION_HEADER:
200 case KLDR_ERR_PE_BAD_FORWARDER:
201 case KLDR_ERR_PE_FORWARDER_IMPORT_NOT_FOUND:
202 case KLDR_ERR_PE_BAD_FIXUP:
203 case KLDR_ERR_PE_BAD_IMPORT:
204 return VERR_GENERAL_FAILURE;
205
206 case KLDR_ERR_LX_BAD_HEADER:
207 case KLDR_ERR_LX_BAD_LOADER_SECTION:
208 case KLDR_ERR_LX_BAD_FIXUP_SECTION:
209 case KLDR_ERR_LX_BAD_OBJECT_TABLE:
210 case KLDR_ERR_LX_BAD_PAGE_MAP:
211 case KLDR_ERR_LX_BAD_ITERDATA:
212 case KLDR_ERR_LX_BAD_ITERDATA2:
213 case KLDR_ERR_LX_BAD_BUNDLE:
214 case KLDR_ERR_LX_NO_SONAME:
215 case KLDR_ERR_LX_BAD_SONAME:
216 case KLDR_ERR_LX_BAD_FORWARDER:
217 case KLDR_ERR_LX_NRICHAIN_NOT_SUPPORTED:
218 return VERR_GENERAL_FAILURE;
219
220 default:
221 if (RT_FAILURE(krc))
222 return krc;
223 AssertMsgFailed(("krc=%d (%#x)\n", krc, krc));
224 return VERR_NO_TRANSLATION;
225 }
226}
227
228
229/**
230 * Converts a IPRT error code to an kLdr one.
231 */
232static int rtkldrConvertErrorFromIPRT(int rc)
233{
234 if (RT_SUCCESS(rc))
235 return 0;
236 switch (rc)
237 {
238 case VERR_NO_MEMORY: return KERR_NO_MEMORY;
239 case VERR_INVALID_PARAMETER: return KERR_INVALID_PARAMETER;
240 case VERR_INVALID_HANDLE: return KERR_INVALID_HANDLE;
241 case VERR_BUFFER_OVERFLOW: return KERR_BUFFER_OVERFLOW;
242 default:
243 return rc;
244 }
245}
246
247
248
249
250
251/**
252 * The file reader operations.
253 * We provide our own based on IPRT instead of using the kLdr ones.
254 */
255extern "C" const KRDROPS g_kLdrRdrFileOps;
256extern "C" const KRDROPS g_kLdrRdrFileOps =
257{
258 /* .pszName = */ "IPRT",
259 /* .pNext = */ NULL,
260 /* .pfnCreate = */ rtkldrRdrCreate,
261 /* .pfnDestroy = */ rtkldrRdrDestroy,
262 /* .pfnRead = */ rtkldrRdrRead,
263 /* .pfnAllMap = */ rtkldrRdrAllMap,
264 /* .pfnAllUnmap = */ rtkldrRdrAllUnmap,
265 /* .pfnSize = */ rtkldrRdrSize,
266 /* .pfnTell = */ rtkldrRdrTell,
267 /* .pfnName = */ rtkldrRdrName,
268 /* .pfnNativeFH = */ rtkldrRdrNativeFH,
269 /* .pfnPageSize = */ rtkldrRdrPageSize,
270 /* .pfnMap = */ rtkldrRdrMap,
271 /* .pfnRefresh = */ rtkldrRdrRefresh,
272 /* .pfnProtect = */ rtkldrRdrProtect,
273 /* .pfnUnmap = */ rtkldrRdrUnmap,
274 /* .pfnDone = */ rtkldrRdrDone,
275 /* .u32Dummy = */ 42
276};
277
278
279/** @copydoc KLDRRDROPS::pfnCreate
280 * @remark This is a dummy which isn't used. */
281static int rtkldrRdrCreate( PPKRDR ppRdr, const char *pszFilename)
282{
283 AssertReleaseFailed();
284 return -1;
285}
286
287
288/** @copydoc KLDRRDROPS::pfnDestroy */
289static int rtkldrRdrDestroy( PKRDR pRdr)
290{
291 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
292 int rc = pReader->pfnDestroy(pReader);
293 return rtkldrConvertErrorFromIPRT(rc);
294}
295
296
297/** @copydoc KLDRRDROPS::pfnRead */
298static int rtkldrRdrRead( PKRDR pRdr, void *pvBuf, KSIZE cb, KFOFF off)
299{
300 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
301 int rc = pReader->pfnRead(pReader, pvBuf, cb, off);
302 return rtkldrConvertErrorFromIPRT(rc);
303}
304
305
306/** @copydoc KLDRRDROPS::pfnAllMap */
307static int rtkldrRdrAllMap( PKRDR pRdr, const void **ppvBits)
308{
309 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
310 int rc = pReader->pfnMap(pReader, ppvBits);
311 return rtkldrConvertErrorFromIPRT(rc);
312}
313
314
315/** @copydoc KLDRRDROPS::pfnAllUnmap */
316static int rtkldrRdrAllUnmap(PKRDR pRdr, const void *pvBits)
317{
318 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
319 int rc = pReader->pfnUnmap(pReader, pvBits);
320 return rtkldrConvertErrorFromIPRT(rc);
321}
322
323
324/** @copydoc KLDRRDROPS::pfnSize */
325static KFOFF rtkldrRdrSize( PKRDR pRdr)
326{
327 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
328 return (KFOFF)pReader->pfnSize(pReader);
329}
330
331
332/** @copydoc KLDRRDROPS::pfnTell */
333static KFOFF rtkldrRdrTell( PKRDR pRdr)
334{
335 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
336 return (KFOFF)pReader->pfnTell(pReader);
337}
338
339
340/** @copydoc KLDRRDROPS::pfnName */
341static const char * rtkldrRdrName(PKRDR pRdr)
342{
343 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
344 return pReader->pfnLogName(pReader);
345}
346
347
348/** @copydoc KLDRRDROPS::pfnNativeFH */
349static KIPTR rtkldrRdrNativeFH(PKRDR pRdr)
350{
351 AssertFailed();
352 return -1;
353}
354
355
356/** @copydoc KLDRRDROPS::pfnPageSize */
357static KSIZE rtkldrRdrPageSize(PKRDR pRdr)
358{
359 return PAGE_SIZE;
360}
361
362
363/** @copydoc KLDRRDROPS::pfnMap */
364static int rtkldrRdrMap( PKRDR pRdr, void **ppvBase, KU32 cSegments, PCKLDRSEG paSegments, KBOOL fFixed)
365{
366 //PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
367 AssertFailed();
368 return -1;
369}
370
371
372/** @copydoc KLDRRDROPS::pfnRefresh */
373static int rtkldrRdrRefresh( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments)
374{
375 //PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
376 AssertFailed();
377 return -1;
378}
379
380
381/** @copydoc KLDRRDROPS::pfnProtect */
382static int rtkldrRdrProtect( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments, KBOOL fUnprotectOrProtect)
383{
384 //PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
385 AssertFailed();
386 return -1;
387}
388
389
390/** @copydoc KLDRRDROPS::pfnUnmap */
391static int rtkldrRdrUnmap( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments)
392{
393 //PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
394 AssertFailed();
395 return -1;
396}
397
398/** @copydoc KLDRRDROPS::pfnDone */
399static void rtkldrRdrDone( PKRDR pRdr)
400{
401 //PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
402}
403
404
405
406
407
408
409/**
410 * Operations for a kLdr module.
411 */
412static const RTLDROPS g_rtkldrOps =
413{
414 "kLdr",
415 rtkldrClose,
416 NULL,
417 rtkldrDone,
418 rtkldrEnumSymbols,
419 /* ext */
420 rtkldrGetImageSize,
421 rtkldrGetBits,
422 rtkldrRelocate,
423 rtkldrGetSymbolEx,
424 42
425};
426
427
428/** @copydoc RTLDROPS::pfnClose */
429static DECLCALLBACK(int) rtkldrClose(PRTLDRMODINTERNAL pMod)
430{
431 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
432 int rc = kLdrModClose(pModkLdr);
433 return rtkldrConvertError(rc);
434}
435
436
437/** @copydoc RTLDROPS::pfnDone */
438static DECLCALLBACK(int) rtkldrDone(PRTLDRMODINTERNAL pMod)
439{
440 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
441 int rc = kLdrModMostlyDone(pModkLdr);
442 return rtkldrConvertError(rc);
443}
444
445
446/** @copydoc RTLDROPS::pfnEnumSymbols */
447static DECLCALLBACK(int) rtkldrEnumSymbols(PRTLDRMODINTERNAL pMod, unsigned fFlags, const void *pvBits, RTUINTPTR BaseAddress,
448 PFNRTLDRENUMSYMS pfnCallback, void *pvUser)
449{
450 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
451 RTLDRMODKLDRARGS Args;
452 Args.pvUser = pvUser;
453 Args.u.pfnEnumSyms = pfnCallback;
454 Args.pMod = (PRTLDRMODKLDR)pMod;
455 Args.pvBits = pvBits;
456 int rc = kLdrModEnumSymbols(pModkLdr, pvBits, BaseAddress,
457 fFlags & RTLDR_ENUM_SYMBOL_FLAGS_ALL ? KLDRMOD_ENUM_SYMS_FLAGS_ALL : 0,
458 rtkldrEnumSymbolsWrapper, &Args);
459 return rtkldrConvertError(rc);
460}
461
462
463/** @copydoc FNKLDRMODENUMSYMS */
464static int rtkldrEnumSymbolsWrapper(PKLDRMOD pMod, uint32_t iSymbol,
465 const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion,
466 KLDRADDR uValue, uint32_t fKind, void *pvUser)
467{
468 PRTLDRMODKLDRARGS pArgs = (PRTLDRMODKLDRARGS)pvUser;
469
470 /* If not zero terminated we'll have to use a temporary buffer. */
471 const char *pszSymbol = pchSymbol;
472 if (pchSymbol && pchSymbol[cchSymbol])
473 {
474 char *psz = (char *)alloca(cchSymbol) + 1;
475 memcpy(psz, pchSymbol, cchSymbol);
476 psz[cchSymbol] = '\0';
477 pszSymbol = psz;
478 }
479
480#if defined(RT_OS_OS2) || (defined(RT_OS_DARWIN) && defined(RT_ARCH_X86))
481 /* skip the underscore prefix. */
482 if (*pszSymbol == '_')
483 pszSymbol++;
484#endif
485
486 int rc = pArgs->u.pfnEnumSyms(&pArgs->pMod->Core, pszSymbol, iSymbol, uValue, pArgs->pvUser);
487 if (RT_FAILURE(rc))
488 return rc; /* don't bother converting. */
489 return 0;
490}
491
492
493/** @copydoc RTLDROPS::pfnGetImageSize */
494static DECLCALLBACK(size_t) rtkldrGetImageSize(PRTLDRMODINTERNAL pMod)
495{
496 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
497 return kLdrModSize(pModkLdr);
498}
499
500
501/** @copydoc RTLDROPS::pfnGetBits */
502static DECLCALLBACK(int) rtkldrGetBits(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR BaseAddress,
503 PFNRTLDRIMPORT pfnGetImport, void *pvUser)
504{
505 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
506 RTLDRMODKLDRARGS Args;
507 Args.pvUser = pvUser;
508 Args.u.pfnGetImport = pfnGetImport;
509 Args.pMod = (PRTLDRMODKLDR)pMod;
510 Args.pvBits = pvBits;
511 int rc = kLdrModGetBits(pModkLdr, pvBits, BaseAddress, rtkldrGetImportWrapper, &Args);
512 return rtkldrConvertError(rc);
513}
514
515
516/** @copydoc RTLDROPS::pfnRelocate */
517static DECLCALLBACK(int) rtkldrRelocate(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR NewBaseAddress,
518 RTUINTPTR OldBaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser)
519{
520 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
521 RTLDRMODKLDRARGS Args;
522 Args.pvUser = pvUser;
523 Args.u.pfnGetImport = pfnGetImport;
524 Args.pMod = (PRTLDRMODKLDR)pMod;
525 Args.pvBits = pvBits;
526 int rc = kLdrModRelocateBits(pModkLdr, pvBits, NewBaseAddress, OldBaseAddress, rtkldrGetImportWrapper, &Args);
527 return rtkldrConvertError(rc);
528}
529
530
531/** @copydoc FNKLDRMODGETIMPORT */
532static int rtkldrGetImportWrapper(PKLDRMOD pMod, uint32_t iImport, uint32_t iSymbol, const char *pchSymbol, KSIZE cchSymbol,
533 const char *pszVersion, PKLDRADDR puValue, uint32_t *pfKind, void *pvUser)
534{
535 PRTLDRMODKLDRARGS pArgs = (PRTLDRMODKLDRARGS)pvUser;
536
537 /* If not zero terminated we'll have to use a temporary buffer. */
538 const char *pszSymbol = pchSymbol;
539 if (pchSymbol && pchSymbol[cchSymbol])
540 {
541 char *psz = (char *)alloca(cchSymbol) + 1;
542 memcpy(psz, pchSymbol, cchSymbol);
543 psz[cchSymbol] = '\0';
544 pszSymbol = psz;
545 }
546
547#if defined(RT_OS_OS2) || (defined(RT_OS_DARWIN) && defined(RT_ARCH_X86))
548 /* skip the underscore prefix. */
549 if (*pszSymbol == '_')
550 pszSymbol++;
551#endif
552
553 /* get the import module name - TODO: cache this */
554 const char *pszModule = NULL;
555 if (iImport != NIL_KLDRMOD_IMPORT)
556 {
557 char *pszBuf = (char *)alloca(64);
558 int rc = kLdrModGetImport(pMod, pArgs->pvBits, iImport, pszBuf, 64);
559 if (rc)
560 return rc;
561 pszModule = pszBuf;
562 }
563
564 /* do the query */
565 RTUINTPTR Value;
566 int rc = pArgs->u.pfnGetImport(&pArgs->pMod->Core, pszModule, pszSymbol, pszSymbol ? ~0 : iSymbol, &Value, pArgs->pvUser);
567 if (RT_SUCCESS(rc))
568 {
569 *puValue = Value;
570 return 0;
571 }
572 return rtkldrConvertErrorFromIPRT(rc);
573}
574
575
576
577/** @copydoc RTLDROPS::pfnGetSymbolEx */
578static DECLCALLBACK(int) rtkldrGetSymbolEx(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress,
579 const char *pszSymbol, RTUINTPTR *pValue)
580{
581 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
582 KLDRADDR uValue;
583
584#if defined(RT_OS_OS2) || (defined(RT_OS_DARWIN) && defined(RT_ARCH_X86))
585 /*
586 * Add underscore prefix.
587 */
588 if (pszSymbol)
589 {
590 size_t cch = strlen(pszSymbol);
591 char *psz = (char *)alloca(cch + 2);
592 memcpy(psz + 1, pszSymbol, cch + 1);
593 *psz = '_';
594 pszSymbol = psz;
595 }
596#endif
597
598 int rc = kLdrModQuerySymbol(pModkLdr, pvBits, BaseAddress,
599 NIL_KLDRMOD_SYM_ORDINAL, pszSymbol, strlen(pszSymbol), NULL,
600 NULL, NULL, &uValue, NULL);
601 if (!rc)
602 {
603 *pValue = uValue;
604 return VINF_SUCCESS;
605 }
606 return rtkldrConvertError(rc);
607}
608
609
610
611/**
612 * Open a image using kLdr.
613 *
614 * @returns iprt status code.
615 * @param pReader The loader reader instance which will provide the raw image bits.
616 * @param phLdrMod Where to store the handle.
617 */
618int rtldrkLdrOpen(PRTLDRREADER pReader, PRTLDRMOD phLdrMod)
619{
620 /* Create a rtkldrRdr instance. */
621 PRTKLDRRDR pRdr = (PRTKLDRRDR)RTMemAllocZ(sizeof(*pRdr));
622 if (!pRdr)
623 return VERR_NO_MEMORY;
624 pRdr->Core.u32Magic = KRDR_MAGIC;
625 pRdr->Core.pOps = &g_kLdrRdrFileOps;
626 pRdr->pReader = pReader;
627
628 /* Try open it. */
629 PKLDRMOD pMod;
630 int krc = kLdrModOpenFromRdr(&pRdr->Core, &pMod);
631 if (!krc)
632 {
633 /* Create a module wrapper for it. */
634 PRTLDRMODKLDR pNewMod = (PRTLDRMODKLDR)RTMemAllocZ(sizeof(*pNewMod));
635 if (pNewMod)
636 {
637 pNewMod->Core.u32Magic = RTLDRMOD_MAGIC;
638 pNewMod->Core.eState = LDR_STATE_OPENED;
639 pNewMod->Core.pOps = &g_rtkldrOps;
640 pNewMod->pMod = pMod;
641 *phLdrMod = &pNewMod->Core;
642 return VINF_SUCCESS;
643 }
644 kLdrModClose(pMod);
645 krc = KERR_NO_MEMORY;
646 }
647 return rtkldrConvertError(krc);
648}
649
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