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
RevLine 
[2826]1/* $Id: kLdrMod.c 2891 2006-11-21 21:40:45Z 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/**
[2848]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{
[2851]500 KLDRMOD_VALIDATE(pMod);
501 return pMod->pOps->pfnMap(pMod);
[2848]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{
[2851]513 KLDRMOD_VALIDATE(pMod);
514 return pMod->pOps->pfnUnmap(pMod);
[2848]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{
[2851]529 KLDRMOD_VALIDATE(pMod);
530 return pMod->pOps->pfnAllocTLS(pMod);
[2848]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{
[2851]545 KLDRMOD_VALIDATE_VOID(pMod);
546 pMod->pOps->pfnFreeTLS(pMod);
[2848]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{
[2851]563 KLDRMOD_VALIDATE(pMod);
564 return pMod->pOps->pfnReload(pMod);
[2848]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{
[2851]581 KLDRMOD_VALIDATE(pMod);
582 return pMod->pOps->pfnFixupMapping(pMod, pfnGetImport, pvUser);
[2848]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.
[2856]591 * @param uHandle The module handle to use if any of the init functions requires the module handle.
[2848]592 */
[2856]593int kLdrModCallInit(PKLDRMOD pMod, uintptr_t uHandle)
[2848]594{
[2851]595 KLDRMOD_VALIDATE(pMod);
[2856]596 return pMod->pOps->pfnCallInit(pMod, uHandle);
[2848]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.
[2856]605 * @param uHandle The module handle to use if any of the term functions requires the module handle.
[2848]606 *
607 * @remark Termination function failure will be ignored by the module interpreter.
608 */
[2856]609int kLdrModCallTerm(PKLDRMOD pMod, uintptr_t uHandle)
[2848]610{
[2851]611 KLDRMOD_VALIDATE(pMod);
[2856]612 return pMod->pOps->pfnCallTerm(pMod, uHandle);
[2848]613}
614
615
616/**
617 * Call the thread attach or detach function of a mapped module (if any).
618 *
[2856]619 * Any per-thread TLS initialization/termination will have to be done at this time too.
620 *
[2848]621 * @returns 0 on success or no attach/detach function, non-zero on attach failure or invalid pMod.
622 * @param pMod The module.
[2856]623 * @param uHandle The module handle to use if any of the thread attach/detach functions
624 * requires the module handle.
[2848]625 *
626 * @remark Detach function failure will be ignored by the module interpreter.
627 */
[2856]628int kLdrModCallThread(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching)
[2848]629{
[2851]630 KLDRMOD_VALIDATE(pMod);
631 KLDRHLP_VALIDATE_FLAGS(fAttachingOrDetaching, 1);
[2856]632 return pMod->pOps->pfnCallThread(pMod, uHandle, fAttachingOrDetaching);
[2848]633}
634
635
636/**
[2849]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 */
[2856]642KLDRADDR kLdrModSize(PKLDRMOD pMod)
[2849]643{
[2851]644 KLDRMOD_VALIDATE_EX(pMod, 0);
645 return pMod->pOps->pfnSize(pMod);
[2849]646}
647
648
649/**
[2848]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{
[2851]665 KLDRMOD_VALIDATE(pMod);
666 return pMod->pOps->pfnGetBits(pMod, pvBits, BaseAddress, pfnGetImport, pvUser);
[2848]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{
[2851]685 KLDRMOD_VALIDATE(pMod);
686 return pMod->pOps->pfnRelocateBits(pMod, pvBits, NewBaseAddress, OldBaseAddress, pfnGetImport, pvUser);
[2848]687}
688
Note: See TracBrowser for help on using the repository browser.