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