VirtualBox

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

Last change on this file since 81 was 81, checked in by bird, 9 years ago

kLdr: some refactoring and fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 37.4 KB
Line 
1/* $Id: kLdrModNative.c 81 2016-08-18 22:10:38Z 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 KSIZE 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 = 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 - (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 = 0;
401
402 /* The section headers. */
403 for (i = 0; i < pNtHdrs->FileHeader.NumberOfSections; i++)
404 {
405 const char *pch;
406
407 /* unused */
408 pMod->aSegments[i + 1].pvUser = NULL;
409 pMod->aSegments[i + 1].MapAddress = 0;
410
411 /* name */
412 pMod->aSegments[i + 1].pchName = pch = &paShdrs[i].Name[0];
413 cb = IMAGE_SIZEOF_SHORT_NAME;
414 while ( cb > 0
415 && (pch[cb - 1] == ' ' || pch[cb - 1] == '\0'))
416 cb--;
417 pMod->aSegments[i + 1].cchName = cb;
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].LinkAddress = paShdrs[i].VirtualAddress
424 + pNtHdrs->OptionalHeader.ImageBase;
425 pMod->aSegments[i + 1].RVA = paShdrs[i].VirtualAddress;
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 }
438
439 /* file location */
440 pMod->aSegments[i + 1].offFile = paShdrs[i].PointerToRawData;
441 pMod->aSegments[i + 1].cbFile = paShdrs[i].SizeOfRawData;
442 if ( pMod->aSegments[i + 1].cbMapped > 0 /* if mapped */
443 && (KLDRSIZE)pMod->aSegments[i + 1].cbFile > pMod->aSegments[i + 1].cbMapped)
444 pMod->aSegments[i + 1].cbFile = pMod->aSegments[i + 1].cbMapped;
445
446 /* protection */
447 switch ( paShdrs[i].Characteristics
448 & (IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE))
449 {
450 case 0:
451 case IMAGE_SCN_MEM_SHARED:
452 pMod->aSegments[i + 1].enmProt = KPROT_NOACCESS;
453 break;
454 case IMAGE_SCN_MEM_READ:
455 case IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED:
456 pMod->aSegments[i + 1].enmProt = KPROT_READONLY;
457 break;
458 case IMAGE_SCN_MEM_WRITE:
459 case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ:
460 pMod->aSegments[i + 1].enmProt = KPROT_WRITECOPY;
461 break;
462 case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED:
463 case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ:
464 pMod->aSegments[i + 1].enmProt = KPROT_READWRITE;
465 break;
466 case IMAGE_SCN_MEM_EXECUTE:
467 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_SHARED:
468 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE;
469 break;
470 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ:
471 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED:
472 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE_READ;
473 break;
474 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE:
475 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ:
476 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE_WRITECOPY;
477 break;
478 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED:
479 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ:
480 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE_READWRITE;
481 break;
482 }
483
484 /* alignment. */
485 switch (paShdrs[i].Characteristics & IMAGE_SCN_ALIGN_MASK)
486 {
487 case 0: /* hope this is right... */
488 pMod->aSegments[i + 1].Alignment = pNtHdrs->OptionalHeader.SectionAlignment;
489 break;
490 case IMAGE_SCN_ALIGN_1BYTES: pMod->aSegments[i + 1].Alignment = 1; break;
491 case IMAGE_SCN_ALIGN_2BYTES: pMod->aSegments[i + 1].Alignment = 2; break;
492 case IMAGE_SCN_ALIGN_4BYTES: pMod->aSegments[i + 1].Alignment = 4; break;
493 case IMAGE_SCN_ALIGN_8BYTES: pMod->aSegments[i + 1].Alignment = 8; break;
494 case IMAGE_SCN_ALIGN_16BYTES: pMod->aSegments[i + 1].Alignment = 16; break;
495 case IMAGE_SCN_ALIGN_32BYTES: pMod->aSegments[i + 1].Alignment = 32; break;
496 case IMAGE_SCN_ALIGN_64BYTES: pMod->aSegments[i + 1].Alignment = 64; break;
497 case IMAGE_SCN_ALIGN_128BYTES: pMod->aSegments[i + 1].Alignment = 128; break;
498 case IMAGE_SCN_ALIGN_256BYTES: pMod->aSegments[i + 1].Alignment = 256; break;
499 case IMAGE_SCN_ALIGN_512BYTES: pMod->aSegments[i + 1].Alignment = 512; break;
500 case IMAGE_SCN_ALIGN_1024BYTES: pMod->aSegments[i + 1].Alignment = 1024; break;
501 case IMAGE_SCN_ALIGN_2048BYTES: pMod->aSegments[i + 1].Alignment = 2048; break;
502 case IMAGE_SCN_ALIGN_4096BYTES: pMod->aSegments[i + 1].Alignment = 4096; break;
503 case IMAGE_SCN_ALIGN_8192BYTES: pMod->aSegments[i + 1].Alignment = 8192; break;
504 default: kHlpAssert(0); pMod->aSegments[i + 1].Alignment = 0; break;
505 }
506 }
507
508#elif K_OS == K_OS_DARWIN
509 /** @todo Figure out the Mac OS X dynamic loader. */
510
511#else
512# error "Port me"
513#endif
514
515 /*
516 * We're done.
517 */
518 pMod->u32Magic = KLDRMOD_MAGIC;
519 pMod->pOps = &g_kLdrModNativeOps;
520 *ppMod = pMod;
521 return 0;
522}
523
524
525/** @copydoc KLDRMODOPS::pfnDestroy */
526static int kldrModNativeDestroy(PKLDRMOD pMod)
527{
528 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
529 int rc;
530
531#if K_OS == K_OS_OS2
532 rc = DosFreeModule(pModNative->hmod);
533
534#elif K_OS == K_OS_WINDOWS
535 if (FreeLibrary(pModNative->hmod))
536 rc = 0;
537 else
538 rc = GetLastError();
539
540#elif K_OS == K_OS_DARWIN
541 dlclose(pModNative->pvMod);
542
543#else
544# error "Port me"
545#endif
546
547 pMod->u32Magic = 0;
548 pMod->pOps = NULL;
549 kHlpFree(pModNative);
550 return rc;
551}
552
553
554/** @copydoc kLdrModQuerySymbol */
555static int kldrModNativeQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 iSymbol,
556 const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion,
557 PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, KU32 *pfKind)
558{
559 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
560 const char *pszSymbol = pchSymbol;
561#if K_OS == K_OS_OS2
562 APIRET rc;
563 PFN pfn;
564#elif K_OS == K_OS_WINDOWS
565 FARPROC pfn;
566#elif K_OS == K_OS_DARWIN
567 void *pfn;
568#else
569# error "Port me"
570#endif
571
572 /* make stack copy of the symbol if it isn't zero terminated. */
573 if (pszSymbol && pszSymbol[cchSymbol])
574 {
575 char *pszCopy = kHlpAllocA(cchSymbol + 1);
576 kHlpMemCopy(pszCopy, pchSymbol, cchSymbol);
577 pszCopy[cchSymbol] = '\0';
578 pszSymbol = pszCopy;
579 }
580
581#if K_OS == K_OS_OS2
582 if (!pchSymbol && iSymbol >= 0x10000)
583 return KLDR_ERR_SYMBOL_NOT_FOUND;
584
585 if (puValue)
586 {
587 rc = DosQueryProcAddr(pModNative->hmod,
588 pszSymbol ? 0 : iSymbol,
589 (PCSZ)pszSymbol,
590 &pfn);
591 if (rc)
592 return rc == ERROR_PROC_NOT_FOUND ? KLDR_ERR_SYMBOL_NOT_FOUND : rc;
593 *puValue = (KUPTR)pfn;
594 }
595 if (pfKind)
596 {
597 ULONG ulProcType;
598 rc = DosQueryProcType(pModNative->hmod,
599 pszSymbol ? 0 : iSymbol,
600 (PCSZ)pszSymbol,
601 &ulProcType);
602 if (rc)
603 {
604 if (puValue)
605 *puValue = 0;
606 return rc == ERROR_PROC_NOT_FOUND ? KLDR_ERR_SYMBOL_NOT_FOUND : rc;
607 }
608 *pfKind = (ulProcType & PT_32BIT ? KLDRSYMKIND_32BIT : KLDRSYMKIND_16BIT)
609 | KLDRSYMKIND_NO_TYPE;
610 }
611
612#elif K_OS == K_OS_WINDOWS
613 if (!pszSymbol && iSymbol >= 0x10000)
614 return KLDR_ERR_SYMBOL_NOT_FOUND;
615
616 pfn = GetProcAddress(pModNative->hmod, pszSymbol ? pszSymbol : (const char *)(KUPTR)iSymbol);
617 if (puValue)
618 *puValue = (KUPTR)pfn;
619 if (pfKind)
620 *pfKind = (pModNative->pNtHdrs->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
621 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_16BIT)
622 | KLDRSYMKIND_NO_TYPE;
623
624#elif K_OS == K_OS_DARWIN
625 if (!pszSymbol && iSymbol != NIL_KLDRMOD_SYM_ORDINAL)
626 return KLDR_ERR_SYMBOL_NOT_FOUND;
627
628 pfn = dlsym(pModNative->pvMod, pszSymbol);
629 if (!pfn)
630 return KLDR_ERR_SYMBOL_NOT_FOUND;
631 if (puValue)
632 *puValue = (KUPTR)pfn;
633 if (pfKind)
634 *pfKind = (sizeof(KUPTR) == 4 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT)
635 | KLDRSYMKIND_NO_TYPE;
636
637#else
638# error "Port me"
639#endif
640
641 return 0;
642}
643
644
645/** @copydoc kLdrModEnumSymbols */
646static int kldrModNativeEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress,
647 KU32 fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
648{
649 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
650#if K_OS == K_OS_OS2
651
652 /** @todo implement export enumeration on OS/2. */
653 (void)pModNative;
654 return ERROR_NOT_SUPPORTED;
655
656#elif K_OS == K_OS_WINDOWS || defined(__NT__)
657 const KU32 *paFunctions;
658 const IMAGE_EXPORT_DIRECTORY *pExpDir;
659 const KU32 *paRVANames;
660 const KU16 *paOrdinals;
661 KU32 iFunction;
662 KU32 cFunctions;
663 KU32 cNames;
664 int rc;
665
666 /*
667 * Make sure we've got mapped bits and resolve any base address aliases.
668 */
669 if ( pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size
670 < sizeof(IMAGE_EXPORT_DIRECTORY))
671 return 0; /* no exports to enumerate, return success. */
672
673 pExpDir = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
674 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
675 PIMAGE_EXPORT_DIRECTORY);
676
677 /*
678 * Enumerate the ordinal exports.
679 */
680 paRVANames = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfNames, const KU32 *);
681 paOrdinals = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfNameOrdinals, const KU16 *);
682 paFunctions = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfFunctions, const KU32 *);
683 cFunctions = pExpDir->NumberOfFunctions;
684 cNames = pExpDir->NumberOfNames;
685 for (iFunction = 0; iFunction < cFunctions; iFunction++)
686 {
687 unsigned fFoundName;
688 KU32 iName;
689 const KU32 uRVA = paFunctions[iFunction];
690 const KLDRADDR uValue = BaseAddress + uRVA;
691 KU32 fKind = (pModNative->pNtHdrs->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
692 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT)
693 | KLDRSYMKIND_NO_TYPE;
694 if ( uRVA - pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
695 < pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
696 fKind |= KLDRSYMKIND_FORWARDER;
697
698 /*
699 * Any symbol names?
700 */
701 fFoundName = 0;
702 for (iName = 0; iName < cNames; iName++)
703 {
704 const char *pszName;
705 if (paOrdinals[iName] != iFunction)
706 continue;
707 fFoundName = 1;
708
709 pszName = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, paRVANames[iName], const char *);
710 rc = pfnCallback(pMod, iFunction + pExpDir->Base, pszName, strlen(pszName), NULL,
711 uValue, fKind, pvUser);
712 if (rc)
713 return rc;
714 }
715
716 /*
717 * If no names, call once with the ordinal only.
718 */
719 if (!fFoundName)
720 {
721 rc = pfnCallback(pMod, iFunction + pExpDir->Base, NULL, 0, NULL, uValue, fKind, pvUser);
722 if (rc)
723 return rc;
724 }
725 }
726 return 0;
727
728#elif K_OS == K_OS_DARWIN
729 /** @todo implement enumeration on darwin. */
730 (void)pModNative;
731 return KLDR_ERR_TODO;
732
733#else
734# error "Port me"
735#endif
736
737}
738
739
740/** @copydoc kLdrModGetImport */
741static int kldrModNativeGetImport(PKLDRMOD pMod, const void *pvBits, KU32 iImport, char *pszName, KSIZE cchName)
742{
743 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
744#if K_OS == K_OS_OS2
745
746 /** @todo implement import enumeration on OS/2. */
747 (void)pModNative;
748 return ERROR_NOT_SUPPORTED;
749
750#elif K_OS == K_OS_WINDOWS || defined(__NT__)
751 const IMAGE_IMPORT_DESCRIPTOR *pImpDesc;
752 const char *pszImportName;
753 KSIZE cchImportName;
754 int rc;
755
756 /*
757 * Simple bounds check.
758 */
759 if (iImport >= (KU32)kldrModNativeNumberOfImports(pMod, pvBits))
760 return KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS;
761
762 /*
763 * Get the name.
764 */
765 pImpDesc = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
766 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
767 + sizeof(IMAGE_IMPORT_DESCRIPTOR) * iImport,
768 const IMAGE_IMPORT_DESCRIPTOR *);
769 pszImportName = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pImpDesc->Name, const char *);
770 cchImportName = kHlpStrLen(pszImportName);
771 if (cchImportName < cchName)
772 {
773 kHlpMemCopy(pszName, pszImportName, cchImportName + 1);
774 rc = 0;
775 }
776 else
777 {
778 kHlpMemCopy(pszName, pszImportName, cchName);
779 if (cchName)
780 pszName[cchName - 1] = '\0';
781 rc = KERR_BUFFER_OVERFLOW;
782 }
783
784 return rc;
785
786#elif K_OS == K_OS_DARWIN
787 /** @todo Implement import enumeration on darwin. */
788 (void)pModNative;
789 return KLDR_ERR_TODO;
790
791#else
792# error "Port me"
793#endif
794}
795
796
797/** @copydoc kLdrModNumberOfImports */
798static KI32 kldrModNativeNumberOfImports(PKLDRMOD pMod, const void *pvBits)
799{
800 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
801#if K_OS == K_OS_OS2
802
803 /** @todo implement import counting on OS/2. */
804 (void)pModNative;
805 return -1;
806
807#elif K_OS == K_OS_WINDOWS || defined(__NT__)
808 if (pModNative->cImportModules == ~(KU32)0)
809 {
810 /*
811 * We'll have to walk the import descriptors to figure out their number.
812 */
813 pModNative->cImportModules = 0;
814 if ( pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size
815 && pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
816 {
817 const IMAGE_IMPORT_DESCRIPTOR *pImpDesc;
818
819 pImpDesc = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
820 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
821 const IMAGE_IMPORT_DESCRIPTOR *);
822 while (pImpDesc->Name && pImpDesc->FirstThunk)
823 {
824 pModNative->cImportModules++;
825 pImpDesc++;
826 }
827 }
828 }
829 return pModNative->cImportModules;
830
831#elif K_OS == K_OS_DARWIN
832 /** @todo Implement import counting on Darwin. */
833 (void)pModNative;
834 return -1;
835
836#else
837# error "Port me"
838#endif
839}
840
841
842/** @copydoc kLdrModGetStackInfo */
843static int kldrModNativeGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
844{
845 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
846#if K_OS == K_OS_OS2
847
848 /** @todo implement stack info on OS/2. */
849 (void)pModNative;
850 return ERROR_NOT_SUPPORTED;
851
852#elif K_OS == K_OS_WINDOWS || defined(__NT__)
853 pStackInfo->Address = NIL_KLDRADDR;
854 pStackInfo->LinkAddress = NIL_KLDRADDR;
855 pStackInfo->cbStack = pStackInfo->cbStackThread = pModNative->pNtHdrs->OptionalHeader.SizeOfStackReserve;
856
857 return 0;
858
859#elif K_OS == K_OS_DARWIN
860 /** @todo Implement stack info on Darwin. */
861 (void)pModNative;
862 return KLDR_ERR_TODO;
863
864#else
865# error "Port me"
866#endif
867}
868
869
870/** @copydoc kLdrModQueryMainEntrypoint */
871static int kldrModNativeQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
872{
873 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
874#if K_OS == K_OS_OS2
875
876 /** @todo implement me on OS/2. */
877 (void)pModNative;
878 return ERROR_NOT_SUPPORTED;
879
880#elif K_OS == K_OS_WINDOWS || defined(__NT__)
881 /*
882 * Convert the address from the header.
883 */
884 *pMainEPAddress = pModNative->pNtHdrs->OptionalHeader.AddressOfEntryPoint
885 ? BaseAddress + pModNative->pNtHdrs->OptionalHeader.AddressOfEntryPoint
886 : NIL_KLDRADDR;
887 return 0;
888
889#elif K_OS == K_OS_DARWIN
890 /** @todo Implement me on Darwin. */
891 (void)pModNative;
892 return KLDR_ERR_TODO;
893
894#else
895# error "Port me"
896#endif
897}
898
899
900/** @copydoc kLdrModEnumDbgInfo */
901static int kldrModNativeEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser)
902{
903 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
904#if K_OS == K_OS_OS2
905
906 /** @todo implement me on OS/2. */
907 (void)pModNative;
908 return ERROR_NOT_SUPPORTED;
909
910#elif K_OS == K_OS_WINDOWS || defined(__NT__)
911 const IMAGE_DEBUG_DIRECTORY *pDbgDir;
912 KU32 iDbgInfo;
913 KU32 cb;
914 int rc;
915
916 /*
917 * Check that there is a debug directory first.
918 */
919 cb = pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
920 if ( cb < sizeof(IMAGE_DEBUG_DIRECTORY) /* screw borland linkers */
921 || !pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress)
922 return 0;
923
924 /*
925 * Enumerate the debug directory.
926 */
927 pDbgDir = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
928 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
929 const IMAGE_DEBUG_DIRECTORY *);
930 for (iDbgInfo = 0;; iDbgInfo++, pDbgDir++, cb -= sizeof(IMAGE_DEBUG_DIRECTORY))
931 {
932 KLDRDBGINFOTYPE enmDbgInfoType;
933
934 /* convert the type. */
935 switch (pDbgDir->Type)
936 {
937 case IMAGE_DEBUG_TYPE_UNKNOWN:
938 case IMAGE_DEBUG_TYPE_FPO:
939 case IMAGE_DEBUG_TYPE_COFF: /*stabs dialect??*/
940 case IMAGE_DEBUG_TYPE_MISC:
941 case IMAGE_DEBUG_TYPE_EXCEPTION:
942 case IMAGE_DEBUG_TYPE_FIXUP:
943 case IMAGE_DEBUG_TYPE_BORLAND:
944 default:
945 enmDbgInfoType = KLDRDBGINFOTYPE_UNKNOWN;
946 break;
947 case IMAGE_DEBUG_TYPE_CODEVIEW:
948 enmDbgInfoType = KLDRDBGINFOTYPE_CODEVIEW;
949 break;
950 }
951
952 rc = pfnCallback(pMod, iDbgInfo,
953 enmDbgInfoType, pDbgDir->MajorVersion, pDbgDir->MinorVersion, NULL /*pszPartNm*/,
954 pDbgDir->PointerToRawData ? pDbgDir->PointerToRawData : -1,
955 pDbgDir->AddressOfRawData ? pDbgDir->AddressOfRawData : NIL_KLDRADDR,
956 pDbgDir->SizeOfData,
957 NULL /*pszExtFile*/, pvUser);
958 if (rc)
959 break;
960
961 /* next */
962 if (cb <= sizeof(IMAGE_DEBUG_DIRECTORY))
963 break;
964 }
965
966 return rc;
967
968#elif K_OS == K_OS_DARWIN
969 /** @todo Implement me on Darwin. */
970 (void)pModNative;
971 return KLDR_ERR_TODO;
972
973#else
974# error "Port me"
975#endif
976}
977
978
979/** @copydoc kLdrModHasDbgInfo */
980static int kldrModNativeHasDbgInfo(PKLDRMOD pMod, const void *pvBits)
981{
982 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
983#if K_OS == K_OS_OS2
984
985 /** @todo implement me on OS/2. */
986 (void)pModNative;
987 return KLDR_ERR_NO_DEBUG_INFO;
988
989#elif K_OS == K_OS_WINDOWS || defined(__NT__)
990 /*
991 * Base this entirely on the presence of a debug directory.
992 */
993 if ( pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size
994 < sizeof(IMAGE_DEBUG_DIRECTORY) /* screw borland linkers */
995 || !pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress)
996 return KLDR_ERR_NO_DEBUG_INFO;
997 return 0;
998
999#elif K_OS == K_OS_DARWIN
1000 /** @todo Implement me on Darwin. */
1001 (void)pModNative;
1002 return KLDR_ERR_NO_DEBUG_INFO;
1003
1004#else
1005# error "Port me"
1006#endif
1007}
1008
1009
1010/** @copydoc kLdrModMap */
1011static int kldrModNativeMap(PKLDRMOD pMod)
1012{
1013 return 0;
1014}
1015
1016
1017/** @copydoc kLdrModUnmap */
1018static int kldrModNativeUnmap(PKLDRMOD pMod)
1019{
1020 return 0;
1021}
1022
1023
1024/** @copydoc kLdrModAllocTLS */
1025static int kldrModNativeAllocTLS(PKLDRMOD pMod, void *pvMapping)
1026{
1027 return 0;
1028}
1029
1030
1031/** @copydoc kLdrModFreeTLS */
1032static void kldrModNativeFreeTLS(PKLDRMOD pMod, void *pvMapping)
1033{
1034}
1035
1036
1037/** @copydoc kLdrModReload */
1038static int kldrModNativeReload(PKLDRMOD pMod)
1039{
1040 return 0;
1041}
1042
1043
1044/** @copydoc kLdrModFixupMapping */
1045static int kldrModNativeFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
1046{
1047 return 0;
1048}
1049
1050
1051/** @copydoc kLdrModCallInit */
1052static int kldrModNativeCallInit(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle)
1053{
1054 return 0;
1055}
1056
1057
1058/** @copydoc kLdrModCallTerm */
1059static int kldrModNativeCallTerm(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle)
1060{
1061 return 0;
1062}
1063
1064
1065/** @copydoc kLdrModCallThread */
1066static int kldrModNativeCallThread(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle, unsigned fAttachingOrDetaching)
1067{
1068 return 0;
1069}
1070
1071
1072/** @copydoc kLdrModSize */
1073static KLDRADDR kldrModNativeSize(PKLDRMOD pMod)
1074{
1075#if K_OS == K_OS_OS2
1076 return 0; /* don't bother */
1077
1078#elif K_OS == K_OS_WINDOWS || defined(__NT__)
1079 /* just because we can. */
1080 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
1081 return pModNative->pNtHdrs->OptionalHeader.SizeOfImage;
1082
1083#elif K_OS == K_OS_DARWIN
1084 /** @todo Implement me on Darwin. */
1085 return 0;
1086
1087#else
1088# error "Port me"
1089#endif
1090}
1091
1092
1093/** @copydoc kLdrModGetBits */
1094static int kldrModNativeGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
1095{
1096#if K_OS == K_OS_OS2
1097 return ERROR_NOT_SUPPORTED; /* don't bother */
1098
1099#elif K_OS == K_OS_WINDOWS || defined(__NT__)
1100 return ERROR_NOT_SUPPORTED; /* don't bother even if we could implement this. */
1101
1102#elif K_OS == K_OS_DARWIN
1103 return KLDR_ERR_TODO; /* don't bother. */
1104
1105#else
1106# error "Port me"
1107#endif
1108}
1109
1110
1111/** @copydoc kLdrModRelocateBits */
1112static int kldrModNativeRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
1113 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
1114{
1115#if K_OS == K_OS_OS2
1116 return ERROR_NOT_SUPPORTED; /* don't bother */
1117
1118#elif K_OS == K_OS_WINDOWS || defined(__NT__)
1119 return ERROR_NOT_SUPPORTED; /* don't bother even if we could implement this. */
1120
1121#elif K_OS == K_OS_DARWIN
1122 return KLDR_ERR_TODO; /* don't bother. */
1123
1124#else
1125# error "Port me"
1126#endif
1127}
1128
1129
1130/**
1131 * The native module interpreter method table.
1132 */
1133KLDRMODOPS g_kLdrModNativeOps =
1134{
1135 "Native",
1136 NULL,
1137 kldrModNativeCreate,
1138 kldrModNativeDestroy,
1139 kldrModNativeQuerySymbol,
1140 kldrModNativeEnumSymbols,
1141 kldrModNativeGetImport,
1142 kldrModNativeNumberOfImports,
1143 NULL /* can execute one is optional */,
1144 kldrModNativeGetStackInfo,
1145 kldrModNativeQueryMainEntrypoint,
1146 NULL /* pfnQueryImageUuid */,
1147 NULL /* fixme */,
1148 NULL /* fixme */,
1149 kldrModNativeEnumDbgInfo,
1150 kldrModNativeHasDbgInfo,
1151 kldrModNativeMap,
1152 kldrModNativeUnmap,
1153 kldrModNativeAllocTLS,
1154 kldrModNativeFreeTLS,
1155 kldrModNativeReload,
1156 kldrModNativeFixupMapping,
1157 kldrModNativeCallInit,
1158 kldrModNativeCallTerm,
1159 kldrModNativeCallThread,
1160 kldrModNativeSize,
1161 kldrModNativeGetBits,
1162 kldrModNativeRelocateBits,
1163 NULL /* fixme */,
1164 42 /* the end */
1165};
1166
Note: See TracBrowser for help on using the repository browser.

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