VirtualBox

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

Last change on this file since 120 was 117, checked in by bird, 5 years ago

kLdrModNative: Added KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM to allow kWorker to re-init mspdb100.dll when _MSPDBSRV_ENDPOINT_ changes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 39.6 KB
Line 
1/* $Id: kLdrModNative.c 117 2020-03-15 15:23:36Z 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), fFlags, 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 fFlags Module open flags, KLDRMOD_OPEN_FLAGS_XXX.
183 * @param ppMod Where to store the module interpreter instance pointer.
184 */
185int kLdrModOpenNative(const char *pszFilename, KU32 fFlags, PPKLDRMOD ppMod)
186{
187 int rc;
188
189 /*
190 * Load the image.
191 */
192#if K_OS == K_OS_OS2
193 HMODULE hmod;
194 kHlpAssertReturn(!(fFlags & ~KLDRMOD_OPEN_FLAGS_VALID_MASK), KERR_INVALID_PARAMETER);
195
196 rc = DosLoadModule(NULL, 0, (PCSZ)pszFilename, &hmod);
197 if (rc)
198 return rc;
199 rc = kLdrModOpenNativeByHandle((KUPTR)hmod, fFlags, ppMod);
200 if (rc)
201 DosFreeModule(hmod);
202
203#elif K_OS == K_OS_WINDOWS
204 HMODULE hmod;
205 kHlpAssertReturn(!(fFlags & ~KLDRMOD_OPEN_FLAGS_VALID_MASK), KERR_INVALID_PARAMETER);
206
207 hmod = LoadLibrary(pszFilename);
208 if (!hmod)
209 return GetLastError();
210 rc = kLdrModOpenNativeByHandle((KUPTR)hmod, fFlags, ppMod);
211 if (rc)
212 FreeLibrary(hmod);
213
214#elif K_OS == K_OS_DARWIN
215 void *pvMod;
216 kHlpAssertReturn(!(fFlags & ~KLDRMOD_OPEN_FLAGS_VALID_MASK), KERR_INVALID_PARAMETER);
217
218 pvMod = dlopen(pszFilename, 0);
219 if (!pvMod)
220 return ENOENT;
221 rc = kLdrModOpenNativeByHandle((KUPTR)pvMod, fFlags, ppMod);
222 if (rc)
223 dlclose(pvMod);
224
225#else
226# error "Port me"
227#endif
228 return rc;
229}
230
231
232/**
233 * Creates a native module interpret for an already module already
234 * loaded by the native loader.
235 *
236 * @returns 0 on success.
237 * @returns non-zero native or kLdr status code on failure.
238 * @param pszFilename The filename or module name to be loaded.
239 * @param fFlags Module open flags, KLDRMOD_OPEN_FLAGS_XXX.
240 * @param ppMod Where to store the module interpreter instance pointer.
241 * @remark This will not make the native loader increment the load count.
242 */
243int kLdrModOpenNativeByHandle(KUPTR uHandle, KU32 fFlags, PPKLDRMOD ppMod)
244{
245 KSIZE cb;
246 KU32 cchFilename;
247 KU32 cSegments;
248 PKLDRMOD pMod;
249 PKLDRMODNATIVE pModNative;
250
251 /*
252 * Delcare variables, parse the module header or whatever and determin the
253 * size of the module instance.
254 */
255#if K_OS == K_OS_OS2
256 char szFilename[CCHMAXPATH];
257 int rc;
258
259 /* get the filename. */
260 rc = DosQueryModuleName((HMODULE)uHandle, sizeof(szFilename), szFilename);
261 if (rc)
262 {
263 KLDRMODNATIVE_ASSERT(rc);
264 szFilename[0] = '\0';
265 }
266
267 /* get the segment count. */
268 /** @todo DosQueryHeaderInfo should be able to get us what we want on OS/2. */
269 cSegments = 1;
270
271#elif K_OS == K_OS_WINDOWS
272 DWORD dw;
273 char szFilename[MAX_PATH];
274 const IMAGE_NT_HEADERS *pNtHdrs;
275 const IMAGE_SECTION_HEADER *paShdrs;
276 const IMAGE_DOS_HEADER *pDosHdr = (const IMAGE_DOS_HEADER *)uHandle;
277 unsigned i;
278
279 /* get the filename. */
280 dw = GetModuleFileName((HANDLE)uHandle, szFilename, sizeof(szFilename));
281 if (dw <= 0)
282 {
283 KLDRMODNATIVE_ASSERT(dw <= 0);
284 szFilename[0] = '\0';
285 }
286
287 /* get the segment count. */
288 if (pDosHdr->e_magic == IMAGE_DOS_SIGNATURE)
289 pNtHdrs = (const IMAGE_NT_HEADERS *)((KUPTR)pDosHdr + pDosHdr->e_lfanew);
290 else
291 pNtHdrs = (const IMAGE_NT_HEADERS *)pDosHdr;
292 if (pNtHdrs->Signature != IMAGE_NT_SIGNATURE)
293 {
294 KLDRMODNATIVE_ASSERT(!"bad signature");
295 return KLDR_ERR_UNKNOWN_FORMAT;
296 }
297 if (pNtHdrs->FileHeader.SizeOfOptionalHeader != sizeof(IMAGE_OPTIONAL_HEADER))
298 {
299 KLDRMODNATIVE_ASSERT(!"bad optional header size");
300 return KLDR_ERR_UNKNOWN_FORMAT;
301 }
302 cSegments = pNtHdrs->FileHeader.NumberOfSections + 1;
303 paShdrs = (const IMAGE_SECTION_HEADER *)(pNtHdrs + 1);
304
305#elif K_OS == K_OS_DARWIN
306 char szFilename[1] = "";
307 cSegments = 0; /** @todo Figure out the Mac OS X dynamic loader. */
308
309#else
310# error "Port me"
311#endif
312
313 kHlpAssertReturn(!(fFlags & ~KLDRMOD_OPEN_FLAGS_VALID_MASK), KERR_INVALID_PARAMETER);
314
315 /*
316 * Calc the instance size, allocate and initialize it.
317 */
318 cchFilename = (KU32)kHlpStrLen(szFilename);
319 cb = K_ALIGN_Z(sizeof(KLDRMODNATIVE), 16)
320 + K_OFFSETOF(KLDRMOD, aSegments[cSegments])
321 + cchFilename + 1;
322 pModNative = (PKLDRMODNATIVE)kHlpAlloc(cb);
323 if (!pModNative)
324 return KERR_NO_MEMORY;
325
326 /* KLDRMOD */
327 pMod = (PKLDRMOD)((KU8 *)pModNative + K_ALIGN_Z(sizeof(KLDRMODNATIVE), 16));
328 pMod->pvData = pModNative;
329 pMod->pRdr = NULL;
330 pMod->pOps = NULL; /* set upon success. */
331 pMod->cSegments = cSegments;
332 pMod->cchFilename = cchFilename;
333 pMod->pszFilename = (char *)&pMod->aSegments[pMod->cSegments];
334 kHlpMemCopy((char *)pMod->pszFilename, szFilename, cchFilename + 1);
335 pMod->pszName = kHlpGetFilename(pMod->pszFilename); /** @todo get soname */
336 pMod->cchName = cchFilename - (KU32)(pMod->pszName - pMod->pszFilename);
337 pMod->fFlags = fFlags;
338#if defined(__i386__) || defined(__X86__) || defined(_M_IX86)
339 pMod->enmCpu = KCPU_I386;
340 pMod->enmArch = KCPUARCH_X86_32;
341 pMod->enmEndian = KLDRENDIAN_LITTLE;
342#elif defined(__X86_64__) || defined(__x86_64__) || defined(__AMD64__) || defined(_M_IX64)
343 pMod->enmCpu = KCPU_K8;
344 pMod->enmArch = KCPUARCH_AMD64;
345 pMod->enmEndian = KLDRENDIAN_LITTLE;
346#else
347# error "Port me"
348#endif
349 pMod->enmFmt = KLDRFMT_NATIVE;
350 pMod->enmType = KLDRTYPE_SHARED_LIBRARY_RELOCATABLE;
351 pMod->u32Magic = 0; /* set upon success. */
352
353 /* KLDRMODNATIVE */
354 pModNative->pMod = pMod;
355 pModNative->f32Reserved = 0;
356 pModNative->cImportModules = ~(KU32)0;
357
358 /*
359 * Set native instance data.
360 */
361#if K_OS == K_OS_OS2
362 pModNative->hmod = (HMODULE)uHandle;
363
364 /* just fake a segment for now. */
365 pMod->aSegments[0].pvUser = NULL;
366 pMod->aSegments[0].pchName = "fake";
367 pMod->aSegments[0].cchName = sizeof("fake") - 1;
368 pMod->aSegments[0].enmProt = KPROT_NOACCESS;
369 pMod->aSegments[0].cb = 0;
370 pMod->aSegments[0].Alignment = 0;
371 pMod->aSegments[0].LinkAddress = NIL_KLDRADDR;
372 pMod->aSegments[0].offFile = -1;
373 pMod->aSegments[0].cbFile = 0;
374 pMod->aSegments[0].RVA = NIL_KLDRADDR;
375 pMod->aSegments[0].cbMapped = 0;
376 pMod->aSegments[0].MapAddress = 0;
377
378#elif K_OS == K_OS_WINDOWS
379 pModNative->hmod = (HMODULE)uHandle;
380 pModNative->pNtHdrs = pNtHdrs;
381 pModNative->paShdrs = paShdrs;
382
383 if (pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL)
384 pMod->enmType = !(pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
385 ? KLDRTYPE_SHARED_LIBRARY_RELOCATABLE
386 : KLDRTYPE_SHARED_LIBRARY_FIXED;
387 else
388 pMod->enmType = !(pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
389 ? KLDRTYPE_EXECUTABLE_RELOCATABLE
390 : KLDRTYPE_EXECUTABLE_FIXED;
391
392 /* The implied headers section. */
393 pMod->aSegments[0].pvUser = NULL;
394 pMod->aSegments[0].pchName = "TheHeaders";
395 pMod->aSegments[0].cchName = sizeof("TheHeaders") - 1;
396 pMod->aSegments[0].enmProt = KPROT_READONLY;
397 pMod->aSegments[0].cb = pNtHdrs->OptionalHeader.SizeOfHeaders;
398 pMod->aSegments[0].Alignment = pNtHdrs->OptionalHeader.SectionAlignment;
399 pMod->aSegments[0].LinkAddress = pNtHdrs->OptionalHeader.ImageBase;
400 pMod->aSegments[0].offFile = 0;
401 pMod->aSegments[0].cbFile = pNtHdrs->OptionalHeader.SizeOfHeaders;
402 pMod->aSegments[0].RVA = 0;
403 if (pMod->cSegments > 1)
404 pMod->aSegments[0].cbMapped = paShdrs[0].VirtualAddress;
405 else
406 pMod->aSegments[0].cbMapped = pNtHdrs->OptionalHeader.SizeOfHeaders;
407 pMod->aSegments[0].MapAddress = uHandle;
408
409 /* The section headers. */
410 for (i = 0; i < pNtHdrs->FileHeader.NumberOfSections; i++)
411 {
412 const char *pch;
413 KU32 cchSegName;
414
415 /* unused */
416 pMod->aSegments[i + 1].pvUser = NULL;
417
418 /* name */
419 pMod->aSegments[i + 1].pchName = pch = &paShdrs[i].Name[0];
420 cchSegName = IMAGE_SIZEOF_SHORT_NAME;
421 while ( cchSegName > 0
422 && (pch[cchSegName - 1] == ' ' || pch[cchSegName - 1] == '\0'))
423 cchSegName--;
424 pMod->aSegments[i + 1].cchName = cchSegName;
425
426 /* size and addresses */
427 if (!(paShdrs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
428 {
429 pMod->aSegments[i + 1].cb = paShdrs[i].Misc.VirtualSize;
430 pMod->aSegments[i + 1].RVA = paShdrs[i].VirtualAddress;
431 pMod->aSegments[i + 1].LinkAddress = paShdrs[i].VirtualAddress + pNtHdrs->OptionalHeader.ImageBase;
432 pMod->aSegments[i + 1].MapAddress = paShdrs[i].VirtualAddress + uHandle;
433 pMod->aSegments[i + 1].cbMapped = paShdrs[i].Misc.VirtualSize;
434 if (i + 2 < pMod->cSegments)
435 pMod->aSegments[i + 1].cbMapped = paShdrs[i + 1].VirtualAddress
436 - paShdrs[i].VirtualAddress;
437 }
438 else
439 {
440 pMod->aSegments[i + 1].cb = 0;
441 pMod->aSegments[i + 1].cbMapped = 0;
442 pMod->aSegments[i + 1].LinkAddress = NIL_KLDRADDR;
443 pMod->aSegments[i + 1].RVA = 0;
444 pMod->aSegments[i + 1].MapAddress = 0;
445 }
446
447 /* file location */
448 pMod->aSegments[i + 1].offFile = paShdrs[i].PointerToRawData;
449 pMod->aSegments[i + 1].cbFile = paShdrs[i].SizeOfRawData;
450 if ( pMod->aSegments[i + 1].cbMapped > 0 /* if mapped */
451 && (KLDRSIZE)pMod->aSegments[i + 1].cbFile > pMod->aSegments[i + 1].cbMapped)
452 pMod->aSegments[i + 1].cbFile = (KLDRFOFF)pMod->aSegments[i + 1].cbMapped;
453
454 /* protection */
455 switch ( paShdrs[i].Characteristics
456 & (IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE))
457 {
458 case 0:
459 case IMAGE_SCN_MEM_SHARED:
460 pMod->aSegments[i + 1].enmProt = KPROT_NOACCESS;
461 break;
462 case IMAGE_SCN_MEM_READ:
463 case IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED:
464 pMod->aSegments[i + 1].enmProt = KPROT_READONLY;
465 break;
466 case IMAGE_SCN_MEM_WRITE:
467 case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ:
468 pMod->aSegments[i + 1].enmProt = KPROT_WRITECOPY;
469 break;
470 case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED:
471 case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ:
472 pMod->aSegments[i + 1].enmProt = KPROT_READWRITE;
473 break;
474 case IMAGE_SCN_MEM_EXECUTE:
475 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_SHARED:
476 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE;
477 break;
478 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ:
479 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED:
480 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE_READ;
481 break;
482 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE:
483 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ:
484 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE_WRITECOPY;
485 break;
486 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED:
487 case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ:
488 pMod->aSegments[i + 1].enmProt = KPROT_EXECUTE_READWRITE;
489 break;
490 }
491
492 /* alignment. */
493 switch (paShdrs[i].Characteristics & IMAGE_SCN_ALIGN_MASK)
494 {
495 case 0: /* hope this is right... */
496 pMod->aSegments[i + 1].Alignment = pNtHdrs->OptionalHeader.SectionAlignment;
497 break;
498 case IMAGE_SCN_ALIGN_1BYTES: pMod->aSegments[i + 1].Alignment = 1; break;
499 case IMAGE_SCN_ALIGN_2BYTES: pMod->aSegments[i + 1].Alignment = 2; break;
500 case IMAGE_SCN_ALIGN_4BYTES: pMod->aSegments[i + 1].Alignment = 4; break;
501 case IMAGE_SCN_ALIGN_8BYTES: pMod->aSegments[i + 1].Alignment = 8; break;
502 case IMAGE_SCN_ALIGN_16BYTES: pMod->aSegments[i + 1].Alignment = 16; break;
503 case IMAGE_SCN_ALIGN_32BYTES: pMod->aSegments[i + 1].Alignment = 32; break;
504 case IMAGE_SCN_ALIGN_64BYTES: pMod->aSegments[i + 1].Alignment = 64; break;
505 case IMAGE_SCN_ALIGN_128BYTES: pMod->aSegments[i + 1].Alignment = 128; break;
506 case IMAGE_SCN_ALIGN_256BYTES: pMod->aSegments[i + 1].Alignment = 256; break;
507 case IMAGE_SCN_ALIGN_512BYTES: pMod->aSegments[i + 1].Alignment = 512; break;
508 case IMAGE_SCN_ALIGN_1024BYTES: pMod->aSegments[i + 1].Alignment = 1024; break;
509 case IMAGE_SCN_ALIGN_2048BYTES: pMod->aSegments[i + 1].Alignment = 2048; break;
510 case IMAGE_SCN_ALIGN_4096BYTES: pMod->aSegments[i + 1].Alignment = 4096; break;
511 case IMAGE_SCN_ALIGN_8192BYTES: pMod->aSegments[i + 1].Alignment = 8192; break;
512 default: kHlpAssert(0); pMod->aSegments[i + 1].Alignment = 0; break;
513 }
514 }
515
516#elif K_OS == K_OS_DARWIN
517 /** @todo Figure out the Mac OS X dynamic loader. */
518
519#else
520# error "Port me"
521#endif
522
523 /*
524 * We're done.
525 */
526 pMod->u32Magic = KLDRMOD_MAGIC;
527 pMod->pOps = &g_kLdrModNativeOps;
528 *ppMod = pMod;
529 return 0;
530}
531
532
533/** @copydoc KLDRMODOPS::pfnDestroy */
534static int kldrModNativeDestroy(PKLDRMOD pMod)
535{
536 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
537 int rc;
538
539#if K_OS == K_OS_OS2
540 rc = DosFreeModule(pModNative->hmod);
541
542#elif K_OS == K_OS_WINDOWS
543 if (FreeLibrary(pModNative->hmod))
544 rc = 0;
545 else
546 rc = GetLastError();
547
548#elif K_OS == K_OS_DARWIN
549 dlclose(pModNative->pvMod);
550
551#else
552# error "Port me"
553#endif
554
555 pMod->u32Magic = 0;
556 pMod->pOps = NULL;
557 kHlpFree(pModNative);
558 return rc;
559}
560
561
562/** @copydoc kLdrModQuerySymbol */
563static int kldrModNativeQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 iSymbol,
564 const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion,
565 PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, KU32 *pfKind)
566{
567 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
568 const char *pszSymbol = pchSymbol;
569#if K_OS == K_OS_OS2
570 APIRET rc;
571 PFN pfn;
572#elif K_OS == K_OS_WINDOWS
573 FARPROC pfn;
574#elif K_OS == K_OS_DARWIN
575 void *pfn;
576#else
577# error "Port me"
578#endif
579
580 /* make stack copy of the symbol if it isn't zero terminated. */
581 if (pszSymbol && pszSymbol[cchSymbol])
582 {
583 char *pszCopy = kHlpAllocA(cchSymbol + 1);
584 kHlpMemCopy(pszCopy, pchSymbol, cchSymbol);
585 pszCopy[cchSymbol] = '\0';
586 pszSymbol = pszCopy;
587 }
588
589#if K_OS == K_OS_OS2
590 if (!pchSymbol && iSymbol >= 0x10000)
591 return KLDR_ERR_SYMBOL_NOT_FOUND;
592
593 if (puValue)
594 {
595 rc = DosQueryProcAddr(pModNative->hmod,
596 pszSymbol ? 0 : iSymbol,
597 (PCSZ)pszSymbol,
598 &pfn);
599 if (rc)
600 return rc == ERROR_PROC_NOT_FOUND ? KLDR_ERR_SYMBOL_NOT_FOUND : rc;
601 *puValue = (KUPTR)pfn;
602 }
603 if (pfKind)
604 {
605 ULONG ulProcType;
606 rc = DosQueryProcType(pModNative->hmod,
607 pszSymbol ? 0 : iSymbol,
608 (PCSZ)pszSymbol,
609 &ulProcType);
610 if (rc)
611 {
612 if (puValue)
613 *puValue = 0;
614 return rc == ERROR_PROC_NOT_FOUND ? KLDR_ERR_SYMBOL_NOT_FOUND : rc;
615 }
616 *pfKind = (ulProcType & PT_32BIT ? KLDRSYMKIND_32BIT : KLDRSYMKIND_16BIT)
617 | KLDRSYMKIND_NO_TYPE;
618 }
619
620#elif K_OS == K_OS_WINDOWS
621 if (!pszSymbol && iSymbol >= 0x10000)
622 return KLDR_ERR_SYMBOL_NOT_FOUND;
623
624 pfn = GetProcAddress(pModNative->hmod, pszSymbol ? pszSymbol : (const char *)(KUPTR)iSymbol);
625 if (puValue)
626 *puValue = (KUPTR)pfn;
627 if (pfKind)
628 *pfKind = (pModNative->pNtHdrs->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
629 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_16BIT)
630 | KLDRSYMKIND_NO_TYPE;
631
632#elif K_OS == K_OS_DARWIN
633 if (!pszSymbol && iSymbol != NIL_KLDRMOD_SYM_ORDINAL)
634 return KLDR_ERR_SYMBOL_NOT_FOUND;
635
636 pfn = dlsym(pModNative->pvMod, pszSymbol);
637 if (!pfn)
638 return KLDR_ERR_SYMBOL_NOT_FOUND;
639 if (puValue)
640 *puValue = (KUPTR)pfn;
641 if (pfKind)
642 *pfKind = (sizeof(KUPTR) == 4 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT)
643 | KLDRSYMKIND_NO_TYPE;
644
645#else
646# error "Port me"
647#endif
648
649 return 0;
650}
651
652
653/** @copydoc kLdrModEnumSymbols */
654static int kldrModNativeEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress,
655 KU32 fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
656{
657 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
658#if K_OS == K_OS_OS2
659
660 /** @todo implement export enumeration on OS/2. */
661 (void)pModNative;
662 return ERROR_NOT_SUPPORTED;
663
664#elif K_OS == K_OS_WINDOWS || defined(__NT__)
665 const KU32 *paFunctions;
666 const IMAGE_EXPORT_DIRECTORY *pExpDir;
667 const KU32 *paRVANames;
668 const KU16 *paOrdinals;
669 KU32 iFunction;
670 KU32 cFunctions;
671 KU32 cNames;
672 int rc;
673
674 /*
675 * Make sure we've got mapped bits and resolve any base address aliases.
676 */
677 if ( pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size
678 < sizeof(IMAGE_EXPORT_DIRECTORY))
679 return 0; /* no exports to enumerate, return success. */
680
681 pExpDir = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
682 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
683 PIMAGE_EXPORT_DIRECTORY);
684
685 /*
686 * Enumerate the ordinal exports.
687 */
688 paRVANames = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfNames, const KU32 *);
689 paOrdinals = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfNameOrdinals, const KU16 *);
690 paFunctions = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfFunctions, const KU32 *);
691 cFunctions = pExpDir->NumberOfFunctions;
692 cNames = pExpDir->NumberOfNames;
693 for (iFunction = 0; iFunction < cFunctions; iFunction++)
694 {
695 unsigned fFoundName;
696 KU32 iName;
697 const KU32 uRVA = paFunctions[iFunction];
698 const KLDRADDR uValue = BaseAddress + uRVA;
699 KU32 fKind = (pModNative->pNtHdrs->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
700 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT)
701 | KLDRSYMKIND_NO_TYPE;
702 if ( uRVA - pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
703 < pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
704 fKind |= KLDRSYMKIND_FORWARDER;
705
706 /*
707 * Any symbol names?
708 */
709 fFoundName = 0;
710 for (iName = 0; iName < cNames; iName++)
711 {
712 const char *pszName;
713 if (paOrdinals[iName] != iFunction)
714 continue;
715 fFoundName = 1;
716
717 pszName = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, paRVANames[iName], const char *);
718 rc = pfnCallback(pMod, iFunction + pExpDir->Base, pszName, strlen(pszName), NULL,
719 uValue, fKind, pvUser);
720 if (rc)
721 return rc;
722 }
723
724 /*
725 * If no names, call once with the ordinal only.
726 */
727 if (!fFoundName)
728 {
729 rc = pfnCallback(pMod, iFunction + pExpDir->Base, NULL, 0, NULL, uValue, fKind, pvUser);
730 if (rc)
731 return rc;
732 }
733 }
734 return 0;
735
736#elif K_OS == K_OS_DARWIN
737 /** @todo implement enumeration on darwin. */
738 (void)pModNative;
739 return KLDR_ERR_TODO;
740
741#else
742# error "Port me"
743#endif
744
745}
746
747
748/** @copydoc kLdrModGetImport */
749static int kldrModNativeGetImport(PKLDRMOD pMod, const void *pvBits, KU32 iImport, char *pszName, KSIZE cchName)
750{
751 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
752#if K_OS == K_OS_OS2
753
754 /** @todo implement import enumeration on OS/2. */
755 (void)pModNative;
756 return ERROR_NOT_SUPPORTED;
757
758#elif K_OS == K_OS_WINDOWS || defined(__NT__)
759 const IMAGE_IMPORT_DESCRIPTOR *pImpDesc;
760 const char *pszImportName;
761 KSIZE cchImportName;
762 int rc;
763
764 /*
765 * Simple bounds check.
766 */
767 if (iImport >= (KU32)kldrModNativeNumberOfImports(pMod, pvBits))
768 return KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS;
769
770 /*
771 * Get the name.
772 */
773 pImpDesc = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
774 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
775 + sizeof(IMAGE_IMPORT_DESCRIPTOR) * iImport,
776 const IMAGE_IMPORT_DESCRIPTOR *);
777 pszImportName = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pImpDesc->Name, const char *);
778 cchImportName = kHlpStrLen(pszImportName);
779 if (cchImportName < cchName)
780 {
781 kHlpMemCopy(pszName, pszImportName, cchImportName + 1);
782 rc = 0;
783 }
784 else
785 {
786 kHlpMemCopy(pszName, pszImportName, cchName);
787 if (cchName)
788 pszName[cchName - 1] = '\0';
789 rc = KERR_BUFFER_OVERFLOW;
790 }
791
792 return rc;
793
794#elif K_OS == K_OS_DARWIN
795 /** @todo Implement import enumeration on darwin. */
796 (void)pModNative;
797 return KLDR_ERR_TODO;
798
799#else
800# error "Port me"
801#endif
802}
803
804
805/** @copydoc kLdrModNumberOfImports */
806static KI32 kldrModNativeNumberOfImports(PKLDRMOD pMod, const void *pvBits)
807{
808 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
809#if K_OS == K_OS_OS2
810
811 /** @todo implement import counting on OS/2. */
812 (void)pModNative;
813 return -1;
814
815#elif K_OS == K_OS_WINDOWS || defined(__NT__)
816 if (pModNative->cImportModules == ~(KU32)0)
817 {
818 /*
819 * We'll have to walk the import descriptors to figure out their number.
820 */
821 pModNative->cImportModules = 0;
822 if ( pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size
823 && pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
824 {
825 const IMAGE_IMPORT_DESCRIPTOR *pImpDesc;
826
827 pImpDesc = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
828 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
829 const IMAGE_IMPORT_DESCRIPTOR *);
830 while (pImpDesc->Name && pImpDesc->FirstThunk)
831 {
832 pModNative->cImportModules++;
833 pImpDesc++;
834 }
835 }
836 }
837 return pModNative->cImportModules;
838
839#elif K_OS == K_OS_DARWIN
840 /** @todo Implement import counting on Darwin. */
841 (void)pModNative;
842 return -1;
843
844#else
845# error "Port me"
846#endif
847}
848
849
850/** @copydoc kLdrModGetStackInfo */
851static int kldrModNativeGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
852{
853 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
854#if K_OS == K_OS_OS2
855
856 /** @todo implement stack info on OS/2. */
857 (void)pModNative;
858 return ERROR_NOT_SUPPORTED;
859
860#elif K_OS == K_OS_WINDOWS || defined(__NT__)
861 pStackInfo->Address = NIL_KLDRADDR;
862 pStackInfo->LinkAddress = NIL_KLDRADDR;
863 pStackInfo->cbStack = pStackInfo->cbStackThread = pModNative->pNtHdrs->OptionalHeader.SizeOfStackReserve;
864
865 return 0;
866
867#elif K_OS == K_OS_DARWIN
868 /** @todo Implement stack info on Darwin. */
869 (void)pModNative;
870 return KLDR_ERR_TODO;
871
872#else
873# error "Port me"
874#endif
875}
876
877
878/** @copydoc kLdrModQueryMainEntrypoint */
879static int kldrModNativeQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
880{
881 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
882#if K_OS == K_OS_OS2
883
884 /** @todo implement me on OS/2. */
885 (void)pModNative;
886 return ERROR_NOT_SUPPORTED;
887
888#elif K_OS == K_OS_WINDOWS || defined(__NT__)
889 /*
890 * Convert the address from the header.
891 */
892 *pMainEPAddress = pModNative->pNtHdrs->OptionalHeader.AddressOfEntryPoint
893 ? BaseAddress + pModNative->pNtHdrs->OptionalHeader.AddressOfEntryPoint
894 : NIL_KLDRADDR;
895 return 0;
896
897#elif K_OS == K_OS_DARWIN
898 /** @todo Implement me on Darwin. */
899 (void)pModNative;
900 return KLDR_ERR_TODO;
901
902#else
903# error "Port me"
904#endif
905}
906
907
908/** @copydoc kLdrModEnumDbgInfo */
909static int kldrModNativeEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser)
910{
911 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
912#if K_OS == K_OS_OS2
913
914 /** @todo implement me on OS/2. */
915 (void)pModNative;
916 return ERROR_NOT_SUPPORTED;
917
918#elif K_OS == K_OS_WINDOWS || defined(__NT__)
919 const IMAGE_DEBUG_DIRECTORY *pDbgDir;
920 KU32 iDbgInfo;
921 KU32 cb;
922 int rc;
923
924 /*
925 * Check that there is a debug directory first.
926 */
927 cb = pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
928 if ( cb < sizeof(IMAGE_DEBUG_DIRECTORY) /* screw borland linkers */
929 || !pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress)
930 return 0;
931
932 /*
933 * Enumerate the debug directory.
934 */
935 pDbgDir = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
936 pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
937 const IMAGE_DEBUG_DIRECTORY *);
938 for (iDbgInfo = 0;; iDbgInfo++, pDbgDir++, cb -= sizeof(IMAGE_DEBUG_DIRECTORY))
939 {
940 KLDRDBGINFOTYPE enmDbgInfoType;
941
942 /* convert the type. */
943 switch (pDbgDir->Type)
944 {
945 case IMAGE_DEBUG_TYPE_UNKNOWN:
946 case IMAGE_DEBUG_TYPE_FPO:
947 case IMAGE_DEBUG_TYPE_COFF: /*stabs dialect??*/
948 case IMAGE_DEBUG_TYPE_MISC:
949 case IMAGE_DEBUG_TYPE_EXCEPTION:
950 case IMAGE_DEBUG_TYPE_FIXUP:
951 case IMAGE_DEBUG_TYPE_BORLAND:
952 default:
953 enmDbgInfoType = KLDRDBGINFOTYPE_UNKNOWN;
954 break;
955 case IMAGE_DEBUG_TYPE_CODEVIEW:
956 enmDbgInfoType = KLDRDBGINFOTYPE_CODEVIEW;
957 break;
958 }
959
960 rc = pfnCallback(pMod, iDbgInfo,
961 enmDbgInfoType, pDbgDir->MajorVersion, pDbgDir->MinorVersion, NULL /*pszPartNm*/,
962 pDbgDir->PointerToRawData ? pDbgDir->PointerToRawData : -1,
963 pDbgDir->AddressOfRawData ? pDbgDir->AddressOfRawData : NIL_KLDRADDR,
964 pDbgDir->SizeOfData,
965 NULL /*pszExtFile*/, pvUser);
966 if (rc)
967 break;
968
969 /* next */
970 if (cb <= sizeof(IMAGE_DEBUG_DIRECTORY))
971 break;
972 }
973
974 return rc;
975
976#elif K_OS == K_OS_DARWIN
977 /** @todo Implement me on Darwin. */
978 (void)pModNative;
979 return KLDR_ERR_TODO;
980
981#else
982# error "Port me"
983#endif
984}
985
986
987/** @copydoc kLdrModHasDbgInfo */
988static int kldrModNativeHasDbgInfo(PKLDRMOD pMod, const void *pvBits)
989{
990 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
991#if K_OS == K_OS_OS2
992
993 /** @todo implement me on OS/2. */
994 (void)pModNative;
995 return KLDR_ERR_NO_DEBUG_INFO;
996
997#elif K_OS == K_OS_WINDOWS || defined(__NT__)
998 /*
999 * Base this entirely on the presence of a debug directory.
1000 */
1001 if ( pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size
1002 < sizeof(IMAGE_DEBUG_DIRECTORY) /* screw borland linkers */
1003 || !pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress)
1004 return KLDR_ERR_NO_DEBUG_INFO;
1005 return 0;
1006
1007#elif K_OS == K_OS_DARWIN
1008 /** @todo Implement me on Darwin. */
1009 (void)pModNative;
1010 return KLDR_ERR_NO_DEBUG_INFO;
1011
1012#else
1013# error "Port me"
1014#endif
1015}
1016
1017
1018/** @copydoc kLdrModMap */
1019static int kldrModNativeMap(PKLDRMOD pMod)
1020{
1021 return 0;
1022}
1023
1024
1025/** @copydoc kLdrModUnmap */
1026static int kldrModNativeUnmap(PKLDRMOD pMod)
1027{
1028 return 0;
1029}
1030
1031
1032/** @copydoc kLdrModAllocTLS */
1033static int kldrModNativeAllocTLS(PKLDRMOD pMod, void *pvMapping)
1034{
1035 return 0;
1036}
1037
1038
1039/** @copydoc kLdrModFreeTLS */
1040static void kldrModNativeFreeTLS(PKLDRMOD pMod, void *pvMapping)
1041{
1042}
1043
1044
1045/** @copydoc kLdrModReload */
1046static int kldrModNativeReload(PKLDRMOD pMod)
1047{
1048 return 0;
1049}
1050
1051
1052/** @copydoc kLdrModFixupMapping */
1053static int kldrModNativeFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
1054{
1055 return 0;
1056}
1057
1058
1059#if K_OS == K_OS_OS2 || K_OS == K_OS_WINDOWS || defined(__NT__)
1060/** Common worker on platforms where there is one entrypoint which does both. */
1061static int kLdrModNativeCallInitTerm(PKLDRMODNATIVE pModNative, KUPTR uHandle, KBOOL fInit)
1062{
1063# if K_OS == K_OS_WINDOWS || defined(__NT__)
1064 /* No TLS init/term for now. */
1065 KU32 const uRvaEntrypoint = pModNative->pNtHdrs->OptionalHeader.AddressOfEntryPoint;
1066 if ( uRvaEntrypoint != 0
1067 && uRvaEntrypoint < pModNative->pNtHdrs->OptionalHeader.SizeOfCode
1068 && (pModNative->pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL))
1069 {
1070 KI32 rc = kldrModPEDoCall(uRvaEntrypoint + (KUPTR)pModNative->hmod, uHandle,
1071 fInit ? DLL_PROCESS_ATTACH : DLL_PROCESS_DETACH, NULL /*pvReserved*/);
1072 if (rc)
1073 return 0;
1074 return fInit ? KLDR_ERR_MODULE_INIT_FAILED : KLDR_ERR_THREAD_ATTACH_FAILED;
1075 }
1076# elif K_OS == K_OS_OS2
1077 //KI32 kldrModLXDoCall(KUPTR uEntrypoint, KUPTR uHandle, KU32 uOp, void *pvReserved)
1078# endif
1079 return 0;
1080}
1081#endif
1082
1083/** @copydoc kLdrModCallInit */
1084static int kldrModNativeCallInit(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle)
1085{
1086#if K_OS == K_OS_OS2 || K_OS == K_OS_WINDOWS || defined(__NT__)
1087 if (pMod->fFlags & KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM)
1088 return kLdrModNativeCallInitTerm((PKLDRMODNATIVE)pMod->pvData, uHandle, K_TRUE /*fInit*/);
1089#endif
1090 return 0;
1091}
1092
1093
1094/** @copydoc kLdrModCallTerm */
1095static int kldrModNativeCallTerm(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle)
1096{
1097#if K_OS == K_OS_OS2 || K_OS == K_OS_WINDOWS || defined(__NT__)
1098 if (pMod->fFlags & KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM)
1099 return kLdrModNativeCallInitTerm((PKLDRMODNATIVE)pMod->pvData, uHandle, K_FALSE /*fInit*/);
1100#endif
1101 return 0;
1102}
1103
1104
1105/** @copydoc kLdrModCallThread */
1106static int kldrModNativeCallThread(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle, unsigned fAttachingOrDetaching)
1107{
1108 return 0;
1109}
1110
1111
1112/** @copydoc kLdrModSize */
1113static KLDRADDR kldrModNativeSize(PKLDRMOD pMod)
1114{
1115#if K_OS == K_OS_OS2
1116 return 0; /* don't bother */
1117
1118#elif K_OS == K_OS_WINDOWS || defined(__NT__)
1119 /* just because we can. */
1120 PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
1121 return pModNative->pNtHdrs->OptionalHeader.SizeOfImage;
1122
1123#elif K_OS == K_OS_DARWIN
1124 /** @todo Implement me on Darwin. */
1125 return 0;
1126
1127#else
1128# error "Port me"
1129#endif
1130}
1131
1132
1133/** @copydoc kLdrModGetBits */
1134static int kldrModNativeGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
1135{
1136#if K_OS == K_OS_OS2
1137 return ERROR_NOT_SUPPORTED; /* don't bother */
1138
1139#elif K_OS == K_OS_WINDOWS || defined(__NT__)
1140 return ERROR_NOT_SUPPORTED; /* don't bother even if we could implement this. */
1141
1142#elif K_OS == K_OS_DARWIN
1143 return KLDR_ERR_TODO; /* don't bother. */
1144
1145#else
1146# error "Port me"
1147#endif
1148}
1149
1150
1151/** @copydoc kLdrModRelocateBits */
1152static int kldrModNativeRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
1153 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
1154{
1155#if K_OS == K_OS_OS2
1156 return ERROR_NOT_SUPPORTED; /* don't bother */
1157
1158#elif K_OS == K_OS_WINDOWS || defined(__NT__)
1159 return ERROR_NOT_SUPPORTED; /* don't bother even if we could implement this. */
1160
1161#elif K_OS == K_OS_DARWIN
1162 return KLDR_ERR_TODO; /* don't bother. */
1163
1164#else
1165# error "Port me"
1166#endif
1167}
1168
1169
1170/**
1171 * The native module interpreter method table.
1172 */
1173KLDRMODOPS g_kLdrModNativeOps =
1174{
1175 "Native",
1176 NULL,
1177 kldrModNativeCreate,
1178 kldrModNativeDestroy,
1179 kldrModNativeQuerySymbol,
1180 kldrModNativeEnumSymbols,
1181 kldrModNativeGetImport,
1182 kldrModNativeNumberOfImports,
1183 NULL /* can execute one is optional */,
1184 kldrModNativeGetStackInfo,
1185 kldrModNativeQueryMainEntrypoint,
1186 NULL /* pfnQueryImageUuid */,
1187 NULL /* fixme */,
1188 NULL /* fixme */,
1189 kldrModNativeEnumDbgInfo,
1190 kldrModNativeHasDbgInfo,
1191 kldrModNativeMap,
1192 kldrModNativeUnmap,
1193 kldrModNativeAllocTLS,
1194 kldrModNativeFreeTLS,
1195 kldrModNativeReload,
1196 kldrModNativeFixupMapping,
1197 kldrModNativeCallInit,
1198 kldrModNativeCallTerm,
1199 kldrModNativeCallThread,
1200 kldrModNativeSize,
1201 kldrModNativeGetBits,
1202 kldrModNativeRelocateBits,
1203 NULL /* fixme */,
1204 42 /* the end */
1205};
1206
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