VirtualBox

source: kStuff/trunk/kLdr/kLdrMod.c@ 24

Last change on this file since 24 was 2, checked in by bird, 17 years ago

Imported http://svn.netlabs.org/repos/libc/trunk/kStuff, revision 3612.

  • Property svn:keywords set to Id Revision
File size: 27.3 KB
Line 
1/* $Id: kLdrMod.c 2 2007-11-16 16:07:14Z bird $ */
2/** @file
3 * kLdr - The Module Interpreter.
4 */
5
6/*
7 * Copyright (c) 2006-2007 knut st. osmundsen <[email protected]>
8 *
9 * This file is part of kStuff.
10 *
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.
15 *
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.
21 *
22 * kStuff is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
26 *
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
31 */
32
33/*******************************************************************************
34* Header Files *
35*******************************************************************************/
36#include <k/kLdr.h>
37#include "kLdrInternal.h"
38#include <k/kCpu.h>
39#include <k/kLdrFmts/mz.h>
40#if 1 /* testing headers */
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>
46#endif
47
48
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
60# define KLDRMOD_ASSERT(expr) kHlpAssert(expr)
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) \
78 KLDRMOD_VALIDATE_EX(pMod, KERR_INVALID_PARAMETER)
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
106/**
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 */
119 PKRDR pRdr;
120 int rc = kRdrOpen(&pRdr, pszFilename);
121 if (!rc)
122 {
123 rc = kLdrModOpenFromRdr(pRdr, ppMod);
124 if (!rc)
125 return 0;
126 kRdrClose(pRdr);
127 }
128 return rc;
129}
130
131
132/**
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 */
143int kLdrModOpenFromRdr(PKRDR pRdr, PPKLDRMOD ppMod)
144{
145 union
146 {
147 KU32 u32;
148 KU16 u16;
149 KU16 au16[2];
150 KU8 au8[4];
151 } u;
152 KLDRFOFF offHdr = 0;
153 int rc;
154
155 /*
156 * Try figure out what kind of image this is.
157 * Always read the 'new header' if we encounter MZ.
158 */
159 rc = kRdrRead(pRdr, &u, sizeof(u), 0);
160 if (rc)
161 return rc;
162 if ( u.u16 == IMAGE_DOS_SIGNATURE
163 && kRdrSize(pRdr) > sizeof(IMAGE_DOS_HEADER))
164 {
165 rc = kRdrRead(pRdr, &u, sizeof(u.u32), K_OFFSETOF(IMAGE_DOS_HEADER, e_lfanew));
166 if (rc)
167 return rc;
168 if ((KLDRFOFF)u.u32 < kRdrSize(pRdr))
169 {
170 offHdr = u.u32;
171 rc = kRdrRead(pRdr, &u, sizeof(u.u32), offHdr);
172 if (rc)
173 return rc;
174 }
175 else
176 u.u16 = IMAGE_DOS_SIGNATURE;
177 }
178
179 /*
180 * Use the magic to select the appropriate image interpreter head on.
181 */
182 if (u.u16 == IMAGE_DOS_SIGNATURE)
183 rc = KLDR_ERR_MZ_NOT_SUPPORTED;
184 else if (u.u16 == IMAGE_NE_SIGNATURE)
185 rc = KLDR_ERR_NE_NOT_SUPPORTED;
186 else if (u.u16 == IMAGE_LX_SIGNATURE)
187 rc = g_kLdrModLXOps.pfnCreate(&g_kLdrModLXOps, pRdr, offHdr, ppMod);
188 else if (u.u16 == IMAGE_LE_SIGNATURE)
189 rc = KLDR_ERR_LE_NOT_SUPPORTED;
190 else if (u.u32 == IMAGE_NT_SIGNATURE)
191 rc = g_kLdrModPEOps.pfnCreate(&g_kLdrModPEOps, pRdr, offHdr, ppMod);
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);
197 else if (u.u32 == IMAGE_ELF_SIGNATURE)
198 rc = KLDR_ERR_ELF_NOT_SUPPORTED;
199 else if ( u.u32 == IMAGE_FAT_SIGNATURE
200 || u.u32 == IMAGE_FAT_SIGNATURE_OE)
201 rc = KLDR_ERR_FAT_NOT_SUPPORTED;
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;
220}
221
222
223/**
224 * Closes an open module.
225 *
226 * The caller is responsible for calling kLdrModUnmap() and kLdrFreeTLS()
227 * before closing the module.
228 *
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.
231 * @param pMod The module.
232 */
233int kLdrModClose(PKLDRMOD pMod)
234{
235 KLDRMOD_VALIDATE(pMod);
236 return pMod->pOps->pfnDestroy(pMod);
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.
253 * @param iSymbol The symbol ordinal. (optional)
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.
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.
261 * @param puValue Where to store the symbol value. (optional)
262 * @param pfKind On input one of the KLDRSYMKIND_REQ_* #defines.
263 * On output the symbol kind. (optional)
264 */
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)
268{
269 KLDRMOD_VALIDATE(pMod);
270 if (!puValue && !pfKind)
271 return KERR_INVALID_PARAMETER;
272 if (puValue)
273 *puValue = 0;
274 if (pfKind)
275 K_VALIDATE_FLAGS(*pfKind, KLDRSYMKIND_REQ_SEGMENTED);
276 return pMod->pOps->pfnQuerySymbol(pMod, pvBits, BaseAddress, iSymbol, pchSymbol, cchSymbol, pszVersion,
277 pfnGetForwarder, pvUser, puValue, pfKind);
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.
291 * @param fFlags The enumeration flags. A combination of the KLDRMOD_ENUM_SYMS_FLAGS_* \#defines.
292 * @param pfnCallback The enumeration callback function.
293 * @param pvUser The user argument to the callback function.
294 */
295int kLdrModEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 fFlags,
296 PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
297{
298 KLDRMOD_VALIDATE(pMod);
299 K_VALIDATE_FLAGS(fFlags, KLDRMOD_ENUM_SYMS_FLAGS_ALL);
300 return pMod->pOps->pfnEnumSymbols(pMod, pvBits, BaseAddress, fFlags, pfnCallback, pvUser);
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.
308 * On buffer overruns KERR_BUFFER_OVERFLOW will be returned.
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 */
317int kLdrModGetImport(PKLDRMOD pMod, const void *pvBits, KU32 iImport, char *pszName, KSIZE cchName)
318{
319 KLDRMOD_VALIDATE(pMod);
320 return pMod->pOps->pfnGetImport(pMod, pvBits, iImport, pszName, cchName);
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 */
332KI32 kLdrModNumberOfImports(PKLDRMOD pMod, const void *pvBits)
333{
334 KLDRMOD_VALIDATE(pMod);
335 return pMod->pOps->pfnNumberOfImports(pMod, pvBits);
336}
337
338
339/**
340 * Checks if this module can be executed by the specified arch+cpu.
341 *
342 * @returns 0 if it can, KCPU_ERR_ARCH_CPU_NOT_COMPATIBLE if it can't.
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 */
348int kLdrModCanExecuteOn(PKLDRMOD pMod, const void *pvBits, KCPUARCH enmArch, KCPU enmCpu)
349{
350 KLDRMOD_VALIDATE(pMod);
351 if (pMod->pOps->pfnCanExecuteOn)
352 return pMod->pOps->pfnCanExecuteOn(pMod, pvBits, enmArch, enmCpu);
353 return kCpuCompare(pMod->enmArch, pMod->enmCpu, enmArch, enmCpu);
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 */
369int kLdrModGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
370{
371 KLDRMOD_VALIDATE(pMod);
372 return pMod->pOps->pfnGetStackInfo(pMod, pvBits, BaseAddress, pStackInfo);
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 */
391int kLdrModQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
392{
393 KLDRMOD_VALIDATE(pMod);
394 *pMainEPAddress = 0;
395 return pMod->pOps->pfnQueryMainEntrypoint(pMod, pvBits, BaseAddress, pMainEPAddress);
396}
397
398
399/**
400 * Queries info about a resource.
401 *
402 * If there are multiple resources matching the criteria, the best or
403 * first match will be return.
404 *
405 *
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.
409 *
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 */
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)
426{
427 KLDRMOD_VALIDATE(pMod);
428 if (!pAddrRsrc && !pcbRsrc)
429 return KERR_INVALID_PARAMETER;
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.
440 *
441 *
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.
445 *
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 */
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)
462{
463 KLDRMOD_VALIDATE(pMod);
464 return pMod->pOps->pfnEnumResources(pMod, pvBits, BaseAddress, idType, pszType, idName, pszName, idLang, pfnCallback, pvUser);
465}
466
467
468/**
469 * Enumerate the debug info formats contained in the executable image.
470 *
471 * @returns 0 on success, non-zero OS or kLdr status code on failure, or non-zero callback status.
472 * @param pMod The module.
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.
478 */
479int kLdrModEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser)
480{
481 KLDRMOD_VALIDATE(pMod);
482 return pMod->pOps->pfnEnumDbgInfo(pMod, pvBits, pfnCallback, pvUser);
483}
484
485
486/**
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 */
495int kLdrModHasDbgInfo(PKLDRMOD pMod, const void *pvBits)
496{
497 KLDRMOD_VALIDATE(pMod);
498 return pMod->pOps->pfnHasDbgInfo(pMod, pvBits);
499}
500
501
502/**
503 * May free up some resources held by the module.
504 *
505 * @todo define exactly what it possible to do after this call.
506 *
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/**
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{
529 KLDRMOD_VALIDATE(pMod);
530 return pMod->pOps->pfnMap(pMod);
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{
542 KLDRMOD_VALIDATE(pMod);
543 return pMod->pOps->pfnUnmap(pMod);
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{
558 KLDRMOD_VALIDATE(pMod);
559 return pMod->pOps->pfnAllocTLS(pMod);
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{
574 KLDRMOD_VALIDATE_VOID(pMod);
575 pMod->pOps->pfnFreeTLS(pMod);
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{
592 KLDRMOD_VALIDATE(pMod);
593 return pMod->pOps->pfnReload(pMod);
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{
610 KLDRMOD_VALIDATE(pMod);
611 return pMod->pOps->pfnFixupMapping(pMod, pfnGetImport, pvUser);
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.
620 * @param uHandle The module handle to use if any of the init functions requires the module handle.
621 */
622int kLdrModCallInit(PKLDRMOD pMod, KUPTR uHandle)
623{
624 KLDRMOD_VALIDATE(pMod);
625 return pMod->pOps->pfnCallInit(pMod, uHandle);
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.
634 * @param uHandle The module handle to use if any of the term functions requires the module handle.
635 *
636 * @remark Termination function failure will be ignored by the module interpreter.
637 */
638int kLdrModCallTerm(PKLDRMOD pMod, KUPTR uHandle)
639{
640 KLDRMOD_VALIDATE(pMod);
641 return pMod->pOps->pfnCallTerm(pMod, uHandle);
642}
643
644
645/**
646 * Call the thread attach or detach function of a mapped module (if any).
647 *
648 * Any per-thread TLS initialization/termination will have to be done at this time too.
649 *
650 * @returns 0 on success or no attach/detach function, non-zero on attach failure or invalid pMod.
651 * @param pMod The module.
652 * @param uHandle The module handle to use if any of the thread attach/detach functions
653 * requires the module handle.
654 *
655 * @remark Detach function failure will be ignored by the module interpreter.
656 */
657int kLdrModCallThread(PKLDRMOD pMod, KUPTR uHandle, unsigned fAttachingOrDetaching)
658{
659 KLDRMOD_VALIDATE(pMod);
660 K_VALIDATE_FLAGS(fAttachingOrDetaching, 1);
661 return pMod->pOps->pfnCallThread(pMod, uHandle, fAttachingOrDetaching);
662}
663
664
665/**
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 */
671KLDRADDR kLdrModSize(PKLDRMOD pMod)
672{
673 KLDRMOD_VALIDATE_EX(pMod, 0);
674 return pMod->pOps->pfnSize(pMod);
675}
676
677
678/**
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{
694 KLDRMOD_VALIDATE(pMod);
695 return pMod->pOps->pfnGetBits(pMod, pvBits, BaseAddress, pfnGetImport, pvUser);
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{
714 KLDRMOD_VALIDATE(pMod);
715 return pMod->pOps->pfnRelocateBits(pMod, pvBits, NewBaseAddress, OldBaseAddress, pfnGetImport, pvUser);
716}
717
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette