source: trunk/kLdr/kLdrMod.c@ 2946

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

Added missing kLdrModMostlyDone().

  • Property svn:keywords set to Id
File size: 26.7 KB
RevLine 
[2826]1/* $Id: kLdrMod.c 2946 2007-01-14 08:42:21Z bird $ */
[2825]2/** @file
3 *
[2854]4 * kLdr - The Module Interpreter.
[2825]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"
[2827]34#include "kLdrModMZ.h"
35#if 1 /* testing headers */
36# include "kLdrModPE.h"
[2828]37# include "kLdrModLX.h"
[2827]38# include "kLdrModELF32.h"
39# include "kLdrModELF64.h"
40#endif
[2825]41
42
[2851]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
[2827]100/**
[2848]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/**
[2827]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 /*
[2851]174 * Use the magic to select the appropriate image interpreter head on.
[2827]175 */
176 if (u.u16 == IMAGE_DOS_SIGNATURE)
[2851]177 rc = KLDR_ERR_MZ_NOT_SUPPORTED;
[2827]178 else if (u.u16 == IMAGE_NE_SIGNATURE)
[2851]179 rc = KLDR_ERR_NE_NOT_SUPPORTED;
[2827]180 else if (u.u16 == IMAGE_LX_SIGNATURE)
[2879]181 rc = g_kLdrModLXOps.pfnCreate(&g_kLdrModLXOps, pRdr, offHdr, ppMod);
[2827]182 else if (u.u16 == IMAGE_LE_SIGNATURE)
[2851]183 rc = KLDR_ERR_LE_NOT_SUPPORTED;
[2827]184 else if (u.u32 == IMAGE_NT_SIGNATURE)
[2858]185 rc = g_kLdrModPEOps.pfnCreate(&g_kLdrModPEOps, pRdr, offHdr, ppMod);
[2827]186 else if (u.u32 == IMAGE_ELF_SIGNATURE)
[2851]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;
[2827]206}
207
208
209/**
[2848]210 * Closes an open module.
211 *
212 * The caller is responsible for calling kLdrModUnmap() and kLdrFreeTLS()
213 * before closing the module.
214 *
[2851]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.
[2848]217 * @param pMod The module.
218 */
219int kLdrModClose(PKLDRMOD pMod)
220{
[2851]221 KLDRMOD_VALIDATE(pMod);
222 return pMod->pOps->pfnDestroy(pMod);
[2848]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.
[2859]239 * @param iSymbol The symbol ordinal. (optional)
[2891]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.
[2854]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.
[2848]247 * @param puValue Where to store the symbol value. (optional)
[2891]248 * @param pfKind On input one of the KLDRSYMKIND_REQ_* #defines.
249 * On output the symbol kind. (optional)
[2848]250 */
[2859]251int kLdrModQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t iSymbol,
[2891]252 const char *pchSymbol, size_t cchSymbol, const char *pszVersion,
253 PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind)
[2848]254{
[2851]255 KLDRMOD_VALIDATE(pMod);
256 if (!puValue && !pfKind)
257 return KLDR_ERR_INVALID_PARAMETER;
258 if (puValue)
259 *puValue = 0;
260 if (pfKind)
[2891]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);
[2848]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.
[2854]277 * @param fFlags The enumeration flags. A combination of the KLDRMOD_ENUM_SYMS_FLAGS_* \#defines.
[2848]278 * @param pfnCallback The enumeration callback function.
279 * @param pvUser The user argument to the callback function.
280 */
[2854]281int kLdrModEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t fFlags,
[2848]282 PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
283{
[2851]284 KLDRMOD_VALIDATE(pMod);
285 KLDRHLP_VALIDATE_FLAGS(fFlags, KLDRMOD_ENUM_SYMS_FLAGS_ALL);
[2854]286 return pMod->pOps->pfnEnumSymbols(pMod, pvBits, BaseAddress, fFlags, pfnCallback, pvUser);
[2848]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 */
[2855]303int kLdrModGetImport(PKLDRMOD pMod, const void *pvBits, uint32_t iImport, char *pszName, size_t cchName)
[2848]304{
[2851]305 KLDRMOD_VALIDATE(pMod);
306 return pMod->pOps->pfnGetImport(pMod, pvBits, iImport, pszName, cchName);
[2848]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 */
[2855]318int32_t kLdrModNumberOfImports(PKLDRMOD pMod, const void *pvBits)
[2848]319{
[2851]320 KLDRMOD_VALIDATE(pMod);
321 return pMod->pOps->pfnNumberOfImports(pMod, pvBits);
[2848]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 */
[2855]334int kLdrModCanExecuteOn(PKLDRMOD pMod, const void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu)
[2848]335{
[2851]336 KLDRMOD_VALIDATE(pMod);
[2855]337 if (pMod->pOps->pfnCanExecuteOn)
338 return pMod->pOps->pfnCanExecuteOn(pMod, pvBits, enmArch, enmCpu);
339 return kLdrCompareCpus(pMod->enmArch, pMod->enmCpu, enmArch, enmCpu);
[2848]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 */
[2855]355int kLdrModGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
[2848]356{
[2851]357 KLDRMOD_VALIDATE(pMod);
358 return pMod->pOps->pfnGetStackInfo(pMod, pvBits, BaseAddress, pStackInfo);
[2848]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 */
[2855]377int kLdrModQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
[2848]378{
[2851]379 KLDRMOD_VALIDATE(pMod);
380 *pMainEPAddress = 0;
381 return pMod->pOps->pfnQueryMainEntrypoint(pMod, pvBits, BaseAddress, pMainEPAddress);
[2848]382}
383
384
385/**
[2891]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/**
[2849]455 * Enumerate the debug info formats contained in the executable image.
[2848]456 *
[2849]457 * @returns 0 on success, non-zero OS or kLdr status code on failure, or non-zero callback status.
[2848]458 * @param pMod The module.
[2849]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.
[2848]464 */
[2855]465int kLdrModEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser)
[2848]466{
[2851]467 KLDRMOD_VALIDATE(pMod);
468 return pMod->pOps->pfnEnumDbgInfo(pMod, pvBits, pfnCallback, pvUser);
[2848]469}
470
471
472/**
[2849]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 */
[2855]481int kLdrModHasDbgInfo(PKLDRMOD pMod, const void *pvBits)
[2849]482{
[2851]483 KLDRMOD_VALIDATE(pMod);
484 return pMod->pOps->pfnHasDbgInfo(pMod, pvBits);
[2849]485}
486
487
488/**
[2946]489 * May free up some resources held by the module.
490 *
491 * @todo define exactly what it possible to do after this call.
492 *
493 * @returns 0 on success, KLDR_ERR_* on failure.
494 * @param pMod The module.
495 */
496int kLdrModMostlyDone(PKLDRMOD pMod)
497{
498 KLDRMOD_VALIDATE(pMod);
499 return pMod->pOps->pfnMostlyDone(pMod);
500}
501
502
503/**
[2848]504 * Maps the module into the memory of the caller.
505 *
506 * On success the actual addresses for the segments can be found in MapAddress
507 * member of each segment in the segment array.
508 *
509 * @returns 0 on success, non-zero OS or kLdr status code on failure.
510 * @param pMod The module to be mapped.
511 * @remark kLdr only supports one mapping at a time of a module.
512 */
513int kLdrModMap(PKLDRMOD pMod)
514{
[2851]515 KLDRMOD_VALIDATE(pMod);
516 return pMod->pOps->pfnMap(pMod);
[2848]517}
518
519
520/**
521 * Unmaps a module previously mapped by kLdrModMap().
522 *
523 * @returns 0 on success, non-zero OS or kLdr status code on failure.
524 * @param pMod The module to unmap.
525 */
526int kLdrModUnmap(PKLDRMOD pMod)
527{
[2851]528 KLDRMOD_VALIDATE(pMod);
529 return pMod->pOps->pfnUnmap(pMod);
[2848]530}
531
532
533/**
534 * Allocates Thread Local Storage for module mapped by kLdrModMap().
535 *
536 * Calling kLdrModAllocTLS() more than once without calling kLdrModFreeTLS()
537 * between each invocation is not supported.
538 *
539 * @returns 0 on success, non-zero OS or kLdr status code on failure.
540 * @param pMod The module.
541 */
542int kLdrModAllocTLS(PKLDRMOD pMod)
543{
[2851]544 KLDRMOD_VALIDATE(pMod);
545 return pMod->pOps->pfnAllocTLS(pMod);
[2848]546}
547
548
549/**
550 * Frees Thread Local Storage previously allocated by kLdrModAllocTLS().
551 *
552 * The caller is responsible for only calling kLdrModFreeTLS() once
553 * after calling kLdrModAllocTLS().
554 *
555 * @returns 0 on success, non-zero OS or kLdr status code on failure.
556 * @param pMod The module.
557 */
558void kLdrModFreeTLS(PKLDRMOD pMod)
559{
[2851]560 KLDRMOD_VALIDATE_VOID(pMod);
561 pMod->pOps->pfnFreeTLS(pMod);
[2848]562}
563
564
565/**
566 * Reloads all dirty pages in a module previously mapped by kLdrModMap().
567 *
568 * The module interpreter may omit code pages if it can safely apply code
569 * fixups again in a subsequent kLdrModFixupMapping() call.
570 *
571 * The caller is responsible for freeing TLS before calling this function.
572 *
573 * @returns 0 on success, non-zero OS or kLdr status code on failure.
574 * @param pMod The module.
575 */
576int kLdrModReload(PKLDRMOD pMod)
577{
[2851]578 KLDRMOD_VALIDATE(pMod);
579 return pMod->pOps->pfnReload(pMod);
[2848]580}
581
582
583/**
584 * Fixup the mapping made by kLdrModMap().
585 *
586 * The caller is only responsible for not calling this function more than
587 * once without doing kLDrModReload() inbetween.
588 *
589 * @returns 0 on success, non-zero OS or kLdr status code on failure.
590 * @param pMod The module.
591 * @param pfnGetImport The callback for resolving external (imported) symbols.
592 * @param pvUser The callback user argument.
593 */
594int kLdrModFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
595{
[2851]596 KLDRMOD_VALIDATE(pMod);
597 return pMod->pOps->pfnFixupMapping(pMod, pfnGetImport, pvUser);
[2848]598}
599
600
601/**
602 * Call the module initializiation function of a mapped module (if any).
603 *
604 * @returns 0 on success or no init function, non-zero on init function failure or invalid pMod.
605 * @param pMod The module.
[2856]606 * @param uHandle The module handle to use if any of the init functions requires the module handle.
[2848]607 */
[2856]608int kLdrModCallInit(PKLDRMOD pMod, uintptr_t uHandle)
[2848]609{
[2851]610 KLDRMOD_VALIDATE(pMod);
[2856]611 return pMod->pOps->pfnCallInit(pMod, uHandle);
[2848]612}
613
614
615/**
616 * Call the module termination function of a mapped module (if any).
617 *
618 * @returns 0 on success or no term function, non-zero on invalid pMod.
619 * @param pMod The module.
[2856]620 * @param uHandle The module handle to use if any of the term functions requires the module handle.
[2848]621 *
622 * @remark Termination function failure will be ignored by the module interpreter.
623 */
[2856]624int kLdrModCallTerm(PKLDRMOD pMod, uintptr_t uHandle)
[2848]625{
[2851]626 KLDRMOD_VALIDATE(pMod);
[2856]627 return pMod->pOps->pfnCallTerm(pMod, uHandle);
[2848]628}
629
630
631/**
632 * Call the thread attach or detach function of a mapped module (if any).
633 *
[2856]634 * Any per-thread TLS initialization/termination will have to be done at this time too.
635 *
[2848]636 * @returns 0 on success or no attach/detach function, non-zero on attach failure or invalid pMod.
637 * @param pMod The module.
[2856]638 * @param uHandle The module handle to use if any of the thread attach/detach functions
639 * requires the module handle.
[2848]640 *
641 * @remark Detach function failure will be ignored by the module interpreter.
642 */
[2856]643int kLdrModCallThread(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching)
[2848]644{
[2851]645 KLDRMOD_VALIDATE(pMod);
646 KLDRHLP_VALIDATE_FLAGS(fAttachingOrDetaching, 1);
[2856]647 return pMod->pOps->pfnCallThread(pMod, uHandle, fAttachingOrDetaching);
[2848]648}
649
650
651/**
[2849]652 * Get the size of the mapped module.
653 *
654 * @returns The size of the mapped module (in bytes).
655 * @param pMod The module.
656 */
[2856]657KLDRADDR kLdrModSize(PKLDRMOD pMod)
[2849]658{
[2851]659 KLDRMOD_VALIDATE_EX(pMod, 0);
660 return pMod->pOps->pfnSize(pMod);
[2849]661}
662
663
664/**
[2848]665 * Gets the module bits.
666 *
667 * The module interpreter will fill a mapping allocated by the caller with the
668 * module bits reallocated to the specified address.
669 *
670 * @returns 0 on succes, non-zero OS or kLdr status code on failure.
671 * @param pMod The module.
672 * @param pvBits Where to put the bits.
673 * @param BaseAddress The base address that should correspond to the first byte in pvBits
674 * upon return.
675 * @param pfnGetImport The callback ufor resolving external (imported) symbols.
676 * @param pvUser The callback user argument.
677 */
678int kLdrModGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
679{
[2851]680 KLDRMOD_VALIDATE(pMod);
681 return pMod->pOps->pfnGetBits(pMod, pvBits, BaseAddress, pfnGetImport, pvUser);
[2848]682}
683
684
685/**
686 * Relocates the module bits previously obtained by kLdrModGetBits().
687 *
688 * @returns 0 on succes, non-zero OS or kLdr status code on failure.
689 * @param pMod The module.
690 * @param pvBits Where to put the bits.
691 * @param NewBaseAddress The new base address.
692 * @param OldBaseAddress The old base address (i.e. the one specified to kLdrModGetBits() or as
693 * NewBaseAddressto the previous kLdrModRelocateBits() call).
694 * @param pfnGetImport The callback ufor resolving external (imported) symbols.
695 * @param pvUser The callback user argument.
696 */
697int kLdrModRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
698 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
699{
[2851]700 KLDRMOD_VALIDATE(pMod);
701 return pMod->pOps->pfnRelocateBits(pMod, pvBits, NewBaseAddress, OldBaseAddress, pfnGetImport, pvUser);
[2848]702}
703
Note: See TracBrowser for help on using the repository browser.