source: trunk/kStuff/kLdr/kLdrMod.c

Last change on this file was 3601, checked in by bird, 18 years ago

license update.

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