VirtualBox

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

Last change on this file since 74355 was 73494, checked in by vboxsync, 6 years ago

IPRT: Added single stack frame unwind function to RTDbgMod and RTLdr, copying over the PoC from DBGFRStack.cpp. bugref:3897

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 36.9 KB
Line 
1/* $Id: ldrkStuff.cpp 73494 2018-08-04 19:41:30Z vboxsync $ */
2/** @file
3 * IPRT - Binary Image Loader, kLdr Interface.
4 */
5
6/*
7 * Copyright (C) 2006-2017 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/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 PFNRTLDRENUMDBG pfnEnumDbgInfo;
89 PFNRTLDRENUMSYMS pfnEnumSyms;
90 PFNRTLDRIMPORT pfnGetImport;
91 } u;
92 void *pvUser;
93 const void *pvBits;
94 PRTLDRMODKLDR pMod;
95 int rc;
96} RTLDRMODKLDRARGS, *PRTLDRMODKLDRARGS;
97
98
99/**
100 * Converts a kLdr error code to an IPRT one.
101 */
102static int rtkldrConvertError(int krc)
103{
104 if (!krc)
105 return VINF_SUCCESS;
106 switch (krc)
107 {
108 case KERR_INVALID_PARAMETER: return VERR_INVALID_PARAMETER;
109 case KERR_INVALID_HANDLE: return VERR_INVALID_HANDLE;
110 case KERR_NO_MEMORY: return VERR_NO_MEMORY;
111 case KLDR_ERR_CPU_ARCH_MISMATCH: return VERR_LDR_ARCH_MISMATCH;
112
113 case KLDR_ERR_UNKNOWN_FORMAT:
114 case KLDR_ERR_MZ_NOT_SUPPORTED: return VERR_MZ_EXE_NOT_SUPPORTED;
115 case KLDR_ERR_NE_NOT_SUPPORTED: return VERR_NE_EXE_NOT_SUPPORTED;
116 case KLDR_ERR_LX_NOT_SUPPORTED: return VERR_LX_EXE_NOT_SUPPORTED;
117 case KLDR_ERR_LE_NOT_SUPPORTED: return VERR_LE_EXE_NOT_SUPPORTED;
118 case KLDR_ERR_PE_NOT_SUPPORTED: return VERR_PE_EXE_NOT_SUPPORTED;
119 case KLDR_ERR_ELF_NOT_SUPPORTED: return VERR_ELF_EXE_NOT_SUPPORTED;
120 case KLDR_ERR_MACHO_NOT_SUPPORTED: return VERR_INVALID_EXE_SIGNATURE;
121 case KLDR_ERR_AOUT_NOT_SUPPORTED: return VERR_AOUT_EXE_NOT_SUPPORTED;
122
123 case KLDR_ERR_MODULE_NOT_FOUND: return VERR_MODULE_NOT_FOUND;
124 case KLDR_ERR_PREREQUISITE_MODULE_NOT_FOUND: return VERR_MODULE_NOT_FOUND;
125 case KLDR_ERR_MAIN_STACK_ALLOC_FAILED: return VERR_NO_MEMORY;
126 case KERR_BUFFER_OVERFLOW: return VERR_BUFFER_OVERFLOW;
127 case KLDR_ERR_SYMBOL_NOT_FOUND: return VERR_SYMBOL_NOT_FOUND;
128 case KLDR_ERR_FORWARDER_SYMBOL: return VERR_BAD_EXE_FORMAT;
129 case KLDR_ERR_BAD_FIXUP: AssertMsgFailedReturn(("KLDR_ERR_BAD_FIXUP\n"), VERR_BAD_EXE_FORMAT);
130 case KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS: return VERR_BAD_EXE_FORMAT;
131 case KLDR_ERR_NO_DEBUG_INFO: return VERR_FILE_NOT_FOUND;
132 case KLDR_ERR_ALREADY_MAPPED: return VERR_WRONG_ORDER;
133 case KLDR_ERR_NOT_MAPPED: return VERR_WRONG_ORDER;
134 case KLDR_ERR_ADDRESS_OVERFLOW: return VERR_NUMBER_TOO_BIG;
135 case KLDR_ERR_TODO: return VERR_NOT_IMPLEMENTED;
136
137 case KLDR_ERR_NOT_LOADED_DYNAMICALLY:
138 case KCPU_ERR_ARCH_CPU_NOT_COMPATIBLE:
139 case KLDR_ERR_TOO_LONG_FORWARDER_CHAIN:
140 case KLDR_ERR_MODULE_TERMINATING:
141 case KLDR_ERR_PREREQUISITE_MODULE_TERMINATING:
142 case KLDR_ERR_MODULE_INIT_FAILED:
143 case KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED:
144 case KLDR_ERR_MODULE_INIT_FAILED_ALREADY:
145 case KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED_ALREADY:
146 case KLDR_ERR_PREREQUISITE_RECURSED_TOO_DEEPLY:
147 case KLDR_ERR_THREAD_ATTACH_FAILED:
148 case KRDR_ERR_TOO_MANY_MAPPINGS:
149 case KLDR_ERR_NOT_DLL:
150 case KLDR_ERR_NOT_EXE:
151 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_LDR_GENERAL_FAILURE);
152
153
154 case KLDR_ERR_PE_UNSUPPORTED_MACHINE:
155 case KLDR_ERR_PE_BAD_FILE_HEADER:
156 case KLDR_ERR_PE_BAD_OPTIONAL_HEADER:
157 case KLDR_ERR_PE_BAD_SECTION_HEADER:
158 case KLDR_ERR_PE_BAD_FORWARDER:
159 case KLDR_ERR_PE_FORWARDER_IMPORT_NOT_FOUND:
160 case KLDR_ERR_PE_BAD_FIXUP:
161 case KLDR_ERR_PE_BAD_IMPORT:
162 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_LDR_GENERAL_FAILURE);
163
164 case KLDR_ERR_LX_BAD_HEADER:
165 case KLDR_ERR_LX_BAD_LOADER_SECTION:
166 case KLDR_ERR_LX_BAD_FIXUP_SECTION:
167 case KLDR_ERR_LX_BAD_OBJECT_TABLE:
168 case KLDR_ERR_LX_BAD_PAGE_MAP:
169 case KLDR_ERR_LX_BAD_ITERDATA:
170 case KLDR_ERR_LX_BAD_ITERDATA2:
171 case KLDR_ERR_LX_BAD_BUNDLE:
172 case KLDR_ERR_LX_NO_SONAME:
173 case KLDR_ERR_LX_BAD_SONAME:
174 case KLDR_ERR_LX_BAD_FORWARDER:
175 case KLDR_ERR_LX_NRICHAIN_NOT_SUPPORTED:
176 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_LDR_GENERAL_FAILURE);
177
178 case KLDR_ERR_MACHO_UNSUPPORTED_FILE_TYPE: return VERR_LDR_GENERAL_FAILURE;
179 case KLDR_ERR_MACHO_OTHER_ENDIAN_NOT_SUPPORTED:
180 case KLDR_ERR_MACHO_BAD_HEADER:
181 case KLDR_ERR_MACHO_UNSUPPORTED_MACHINE:
182 case KLDR_ERR_MACHO_BAD_LOAD_COMMAND:
183 case KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND:
184 case KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND:
185 case KLDR_ERR_MACHO_BAD_SECTION:
186 case KLDR_ERR_MACHO_UNSUPPORTED_SECTION:
187#ifdef KLDR_ERR_MACHO_UNSUPPORTED_INIT_SECTION
188 case KLDR_ERR_MACHO_UNSUPPORTED_INIT_SECTION:
189 case KLDR_ERR_MACHO_UNSUPPORTED_TERM_SECTION:
190#endif
191 case KLDR_ERR_MACHO_UNKNOWN_SECTION:
192 case KLDR_ERR_MACHO_BAD_SECTION_ORDER:
193 case KLDR_ERR_MACHO_BIT_MIX:
194 case KLDR_ERR_MACHO_BAD_OBJECT_FILE:
195 case KLDR_ERR_MACHO_BAD_SYMBOL:
196 case KLDR_ERR_MACHO_UNSUPPORTED_FIXUP_TYPE:
197 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_LDR_GENERAL_FAILURE);
198
199 default:
200 if (RT_FAILURE(krc))
201 return krc;
202 AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_NO_TRANSLATION);
203 }
204}
205
206
207/**
208 * Converts a IPRT error code to an kLdr one.
209 */
210static int rtkldrConvertErrorFromIPRT(int rc)
211{
212 if (RT_SUCCESS(rc))
213 return 0;
214 switch (rc)
215 {
216 case VERR_NO_MEMORY: return KERR_NO_MEMORY;
217 case VERR_INVALID_PARAMETER: return KERR_INVALID_PARAMETER;
218 case VERR_INVALID_HANDLE: return KERR_INVALID_HANDLE;
219 case VERR_BUFFER_OVERFLOW: return KERR_BUFFER_OVERFLOW;
220 default:
221 return rc;
222 }
223}
224
225
226
227
228
229
230/** @interface_method_impl{KLDRRDROPS,pfnCreate}
231 * @remark This is a dummy which isn't used. */
232static int rtkldrRdr_Create( PPKRDR ppRdr, const char *pszFilename)
233{
234 NOREF(ppRdr); NOREF(pszFilename);
235 AssertReleaseFailed();
236 return -1;
237}
238
239
240/** @interface_method_impl{KLDRRDROPS,pfnDestroy} */
241static int rtkldrRdr_Destroy( PKRDR pRdr)
242{
243 PRTKLDRRDR pThis = (PRTKLDRRDR)pRdr;
244 pThis->pReader = NULL;
245 RTMemFree(pThis);
246 return 0;
247}
248
249
250/** @interface_method_impl{KLDRRDROPS,pfnRead} */
251static int rtkldrRdr_Read( PKRDR pRdr, void *pvBuf, KSIZE cb, KFOFF off)
252{
253 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
254 int rc = pReader->pfnRead(pReader, pvBuf, cb, off);
255 return rtkldrConvertErrorFromIPRT(rc);
256}
257
258
259/** @interface_method_impl{KLDRRDROPS,pfnAllMap} */
260static int rtkldrRdr_AllMap( PKRDR pRdr, const void **ppvBits)
261{
262 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
263 int rc = pReader->pfnMap(pReader, ppvBits);
264 return rtkldrConvertErrorFromIPRT(rc);
265}
266
267
268/** @interface_method_impl{KLDRRDROPS,pfnAllUnmap} */
269static int rtkldrRdr_AllUnmap(PKRDR pRdr, const void *pvBits)
270{
271 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
272 int rc = pReader->pfnUnmap(pReader, pvBits);
273 return rtkldrConvertErrorFromIPRT(rc);
274}
275
276
277/** @interface_method_impl{KLDRRDROPS,pfnSize} */
278static KFOFF rtkldrRdr_Size( PKRDR pRdr)
279{
280 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
281 return (KFOFF)pReader->pfnSize(pReader);
282}
283
284
285/** @interface_method_impl{KLDRRDROPS,pfnTell} */
286static KFOFF rtkldrRdr_Tell( PKRDR pRdr)
287{
288 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
289 return (KFOFF)pReader->pfnTell(pReader);
290}
291
292
293/** @interface_method_impl{KLDRRDROPS,pfnName} */
294static const char * rtkldrRdr_Name(PKRDR pRdr)
295{
296 PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
297 return pReader->pfnLogName(pReader);
298}
299
300
301/** @interface_method_impl{KLDRRDROPS,pfnNativeFH} */
302static KIPTR rtkldrRdr_NativeFH(PKRDR pRdr)
303{
304 NOREF(pRdr);
305 AssertFailed();
306 return -1;
307}
308
309
310/** @interface_method_impl{KLDRRDROPS,pfnPageSize} */
311static KSIZE rtkldrRdr_PageSize(PKRDR pRdr)
312{
313 NOREF(pRdr);
314 return PAGE_SIZE;
315}
316
317
318/** @interface_method_impl{KLDRRDROPS,pfnMap} */
319static int rtkldrRdr_Map( PKRDR pRdr, void **ppvBase, KU32 cSegments, PCKLDRSEG paSegments, KBOOL fFixed)
320{
321 //PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
322 NOREF(pRdr); NOREF(ppvBase); NOREF(cSegments); NOREF(paSegments); NOREF(fFixed);
323 AssertFailed();
324 return -1;
325}
326
327
328/** @interface_method_impl{KLDRRDROPS,pfnRefresh} */
329static int rtkldrRdr_Refresh( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments)
330{
331 //PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
332 NOREF(pRdr); NOREF(pvBase); NOREF(cSegments); NOREF(paSegments);
333 AssertFailed();
334 return -1;
335}
336
337
338/** @interface_method_impl{KLDRRDROPS,pfnProtect} */
339static int rtkldrRdr_Protect( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments, KBOOL fUnprotectOrProtect)
340{
341 //PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
342 NOREF(pRdr); NOREF(pvBase); NOREF(cSegments); NOREF(paSegments); NOREF(fUnprotectOrProtect);
343 AssertFailed();
344 return -1;
345}
346
347
348/** @interface_method_impl{KLDRRDROPS,pfnUnmap} */
349static int rtkldrRdr_Unmap( PKRDR pRdr, void *pvBase, KU32 cSegments, PCKLDRSEG paSegments)
350{
351 //PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
352 NOREF(pRdr); NOREF(pvBase); NOREF(cSegments); NOREF(paSegments);
353 AssertFailed();
354 return -1;
355}
356
357/** @interface_method_impl{KLDRRDROPS,pfnDone} */
358static void rtkldrRdr_Done( PKRDR pRdr)
359{
360 NOREF(pRdr);
361 //PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
362}
363
364
365/**
366 * The file reader operations.
367 * We provide our own based on IPRT instead of using the kLdr ones.
368 */
369extern "C" const KRDROPS g_kLdrRdrFileOps;
370extern "C" const KRDROPS g_kLdrRdrFileOps =
371{
372 /* .pszName = */ "IPRT",
373 /* .pNext = */ NULL,
374 /* .pfnCreate = */ rtkldrRdr_Create,
375 /* .pfnDestroy = */ rtkldrRdr_Destroy,
376 /* .pfnRead = */ rtkldrRdr_Read,
377 /* .pfnAllMap = */ rtkldrRdr_AllMap,
378 /* .pfnAllUnmap = */ rtkldrRdr_AllUnmap,
379 /* .pfnSize = */ rtkldrRdr_Size,
380 /* .pfnTell = */ rtkldrRdr_Tell,
381 /* .pfnName = */ rtkldrRdr_Name,
382 /* .pfnNativeFH = */ rtkldrRdr_NativeFH,
383 /* .pfnPageSize = */ rtkldrRdr_PageSize,
384 /* .pfnMap = */ rtkldrRdr_Map,
385 /* .pfnRefresh = */ rtkldrRdr_Refresh,
386 /* .pfnProtect = */ rtkldrRdr_Protect,
387 /* .pfnUnmap = */ rtkldrRdr_Unmap,
388 /* .pfnDone = */ rtkldrRdr_Done,
389 /* .u32Dummy = */ 42
390};
391
392
393
394
395
396/** @interface_method_impl{RTLDROPS,pfnClose} */
397static DECLCALLBACK(int) rtkldr_Close(PRTLDRMODINTERNAL pMod)
398{
399 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
400 int rc = kLdrModClose(pModkLdr);
401 return rtkldrConvertError(rc);
402}
403
404
405/** @interface_method_impl{RTLDROPS,pfnDone} */
406static DECLCALLBACK(int) rtkldr_Done(PRTLDRMODINTERNAL pMod)
407{
408 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
409 int rc = kLdrModMostlyDone(pModkLdr);
410 return rtkldrConvertError(rc);
411}
412
413
414/** @copydoc FNKLDRMODENUMSYMS */
415static int rtkldrEnumSymbolsWrapper(PKLDRMOD pMod, uint32_t iSymbol,
416 const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion,
417 KLDRADDR uValue, uint32_t fKind, void *pvUser)
418{
419 PRTLDRMODKLDRARGS pArgs = (PRTLDRMODKLDRARGS)pvUser;
420 NOREF(pMod); NOREF(pszVersion); NOREF(fKind);
421
422 /* If not zero terminated we'll have to use a temporary buffer. */
423 const char *pszSymbol = pchSymbol;
424 if (pchSymbol && pchSymbol[cchSymbol])
425 {
426 char *psz = (char *)alloca(cchSymbol + 1);
427 memcpy(psz, pchSymbol, cchSymbol);
428 psz[cchSymbol] = '\0';
429 pszSymbol = psz;
430 }
431
432#if defined(RT_OS_OS2) || defined(RT_OS_DARWIN)
433 /* skip the underscore prefix. */
434 if (*pszSymbol == '_')
435 pszSymbol++;
436#endif
437
438 int rc = pArgs->u.pfnEnumSyms(&pArgs->pMod->Core, pszSymbol, iSymbol, uValue, pArgs->pvUser);
439 if (RT_FAILURE(rc))
440 return rc; /* don't bother converting. */
441 return 0;
442}
443
444
445/** @interface_method_impl{RTLDROPS,pfnEnumSymbols} */
446static DECLCALLBACK(int) rtkldr_EnumSymbols(PRTLDRMODINTERNAL pMod, unsigned fFlags, const void *pvBits, RTUINTPTR BaseAddress,
447 PFNRTLDRENUMSYMS pfnCallback, void *pvUser)
448{
449 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
450 RTLDRMODKLDRARGS Args;
451 Args.pvUser = pvUser;
452 Args.u.pfnEnumSyms = pfnCallback;
453 Args.pMod = (PRTLDRMODKLDR)pMod;
454 Args.pvBits = pvBits;
455 Args.rc = VINF_SUCCESS;
456 int rc = kLdrModEnumSymbols(pModkLdr, pvBits, BaseAddress,
457 fFlags & RTLDR_ENUM_SYMBOL_FLAGS_ALL ? KLDRMOD_ENUM_SYMS_FLAGS_ALL : 0,
458 rtkldrEnumSymbolsWrapper, &Args);
459 if (Args.rc != VINF_SUCCESS)
460 rc = Args.rc;
461 else
462 rc = rtkldrConvertError(rc);
463 return rc;
464}
465
466
467/** @interface_method_impl{RTLDROPS,pfnGetImageSize} */
468static DECLCALLBACK(size_t) rtkldr_GetImageSize(PRTLDRMODINTERNAL pMod)
469{
470 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
471 return kLdrModSize(pModkLdr);
472}
473
474
475/** @copydoc FNKLDRMODGETIMPORT */
476static int rtkldrGetImportWrapper(PKLDRMOD pMod, uint32_t iImport, uint32_t iSymbol, const char *pchSymbol, KSIZE cchSymbol,
477 const char *pszVersion, PKLDRADDR puValue, uint32_t *pfKind, void *pvUser)
478{
479 PRTLDRMODKLDRARGS pArgs = (PRTLDRMODKLDRARGS)pvUser;
480 NOREF(pMod); NOREF(pszVersion); NOREF(pfKind);
481
482 /* If not zero terminated we'll have to use a temporary buffer. */
483 const char *pszSymbol = pchSymbol;
484 if (pchSymbol && pchSymbol[cchSymbol])
485 {
486 char *psz = (char *)alloca(cchSymbol + 1);
487 memcpy(psz, pchSymbol, cchSymbol);
488 psz[cchSymbol] = '\0';
489 pszSymbol = psz;
490 }
491
492#if defined(RT_OS_OS2) || defined(RT_OS_DARWIN)
493 /* skip the underscore prefix. */
494 if (*pszSymbol == '_')
495 pszSymbol++;
496#endif
497
498 /* get the import module name - TODO: cache this */
499 const char *pszModule = NULL;
500 if (iImport != NIL_KLDRMOD_IMPORT)
501 {
502 char *pszBuf = (char *)alloca(64);
503 int rc = kLdrModGetImport(pMod, pArgs->pvBits, iImport, pszBuf, 64);
504 if (rc)
505 return rc;
506 pszModule = pszBuf;
507 }
508
509 /* do the query */
510 RTUINTPTR Value;
511 int rc = pArgs->u.pfnGetImport(&pArgs->pMod->Core, pszModule, pszSymbol, pszSymbol ? ~0 : iSymbol, &Value, pArgs->pvUser);
512 if (RT_SUCCESS(rc))
513 {
514 *puValue = Value;
515 return 0;
516 }
517 return rtkldrConvertErrorFromIPRT(rc);
518}
519
520
521/** @interface_method_impl{RTLDROPS,pfnGetBits} */
522static DECLCALLBACK(int) rtkldr_GetBits(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR BaseAddress,
523 PFNRTLDRIMPORT pfnGetImport, void *pvUser)
524{
525 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
526 RTLDRMODKLDRARGS Args;
527 Args.pvUser = pvUser;
528 Args.u.pfnGetImport = pfnGetImport;
529 Args.pMod = (PRTLDRMODKLDR)pMod;
530 Args.pvBits = pvBits;
531 Args.rc = VINF_SUCCESS;
532 int rc = kLdrModGetBits(pModkLdr, pvBits, BaseAddress, rtkldrGetImportWrapper, &Args);
533 if (Args.rc != VINF_SUCCESS)
534 rc = Args.rc;
535 else
536 rc = rtkldrConvertError(rc);
537 return rc;
538}
539
540
541/** @interface_method_impl{RTLDROPS,pfnRelocate} */
542static DECLCALLBACK(int) rtkldr_Relocate(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR NewBaseAddress,
543 RTUINTPTR OldBaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser)
544{
545 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
546 RTLDRMODKLDRARGS Args;
547 Args.pvUser = pvUser;
548 Args.u.pfnGetImport = pfnGetImport;
549 Args.pMod = (PRTLDRMODKLDR)pMod;
550 Args.pvBits = pvBits;
551 Args.rc = VINF_SUCCESS;
552 int rc = kLdrModRelocateBits(pModkLdr, pvBits, NewBaseAddress, OldBaseAddress, rtkldrGetImportWrapper, &Args);
553 if (Args.rc != VINF_SUCCESS)
554 rc = Args.rc;
555 else
556 rc = rtkldrConvertError(rc);
557 return rc;
558}
559
560
561/** @interface_method_impl{RTLDROPS,pfnGetSymbolEx} */
562static DECLCALLBACK(int) rtkldr_GetSymbolEx(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress,
563 uint32_t iOrdinal, const char *pszSymbol, RTUINTPTR *pValue)
564{
565 PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
566 KLDRADDR uValue;
567
568#if defined(RT_OS_OS2) || defined(RT_OS_DARWIN)
569 /*
570 * Add underscore prefix.
571 */
572 if (pszSymbol)
573 {
574 size_t cch = strlen(pszSymbol);
575 char *psz = (char *)alloca(cch + 2);
576 memcpy(psz + 1, pszSymbol, cch + 1);
577 *psz = '_';
578 pszSymbol = psz;
579 }
580#endif
581
582 int rc = kLdrModQuerySymbol(pModkLdr, pvBits, BaseAddress,
583 iOrdinal == UINT32_MAX ? NIL_KLDRMOD_SYM_ORDINAL : iOrdinal,
584 pszSymbol, strlen(pszSymbol), NULL,
585 NULL, NULL,
586 &uValue, NULL);
587 if (!rc)
588 {
589 *pValue = uValue;
590 return VINF_SUCCESS;
591 }
592 return rtkldrConvertError(rc);
593}
594
595
596/** @copydoc FNKLDRENUMDBG */
597static int rtkldrEnumDbgInfoWrapper(PKLDRMOD pMod, KU32 iDbgInfo, KLDRDBGINFOTYPE enmType, KI16 iMajorVer, KI16 iMinorVer,
598 const char *pszPartNm, KLDRFOFF offFile, KLDRADDR LinkAddress, KLDRSIZE cb,
599 const char *pszExtFile, void *pvUser)
600{
601 PRTLDRMODKLDRARGS pArgs = (PRTLDRMODKLDRARGS)pvUser;
602 RT_NOREF_PV(pMod); RT_NOREF_PV(iMajorVer); RT_NOREF_PV(iMinorVer);
603
604
605 RTLDRDBGINFO DbgInfo;
606 RT_ZERO(DbgInfo.u);
607 DbgInfo.iDbgInfo = iDbgInfo;
608 DbgInfo.offFile = offFile;
609 DbgInfo.LinkAddress = LinkAddress;
610 DbgInfo.cb = cb;
611 DbgInfo.pszExtFile = pszExtFile;
612
613 switch (enmType)
614 {
615 case KLDRDBGINFOTYPE_UNKNOWN:
616 DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN;
617 break;
618 case KLDRDBGINFOTYPE_STABS:
619 DbgInfo.enmType = RTLDRDBGINFOTYPE_STABS;
620 break;
621 case KLDRDBGINFOTYPE_DWARF:
622 DbgInfo.enmType = RTLDRDBGINFOTYPE_DWARF;
623 if (!pszExtFile)
624 DbgInfo.u.Dwarf.pszSection = pszPartNm;
625 else
626 {
627 DbgInfo.enmType = RTLDRDBGINFOTYPE_DWARF_DWO;
628 DbgInfo.u.Dwo.uCrc32 = 0;
629 }
630 break;
631 case KLDRDBGINFOTYPE_CODEVIEW:
632 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW;
633 /* Should make some more effort here... Assume the IPRT loader will kick in before we get here! */
634 break;
635 case KLDRDBGINFOTYPE_WATCOM:
636 DbgInfo.enmType = RTLDRDBGINFOTYPE_WATCOM;
637 break;
638 case KLDRDBGINFOTYPE_HLL:
639 DbgInfo.enmType = RTLDRDBGINFOTYPE_HLL;
640 break;
641 default:
642 AssertFailed();
643 DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN;
644 break;
645 }
646
647 int rc = pArgs->u.pfnEnumDbgInfo(&pArgs->pMod->Core, &DbgInfo, pArgs->pvUser);
648 if (RT_FAILURE(rc))
649 return rc; /* don't bother converting. */
650 return 0;
651}
652
653
654/** @interface_method_impl{RTLDROPS,pfnEnumDbgInfo} */
655static DECLCALLBACK(int) rtkldr_EnumDbgInfo(PRTLDRMODINTERNAL pMod, const void *pvBits,
656 PFNRTLDRENUMDBG pfnCallback, void *pvUser)
657{
658 PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod;
659 RTLDRMODKLDRARGS Args;
660 Args.pvUser = pvUser;
661 Args.u.pfnEnumDbgInfo = pfnCallback;
662 Args.pvBits = pvBits;
663 Args.pMod = pThis;
664 Args.rc = VINF_SUCCESS;
665 int rc = kLdrModEnumDbgInfo(pThis->pMod, pvBits, rtkldrEnumDbgInfoWrapper, &Args);
666 if (Args.rc != VINF_SUCCESS)
667 rc = Args.rc;
668 return rc;
669}
670
671
672/** @interface_method_impl{RTLDROPS,pfnEnumSegments} */
673static DECLCALLBACK(int) rtkldr_EnumSegments(PRTLDRMODINTERNAL pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
674{
675 PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod;
676 uint32_t const cSegments = pThis->pMod->cSegments;
677 PCKLDRSEG paSegments = &pThis->pMod->aSegments[0];
678 char szName[128];
679
680 for (uint32_t iSeg = 0; iSeg < cSegments; iSeg++)
681 {
682 RTLDRSEG Seg;
683
684 if (!paSegments[iSeg].cchName)
685 {
686 Seg.pszName = szName;
687 Seg.cchName = (uint32_t)RTStrPrintf(szName, sizeof(szName), "Seg%02u", iSeg);
688 }
689 else if (paSegments[iSeg].pchName[paSegments[iSeg].cchName])
690 {
691 AssertReturn(paSegments[iSeg].cchName < sizeof(szName), VERR_INTERNAL_ERROR_3);
692 RTStrCopyEx(szName, sizeof(szName), paSegments[iSeg].pchName, paSegments[iSeg].cchName);
693 Seg.pszName = szName;
694 Seg.cchName = paSegments[iSeg].cchName;
695 }
696 else
697 {
698 Seg.pszName = paSegments[iSeg].pchName;
699 Seg.cchName = paSegments[iSeg].cchName;
700 }
701 Seg.SelFlat = paSegments[iSeg].SelFlat;
702 Seg.Sel16bit = paSegments[iSeg].Sel16bit;
703 Seg.fFlags = paSegments[iSeg].fFlags;
704 AssertCompile(KLDRSEG_FLAG_16BIT == RTLDRSEG_FLAG_16BIT );
705 AssertCompile(KLDRSEG_FLAG_OS2_ALIAS16 == RTLDRSEG_FLAG_OS2_ALIAS16);
706 AssertCompile(KLDRSEG_FLAG_OS2_CONFORM == RTLDRSEG_FLAG_OS2_CONFORM);
707 AssertCompile(KLDRSEG_FLAG_OS2_IOPL == RTLDRSEG_FLAG_OS2_IOPL );
708
709 switch (paSegments[iSeg].enmProt)
710 {
711 default:
712 AssertMsgFailed(("%d\n", paSegments[iSeg].enmProt));
713 RT_FALL_THRU();
714 case KPROT_NOACCESS:
715 Seg.fProt = 0;
716 break;
717
718 case KPROT_READONLY: Seg.fProt = RTMEM_PROT_READ; break;
719 case KPROT_READWRITE: Seg.fProt = RTMEM_PROT_READ | RTMEM_PROT_WRITE; break;
720 case KPROT_WRITECOPY: Seg.fProt = RTMEM_PROT_WRITE; break;
721 case KPROT_EXECUTE: Seg.fProt = RTMEM_PROT_EXEC; break;
722 case KPROT_EXECUTE_READ: Seg.fProt = RTMEM_PROT_EXEC | RTMEM_PROT_READ; break;
723 case KPROT_EXECUTE_READWRITE: Seg.fProt = RTMEM_PROT_EXEC | RTMEM_PROT_READ | RTMEM_PROT_WRITE; break;
724 case KPROT_EXECUTE_WRITECOPY: Seg.fProt = RTMEM_PROT_EXEC | RTMEM_PROT_WRITE; break;
725 }
726 Seg.cb = paSegments[iSeg].cb;
727 Seg.Alignment = paSegments[iSeg].Alignment;
728 Seg.LinkAddress = paSegments[iSeg].LinkAddress;
729 Seg.offFile = paSegments[iSeg].offFile;
730 Seg.cbFile = paSegments[iSeg].cbFile;
731 Seg.RVA = paSegments[iSeg].RVA;
732 Seg.cbMapped = paSegments[iSeg].cbMapped;
733
734 int rc = pfnCallback(pMod, &Seg, pvUser);
735 if (rc != VINF_SUCCESS)
736 return rc;
737 }
738
739 return VINF_SUCCESS;
740}
741
742
743/** @interface_method_impl{RTLDROPS,pfnLinkAddressToSegOffset} */
744static DECLCALLBACK(int) rtkldr_LinkAddressToSegOffset(PRTLDRMODINTERNAL pMod, RTLDRADDR LinkAddress,
745 uint32_t *piSeg, PRTLDRADDR poffSeg)
746{
747 PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod;
748 uint32_t const cSegments = pThis->pMod->cSegments;
749 PCKLDRSEG paSegments = &pThis->pMod->aSegments[0];
750
751 for (uint32_t iSeg = 0; iSeg < cSegments; iSeg++)
752 {
753 KLDRADDR offSeg = LinkAddress - paSegments[iSeg].LinkAddress;
754 if ( offSeg < paSegments[iSeg].cbMapped
755 || offSeg < paSegments[iSeg].cb)
756 {
757 *piSeg = iSeg;
758 *poffSeg = offSeg;
759 return VINF_SUCCESS;
760 }
761 }
762
763 return VERR_LDR_INVALID_LINK_ADDRESS;
764}
765
766
767/** @interface_method_impl{RTLDROPS,pfnLinkAddressToRva}. */
768static DECLCALLBACK(int) rtkldr_LinkAddressToRva(PRTLDRMODINTERNAL pMod, RTLDRADDR LinkAddress, PRTLDRADDR pRva)
769{
770 PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod;
771 uint32_t const cSegments = pThis->pMod->cSegments;
772 PCKLDRSEG paSegments = &pThis->pMod->aSegments[0];
773
774 for (uint32_t iSeg = 0; iSeg < cSegments; iSeg++)
775 {
776 KLDRADDR offSeg = LinkAddress - paSegments[iSeg].LinkAddress;
777 if ( offSeg < paSegments[iSeg].cbMapped
778 || offSeg < paSegments[iSeg].cb)
779 {
780 *pRva = paSegments[iSeg].RVA + offSeg;
781 return VINF_SUCCESS;
782 }
783 }
784
785 return VERR_LDR_INVALID_RVA;
786}
787
788
789/** @interface_method_impl{RTLDROPS,pfnSegOffsetToRva} */
790static DECLCALLBACK(int) rtkldr_SegOffsetToRva(PRTLDRMODINTERNAL pMod, uint32_t iSeg, RTLDRADDR offSeg, PRTLDRADDR pRva)
791{
792 PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod;
793
794 if (iSeg >= pThis->pMod->cSegments)
795 return VERR_LDR_INVALID_SEG_OFFSET;
796 PCKLDRSEG const pSegment = &pThis->pMod->aSegments[iSeg];
797
798 if ( offSeg > pSegment->cbMapped
799 && offSeg > pSegment->cb
800 && ( pSegment->cbFile < 0
801 || offSeg > (uint64_t)pSegment->cbFile))
802 return VERR_LDR_INVALID_SEG_OFFSET;
803
804 *pRva = pSegment->RVA + offSeg;
805 return VINF_SUCCESS;
806}
807
808
809/** @interface_method_impl{RTLDROPS,pfnRvaToSegOffset} */
810static DECLCALLBACK(int) rtkldr_RvaToSegOffset(PRTLDRMODINTERNAL pMod, RTLDRADDR Rva, uint32_t *piSeg, PRTLDRADDR poffSeg)
811{
812 PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod;
813 uint32_t const cSegments = pThis->pMod->cSegments;
814 PCKLDRSEG paSegments = &pThis->pMod->aSegments[0];
815
816 for (uint32_t iSeg = 0; iSeg < cSegments; iSeg++)
817 {
818 KLDRADDR offSeg = Rva - paSegments[iSeg].RVA;
819 if ( offSeg < paSegments[iSeg].cbMapped
820 || offSeg < paSegments[iSeg].cb)
821 {
822 *piSeg = iSeg;
823 *poffSeg = offSeg;
824 return VINF_SUCCESS;
825 }
826 }
827
828 return VERR_LDR_INVALID_RVA;
829}
830
831
832/** @interface_method_impl{RTLDROPS,pfnReadDbgInfo} */
833static DECLCALLBACK(int) rtkldr_ReadDbgInfo(PRTLDRMODINTERNAL pMod, uint32_t iDbgInfo, RTFOFF off, size_t cb, void *pvBuf)
834{
835 PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod;
836 RT_NOREF_PV(iDbgInfo);
837 /** @todo May have to apply fixups here. */
838 return pThis->Core.pReader->pfnRead(pThis->Core.pReader, pvBuf, cb, off);
839}
840
841
842/** @interface_method_impl{RTLDROPS,pfnQueryProp} */
843static DECLCALLBACK(int) rtkldr_QueryProp(PRTLDRMODINTERNAL pMod, RTLDRPROP enmProp, void const *pvBits,
844 void *pvBuf, size_t cbBuf, size_t *pcbRet)
845{
846 PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod;
847 int rc;
848 size_t const cbBufAvail = cbBuf;
849 switch (enmProp)
850 {
851 case RTLDRPROP_UUID:
852 rc = kLdrModQueryImageUuid(pThis->pMod, /*pvBits*/ NULL, (uint8_t *)pvBuf, cbBuf);
853 if (rc == KLDR_ERR_NO_IMAGE_UUID)
854 return VERR_NOT_FOUND;
855 AssertReturn(rc == 0, VERR_INVALID_PARAMETER);
856 cbBuf = RT_MIN(cbBuf, sizeof(RTUUID));
857 break;
858
859 case RTLDRPROP_INTERNAL_NAME:
860 if (!pThis->pMod->cchName)
861 return VERR_NOT_FOUND;
862 cbBuf = pThis->pMod->cchName + 1;
863 if (cbBufAvail < cbBuf)
864 {
865 if (pcbRet)
866 *pcbRet = cbBufAvail;
867 return VERR_BUFFER_OVERFLOW;
868 }
869 memcpy(pvBuf, pThis->pMod->pszName, cbBuf);
870 break;
871
872 default:
873 return VERR_NOT_FOUND;
874 }
875 if (pcbRet)
876 *pcbRet = cbBuf;
877 RT_NOREF_PV(pvBits);
878 return VINF_SUCCESS;
879}
880
881
882/**
883 * Operations for a kLdr module.
884 */
885static const RTLDROPS g_rtkldrOps =
886{
887 "kLdr",
888 rtkldr_Close,
889 NULL,
890 rtkldr_Done,
891 rtkldr_EnumSymbols,
892 /* ext */
893 rtkldr_GetImageSize,
894 rtkldr_GetBits,
895 rtkldr_Relocate,
896 rtkldr_GetSymbolEx,
897 NULL /*pfnQueryForwarderInfo*/,
898 rtkldr_EnumDbgInfo,
899 rtkldr_EnumSegments,
900 rtkldr_LinkAddressToSegOffset,
901 rtkldr_LinkAddressToRva,
902 rtkldr_SegOffsetToRva,
903 rtkldr_RvaToSegOffset,
904 rtkldr_ReadDbgInfo,
905 rtkldr_QueryProp,
906 NULL,
907 NULL,
908 NULL /*pfnUnwindFrame*/,
909 42
910};
911
912
913/**
914 * Open a image using kLdr.
915 *
916 * @returns iprt status code.
917 * @param pReader The loader reader instance which will provide the raw image bits.
918 * @param fFlags Reserved, MBZ.
919 * @param enmArch CPU architecture specifier for the image to be loaded.
920 * @param phLdrMod Where to store the handle.
921 * @param pErrInfo Where to return extended error information. Optional.
922 */
923int rtldrkLdrOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo)
924{
925 RT_NOREF_PV(pErrInfo);
926
927 /* Convert enmArch to k-speak. */
928 KCPUARCH enmCpuArch;
929 switch (enmArch)
930 {
931 case RTLDRARCH_WHATEVER:
932 enmCpuArch = KCPUARCH_UNKNOWN;
933 break;
934 case RTLDRARCH_X86_16:
935 enmCpuArch = KCPUARCH_X86_16;
936 break;
937 case RTLDRARCH_X86_32:
938 enmCpuArch = KCPUARCH_X86_32;
939 break;
940 case RTLDRARCH_AMD64:
941 enmCpuArch = KCPUARCH_AMD64;
942 break;
943 case RTLDRARCH_ARM32:
944 enmCpuArch = KCPUARCH_ARM_32;
945 break;
946 case RTLDRARCH_ARM64:
947 enmCpuArch = KCPUARCH_ARM_64;
948 break;
949 default:
950 return VERR_INVALID_PARAMETER;
951 }
952 KU32 fKFlags = 0;
953 if (fFlags & RTLDR_O_FOR_DEBUG)
954 fKFlags |= KLDRMOD_OPEN_FLAGS_FOR_INFO;
955
956 /* Create a rtkldrRdr_ instance. */
957 PRTKLDRRDR pRdr = (PRTKLDRRDR)RTMemAllocZ(sizeof(*pRdr));
958 if (!pRdr)
959 return VERR_NO_MEMORY;
960 pRdr->Core.u32Magic = KRDR_MAGIC;
961 pRdr->Core.pOps = &g_kLdrRdrFileOps;
962 pRdr->pReader = pReader;
963
964 /* Try open it. */
965 PKLDRMOD pMod;
966 int krc = kLdrModOpenFromRdr(&pRdr->Core, fKFlags, enmCpuArch, &pMod);
967 if (!krc)
968 {
969 /* Create a module wrapper for it. */
970 PRTLDRMODKLDR pNewMod = (PRTLDRMODKLDR)RTMemAllocZ(sizeof(*pNewMod));
971 if (pNewMod)
972 {
973 pNewMod->Core.u32Magic = RTLDRMOD_MAGIC;
974 pNewMod->Core.eState = LDR_STATE_OPENED;
975 pNewMod->Core.pOps = &g_rtkldrOps;
976 pNewMod->Core.pReader = pReader;
977 switch (pMod->enmFmt)
978 {
979 case KLDRFMT_NATIVE: pNewMod->Core.enmFormat = RTLDRFMT_NATIVE; break;
980 case KLDRFMT_AOUT: pNewMod->Core.enmFormat = RTLDRFMT_AOUT; break;
981 case KLDRFMT_ELF: pNewMod->Core.enmFormat = RTLDRFMT_ELF; break;
982 case KLDRFMT_LX: pNewMod->Core.enmFormat = RTLDRFMT_LX; break;
983 case KLDRFMT_MACHO: pNewMod->Core.enmFormat = RTLDRFMT_MACHO; break;
984 case KLDRFMT_PE: pNewMod->Core.enmFormat = RTLDRFMT_PE; break;
985 default:
986 AssertMsgFailed(("%d\n", pMod->enmFmt));
987 pNewMod->Core.enmFormat = RTLDRFMT_NATIVE;
988 break;
989 }
990 switch (pMod->enmType)
991 {
992 case KLDRTYPE_OBJECT: pNewMod->Core.enmType = RTLDRTYPE_OBJECT; break;
993 case KLDRTYPE_EXECUTABLE_FIXED: pNewMod->Core.enmType = RTLDRTYPE_EXECUTABLE_FIXED; break;
994 case KLDRTYPE_EXECUTABLE_RELOCATABLE: pNewMod->Core.enmType = RTLDRTYPE_EXECUTABLE_RELOCATABLE; break;
995 case KLDRTYPE_EXECUTABLE_PIC: pNewMod->Core.enmType = RTLDRTYPE_EXECUTABLE_PIC; break;
996 case KLDRTYPE_SHARED_LIBRARY_FIXED: pNewMod->Core.enmType = RTLDRTYPE_SHARED_LIBRARY_FIXED; break;
997 case KLDRTYPE_SHARED_LIBRARY_RELOCATABLE: pNewMod->Core.enmType = RTLDRTYPE_SHARED_LIBRARY_RELOCATABLE; break;
998 case KLDRTYPE_SHARED_LIBRARY_PIC: pNewMod->Core.enmType = RTLDRTYPE_SHARED_LIBRARY_PIC; break;
999 case KLDRTYPE_FORWARDER_DLL: pNewMod->Core.enmType = RTLDRTYPE_FORWARDER_DLL; break;
1000 case KLDRTYPE_CORE: pNewMod->Core.enmType = RTLDRTYPE_CORE; break;
1001 case KLDRTYPE_DEBUG_INFO: pNewMod->Core.enmType = RTLDRTYPE_DEBUG_INFO; break;
1002 default:
1003 AssertMsgFailed(("%d\n", pMod->enmType));
1004 pNewMod->Core.enmType = RTLDRTYPE_OBJECT;
1005 break;
1006 }
1007 switch (pMod->enmEndian)
1008 {
1009 case KLDRENDIAN_LITTLE: pNewMod->Core.enmEndian = RTLDRENDIAN_LITTLE; break;
1010 case KLDRENDIAN_BIG: pNewMod->Core.enmEndian = RTLDRENDIAN_BIG; break;
1011 case KLDRENDIAN_NA: pNewMod->Core.enmEndian = RTLDRENDIAN_NA; break;
1012 default:
1013 AssertMsgFailed(("%d\n", pMod->enmEndian));
1014 pNewMod->Core.enmEndian = RTLDRENDIAN_NA;
1015 break;
1016 }
1017 switch (pMod->enmArch)
1018 {
1019 case KCPUARCH_X86_32: pNewMod->Core.enmArch = RTLDRARCH_X86_32; break;
1020 case KCPUARCH_AMD64: pNewMod->Core.enmArch = RTLDRARCH_AMD64; break;
1021 default:
1022 AssertMsgFailed(("%d\n", pMod->enmArch));
1023 pNewMod->Core.enmArch = RTLDRARCH_WHATEVER;
1024 break;
1025 }
1026 pNewMod->pMod = pMod;
1027 *phLdrMod = &pNewMod->Core;
1028
1029#ifdef LOG_ENABLED
1030 Log(("rtldrkLdrOpen: '%s' (%s) %u segments\n",
1031 pMod->pszName, pMod->pszFilename, pMod->cSegments));
1032 for (unsigned iSeg = 0; iSeg < pMod->cSegments; iSeg++)
1033 {
1034 Log(("Segment #%-2u: RVA=%08llx cb=%08llx '%.*s'\n", iSeg,
1035 pMod->aSegments[iSeg].RVA,
1036 pMod->aSegments[iSeg].cb,
1037 pMod->aSegments[iSeg].cchName,
1038 pMod->aSegments[iSeg].pchName));
1039 }
1040#endif
1041 return VINF_SUCCESS;
1042 }
1043
1044 /* bail out */
1045 kLdrModClose(pMod);
1046 krc = KERR_NO_MEMORY;
1047 }
1048 else
1049 RTMemFree(pRdr);
1050
1051 return rtkldrConvertError(krc);
1052}
1053
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