VirtualBox

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

Last change on this file since 5606 was 5552, checked in by vboxsync, 17 years ago

Darwin build fixes.

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