VirtualBox

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

最後變更 在這個檔案從38515是 38515,由 vboxsync 提交於 14 年 前

IPRT: Working on debug info again.

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

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