source: trunk/kLdr/kLdrMod.c@ 2891

Last change on this file since 2891 was 2891, checked in by bird, 19 years ago

interface adjustment (in progress).

  • Property svn:keywords set to Id
File size: 26.3 KB
Line 
1/* $Id: kLdrMod.c 2891 2006-11-21 21:40:45Z bird $ */
2/** @file
3 *
4 * kLdr - The Module Interpreter.
5 *
6 * Copyright (c) 2006 knut st. osmundsen <bird-kbuild-src@anduin.net>
7 *
8 *
9 * This file is part of kLdr.
10 *
11 * kLdr is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * kLdr is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kLdr; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include <kLdr.h>
32#include "kLdrHlp.h"
33#include "kLdrInternal.h"
34#include "kLdrModMZ.h"
35#if 1 /* testing headers */
36# include "kLdrModPE.h"
37# include "kLdrModLX.h"
38# include "kLdrModELF32.h"
39# include "kLdrModELF64.h"
40#endif
41
42
43/*******************************************************************************
44* Defined Constants And Macros *
45*******************************************************************************/
46/** @def KLDRMOD_STRICT
47 * Define KLDRMOD_STRICT to enabled strict checks in KLDRMOD. */
48#define KLDRMOD_STRICT 1
49
50/** @def KLDRMOD_ASSERT
51 * Assert that an expression is true when KLDR_STRICT is defined.
52 */
53#ifdef KLDRMOD_STRICT
54# define KLDRMOD_ASSERT(expr) kldrHlpAssert(expr)
55#else
56# define KLDRMOD_ASSERT(expr) do {} while (0)
57#endif
58
59/** Return / crash validation of a module argument. */
60#define KLDRMOD_VALIDATE_EX(pMod, rc) \
61 do { \
62 if ( (pMod)->u32Magic != KLDRMOD_MAGIC \
63 || (pMod)->pOps == NULL \
64 )\
65 { \
66 return (rc); \
67 } \
68 } while (0)
69
70/** Return / crash validation of a module argument. */
71#define KLDRMOD_VALIDATE(pMod) \
72 KLDRMOD_VALIDATE_EX(pMod, KLDR_ERR_INVALID_PARAMETER)
73
74/** Return / crash validation of a module argument. */
75#define KLDRMOD_VALIDATE_VOID(pMod) \
76 do { \
77 if ( (pMod)->u32Magic != KLDRMOD_MAGIC \
78 || (pMod)->pOps == NULL \
79 )\
80 { \
81 return; \
82 } \
83 } while (0)
84
85
86/*******************************************************************************
87* Global Variables *
88*******************************************************************************/
89/** The list of module interpreters. */
90static PCKLDRMODOPS g_pModInterpreterHead = NULL;
91
92
93
94/*******************************************************************************
95* Internal Functions *
96*******************************************************************************/
97
98
99
100/**
101 * Open a executable image by file name.
102 *
103 * @returns 0 on success and *ppMod pointing to a module instance.
104 * On failure, a non-zero OS specific error code is returned.
105 * @param pszFilename The filename to open.
106 * @param ppMod Where to store the module handle.
107 */
108int kLdrModOpen(const char *pszFilename, PPKLDRMOD ppMod)
109{
110 /*
111 * Open the file using a bit provider.
112 */
113 PKLDRRDR pRdr;
114 int rc = kLdrRdrOpen(&pRdr, pszFilename);
115 if (!rc)
116 {
117 rc = kLdrModOpenFromRdr(pRdr, ppMod);
118 if (!rc)
119 return 0;
120 kLdrRdrClose(pRdr);
121 }
122 return rc;
123}
124
125
126/**
127 * Open a executable image from a file provider instance.
128 *
129 * @returns 0 on success and *ppMod pointing to a module instance.
130 * On failure, a non-zero OS specific error code is returned.
131 * @param pRdr The file provider instance to use.
132 * On success, the ownership of the instance is taken by the
133 * module and the caller must not ever touch it again.
134 * (The instance is not closed on failure, the call has to do that.)
135 * @param ppMod Where to store the module handle.
136 */
137int kLdrModOpenFromRdr(PKLDRRDR pRdr, PPKLDRMOD ppMod)
138{
139 union
140 {
141 uint32_t u32;
142 uint16_t u16;
143 uint16_t au16[2];
144 uint8_t au8[4];
145 } u;
146 off_t offHdr = 0;
147 int rc;
148
149 /*
150 * Try figure out what kind of image this is.
151 * Always read the 'new header' if we encounter MZ.
152 */
153 rc = kLdrRdrRead(pRdr, &u, sizeof(u), 0);
154 if (rc)
155 return rc;
156 if ( u.u16 == IMAGE_DOS_SIGNATURE
157 && kLdrRdrSize(pRdr) > sizeof(IMAGE_DOS_HEADER))
158 {
159 rc = kLdrRdrRead(pRdr, &u, sizeof(u.u32), KLDR_OFFSETOF(IMAGE_DOS_HEADER, e_lfanew));
160 if (rc)
161 return rc;
162 if ((off_t)u.u32 < kLdrRdrSize(pRdr))
163 {
164 offHdr = u.u32;
165 rc = kLdrRdrRead(pRdr, &u, sizeof(u.u32), offHdr);
166 if (rc)
167 return rc;
168 }
169 else
170 u.u16 = IMAGE_DOS_SIGNATURE;
171 }
172
173 /*
174 * Use the magic to select the appropriate image interpreter head on.
175 */
176 if (u.u16 == IMAGE_DOS_SIGNATURE)
177 rc = KLDR_ERR_MZ_NOT_SUPPORTED;
178 else if (u.u16 == IMAGE_NE_SIGNATURE)
179 rc = KLDR_ERR_NE_NOT_SUPPORTED;
180 else if (u.u16 == IMAGE_LX_SIGNATURE)
181 rc = g_kLdrModLXOps.pfnCreate(&g_kLdrModLXOps, pRdr, offHdr, ppMod);
182 else if (u.u16 == IMAGE_LE_SIGNATURE)
183 rc = KLDR_ERR_LE_NOT_SUPPORTED;
184 else if (u.u32 == IMAGE_NT_SIGNATURE)
185 rc = g_kLdrModPEOps.pfnCreate(&g_kLdrModPEOps, pRdr, offHdr, ppMod);
186 else if (u.u32 == IMAGE_ELF_SIGNATURE)
187 rc = KLDR_ERR_ELF_NOT_SUPPORTED;
188 else
189 rc = KLDR_ERR_UNKNOWN_FORMAT;
190
191 /*
192 * If no head on hit, let each interpreter have a go.
193 */
194 if (rc)
195 {
196 PCKLDRMODOPS pOps;
197 for (pOps = g_pModInterpreterHead; pOps; pOps = pOps->pNext)
198 {
199 int rc2 = pOps->pfnCreate(pOps, pRdr, offHdr, ppMod);
200 if (!rc2)
201 return rc;
202 }
203 *ppMod = NULL;
204 }
205 return rc;
206}
207
208
209/**
210 * Closes an open module.
211 *
212 * The caller is responsible for calling kLdrModUnmap() and kLdrFreeTLS()
213 * before closing the module.
214 *
215 * @returns 0 on success, non-zero on failure. The module instance state
216 * is unknown on failure, it's best not to touch it.
217 * @param pMod The module.
218 */
219int kLdrModClose(PKLDRMOD pMod)
220{
221 KLDRMOD_VALIDATE(pMod);
222 return pMod->pOps->pfnDestroy(pMod);
223}
224
225
226/**
227 * Queries a symbol by name or ordinal number.
228 *
229 * @returns 0 and *puValue and *pfKind on success.
230 * KLDR_ERR_SYMBOL_NOT_FOUND is returned if the symbol wasn't found.
231 * Other failures could stem from bad executable format failures,
232 * read failure in case pvBits isn't specified and no mapping should be used.
233 * @param pMod The module.
234 * @param pvBits Optional pointer to bits returned by kLdrModGetBits() currently located at BaseAddress.
235 * This can be used by some module interpreters to reduce memory consumption.
236 * @param BaseAddress The module base address to use when calculating the symbol value.
237 * There are two special values that can be used:
238 * KLDRMOD_BASEADDRESS_LINK and KLDRMOD_BASEADDRESS_MAP.
239 * @param iSymbol The symbol ordinal. (optional)
240 * @param pchSymbol The symbol name. (optional)
241 * Important, this doesn't have to be a null-terminated string.
242 * @param cchSymbol The length of the symbol name.
243 * @param pszVersion The symbol version. NULL if not versioned.
244 * @param pfnGetForwarder The callback to use when resolving a forwarder symbol. This is optional
245 * and if not specified KLDR_ERR_FORWARDER is returned instead.
246 * @param pvUser The user argument for the pfnGetForwarder callback.
247 * @param puValue Where to store the symbol value. (optional)
248 * @param pfKind On input one of the KLDRSYMKIND_REQ_* #defines.
249 * On output the symbol kind. (optional)
250 */
251int kLdrModQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t iSymbol,
252 const char *pchSymbol, size_t cchSymbol, const char *pszVersion,
253 PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind)
254{
255 KLDRMOD_VALIDATE(pMod);
256 if (!puValue && !pfKind)
257 return KLDR_ERR_INVALID_PARAMETER;
258 if (puValue)
259 *puValue = 0;
260 if (pfKind)
261 KLDRHLP_VALIDATE_FLAGS(*pfKind, KLDRSYMKIND_REQ_SEGMENTED);
262 return pMod->pOps->pfnQuerySymbol(pMod, pvBits, BaseAddress, iSymbol, pchSymbol, cchSymbol, pszVersion,
263 pfnGetForwarder, pvUser, puValue, pfKind);
264}
265
266
267/**
268 * Enumerate the symbols in the module.
269 *
270 * @returns 0 on success and non-zero a status code on failure.
271 * @param pMod The module which symbols should be enumerated.
272 * @param pvBits Optional pointer to bits returned by kLdrModGetBits() currently located at BaseAddress.
273 * This can be used by some module interpreters to reduce memory consumption.
274 * @param BaseAddress The module base address to use when calculating the symbol values.
275 * There are two special values that could be can:
276 * KLDRMOD_BASEADDRESS_LINK and KLDRMOD_BASEADDRESS_MAP.
277 * @param fFlags The enumeration flags. A combination of the KLDRMOD_ENUM_SYMS_FLAGS_* \#defines.
278 * @param pfnCallback The enumeration callback function.
279 * @param pvUser The user argument to the callback function.
280 */
281int kLdrModEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t fFlags,
282 PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
283{
284 KLDRMOD_VALIDATE(pMod);
285 KLDRHLP_VALIDATE_FLAGS(fFlags, KLDRMOD_ENUM_SYMS_FLAGS_ALL);
286 return pMod->pOps->pfnEnumSymbols(pMod, pvBits, BaseAddress, fFlags, pfnCallback, pvUser);
287}
288
289
290/**
291 * Get the name of an import module by ordinal number.
292 *
293 * @returns 0 and name in pszName on success.
294 * On buffer overruns KLDR_ERR_BUFFER_OVERFLOW will be returned.
295 * On other failures and appropriate error code is returned.
296 * @param pMod The module.
297 * @param pvBits Optional pointer to bits returned by kLdrModGetBits().
298 * This can be used by some module interpreters to reduce memory consumption.
299 * @param iImport The import module ordinal number.
300 * @param pszName Where to store the name.
301 * @param cchName The size of the name buffer.
302 */
303int kLdrModGetImport(PKLDRMOD pMod, const void *pvBits, uint32_t iImport, char *pszName, size_t cchName)
304{
305 KLDRMOD_VALIDATE(pMod);
306 return pMod->pOps->pfnGetImport(pMod, pvBits, iImport, pszName, cchName);
307}
308
309
310/**
311 * Get the number of import modules.
312 *
313 * @returns The number of import modules. -1 if something really bad happens.
314 * @param pMod The module.
315 * @param pvBits Optional pointer to bits returned by kLdrModGetBits().
316 * This can be used by some module interpreters to reduce memory consumption.
317 */
318int32_t kLdrModNumberOfImports(PKLDRMOD pMod, const void *pvBits)
319{
320 KLDRMOD_VALIDATE(pMod);
321 return pMod->pOps->pfnNumberOfImports(pMod, pvBits);
322}
323
324
325/**
326 * Checks if this module can be executed by the specified arch+cpu.
327 *
328 * @returns 0 if it can, KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE if it can't.
329 * Other failures may occur and cause other return values.
330 * @param pMod The module.
331 * @param pvBits Optional pointer to bits returned by kLdrModGetBits().
332 * This can be used by some module interpreters to reduce memory consumption.
333 */
334int kLdrModCanExecuteOn(PKLDRMOD pMod, const void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu)
335{
336 KLDRMOD_VALIDATE(pMod);
337 if (pMod->pOps->pfnCanExecuteOn)
338 return pMod->pOps->pfnCanExecuteOn(pMod, pvBits, enmArch, enmCpu);
339 return kLdrCompareCpus(pMod->enmArch, pMod->enmCpu, enmArch, enmCpu);
340}
341
342
343/**
344 * Gets the image stack info.
345 *
346 * @returns 0 on success, non-zero on failure.
347 * @param pMod
348 * @param pvBits Optional pointer to bits returned by kLdrModGetBits() currently located at BaseAddress.
349 * This can be used by some module interpreters to reduce memory consumption.
350 * @param BaseAddress The module base address to use when calculating the stack address.
351 * There are two special values that can be used:
352 * KLDRMOD_BASEADDRESS_LINK and KLDRMOD_BASEADDRESS_MAP.
353 * @param pStackInfo The stack information.
354 */
355int kLdrModGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
356{
357 KLDRMOD_VALIDATE(pMod);
358 return pMod->pOps->pfnGetStackInfo(pMod, pvBits, BaseAddress, pStackInfo);
359}
360
361
362/**
363 * Queries the main entrypoint of the module.
364 *
365 * Only executable are supposed to have an main entrypoint, though some object and DLL
366 * formats will also allow this.
367 *
368 * @returns 0 and *pMainEPAddress on success. Non-zero status code on failure.
369 * @param pMod The module.
370 * @param pvBits Optional pointer to bits returned by kLdrModGetBits() currently located at BaseAddress.
371 * This can be used by some module interpreters to reduce memory consumption.
372 * @param BaseAddress The module base address to use when calculating the entrypoint address.
373 * There are two special values that can be used:
374 * KLDRMOD_BASEADDRESS_LINK and KLDRMOD_BASEADDRESS_MAP.
375 * @param pMainEPAddress Where to store the entry point address.
376 */
377int kLdrModQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
378{
379 KLDRMOD_VALIDATE(pMod);
380 *pMainEPAddress = 0;
381 return pMod->pOps->pfnQueryMainEntrypoint(pMod, pvBits, BaseAddress, pMainEPAddress);
382}
383
384
385/**
386 * Queries info about a resource.
387 *
388 * If there are multiple resources matching the criteria, the best or
389 * first match will be return.
390 *
391 *
392 * @returns 0 on success.
393 * @returns Whatever non-zero status returned by pfnCallback (enumeration was stopped).
394 * @returns non-zero kLdr or native status code on failure.
395 *
396 * @param pMod The module.
397 * @param pvBits Optional pointer to bits returned by kLdrModGetBits() currently located at BaseAddress.
398 * This can be used by some module interpreters to reduce memory consumption.
399 * @param BaseAddress The module base address to use when calculating the resource addresses.
400 * There are two special values that can be used:
401 * KLDRMOD_BASEADDRESS_LINK and KLDRMOD_BASEADDRESS_MAP.
402 * @param idType The resource type id to match if not NIL_KLDRMOD_RSRC_TYPE_ID.
403 * @param pszType The resource type name to match if no NULL.
404 * @param idName The resource name id to match if not NIL_KLDRMOD_RSRC_NAME_ID.
405 * @param pszName The resource name to match if not NULL.
406 * @param idLang The language id to match.
407 * @param pfnCallback The callback function.
408 * @param pvUser The user argument for the callback.
409 */
410int kLdrModQueryResource(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t idType, const char *pszType,
411 uint32_t idName, const char *pszName, uint32_t idLang, PKLDRADDR pAddrRsrc, size_t *pcbRsrc)
412{
413 KLDRMOD_VALIDATE(pMod);
414 if (!pAddrRsrc && !pcbRsrc)
415 return KLDR_ERR_INVALID_PARAMETER;
416 if (pAddrRsrc)
417 *pAddrRsrc = NIL_KLDRADDR;
418 if (pcbRsrc)
419 *pcbRsrc = 0;
420 return pMod->pOps->pfnQueryResource(pMod, pvBits, BaseAddress, idType, pszType, idName, pszName, idLang, pAddrRsrc, pcbRsrc);
421}
422
423
424/**
425 * Enumerates the resources matching the specfied criteria.
426 *
427 *
428 * @returns 0 on success.
429 * @returns Whatever non-zero status returned by pfnCallback (enumeration was stopped).
430 * @returns non-zero kLdr or native status code on failure.
431 *
432 * @param pMod The module.
433 * @param pvBits Optional pointer to bits returned by kLdrModGetBits() currently located at BaseAddress.
434 * This can be used by some module interpreters to reduce memory consumption.
435 * @param BaseAddress The module base address to use when calculating the resource addresses.
436 * There are two special values that can be used:
437 * KLDRMOD_BASEADDRESS_LINK and KLDRMOD_BASEADDRESS_MAP.
438 * @param idType The resource type id to match if not NIL_KLDRMOD_RSRC_TYPE_ID.
439 * @param pszType The resource type name to match if no NULL.
440 * @param idName The resource name id to match if not NIL_KLDRMOD_RSRC_NAME_ID.
441 * @param pszName The resource name to match if not NULL.
442 * @param idLang The language id to match.
443 * @param pfnCallback The callback function.
444 * @param pvUser The user argument for the callback.
445 */
446int kLdrModEnumResources(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t idType, const char *pszType,
447 uint32_t idName, const char *pszName, uint32_t idLang, PFNKLDRENUMRSRC pfnCallback, void *pvUser)
448{
449 KLDRMOD_VALIDATE(pMod);
450 return pMod->pOps->pfnEnumResources(pMod, pvBits, BaseAddress, idType, pszType, idName, pszName, idLang, pfnCallback, pvUser);
451}
452
453
454/**
455 * Enumerate the debug info formats contained in the executable image.
456 *
457 * @returns 0 on success, non-zero OS or kLdr status code on failure, or non-zero callback status.
458 * @param pMod The module.
459 * @param pvBits Optional pointer to bits returned by kLdrModGetBits().
460 * This can be used by some module interpreters to reduce memory consumption.
461 * @param pfnCallback The callback function.
462 * @param pvUser The user argument.
463 * @see pg_kDbg for the debug info reader.
464 */
465int kLdrModEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser)
466{
467 KLDRMOD_VALIDATE(pMod);
468 return pMod->pOps->pfnEnumDbgInfo(pMod, pvBits, pfnCallback, pvUser);
469}
470
471
472/**
473 * Checks if the module has debug info embedded or otherwise associated with it.
474 *
475 * @returns 0 if it has debug info, KLDR_ERR_NO_DEBUG_INFO if no debug info,
476 * and non-zero OS or kLdr status code on failure.
477 * @param pMod The module.
478 * @param pvBits Optional pointer to bits returned by kLdrModGetBits().
479 * This can be used by some module interpreters to reduce memory consumption.
480 */
481int kLdrModHasDbgInfo(PKLDRMOD pMod, const void *pvBits)
482{
483 KLDRMOD_VALIDATE(pMod);
484 return pMod->pOps->pfnHasDbgInfo(pMod, pvBits);
485}
486
487
488/**
489 * Maps the module into the memory of the caller.
490 *
491 * On success the actual addresses for the segments can be found in MapAddress
492 * member of each segment in the segment array.
493 *
494 * @returns 0 on success, non-zero OS or kLdr status code on failure.
495 * @param pMod The module to be mapped.
496 * @remark kLdr only supports one mapping at a time of a module.
497 */
498int kLdrModMap(PKLDRMOD pMod)
499{
500 KLDRMOD_VALIDATE(pMod);
501 return pMod->pOps->pfnMap(pMod);
502}
503
504
505/**
506 * Unmaps a module previously mapped by kLdrModMap().
507 *
508 * @returns 0 on success, non-zero OS or kLdr status code on failure.
509 * @param pMod The module to unmap.
510 */
511int kLdrModUnmap(PKLDRMOD pMod)
512{
513 KLDRMOD_VALIDATE(pMod);
514 return pMod->pOps->pfnUnmap(pMod);
515}
516
517
518/**
519 * Allocates Thread Local Storage for module mapped by kLdrModMap().
520 *
521 * Calling kLdrModAllocTLS() more than once without calling kLdrModFreeTLS()
522 * between each invocation is not supported.
523 *
524 * @returns 0 on success, non-zero OS or kLdr status code on failure.
525 * @param pMod The module.
526 */
527int kLdrModAllocTLS(PKLDRMOD pMod)
528{
529 KLDRMOD_VALIDATE(pMod);
530 return pMod->pOps->pfnAllocTLS(pMod);
531}
532
533
534/**
535 * Frees Thread Local Storage previously allocated by kLdrModAllocTLS().
536 *
537 * The caller is responsible for only calling kLdrModFreeTLS() once
538 * after calling kLdrModAllocTLS().
539 *
540 * @returns 0 on success, non-zero OS or kLdr status code on failure.
541 * @param pMod The module.
542 */
543void kLdrModFreeTLS(PKLDRMOD pMod)
544{
545 KLDRMOD_VALIDATE_VOID(pMod);
546 pMod->pOps->pfnFreeTLS(pMod);
547}
548
549
550/**
551 * Reloads all dirty pages in a module previously mapped by kLdrModMap().
552 *
553 * The module interpreter may omit code pages if it can safely apply code
554 * fixups again in a subsequent kLdrModFixupMapping() call.
555 *
556 * The caller is responsible for freeing TLS before calling this function.
557 *
558 * @returns 0 on success, non-zero OS or kLdr status code on failure.
559 * @param pMod The module.
560 */
561int kLdrModReload(PKLDRMOD pMod)
562{
563 KLDRMOD_VALIDATE(pMod);
564 return pMod->pOps->pfnReload(pMod);
565}
566
567
568/**
569 * Fixup the mapping made by kLdrModMap().
570 *
571 * The caller is only responsible for not calling this function more than
572 * once without doing kLDrModReload() inbetween.
573 *
574 * @returns 0 on success, non-zero OS or kLdr status code on failure.
575 * @param pMod The module.
576 * @param pfnGetImport The callback for resolving external (imported) symbols.
577 * @param pvUser The callback user argument.
578 */
579int kLdrModFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
580{
581 KLDRMOD_VALIDATE(pMod);
582 return pMod->pOps->pfnFixupMapping(pMod, pfnGetImport, pvUser);
583}
584
585
586/**
587 * Call the module initializiation function of a mapped module (if any).
588 *
589 * @returns 0 on success or no init function, non-zero on init function failure or invalid pMod.
590 * @param pMod The module.
591 * @param uHandle The module handle to use if any of the init functions requires the module handle.
592 */
593int kLdrModCallInit(PKLDRMOD pMod, uintptr_t uHandle)
594{
595 KLDRMOD_VALIDATE(pMod);
596 return pMod->pOps->pfnCallInit(pMod, uHandle);
597}
598
599
600/**
601 * Call the module termination function of a mapped module (if any).
602 *
603 * @returns 0 on success or no term function, non-zero on invalid pMod.
604 * @param pMod The module.
605 * @param uHandle The module handle to use if any of the term functions requires the module handle.
606 *
607 * @remark Termination function failure will be ignored by the module interpreter.
608 */
609int kLdrModCallTerm(PKLDRMOD pMod, uintptr_t uHandle)
610{
611 KLDRMOD_VALIDATE(pMod);
612 return pMod->pOps->pfnCallTerm(pMod, uHandle);
613}
614
615
616/**
617 * Call the thread attach or detach function of a mapped module (if any).
618 *
619 * Any per-thread TLS initialization/termination will have to be done at this time too.
620 *
621 * @returns 0 on success or no attach/detach function, non-zero on attach failure or invalid pMod.
622 * @param pMod The module.
623 * @param uHandle The module handle to use if any of the thread attach/detach functions
624 * requires the module handle.
625 *
626 * @remark Detach function failure will be ignored by the module interpreter.
627 */
628int kLdrModCallThread(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching)
629{
630 KLDRMOD_VALIDATE(pMod);
631 KLDRHLP_VALIDATE_FLAGS(fAttachingOrDetaching, 1);
632 return pMod->pOps->pfnCallThread(pMod, uHandle, fAttachingOrDetaching);
633}
634
635
636/**
637 * Get the size of the mapped module.
638 *
639 * @returns The size of the mapped module (in bytes).
640 * @param pMod The module.
641 */
642KLDRADDR kLdrModSize(PKLDRMOD pMod)
643{
644 KLDRMOD_VALIDATE_EX(pMod, 0);
645 return pMod->pOps->pfnSize(pMod);
646}
647
648
649/**
650 * Gets the module bits.
651 *
652 * The module interpreter will fill a mapping allocated by the caller with the
653 * module bits reallocated to the specified address.
654 *
655 * @returns 0 on succes, non-zero OS or kLdr status code on failure.
656 * @param pMod The module.
657 * @param pvBits Where to put the bits.
658 * @param BaseAddress The base address that should correspond to the first byte in pvBits
659 * upon return.
660 * @param pfnGetImport The callback ufor resolving external (imported) symbols.
661 * @param pvUser The callback user argument.
662 */
663int kLdrModGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
664{
665 KLDRMOD_VALIDATE(pMod);
666 return pMod->pOps->pfnGetBits(pMod, pvBits, BaseAddress, pfnGetImport, pvUser);
667}
668
669
670/**
671 * Relocates the module bits previously obtained by kLdrModGetBits().
672 *
673 * @returns 0 on succes, non-zero OS or kLdr status code on failure.
674 * @param pMod The module.
675 * @param pvBits Where to put the bits.
676 * @param NewBaseAddress The new base address.
677 * @param OldBaseAddress The old base address (i.e. the one specified to kLdrModGetBits() or as
678 * NewBaseAddressto the previous kLdrModRelocateBits() call).
679 * @param pfnGetImport The callback ufor resolving external (imported) symbols.
680 * @param pvUser The callback user argument.
681 */
682int kLdrModRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
683 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
684{
685 KLDRMOD_VALIDATE(pMod);
686 return pMod->pOps->pfnRelocateBits(pMod, pvBits, NewBaseAddress, OldBaseAddress, pfnGetImport, pvUser);
687}
688
Note: See TracBrowser for help on using the repository browser.