VirtualBox

source: kStuff/trunk/kLdr/kLdrModNative.c@ 89

Last change on this file since 89 was 82, checked in by bird, 8 years ago

kLdrModNative.c: Report the actual section load addresses in the aSegments[].MapAddress members.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 37.5 KB
Line 
1/* $Id: kLdrModNative.c 82 2016-08-22 21:01:51Z bird $ */
2/** @file
3 * kLdr - The Module Interpreter for the Native Loaders.
4 */
5
6/*
7 * Copyright (c) 2006-2007 Knut St. Osmundsen <[email protected]>
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#include <k/kLdr.h>
35#include "kLdrInternal.h"
36
37#if K_OS == K_OS_OS2
38# define INCL_BASE
39# include <os2.h>
40
41# ifndef LIBPATHSTRICT
42# define LIBPATHSTRICT 3
43# endif
44 extern APIRET DosQueryHeaderInfo(HMODULE hmod, ULONG ulIndex, PVOID pvBuffer, ULONG cbBuffer, ULONG ulSubFunction);
45# define QHINF_EXEINFO 1 /* NE exeinfo. */
46# define QHINF_READRSRCTBL 2 /* Reads from the resource table. */
47# define QHINF_READFILE 3 /* Reads from the executable file. */
48# define QHINF_LIBPATHLENGTH 4 /* Gets the libpath length. */
49# define QHINF_LIBPATH 5 /* Gets the entire libpath. */
50# define QHINF_FIXENTRY 6 /* NE only */
51# define QHINF_STE 7 /* NE only */
52# define QHINF_MAPSEL 8 /* NE only */
53
54#elif K_OS == K_OS_WINDOWS
55# undef IMAGE_NT_SIGNATURE
56# undef IMAGE_DOS_SIGNATURE
57# include <windows.h>
58# ifndef IMAGE_SCN_TYPE_NOLOAD
59# define IMAGE_SCN_TYPE_NOLOAD 0x00000002
60# endif
61
62/*#elif defined(__NT__)
63#include <winnt.h> */
64
65#elif K_OS == K_OS_DARWIN
66# include <dlfcn.h>
67# include <errno.h>
68
69#else
70# error "port me"
71#endif
72
73
74
75/*******************************************************************************
76* Defined Constants And Macros *
77*******************************************************************************/
78/** @def KLDRMODNATIVE_STRICT
79 * Define KLDRMODNATIVE_STRICT to enabled strict checks in KLDRMODNATIVE. */
80#define KLDRMODNATIVE_STRICT 1
81
82/** @def KLDRMODNATIVE_ASSERT
83 * Assert that an expression is true when KLDR_STRICT is defined.
84 */
85#ifdef KLDRMODNATIVE_STRICT
86# define KLDRMODNATIVE_ASSERT(expr) kHlpAssert(expr)
87#else
88# define KLDRMODNATIVE_ASSERT(expr) do {} while (0)
89#endif
90
91#if K_OS == K_OS_WINDOWS
92/** @def KLDRMODNATIVE_RVA2TYPE
93 * Converts a RVA to a pointer of the specified type.
94 * @param pvBits The bits (image base).
95 * @param uRVA The image relative virtual address.
96 * @param type The type to cast to.
97 */
98# define KLDRMODNATIVE_RVA2TYPE(pvBits, uRVA, type) \
99 ( (type) ((KUPTR)(pvBits) + (uRVA)) )
100
101#endif /* PE OSes */
102
103
104
105/*******************************************************************************
106* Structures and Typedefs *
107*******************************************************************************/
108/**
109 * Instance data for the module interpreter for the Native Loaders.
110 */
111typedef struct KLDRMODNATIVE
112{
113 /** Pointer to the module. (Follows the section table.) */
114 PKLDRMOD pMod;
115 /** Reserved flags. */
116 KU32 f32Reserved;
117 /** The number of imported modules.
118 * If ~(KU32)0 this hasn't been determined yet. */
119 KU32 cImportModules;
120#if K_OS == K_OS_OS2
121 /** The module handle. */
122 HMODULE hmod;
123
124#elif K_OS == K_OS_WINDOWS
125 /** The module handle. */
126 HANDLE hmod;
127 /** Pointer to the NT headers. */
128 const IMAGE_NT_HEADERS *pNtHdrs;
129 /** Pointer to the section header array. */
130 const IMAGE_SECTION_HEADER *paShdrs;
131
132#elif K_OS == K_OS_DARWIN
133 /** The dlopen() handle.*/
134 void *pvMod;
135
136#else
137# error "Port me"
138#endif
139} KLDRMODNATIVE, *PKLDRMODNATIVE;
140
141
142/*******************************************************************************
143* Internal Functions *
144*******************************************************************************/
145static KI32 kldrModNativeNumberOfImports(PKLDRMOD pMod, const void *pvBits);
146
147/*********************************************************************************************************************************
148* Global Variables *
149*********************************************************************************************************************************/
150extern KLDRMODOPS g_kLdrModNativeOps;
151
152
153
154/**
155 * Use native loader to load the file opened by pRdr.
156 *
157 * @returns 0 on success and *ppMod pointing to a module instance.
158 * On failure, a non-zero OS specific error code is returned.
159 * @param pOps Pointer to the registered method table.
160 * @param pRdr The file provider instance to use.
161 * @param offNewHdr The offset of the new header in MZ files. -1 if not found.
162 * @param ppMod Where to store the module instance pointer.
163 */
164static int kldrModNativeCreate(PCKLDRMODOPS pOps, PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch,
165 KLDRFOFF offNewHdr, PPKLDRMOD ppMod)
166{
167 int rc = kLdrModOpenNative(kRdrName(pRdr), ppMod);
168 if (rc)
169 return rc;
170 rc = kRdrClose(pRdr);
171 KLDRMODNATIVE_ASSERT(!rc);
172 return 0;
173}
174
175
176/**
177 * Loads a module using the native module loader.
178 *
179 * @returns 0 on success.
180 * @returns non-zero native or kLdr status code on failure.
181 * @param pszFilename The filename or module name to be loaded.
182 * @param ppMod Where to store the module interpreter instance pointer.
183 */
184int kLdrModOpenNative(const char *pszFilename, PPKLDRMOD ppMod)
185{
186 int rc;
187
188 /*
189 * Load the image.
190 */
191#if K_OS == K_OS_OS2
192 HMODULE hmod;
193
194 rc = DosLoadModule(NULL, 0, (PCSZ)pszFilename, &hmod);
195 if (rc)
196 return rc;
197 rc = kLdrModOpenNativeByHandle((KUPTR)hmod, ppMod);
198 if (rc)
199 DosFreeModule(hmod);
200
201#elif K_OS == K_OS_WINDOWS
202 HMODULE hmod;
203
204 hmod = LoadLibrary(pszFilename);
205 if (!hmod)
206 return GetLastError();
207 rc = kLdrModOpenNativeByHandle((KUPTR)hmod, ppMod);
208 if (rc)
209 FreeLibrary(hmod);
210
211#elif K_OS == K_OS_DARWIN
212 void *pvMod;
213
214 pvMod = dlopen(pszFilename, 0);
215 if (!pvMod)
216 return ENOENT;
217 rc = kLdrModOpenNativeByHandle((KUPTR)pvMod, ppMod);
218 if (rc)
219 dlclose(pvMod);
220
221#else
222# error "Port me"
223#endif
224 return rc;
225}
226
227
228/**
229 * Creates a native module interpret for an already module already
230 * loaded by the native loader.
231 *
232 * @returns 0 on success.
233 * @returns non-zero native or kLdr status code on failure.
234 * @param pszFilename The filename or module name to be loaded.
235 * @param ppMod Where to store the module interpreter instance pointer.
236 * @remark This will not make the native loader increment the load count.
237 */
238int kLdrModOpenNativeByHandle(KUPTR uHandle, PPKLDRMOD ppMod)
239{
240 KSIZE cb;
241 KU32 cchFilename;
242 KU32 cSegments;
243 PKLDRMOD pMod;
244 PKLDRMODNATIVE pModNative;
245
246 /*
247 * Delcare variables, parse the module header or whatever and determin the
248 * size of the module instance.
249 */
250#if K_OS == K_OS_OS2
251 char szFilename[CCHMAXPATH];
252 int rc;
253
254 /* get the filename. */
255 rc = DosQueryModuleName((HMODULE)uHandle, sizeof(szFilename), szFilename);
256 if (rc)
257 {
258 KLDRMODNATIVE_ASSERT(rc);
259 szFilename[0] = '\0';
260 }
261
262 /* get the segment count. */
263 /** @todo DosQueryHeaderInfo should be able to get us what we want on OS/2. */
264 cSegments = 1;
265
266#elif K_OS == K_OS_WINDOWS
267 DWORD dw;
268 char szFilename[MAX_PATH];
269 const IMAGE_NT_HEADERS *pNtHdrs;
270 const IMAGE_SECTION_HEADER *paShdrs;
271 const IMAGE_DOS_HEADER *pDosHdr = (const IMAGE_DOS_HEADER *)uHandle;
272 unsigned i;
273
274 /* get the filename. */
275 dw = GetModuleFileName((HANDLE)uHandle, szFilename, sizeof(szFilename));
276 if (dw <= 0)
277 {
278 KLDRMODNATIVE_ASSERT(dw <= 0);
279 szFilename[0] = '\0';
280 }
281
282 /* get the segment count. */
283 if (pDosHdr->e_magic == IMAGE_DOS_SIGNATURE)
284 pNtHdrs = (const IMAGE_NT_HEADERS *)((KUPTR)pDosHdr + pDosHdr->e_lfanew);
285 else
286 pNtHdrs = (const IMAGE_NT_HEADERS *)pDosHdr;
287 if (pNtHdrs->Signature != IMAGE_NT_SIGNATURE)
288 {
289 KLDRMODNATIVE_ASSERT(!"bad signature");
290 return KLDR_ERR_UNKNOWN_FORMAT;
291 }
292 if (pNtHdrs->FileHeader.SizeOfOptionalHeader != sizeof(IMAGE_OPTIONAL_HEADER))
293 {
294 KLDRMODNATIVE_ASSERT(!"bad optional header size");
295 return KLDR_ERR_UNKNOWN_FORMAT;
296 }
297 cSegments = pNtHdrs->FileHeader.NumberOfSections + 1;
298 paShdrs = (const IMAGE_SECTION_HEADER *)(pNtHdrs + 1);
299
300#elif K_OS == K_OS_DARWIN
301 char szFilename[1] = "";
302 cSegments = 0; /** @todo Figure out the Mac OS X dynamic loader. */
303
304#else
305# error "Port me"
306#endif
307
308 /*
309 * Calc the instance size, allocate and initialize it.
310 */
311 cchFilename = (KU32)kHlpStrLen(szFilename);
312 cb = K_ALIGN_Z(sizeof(KLDRMODNATIVE), 16)
313 + K_OFFSETOF(KLDRMOD, aSegments[cSegments])
314 + cchFilename + 1;
315 pModNative = (PKLDRMODNATIVE)kHlpAlloc(cb);
316 if (!pModNative)
317 return KERR_NO_MEMORY;
318
319 /* KLDRMOD */
320 pMod = (PKLDRMOD)((KU8 *)pModNative + K_ALIGN_Z(sizeof(KLDRMODNATIVE), 16));
321 pMod->pvData = pModNative;
322 pMod->pRdr = NULL;
323 pMod->pOps = NULL; /* set upon success. */
324 pMod->cSegments = cSegments;
325 pMod->cchFilename = cchFilename;
326 pMod->pszFilename = (char *)&pMod->aSegments[pMod->cSegments];
327 kHlpMemCopy((char *)pMod->pszFilename, szFilename, cchFilename + 1);
328 pMod->pszName = kHlpGetFilename(pMod->pszFilename); /** @todo get soname */
329 pMod->cchName = cchFilename - (KU32)(pMod->pszName - pMod->pszFilename);
330 pMod->fFlags = 0;
331#if defined(__i386__) || defined(__X86__) || defined(_M_IX86)
332 pMod->enmCpu = KCPU_I386;
333 pMod->enmArch = KCPUARCH_X86_32;
334 pMod->enmEndian = KLDRENDIAN_LITTLE;
335#elif defined(__X86_64__) || defined(__x86_64__) || defined(__AMD64__) || defined(_M_IX64)
336 pMod->enmCpu = KCPU_K8;
337 pMod->enmArch = KCPUARCH_AMD64;
338 pMod->enmEndian = KLDRENDIAN_LITTLE;
339#else
340# error "Port me"
341#endif
342 pMod->enmFmt = KLDRFMT_NATIVE;
343 pMod->enmType = KLDRTYPE_SHARED_LIBRARY_RELOCATABLE;
344 pMod->u32Magic = 0; /* set upon success. */
345
346 /* KLDRMODNATIVE */
347 pModNative->pMod = pMod;
348 pModNative->f32Reserved = 0;
349 pModNative->cImportModules = ~(KU32)0;
350
351 /*
352 * Set native instance data.
353 */
354#if K_OS == K_OS_OS2
355 pModNative->hmod = (HMODULE)uHandle;
356
357 /* just fake a segment for now. */
358 pMod->aSegments[0].pvUser = NULL;
359 pMod->aSegments[0].pchName = "fake";
360 pMod->aSegments[0].cchName = sizeof("fake") - 1;
361 pMod->aSegments[0].enmProt = KPROT_NOACCESS;
362 pMod->aSegments[0].cb = 0;
363 pMod->aSegments[0].Alignment = 0;
364 pMod->aSegments[0].LinkAddress = NIL_KLDRADDR;
365 pMod->aSegments[0].offFile = -1;
366 pMod->aSegments[0].cbFile = 0;
367 pMod->aSegments[0].RVA = NIL_KLDRADDR;
368 pMod->aSegments[0].cbMapped = 0;
369 pMod->aSegments[0].MapAddress = 0;
370
371#elif K_OS == K_OS_WINDOWS
372 pModNative->hmod = (HMODULE)uHandle;
373 pModNative->pNtHdrs = pNtHdrs;
374 pModNative->paShdrs = paShdrs;
375
376 if (pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL)
377 pMod->enmType = !(pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
378 ? KLDRTYPE_SHARED_LIBRARY_RELOCATABLE
379 : KLDRTYPE_SHARED_LIBRARY_FIXED;
380 else
381 pMod->enmType = !(pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
382 ? KLDRTYPE_EXECUTABLE_RELOCATABLE
383 : KLDRTYPE_EXECUTABLE_FIXED;
384
385 /* The implied headers section. */
386 pMod->aSegments[0].pvUser = NULL;
387 pMod->aSegments[0].pchName = "TheHeaders";
388 pMod->aSegments[0].cchName = sizeof("TheHeaders") - 1;
389 pMod->aSegments[0].enmProt = KPROT_READONLY;
390 pMod->aSegments[0].cb = pNtHdrs->OptionalHeader.SizeOfHeaders;
391 pMod->aSegments[0].Alignment = pNtHdrs->OptionalHeader.SectionAlignment;
392 pMod->aSegments[0].LinkAddress = pNtHdrs->OptionalHeader.ImageBase;
393 pMod->aSegments[0].offFile = 0;
394 pMod->aSegments[0].cbFile = pNtHdrs->OptionalHeader.SizeOfHeaders;
395 pMod->aSegments[0].RVA = 0;
396 if (pMod->cSegments > 1)
397 pMod->aSegments[0].cbMapped = paShdrs[0].VirtualAddress;
398 else
399 pMod->aSegments[0].cbMapped = pNtHdrs->OptionalHeader.SizeOfHeaders;
400 pMod->aSegments[0].MapAddress = uHandle;
401
402 /* The section headers. */
403 for (i = 0; i < pNtHdrs->FileHeader.NumberOfSections; i++)
404 {
405 const char *pch;
406 KU32 cchSegName;
407
408 /* unused */
409 pMod->aSegments[i + 1].pvUser = NULL;
410
411 /* name */
412 pMod->aSegments[i + 1].pchName = pch = &paShdrs[i].Name[0];
413 cchSegName = IMAGE_SIZEOF_SHORT_NAME;
414 while ( cchSegName > 0
415 && (pch[cchSegName - 1] == ' ' || pch[cchSegName - 1] == '\0'))
416 cchSegName--;
417 pMod->aSegments[i + 1].cchName = cchSegName;
418
419 /* size and addresses */
420 if (!(paShdrs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
421 {
422 pMod->aSegments[i + 1].cb = paShdrs[i].Misc.VirtualSize;
423 pMod->aSegments[i + 1].RVA = paShdrs[i].VirtualAddress;
424 pMod->aSegments[i + 1].LinkAddress = paShdrs[i].VirtualAddress + pNtHdrs->OptionalHeader.ImageBase;
425 pMod->aSegments[i + 1].MapAddress = paShdrs[i].VirtualAddress + uHandle;
426 pMod->aSegments[i + 1].cbMapped = paShdrs[i].Misc.VirtualSize;
427 if (i + 2 < pMod->cSegments)
428 pMod->aSegments[i + 1].cbMapped = paShdrs[i + 1].VirtualAddress
429 - paShdrs[i].VirtualAddress;
430 }
431 else
432 {
433 pMod->aSegments[i + 1].cb = 0;
434 pMod->aSegments[i + 1].cbMapped = 0;
435 pMod->aSegments[i + 1].LinkAddress = NIL_KLDRADDR;
436 pMod->aSegments[i + 1].RVA = 0;
437 pMod->aSegments[i + 1].MapAddress = 0;
438 }
439
440 /* file location */
441 pMod->aSegments[i + 1].offFile = paShdrs[i].PointerToRawData;
442 pMod->aSegments[i + 1].cbFile = paShdrs[i].SizeOfRawData;
443 if ( pMod->aSegments[i + 1].cbMapped > 0 /* if mapped */
444 && (KLDRSIZE)pMod->aSegments[i + 1].cbFile > pMod->aSegments[i + 1].cbMapped)
445 pMod->aSegments[i + 1].cbFile = (KLDRFOFF)pMod->aSegments[i + 1].cbMapped;
446
447 /* protection */
448 switch ( paShdrs[i].Characteristics
449 & (IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE))
450 {
451 case 0:
452 case IMAGE_SCN_MEM_SHARED:
453 pMod->aSegments[i + 1].enmProt = KPROT_NOACCESS;
454 break;
455 case IMAGE_SCN_MEM_READ:
456 case IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED:
457 pMod->aSegments[i + 1].enmProt = KPROT_READONLY;
458 break;
459 case IMAGE_SCN_MEM_WRITE:
460 case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ:
461 pMod->aSegments[i + 1].enmProt = KPROT_WRITECOPY;
462 break;
463 case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED:
464 case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ:
465 pMod->aSegments[i + 1].enmProt = KPROT_READWRITE;
466 break;
467 case IMAGE_SCN_MEM_EXECUTE:
468 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_SHARED:
469 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE;
470 break;
471 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ:
472 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED:
473 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE_READ;
474 break;
475 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE:
476 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ:
477 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE_WRITECOPY;
478 break;
479 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED:
480 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ:
481 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE_READWRITE;
482 break;
483 }
484
485 /* alignment. */
486 switch (paShdrs[i].Characteristics & IMAGE_SCN_ALIGN_MASK)
487 {
488 case 0: /* hope this is right... */
489 pMod->aSegments[i + 1].Alignment = pNtHdrs->OptionalHeader.SectionAlignment;
490 break;
491 case IMAGE_SCN_ALIGN_1BYTES: pMod->aSegments[i + 1].Alignment = 1; break;
492 case IMAGE_SCN_ALIGN_2BYTES: pMod->aSegments[i + 1].Alignment = 2; break;
493 case IMAGE_SCN_ALIGN_4BYTES: pMod->aSegments[i + 1].Alignment = 4; break;
494 case IMAGE_SCN_ALIGN_8BYTES: pMod->aSegments[i + 1].Alignment = 8; break;
495 case IMAGE_SCN_ALIGN_16BYTES: pMod->aSegments[i + 1].Alignment = 16; break;
496 case IMAGE_SCN_ALIGN_32BYTES: pMod->aSegments[i + 1].Alignment = 32; break;
497 case IMAGE_SCN_ALIGN_64BYTES: pMod->aSegments[i + 1].Alignment = 64; break;
498 case IMAGE_SCN_ALIGN_128BYTES: pMod->aSegments[i + 1].Alignment = 128; break;
499 case IMAGE_SCN_ALIGN_256BYTES: pMod->aSegments[i + 1].Alignment = 256; break;
500 case IMAGE_SCN_ALIGN_512BYTES: pMod->aSegments[i + 1].Alignment = 512; break;
501 case IMAGE_SCN_ALIGN_1024BYTES: pMod->aSegments[i + 1].Alignment = 1024; break;
502 case IMAGE_SCN_ALIGN_2048BYTES: pMod->aSegments[i + 1].Alignment = 2048; break;
503 case IMAGE_SCN_ALIGN_4096BYTES: pMod->aSegments[i + 1].Alignment = 4096; break;
504 case IMAGE_SCN_ALIGN_8192BYTES: pMod->aSegments[i + 1].Alignment = 8192; break;
505 default: kHlpAssert(0); pMod->aSegments[i + 1].Alignment = 0; break;
506 }
507 }
508
509#elif K_OS == K_OS_DARWIN
510 /** @todo Figure out the Mac OS X dynamic loader. */
511
512#else
513# error "Port me"
514#endif
515
516 /*
517 * We're done.
518 */
519 pMod->u32Magic = KLDRMOD_MAGIC;
520 pMod->pOps = &g_kLdrModNativeOps;
521 *ppMod = pMod;
522 return 0;
523}
524
525
526/** @copydoc KLDRMODOPS::pfnDestroy */
527static int kldrModNativeDestroy(PKLDRMOD pMod)
528{
529 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
530 int rc;
531
532#if K_OS == K_OS_OS2
533 rc = DosFreeModule(pModNative->hmod);
534
535#elif K_OS == K_OS_WINDOWS
536 if (FreeLibrary(pModNative->hmod))
537 rc = 0;
538 else
539 rc = GetLastError();
540
541#elif K_OS == K_OS_DARWIN
542 dlclose(pModNative->pvMod);
543
544#else
545# error "Port me"
546#endif
547
548 pMod->u32Magic = 0;
549 pMod->pOps = NULL;
550 kHlpFree(pModNative);
551 return rc;
552}
553
554
555/** @copydoc kLdrModQuerySymbol */
556static int kldrModNativeQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 iSymbol,
557 const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion,
558 PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, KU32 *pfKind)
559{
560 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
561 const char *pszSymbol = pchSymbol;
562#if K_OS == K_OS_OS2
563 APIRET rc;
564 PFN pfn;
565#elif K_OS == K_OS_WINDOWS
566 FARPROC pfn;
567#elif K_OS == K_OS_DARWIN
568 void *pfn;
569#else
570# error "Port me"
571#endif
572
573 /* make stack copy of the symbol if it isn't zero terminated. */
574 if (pszSymbol && pszSymbol[cchSymbol])
575 {
576 char *pszCopy = kHlpAllocA(cchSymbol + 1);
577 kHlpMemCopy(pszCopy, pchSymbol, cchSymbol);
578 pszCopy[cchSymbol] = '\0';
579 pszSymbol = pszCopy;
580 }
581
582#if K_OS == K_OS_OS2
583 if (!pchSymbol && iSymbol >= 0x10000)
584 return KLDR_ERR_SYMBOL_NOT_FOUND;
585
586 if (puValue)
587 {
588 rc = DosQueryProcAddr(pModNative->hmod,
589 pszSymbol ? 0 : iSymbol,
590 (PCSZ)pszSymbol,
591 &pfn);
592 if (rc)
593 return rc == ERROR_PROC_NOT_FOUND ? KLDR_ERR_SYMBOL_NOT_FOUND : rc;
594 *puValue = (KUPTR)pfn;
595 }
596 if (pfKind)
597 {
598 ULONG ulProcType;
599 rc = DosQueryProcType(pModNative->hmod,
600 pszSymbol ? 0 : iSymbol,
601 (PCSZ)pszSymbol,
602 &ulProcType);
603 if (rc)
604 {
605 if (puValue)
606 *puValue = 0;
607 return rc == ERROR_PROC_NOT_FOUND ? KLDR_ERR_SYMBOL_NOT_FOUND : rc;
608 }
609 *pfKind = (ulProcType & PT_32BIT ? KLDRSYMKIND_32BIT : KLDRSYMKIND_16BIT)
610 | KLDRSYMKIND_NO_TYPE;
611 }
612
613#elif K_OS == K_OS_WINDOWS
614 if (!pszSymbol && iSymbol >= 0x10000)
615 return KLDR_ERR_SYMBOL_NOT_FOUND;
616
617 pfn = GetProcAddress(pModNative->hmod, pszSymbol ? pszSymbol : (const char *)(KUPTR)iSymbol);
618 if (puValue)
619 *puValue = (KUPTR)pfn;
620 if (pfKind)
621 *pfKind = (pModNative->pNtHdrs->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
622 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_16BIT)
623 | KLDRSYMKIND_NO_TYPE;
624
625#elif K_OS == K_OS_DARWIN
626 if (!pszSymbol && iSymbol != NIL_KLDRMOD_SYM_ORDINAL)
627 return KLDR_ERR_SYMBOL_NOT_FOUND;
628
629 pfn = dlsym(pModNative->pvMod, pszSymbol);
630 if (!pfn)
631 return KLDR_ERR_SYMBOL_NOT_FOUND;
632 if (puValue)
633 *puValue = (KUPTR)pfn;
634 if (pfKind)
635 *pfKind = (sizeof(KUPTR) == 4 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT)
636 | KLDRSYMKIND_NO_TYPE;
637
638#else
639# error "Port me"
640#endif
641
642 return 0;
643}
644
645
646/** @copydoc kLdrModEnumSymbols */
647static int kldrModNativeEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress,
648 KU32 fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
649{
650 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
651#if K_OS == K_OS_OS2
652
653 /** @todo implement export enumeration on OS/2. */
654 (void)pModNative;
655 return ERROR_NOT_SUPPORTED;
656
657#elif K_OS == K_OS_WINDOWS || defined(__NT__)
658 const KU32 *paFunctions;
659 const IMAGE_EXPORT_DIRECTORY *pExpDir;
660 const KU32 *paRVANames;
661 const KU16 *paOrdinals;
662 KU32 iFunction;
663 KU32 cFunctions;
664 KU32 cNames;
665 int rc;
666
667 /*
668 * Make sure we've got mapped bits and resolve any base address aliases.
669 */
670 if ( pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size
671 < sizeof(IMAGE_EXPORT_DIRECTORY))
672 return 0; /* no exports to enumerate, return success. */
673
674 pExpDir = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
675 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
676 PIMAGE_EXPORT_DIRECTORY);
677
678 /*
679 * Enumerate the ordinal exports.
680 */
681 paRVANames = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfNames, const KU32 *);
682 paOrdinals = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfNameOrdinals, const KU16 *);
683 paFunctions = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfFunctions, const KU32 *);
684 cFunctions = pExpDir->NumberOfFunctions;
685 cNames = pExpDir->NumberOfNames;
686 for (iFunction = 0; iFunction < cFunctions; iFunction++)
687 {
688 unsigned fFoundName;
689 KU32 iName;
690 const KU32 uRVA = paFunctions[iFunction];
691 const KLDRADDR uValue = BaseAddress + uRVA;
692 KU32 fKind = (pModNative->pNtHdrs->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
693 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT)
694 | KLDRSYMKIND_NO_TYPE;
695 if ( uRVA - pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
696 < pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
697 fKind |= KLDRSYMKIND_FORWARDER;
698
699 /*
700 * Any symbol names?
701 */
702 fFoundName = 0;
703 for (iName = 0; iName < cNames; iName++)
704 {
705 const char *pszName;
706 if (paOrdinals[iName] != iFunction)
707 continue;
708 fFoundName = 1;
709
710 pszName = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, paRVANames[iName], const char *);
711 rc = pfnCallback(pMod, iFunction + pExpDir->Base, pszName, strlen(pszName), NULL,
712 uValue, fKind, pvUser);
713 if (rc)
714 return rc;
715 }
716
717 /*
718 * If no names, call once with the ordinal only.
719 */
720 if (!fFoundName)
721 {
722 rc = pfnCallback(pMod, iFunction + pExpDir->Base, NULL, 0, NULL, uValue, fKind, pvUser);
723 if (rc)
724 return rc;
725 }
726 }
727 return 0;
728
729#elif K_OS == K_OS_DARWIN
730 /** @todo implement enumeration on darwin. */
731 (void)pModNative;
732 return KLDR_ERR_TODO;
733
734#else
735# error "Port me"
736#endif
737
738}
739
740
741/** @copydoc kLdrModGetImport */
742static int kldrModNativeGetImport(PKLDRMOD pMod, const void *pvBits, KU32 iImport, char *pszName, KSIZE cchName)
743{
744 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
745#if K_OS == K_OS_OS2
746
747 /** @todo implement import enumeration on OS/2. */
748 (void)pModNative;
749 return ERROR_NOT_SUPPORTED;
750
751#elif K_OS == K_OS_WINDOWS || defined(__NT__)
752 const IMAGE_IMPORT_DESCRIPTOR *pImpDesc;
753 const char *pszImportName;
754 KSIZE cchImportName;
755 int rc;
756
757 /*
758 * Simple bounds check.
759 */
760 if (iImport >= (KU32)kldrModNativeNumberOfImports(pMod, pvBits))
761 return KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS;
762
763 /*
764 * Get the name.
765 */
766 pImpDesc = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
767 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
768 + sizeof(IMAGE_IMPORT_DESCRIPTOR) * iImport,
769 const IMAGE_IMPORT_DESCRIPTOR *);
770 pszImportName = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pImpDesc->Name, const char *);
771 cchImportName = kHlpStrLen(pszImportName);
772 if (cchImportName < cchName)
773 {
774 kHlpMemCopy(pszName, pszImportName, cchImportName + 1);
775 rc = 0;
776 }
777 else
778 {
779 kHlpMemCopy(pszName, pszImportName, cchName);
780 if (cchName)
781 pszName[cchName - 1] = '\0';
782 rc = KERR_BUFFER_OVERFLOW;
783 }
784
785 return rc;
786
787#elif K_OS == K_OS_DARWIN
788 /** @todo Implement import enumeration on darwin. */
789 (void)pModNative;
790 return KLDR_ERR_TODO;
791
792#else
793# error "Port me"
794#endif
795}
796
797
798/** @copydoc kLdrModNumberOfImports */
799static KI32 kldrModNativeNumberOfImports(PKLDRMOD pMod, const void *pvBits)
800{
801 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
802#if K_OS == K_OS_OS2
803
804 /** @todo implement import counting on OS/2. */
805 (void)pModNative;
806 return -1;
807
808#elif K_OS == K_OS_WINDOWS || defined(__NT__)
809 if (pModNative->cImportModules == ~(KU32)0)
810 {
811 /*
812 * We'll have to walk the import descriptors to figure out their number.
813 */
814 pModNative->cImportModules = 0;
815 if ( pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size
816 && pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
817 {
818 const IMAGE_IMPORT_DESCRIPTOR *pImpDesc;
819
820 pImpDesc = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
821 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
822 const IMAGE_IMPORT_DESCRIPTOR *);
823 while (pImpDesc->Name && pImpDesc->FirstThunk)
824 {
825 pModNative->cImportModules++;
826 pImpDesc++;
827 }
828 }
829 }
830 return pModNative->cImportModules;
831
832#elif K_OS == K_OS_DARWIN
833 /** @todo Implement import counting on Darwin. */
834 (void)pModNative;
835 return -1;
836
837#else
838# error "Port me"
839#endif
840}
841
842
843/** @copydoc kLdrModGetStackInfo */
844static int kldrModNativeGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
845{
846 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
847#if K_OS == K_OS_OS2
848
849 /** @todo implement stack info on OS/2. */
850 (void)pModNative;
851 return ERROR_NOT_SUPPORTED;
852
853#elif K_OS == K_OS_WINDOWS || defined(__NT__)
854 pStackInfo->Address = NIL_KLDRADDR;
855 pStackInfo->LinkAddress = NIL_KLDRADDR;
856 pStackInfo->cbStack = pStackInfo->cbStackThread = pModNative->pNtHdrs->OptionalHeader.SizeOfStackReserve;
857
858 return 0;
859
860#elif K_OS == K_OS_DARWIN
861 /** @todo Implement stack info on Darwin. */
862 (void)pModNative;
863 return KLDR_ERR_TODO;
864
865#else
866# error "Port me"
867#endif
868}
869
870
871/** @copydoc kLdrModQueryMainEntrypoint */
872static int kldrModNativeQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
873{
874 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
875#if K_OS == K_OS_OS2
876
877 /** @todo implement me on OS/2. */
878 (void)pModNative;
879 return ERROR_NOT_SUPPORTED;
880
881#elif K_OS == K_OS_WINDOWS || defined(__NT__)
882 /*
883 * Convert the address from the header.
884 */
885 *pMainEPAddress = pModNative->pNtHdrs->OptionalHeader.AddressOfEntryPoint
886 ? BaseAddress + pModNative->pNtHdrs->OptionalHeader.AddressOfEntryPoint
887 : NIL_KLDRADDR;
888 return 0;
889
890#elif K_OS == K_OS_DARWIN
891 /** @todo Implement me on Darwin. */
892 (void)pModNative;
893 return KLDR_ERR_TODO;
894
895#else
896# error "Port me"
897#endif
898}
899
900
901/** @copydoc kLdrModEnumDbgInfo */
902static int kldrModNativeEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser)
903{
904 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
905#if K_OS == K_OS_OS2
906
907 /** @todo implement me on OS/2. */
908 (void)pModNative;
909 return ERROR_NOT_SUPPORTED;
910
911#elif K_OS == K_OS_WINDOWS || defined(__NT__)
912 const IMAGE_DEBUG_DIRECTORY *pDbgDir;
913 KU32 iDbgInfo;
914 KU32 cb;
915 int rc;
916
917 /*
918 * Check that there is a debug directory first.
919 */
920 cb = pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
921 if ( cb < sizeof(IMAGE_DEBUG_DIRECTORY) /* screw borland linkers */
922 || !pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress)
923 return 0;
924
925 /*
926 * Enumerate the debug directory.
927 */
928 pDbgDir = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
929 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
930 const IMAGE_DEBUG_DIRECTORY *);
931 for (iDbgInfo = 0;; iDbgInfo++, pDbgDir++, cb -= sizeof(IMAGE_DEBUG_DIRECTORY))
932 {
933 KLDRDBGINFOTYPE enmDbgInfoType;
934
935 /* convert the type. */
936 switch (pDbgDir->Type)
937 {
938 case IMAGE_DEBUG_TYPE_UNKNOWN:
939 case IMAGE_DEBUG_TYPE_FPO:
940 case IMAGE_DEBUG_TYPE_COFF: /*stabs dialect??*/
941 case IMAGE_DEBUG_TYPE_MISC:
942 case IMAGE_DEBUG_TYPE_EXCEPTION:
943 case IMAGE_DEBUG_TYPE_FIXUP:
944 case IMAGE_DEBUG_TYPE_BORLAND:
945 default:
946 enmDbgInfoType = KLDRDBGINFOTYPE_UNKNOWN;
947 break;
948 case IMAGE_DEBUG_TYPE_CODEVIEW:
949 enmDbgInfoType = KLDRDBGINFOTYPE_CODEVIEW;
950 break;
951 }
952
953 rc = pfnCallback(pMod, iDbgInfo,
954 enmDbgInfoType, pDbgDir->MajorVersion, pDbgDir->MinorVersion, NULL /*pszPartNm*/,
955 pDbgDir->PointerToRawData ? pDbgDir->PointerToRawData : -1,
956 pDbgDir->AddressOfRawData ? pDbgDir->AddressOfRawData : NIL_KLDRADDR,
957 pDbgDir->SizeOfData,
958 NULL /*pszExtFile*/, pvUser);
959 if (rc)
960 break;
961
962 /* next */
963 if (cb <= sizeof(IMAGE_DEBUG_DIRECTORY))
964 break;
965 }
966
967 return rc;
968
969#elif K_OS == K_OS_DARWIN
970 /** @todo Implement me on Darwin. */
971 (void)pModNative;
972 return KLDR_ERR_TODO;
973
974#else
975# error "Port me"
976#endif
977}
978
979
980/** @copydoc kLdrModHasDbgInfo */
981static int kldrModNativeHasDbgInfo(PKLDRMOD pMod, const void *pvBits)
982{
983 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
984#if K_OS == K_OS_OS2
985
986 /** @todo implement me on OS/2. */
987 (void)pModNative;
988 return KLDR_ERR_NO_DEBUG_INFO;
989
990#elif K_OS == K_OS_WINDOWS || defined(__NT__)
991 /*
992 * Base this entirely on the presence of a debug directory.
993 */
994 if ( pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size
995 < sizeof(IMAGE_DEBUG_DIRECTORY) /* screw borland linkers */
996 || !pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress)
997 return KLDR_ERR_NO_DEBUG_INFO;
998 return 0;
999
1000#elif K_OS == K_OS_DARWIN
1001 /** @todo Implement me on Darwin. */
1002 (void)pModNative;
1003 return KLDR_ERR_NO_DEBUG_INFO;
1004
1005#else
1006# error "Port me"
1007#endif
1008}
1009
1010
1011/** @copydoc kLdrModMap */
1012static int kldrModNativeMap(PKLDRMOD pMod)
1013{
1014 return 0;
1015}
1016
1017
1018/** @copydoc kLdrModUnmap */
1019static int kldrModNativeUnmap(PKLDRMOD pMod)
1020{
1021 return 0;
1022}
1023
1024
1025/** @copydoc kLdrModAllocTLS */
1026static int kldrModNativeAllocTLS(PKLDRMOD pMod, void *pvMapping)
1027{
1028 return 0;
1029}
1030
1031
1032/** @copydoc kLdrModFreeTLS */
1033static void kldrModNativeFreeTLS(PKLDRMOD pMod, void *pvMapping)
1034{
1035}
1036
1037
1038/** @copydoc kLdrModReload */
1039static int kldrModNativeReload(PKLDRMOD pMod)
1040{
1041 return 0;
1042}
1043
1044
1045/** @copydoc kLdrModFixupMapping */
1046static int kldrModNativeFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
1047{
1048 return 0;
1049}
1050
1051
1052/** @copydoc kLdrModCallInit */
1053static int kldrModNativeCallInit(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle)
1054{
1055 return 0;
1056}
1057
1058
1059/** @copydoc kLdrModCallTerm */
1060static int kldrModNativeCallTerm(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle)
1061{
1062 return 0;
1063}
1064
1065
1066/** @copydoc kLdrModCallThread */
1067static int kldrModNativeCallThread(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle, unsigned fAttachingOrDetaching)
1068{
1069 return 0;
1070}
1071
1072
1073/** @copydoc kLdrModSize */
1074static KLDRADDR kldrModNativeSize(PKLDRMOD pMod)
1075{
1076#if K_OS == K_OS_OS2
1077 return 0; /* don't bother */
1078
1079#elif K_OS == K_OS_WINDOWS || defined(__NT__)
1080 /* just because we can. */
1081 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
1082 return pModNative->pNtHdrs->OptionalHeader.SizeOfImage;
1083
1084#elif K_OS == K_OS_DARWIN
1085 /** @todo Implement me on Darwin. */
1086 return 0;
1087
1088#else
1089# error "Port me"
1090#endif
1091}
1092
1093
1094/** @copydoc kLdrModGetBits */
1095static int kldrModNativeGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
1096{
1097#if K_OS == K_OS_OS2
1098 return ERROR_NOT_SUPPORTED; /* don't bother */
1099
1100#elif K_OS == K_OS_WINDOWS || defined(__NT__)
1101 return ERROR_NOT_SUPPORTED; /* don't bother even if we could implement this. */
1102
1103#elif K_OS == K_OS_DARWIN
1104 return KLDR_ERR_TODO; /* don't bother. */
1105
1106#else
1107# error "Port me"
1108#endif
1109}
1110
1111
1112/** @copydoc kLdrModRelocateBits */
1113static int kldrModNativeRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
1114 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
1115{
1116#if K_OS == K_OS_OS2
1117 return ERROR_NOT_SUPPORTED; /* don't bother */
1118
1119#elif K_OS == K_OS_WINDOWS || defined(__NT__)
1120 return ERROR_NOT_SUPPORTED; /* don't bother even if we could implement this. */
1121
1122#elif K_OS == K_OS_DARWIN
1123 return KLDR_ERR_TODO; /* don't bother. */
1124
1125#else
1126# error "Port me"
1127#endif
1128}
1129
1130
1131/**
1132 * The native module interpreter method table.
1133 */
1134KLDRMODOPS g_kLdrModNativeOps =
1135{
1136 "Native",
1137 NULL,
1138 kldrModNativeCreate,
1139 kldrModNativeDestroy,
1140 kldrModNativeQuerySymbol,
1141 kldrModNativeEnumSymbols,
1142 kldrModNativeGetImport,
1143 kldrModNativeNumberOfImports,
1144 NULL /* can execute one is optional */,
1145 kldrModNativeGetStackInfo,
1146 kldrModNativeQueryMainEntrypoint,
1147 NULL /* pfnQueryImageUuid */,
1148 NULL /* fixme */,
1149 NULL /* fixme */,
1150 kldrModNativeEnumDbgInfo,
1151 kldrModNativeHasDbgInfo,
1152 kldrModNativeMap,
1153 kldrModNativeUnmap,
1154 kldrModNativeAllocTLS,
1155 kldrModNativeFreeTLS,
1156 kldrModNativeReload,
1157 kldrModNativeFixupMapping,
1158 kldrModNativeCallInit,
1159 kldrModNativeCallTerm,
1160 kldrModNativeCallThread,
1161 kldrModNativeSize,
1162 kldrModNativeGetBits,
1163 kldrModNativeRelocateBits,
1164 NULL /* fixme */,
1165 42 /* the end */
1166};
1167
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