| 1 | /* $Id: kLdrModNative.c 2974 2007-02-14 10:12:44Z bird $ */
 | 
|---|
| 2 | /** @file
 | 
|---|
| 3 |  *
 | 
|---|
| 4 |  * kLdr - The Module Interpreter for the Native Loaders.
 | 
|---|
| 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 | #ifdef __OS2__
 | 
|---|
| 35 | # define INCL_BASE
 | 
|---|
| 36 | # include <os2.h>
 | 
|---|
| 37 | 
 | 
|---|
| 38 | # ifndef LIBPATHSTRICT
 | 
|---|
| 39 | #  define LIBPATHSTRICT 3
 | 
|---|
| 40 | # endif
 | 
|---|
| 41 |   extern APIRET DosQueryHeaderInfo(HMODULE hmod, ULONG ulIndex, PVOID pvBuffer, ULONG cbBuffer, ULONG ulSubFunction);
 | 
|---|
| 42 | # define QHINF_EXEINFO       1 /* NE exeinfo. */
 | 
|---|
| 43 | # define QHINF_READRSRCTBL   2 /* Reads from the resource table. */
 | 
|---|
| 44 | # define QHINF_READFILE      3 /* Reads from the executable file. */
 | 
|---|
| 45 | # define QHINF_LIBPATHLENGTH 4 /* Gets the libpath length. */
 | 
|---|
| 46 | # define QHINF_LIBPATH       5 /* Gets the entire libpath. */
 | 
|---|
| 47 | # define QHINF_FIXENTRY      6 /* NE only */
 | 
|---|
| 48 | # define QHINF_STE           7 /* NE only */
 | 
|---|
| 49 | # define QHINF_MAPSEL        8 /* NE only */
 | 
|---|
| 50 | 
 | 
|---|
| 51 | #elif defined(__WIN__)
 | 
|---|
| 52 | # undef IMAGE_NT_SIGNATURE
 | 
|---|
| 53 | # undef IMAGE_DOS_SIGNATURE
 | 
|---|
| 54 | # include <windows.h>
 | 
|---|
| 55 | # ifndef IMAGE_SCN_TYPE_NOLOAD
 | 
|---|
| 56 | #  define IMAGE_SCN_TYPE_NOLOAD 0x00000002
 | 
|---|
| 57 | # endif
 | 
|---|
| 58 | 
 | 
|---|
| 59 | /*#elif defined(__NT__)
 | 
|---|
| 60 | #include <winnt.h> */
 | 
|---|
| 61 | 
 | 
|---|
| 62 | #elif defined(__DARWIN__)
 | 
|---|
| 63 | # include <dlfcn.h>
 | 
|---|
| 64 | # include <errno.h>
 | 
|---|
| 65 | 
 | 
|---|
| 66 | #else
 | 
|---|
| 67 | # error "port me"
 | 
|---|
| 68 | #endif
 | 
|---|
| 69 | 
 | 
|---|
| 70 | 
 | 
|---|
| 71 | 
 | 
|---|
| 72 | /*******************************************************************************
 | 
|---|
| 73 | *   Defined Constants And Macros                                               *
 | 
|---|
| 74 | *******************************************************************************/
 | 
|---|
| 75 | /** @def KLDRMODNATIVE_STRICT
 | 
|---|
| 76 |  * Define KLDRMODNATIVE_STRICT to enabled strict checks in KLDRMODNATIVE. */
 | 
|---|
| 77 | #define KLDRMODNATIVE_STRICT 1
 | 
|---|
| 78 | 
 | 
|---|
| 79 | /** @def KLDRMODNATIVE_ASSERT
 | 
|---|
| 80 |  * Assert that an expression is true when KLDR_STRICT is defined.
 | 
|---|
| 81 |  */
 | 
|---|
| 82 | #ifdef KLDRMODNATIVE_STRICT
 | 
|---|
| 83 | # define KLDRMODNATIVE_ASSERT(expr)  kldrHlpAssert(expr)
 | 
|---|
| 84 | #else
 | 
|---|
| 85 | # define KLDRMODNATIVE_ASSERT(expr)  do {} while (0)
 | 
|---|
| 86 | #endif
 | 
|---|
| 87 | 
 | 
|---|
| 88 | #if defined(__WIN__) || defined(__NT__)
 | 
|---|
| 89 | /** @def KLDRMODNATIVE_RVA2TYPE
 | 
|---|
| 90 |  * Converts a RVA to a pointer of the specified type.
 | 
|---|
| 91 |  * @param   pvBits      The bits (image base).
 | 
|---|
| 92 |  * @param   uRVA        The image relative virtual address.
 | 
|---|
| 93 |  * @param   type        The type to cast to.
 | 
|---|
| 94 |  */
 | 
|---|
| 95 | # define KLDRMODNATIVE_RVA2TYPE(pvBits, uRVA, type) \
 | 
|---|
| 96 |         ( (type) ((uintptr_t)(pvBits) + (uRVA)) )
 | 
|---|
| 97 | 
 | 
|---|
| 98 | #endif /* PE OSes */
 | 
|---|
| 99 | 
 | 
|---|
| 100 | 
 | 
|---|
| 101 | 
 | 
|---|
| 102 | /*******************************************************************************
 | 
|---|
| 103 | *   Structures and Typedefs                                                    *
 | 
|---|
| 104 | *******************************************************************************/
 | 
|---|
| 105 | /**
 | 
|---|
| 106 |  * Instance data for the module interpreter for the Native Loaders.
 | 
|---|
| 107 |  */
 | 
|---|
| 108 | typedef struct KLDRMODNATIVE
 | 
|---|
| 109 | {
 | 
|---|
| 110 |     /** Pointer to the module. (Follows the section table.) */
 | 
|---|
| 111 |     PKLDRMOD                    pMod;
 | 
|---|
| 112 |     /** Reserved flags. */
 | 
|---|
| 113 |     uint32_t                    f32Reserved;
 | 
|---|
| 114 |     /** The number of imported modules.
 | 
|---|
| 115 |      * If ~(uint32_t)0 this hasn't been determined yet. */
 | 
|---|
| 116 |     uint32_t                    cImportModules;
 | 
|---|
| 117 | #ifdef __OS2__
 | 
|---|
| 118 |     /** The module handle. */
 | 
|---|
| 119 |     HMODULE                     hmod;
 | 
|---|
| 120 | 
 | 
|---|
| 121 | #elif defined(__WIN__)
 | 
|---|
| 122 |     /** The module handle. */
 | 
|---|
| 123 |     HANDLE                      hmod;
 | 
|---|
| 124 |     /** Pointer to the NT headers. */
 | 
|---|
| 125 |     const IMAGE_NT_HEADERS     *pNtHdrs;
 | 
|---|
| 126 |     /** Pointer to the section header array. */
 | 
|---|
| 127 |     const IMAGE_SECTION_HEADER *paShdrs;
 | 
|---|
| 128 | 
 | 
|---|
| 129 | #elif defined(__DARWIN__)
 | 
|---|
| 130 |     /** The dlopen() handle.*/
 | 
|---|
| 131 |     void                       *pvMod;
 | 
|---|
| 132 | 
 | 
|---|
| 133 | #else
 | 
|---|
| 134 | # error "Port me"
 | 
|---|
| 135 | #endif
 | 
|---|
| 136 | } KLDRMODNATIVE, *PKLDRMODNATIVE;
 | 
|---|
| 137 | 
 | 
|---|
| 138 | 
 | 
|---|
| 139 | /*******************************************************************************
 | 
|---|
| 140 | *   Internal Functions                                                         *
 | 
|---|
| 141 | *******************************************************************************/
 | 
|---|
| 142 | static int32_t kldrModNativeNumberOfImports(PKLDRMOD pMod, const void *pvBits);
 | 
|---|
| 143 | 
 | 
|---|
| 144 | 
 | 
|---|
| 145 | 
 | 
|---|
| 146 | /**
 | 
|---|
| 147 |  * Use native loader to load the file opened by pRdr.
 | 
|---|
| 148 |  *
 | 
|---|
| 149 |  * @returns 0 on success and *ppMod pointing to a module instance.
 | 
|---|
| 150 |  *          On failure, a non-zero OS specific error code is returned.
 | 
|---|
| 151 |  * @param   pOps            Pointer to the registered method table.
 | 
|---|
| 152 |  * @param   pRdr            The file provider instance to use.
 | 
|---|
| 153 |  * @param   offNewHdr       The offset of the new header in MZ files. -1 if not found.
 | 
|---|
| 154 |  * @param   ppMod           Where to store the module instance pointer.
 | 
|---|
| 155 |  */
 | 
|---|
| 156 | static int kldrModNativeCreate(PCKLDRMODOPS pOps, PKLDRRDR pRdr, KLDRFOFF offNewHdr, PPKLDRMOD ppMod)
 | 
|---|
| 157 | {
 | 
|---|
| 158 |     int rc = kLdrModOpenNative(kLdrRdrName(pRdr), ppMod);
 | 
|---|
| 159 |     if (rc)
 | 
|---|
| 160 |         return rc;
 | 
|---|
| 161 |     rc = kLdrRdrClose(pRdr);
 | 
|---|
| 162 |     KLDRMODNATIVE_ASSERT(!rc);
 | 
|---|
| 163 |     return 0;
 | 
|---|
| 164 | }
 | 
|---|
| 165 | 
 | 
|---|
| 166 | 
 | 
|---|
| 167 | /**
 | 
|---|
| 168 |  * Loads a module using the native module loader.
 | 
|---|
| 169 |  *
 | 
|---|
| 170 |  * @returns 0 on success.
 | 
|---|
| 171 |  * @returns non-zero native or kLdr status code on failure.
 | 
|---|
| 172 |  * @param   pszFilename         The filename or module name to be loaded.
 | 
|---|
| 173 |  * @param   ppMod               Where to store the module interpreter instance pointer.
 | 
|---|
| 174 |  */
 | 
|---|
| 175 | int kLdrModOpenNative(const char *pszFilename, PPKLDRMOD ppMod)
 | 
|---|
| 176 | {
 | 
|---|
| 177 |     int rc;
 | 
|---|
| 178 | 
 | 
|---|
| 179 |     /*
 | 
|---|
| 180 |      * Load the image.
 | 
|---|
| 181 |      */
 | 
|---|
| 182 | #ifdef __OS2__
 | 
|---|
| 183 |     HMODULE hmod;
 | 
|---|
| 184 | 
 | 
|---|
| 185 |     rc = DosLoadModule(NULL, 0, (PCSZ)pszFilename, &hmod);
 | 
|---|
| 186 |     if (rc)
 | 
|---|
| 187 |         return rc;
 | 
|---|
| 188 |     rc = kLdrModOpenNativeByHandle((uintptr_t)hmod, ppMod);
 | 
|---|
| 189 |     if (rc)
 | 
|---|
| 190 |         DosFreeModule(hmod);
 | 
|---|
| 191 | 
 | 
|---|
| 192 | #elif defined(__WIN__)
 | 
|---|
| 193 |     HMODULE hmod;
 | 
|---|
| 194 | 
 | 
|---|
| 195 |     hmod = LoadLibrary(pszFilename);
 | 
|---|
| 196 |     if (!hmod)
 | 
|---|
| 197 |         return GetLastError();
 | 
|---|
| 198 |     rc = kLdrModOpenNativeByHandle((uintptr_t)hmod, ppMod);
 | 
|---|
| 199 |     if (rc)
 | 
|---|
| 200 |         FreeLibrary(hmod);
 | 
|---|
| 201 | 
 | 
|---|
| 202 | #elif defined(__DARWIN__)
 | 
|---|
| 203 |     void *pvMod;
 | 
|---|
| 204 | 
 | 
|---|
| 205 |     pvMod = dlopen(pszFilename, 0);
 | 
|---|
| 206 |     if (!pvMod)
 | 
|---|
| 207 |         return ENOENT;
 | 
|---|
| 208 |     rc = kLdrModOpenNativeByHandle((uintptr_t)pvMod, ppMod);
 | 
|---|
| 209 |     if (rc)
 | 
|---|
| 210 |         dlclose(pvMod);
 | 
|---|
| 211 | 
 | 
|---|
| 212 | #else
 | 
|---|
| 213 | # error "Port me"
 | 
|---|
| 214 | #endif
 | 
|---|
| 215 |     return rc;
 | 
|---|
| 216 | }
 | 
|---|
| 217 | 
 | 
|---|
| 218 | 
 | 
|---|
| 219 | /**
 | 
|---|
| 220 |  * Creates a native module interpret for an already module already
 | 
|---|
| 221 |  * loaded by the native loader.
 | 
|---|
| 222 |  *
 | 
|---|
| 223 |  * @returns 0 on success.
 | 
|---|
| 224 |  * @returns non-zero native or kLdr status code on failure.
 | 
|---|
| 225 |  * @param   pszFilename         The filename or module name to be loaded.
 | 
|---|
| 226 |  * @param   ppMod               Where to store the module interpreter instance pointer.
 | 
|---|
| 227 |  * @remark  This will not make the native loader increment the load count.
 | 
|---|
| 228 |  */
 | 
|---|
| 229 | int kLdrModOpenNativeByHandle(uintptr_t uHandle, PPKLDRMOD ppMod)
 | 
|---|
| 230 | {
 | 
|---|
| 231 |     size_t cb;
 | 
|---|
| 232 |     size_t cchFilename;
 | 
|---|
| 233 |     uint32_t cSegments;
 | 
|---|
| 234 |     PKLDRMOD pMod;
 | 
|---|
| 235 |     PKLDRMODNATIVE pModNative;
 | 
|---|
| 236 | 
 | 
|---|
| 237 |     /*
 | 
|---|
| 238 |      * Delcare variables, parse the module header or whatever and determin the
 | 
|---|
| 239 |      * size of the module instance.
 | 
|---|
| 240 |      */
 | 
|---|
| 241 | #ifdef __OS2__
 | 
|---|
| 242 |     char szFilename[CCHMAXPATH];
 | 
|---|
| 243 |     int rc;
 | 
|---|
| 244 | 
 | 
|---|
| 245 |     /* get the filename. */
 | 
|---|
| 246 |     rc = DosQueryModuleName((HMODULE)uHandle, sizeof(szFilename), szFilename);
 | 
|---|
| 247 |     if (rc)
 | 
|---|
| 248 |     {
 | 
|---|
| 249 |         KLDRMODNATIVE_ASSERT(rc);
 | 
|---|
| 250 |         szFilename[0] = '\0';
 | 
|---|
| 251 |     }
 | 
|---|
| 252 | 
 | 
|---|
| 253 |     /* get the segment count. */
 | 
|---|
| 254 |     /** @todo DosQueryHeaderInfo should be able to get us what we want on OS/2. */
 | 
|---|
| 255 |     cSegments = 1;
 | 
|---|
| 256 | 
 | 
|---|
| 257 | #elif defined(__WIN__)
 | 
|---|
| 258 |     DWORD                       dw;
 | 
|---|
| 259 |     char                        szFilename[MAX_PATH];
 | 
|---|
| 260 |     const IMAGE_NT_HEADERS     *pNtHdrs;
 | 
|---|
| 261 |     const IMAGE_SECTION_HEADER *paShdrs;
 | 
|---|
| 262 |     const IMAGE_DOS_HEADER     *pDosHdr = (const IMAGE_DOS_HEADER *)uHandle;
 | 
|---|
| 263 |     unsigned                    i;
 | 
|---|
| 264 | 
 | 
|---|
| 265 |     /* get the filename. */
 | 
|---|
| 266 |     dw = GetModuleFileName((HANDLE)uHandle, szFilename, sizeof(szFilename));
 | 
|---|
| 267 |     if (dw <= 0)
 | 
|---|
| 268 |     {
 | 
|---|
| 269 |         KLDRMODNATIVE_ASSERT(dw <= 0);
 | 
|---|
| 270 |         szFilename[0] = '\0';
 | 
|---|
| 271 |     }
 | 
|---|
| 272 | 
 | 
|---|
| 273 |     /* get the segment count. */
 | 
|---|
| 274 |     if (pDosHdr->e_magic == IMAGE_DOS_SIGNATURE)
 | 
|---|
| 275 |         pNtHdrs = (const IMAGE_NT_HEADERS *)((uintptr_t)pDosHdr + pDosHdr->e_lfanew);
 | 
|---|
| 276 |     else
 | 
|---|
| 277 |         pNtHdrs = (const IMAGE_NT_HEADERS *)pDosHdr;
 | 
|---|
| 278 |     if (pNtHdrs->Signature != IMAGE_NT_SIGNATURE)
 | 
|---|
| 279 |     {
 | 
|---|
| 280 |         KLDRMODNATIVE_ASSERT(!"bad signature");
 | 
|---|
| 281 |         return KLDR_ERR_UNKNOWN_FORMAT;
 | 
|---|
| 282 |     }
 | 
|---|
| 283 |     if (pNtHdrs->FileHeader.SizeOfOptionalHeader != sizeof(IMAGE_OPTIONAL_HEADER))
 | 
|---|
| 284 |     {
 | 
|---|
| 285 |         KLDRMODNATIVE_ASSERT(!"bad optional header size");
 | 
|---|
| 286 |         return KLDR_ERR_UNKNOWN_FORMAT;
 | 
|---|
| 287 |     }
 | 
|---|
| 288 |     cSegments = pNtHdrs->FileHeader.NumberOfSections + 1;
 | 
|---|
| 289 |     paShdrs = (const IMAGE_SECTION_HEADER *)(pNtHdrs + 1);
 | 
|---|
| 290 | 
 | 
|---|
| 291 | #elif defined(__DARWIN__)
 | 
|---|
| 292 |     char    szFilename[1] = "";
 | 
|---|
| 293 |     cSegments = 0; /** @todo Figure out the Mac OS X dynamic loader. */
 | 
|---|
| 294 | 
 | 
|---|
| 295 | #else
 | 
|---|
| 296 | # error "Port me"
 | 
|---|
| 297 | #endif
 | 
|---|
| 298 | 
 | 
|---|
| 299 |     /*
 | 
|---|
| 300 |      * Calc the instance size, allocate and initialize it.
 | 
|---|
| 301 |      */
 | 
|---|
| 302 |     cchFilename = kLdrHlpStrLen(szFilename);
 | 
|---|
| 303 |     cb = KLDR_ALIGN_Z(sizeof(KLDRMODNATIVE), 16)
 | 
|---|
| 304 |        + KLDR_OFFSETOF(KLDRMOD, aSegments[cSegments])
 | 
|---|
| 305 |        + cchFilename + 1;
 | 
|---|
| 306 |     pModNative = (PKLDRMODNATIVE)kldrHlpAlloc(cb);
 | 
|---|
| 307 |     if (!pModNative)
 | 
|---|
| 308 |         return KLDR_ERR_NO_MEMORY;
 | 
|---|
| 309 | 
 | 
|---|
| 310 |     /* KLDRMOD */
 | 
|---|
| 311 |     pMod = (PKLDRMOD)((uint8_t *)pModNative + KLDR_ALIGN_Z(sizeof(KLDRMODNATIVE), 16));
 | 
|---|
| 312 |     pMod->pvData = pModNative;
 | 
|---|
| 313 |     pMod->pRdr = NULL;
 | 
|---|
| 314 |     pMod->pOps = NULL;      /* set upon success. */
 | 
|---|
| 315 |     pMod->cSegments = cSegments;
 | 
|---|
| 316 |     pMod->cchFilename = cchFilename;
 | 
|---|
| 317 |     pMod->pszFilename = (char *)&pMod->aSegments[pMod->cSegments];
 | 
|---|
| 318 |     kLdrHlpMemCopy((char *)pMod->pszFilename, szFilename, cchFilename + 1);
 | 
|---|
| 319 |     pMod->pszName = kldrHlpGetFilename(pMod->pszFilename); /** @todo get soname */
 | 
|---|
| 320 |     pMod->cchName = cchFilename - (pMod->pszName - pMod->pszFilename);
 | 
|---|
| 321 | #if defined(__i386__) || defined(__X86__) || defined(_M_IX86)
 | 
|---|
| 322 |     pMod->enmCpu = KLDRCPU_I386;
 | 
|---|
| 323 |     pMod->enmArch = KLDRARCH_X86_32;
 | 
|---|
| 324 |     pMod->enmEndian = KLDRENDIAN_LITTLE;
 | 
|---|
| 325 | #elif defined(__X86_64__) || defined(__x86_64__) || defined(__AMD64__) || defined(_M_IX64)
 | 
|---|
| 326 |     pMod->enmCpu = KLDRCPU_K8;
 | 
|---|
| 327 |     pMod->enmArch = KLDRARCH_AMD64;
 | 
|---|
| 328 |     pMod->enmEndian = KLDRENDIAN_LITTLE;
 | 
|---|
| 329 | #else
 | 
|---|
| 330 | # error "Port me"
 | 
|---|
| 331 | #endif
 | 
|---|
| 332 |     pMod->enmFmt = KLDRFMT_NATIVE;
 | 
|---|
| 333 |     pMod->enmType = KLDRTYPE_SHARED_LIBRARY_RELOCATABLE;
 | 
|---|
| 334 |     pMod->u32Magic = 0;     /* set upon success. */
 | 
|---|
| 335 | 
 | 
|---|
| 336 |     /* KLDRMODNATIVE */
 | 
|---|
| 337 |     pModNative->pMod = pMod;
 | 
|---|
| 338 |     pModNative->f32Reserved = 0;
 | 
|---|
| 339 |     pModNative->cImportModules = ~(uint32_t)0;
 | 
|---|
| 340 | 
 | 
|---|
| 341 |     /*
 | 
|---|
| 342 |      * Set native instance data.
 | 
|---|
| 343 |      */
 | 
|---|
| 344 | #ifdef __OS2__
 | 
|---|
| 345 |     pModNative->hmod = (HMODULE)uHandle;
 | 
|---|
| 346 | 
 | 
|---|
| 347 |     /* just fake a segment for now. */
 | 
|---|
| 348 |     pMod->aSegments[0].pvUser = NULL;
 | 
|---|
| 349 |     pMod->aSegments[0].pchName = "fake";
 | 
|---|
| 350 |     pMod->aSegments[0].cchName = sizeof("fake") - 1;
 | 
|---|
| 351 |     pMod->aSegments[0].enmProt = KLDRPROT_NOACCESS;
 | 
|---|
| 352 |     pMod->aSegments[0].cb = 0;
 | 
|---|
| 353 |     pMod->aSegments[0].Alignment = 0;
 | 
|---|
| 354 |     pMod->aSegments[0].LinkAddress = NIL_KLDRADDR;
 | 
|---|
| 355 |     pMod->aSegments[0].offFile = -1;
 | 
|---|
| 356 |     pMod->aSegments[0].cbFile = 0;
 | 
|---|
| 357 |     pMod->aSegments[0].RVA = NIL_KLDRADDR;
 | 
|---|
| 358 |     pMod->aSegments[0].cbMapped = 0;
 | 
|---|
| 359 |     pMod->aSegments[0].MapAddress = 0;
 | 
|---|
| 360 | 
 | 
|---|
| 361 | #elif defined(__WIN__)
 | 
|---|
| 362 |     pModNative->hmod = (HMODULE)uHandle;
 | 
|---|
| 363 |     pModNative->pNtHdrs = pNtHdrs;
 | 
|---|
| 364 |     pModNative->paShdrs = paShdrs;
 | 
|---|
| 365 | 
 | 
|---|
| 366 |     if (pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_DLL)
 | 
|---|
| 367 |         pMod->enmType = !(pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
 | 
|---|
| 368 |             ? KLDRTYPE_SHARED_LIBRARY_RELOCATABLE
 | 
|---|
| 369 |             : KLDRTYPE_SHARED_LIBRARY_FIXED;
 | 
|---|
| 370 |     else
 | 
|---|
| 371 |         pMod->enmType = !(pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
 | 
|---|
| 372 |             ? KLDRTYPE_EXECUTABLE_RELOCATABLE
 | 
|---|
| 373 |             : KLDRTYPE_EXECUTABLE_FIXED;
 | 
|---|
| 374 | 
 | 
|---|
| 375 |     /* The implied headers section. */
 | 
|---|
| 376 |     pMod->aSegments[0].pvUser = NULL;
 | 
|---|
| 377 |     pMod->aSegments[0].pchName = "TheHeaders";
 | 
|---|
| 378 |     pMod->aSegments[0].cchName = sizeof("TheHeaders") - 1;
 | 
|---|
| 379 |     pMod->aSegments[0].enmProt = KLDRPROT_READONLY;
 | 
|---|
| 380 |     pMod->aSegments[0].cb = pNtHdrs->OptionalHeader.SizeOfHeaders;
 | 
|---|
| 381 |     pMod->aSegments[0].Alignment = pNtHdrs->OptionalHeader.SectionAlignment;
 | 
|---|
| 382 |     pMod->aSegments[0].LinkAddress = pNtHdrs->OptionalHeader.ImageBase;
 | 
|---|
| 383 |     pMod->aSegments[0].offFile = 0;
 | 
|---|
| 384 |     pMod->aSegments[0].cbFile = pNtHdrs->OptionalHeader.SizeOfHeaders;
 | 
|---|
| 385 |     pMod->aSegments[0].RVA = 0;
 | 
|---|
| 386 |     if (pMod->cSegments > 1)
 | 
|---|
| 387 |         pMod->aSegments[0].cbMapped = paShdrs[0].VirtualAddress;
 | 
|---|
| 388 |     else
 | 
|---|
| 389 |         pMod->aSegments[0].cbMapped = pNtHdrs->OptionalHeader.SizeOfHeaders;
 | 
|---|
| 390 |     pMod->aSegments[0].MapAddress = 0;
 | 
|---|
| 391 | 
 | 
|---|
| 392 |     /* The section headers. */
 | 
|---|
| 393 |     for (i = 0; i < pNtHdrs->FileHeader.NumberOfSections; i++)
 | 
|---|
| 394 |     {
 | 
|---|
| 395 |         const char *pch;
 | 
|---|
| 396 | 
 | 
|---|
| 397 |         /* unused */
 | 
|---|
| 398 |         pMod->aSegments[i + 1].pvUser = NULL;
 | 
|---|
| 399 |         pMod->aSegments[i + 1].MapAddress = 0;
 | 
|---|
| 400 | 
 | 
|---|
| 401 |         /* name */
 | 
|---|
| 402 |         pMod->aSegments[i + 1].pchName = pch = &paShdrs[i].Name[0];
 | 
|---|
| 403 |         cb = IMAGE_SIZEOF_SHORT_NAME;
 | 
|---|
| 404 |         while (     cb > 0
 | 
|---|
| 405 |                &&   (pch[cb - 1] == ' ' || pch[cb - 1] == '\0'))
 | 
|---|
| 406 |             cb--;
 | 
|---|
| 407 |         pMod->aSegments[i + 1].cchName = cb;
 | 
|---|
| 408 | 
 | 
|---|
| 409 |         /* size and addresses */
 | 
|---|
| 410 |         if (!(paShdrs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
 | 
|---|
| 411 |         {
 | 
|---|
| 412 |             pMod->aSegments[i + 1].cb          = paShdrs[i].Misc.VirtualSize;
 | 
|---|
| 413 |             pMod->aSegments[i + 1].LinkAddress = paShdrs[i].VirtualAddress
 | 
|---|
| 414 |                                                + pNtHdrs->OptionalHeader.ImageBase;
 | 
|---|
| 415 |             pMod->aSegments[i + 1].RVA         = paShdrs[i].VirtualAddress;
 | 
|---|
| 416 |             pMod->aSegments[i + 1].cbMapped    = paShdrs[i].Misc.VirtualSize;
 | 
|---|
| 417 |             if (i + 2 < pMod->cSegments)
 | 
|---|
| 418 |                 pMod->aSegments[i + 1].cbMapped= paShdrs[i + 1].VirtualAddress
 | 
|---|
| 419 |                                                - paShdrs[i].VirtualAddress;
 | 
|---|
| 420 |         }
 | 
|---|
| 421 |         else
 | 
|---|
| 422 |         {
 | 
|---|
| 423 |             pMod->aSegments[i + 1].cb          = 0;
 | 
|---|
| 424 |             pMod->aSegments[i + 1].cbMapped    = 0;
 | 
|---|
| 425 |             pMod->aSegments[i + 1].LinkAddress = NIL_KLDRADDR;
 | 
|---|
| 426 |             pMod->aSegments[i + 1].RVA         = 0;
 | 
|---|
| 427 |         }
 | 
|---|
| 428 | 
 | 
|---|
| 429 |         /* file location */
 | 
|---|
| 430 |         pMod->aSegments[i + 1].offFile = paShdrs[i].PointerToRawData;
 | 
|---|
| 431 |         pMod->aSegments[i + 1].cbFile = paShdrs[i].SizeOfRawData;
 | 
|---|
| 432 |         if (    pMod->aSegments[i + 1].cbMapped > 0 /* if mapped */
 | 
|---|
| 433 |             &&  (KLDRSIZE)pMod->aSegments[i + 1].cbFile > pMod->aSegments[i + 1].cbMapped)
 | 
|---|
| 434 |             pMod->aSegments[i + 1].cbFile = pMod->aSegments[i + 1].cbMapped;
 | 
|---|
| 435 | 
 | 
|---|
| 436 |         /* protection */
 | 
|---|
| 437 |         switch (  paShdrs[i].Characteristics
 | 
|---|
| 438 |                 & (IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE))
 | 
|---|
| 439 |         {
 | 
|---|
| 440 |             case 0:
 | 
|---|
| 441 |             case IMAGE_SCN_MEM_SHARED:
 | 
|---|
| 442 |                 pMod->aSegments[i + 1].enmProt = KLDRPROT_NOACCESS;
 | 
|---|
| 443 |                 break;
 | 
|---|
| 444 |             case IMAGE_SCN_MEM_READ:
 | 
|---|
| 445 |             case IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED:
 | 
|---|
| 446 |                 pMod->aSegments[i + 1].enmProt = KLDRPROT_READONLY;
 | 
|---|
| 447 |                 break;
 | 
|---|
| 448 |             case IMAGE_SCN_MEM_WRITE:
 | 
|---|
| 449 |             case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ:
 | 
|---|
| 450 |                 pMod->aSegments[i + 1].enmProt = KLDRPROT_WRITECOPY;
 | 
|---|
| 451 |                 break;
 | 
|---|
| 452 |             case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED:
 | 
|---|
| 453 |             case IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ:
 | 
|---|
| 454 |                 pMod->aSegments[i + 1].enmProt = KLDRPROT_READWRITE;
 | 
|---|
| 455 |                 break;
 | 
|---|
| 456 |             case IMAGE_SCN_MEM_EXECUTE:
 | 
|---|
| 457 |             case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_SHARED:
 | 
|---|
| 458 |                 pMod->aSegments[i + 1].enmProt = KLDRPROT_EXECUTE;
 | 
|---|
| 459 |                 break;
 | 
|---|
| 460 |             case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ:
 | 
|---|
| 461 |             case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED:
 | 
|---|
| 462 |                 pMod->aSegments[i + 1].enmProt = KLDRPROT_EXECUTE_READ;
 | 
|---|
| 463 |                 break;
 | 
|---|
| 464 |             case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE:
 | 
|---|
| 465 |             case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ:
 | 
|---|
| 466 |                 pMod->aSegments[i + 1].enmProt = KLDRPROT_EXECUTE_WRITECOPY;
 | 
|---|
| 467 |                 break;
 | 
|---|
| 468 |             case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED:
 | 
|---|
| 469 |             case IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ:
 | 
|---|
| 470 |                 pMod->aSegments[i + 1].enmProt = KLDRPROT_EXECUTE_READWRITE;
 | 
|---|
| 471 |                 break;
 | 
|---|
| 472 |         }
 | 
|---|
| 473 | 
 | 
|---|
| 474 |         /* alignment. */
 | 
|---|
| 475 |         switch (paShdrs[i].Characteristics & IMAGE_SCN_ALIGN_MASK)
 | 
|---|
| 476 |         {
 | 
|---|
| 477 |             case 0: /* hope this is right... */
 | 
|---|
| 478 |                 pMod->aSegments[i + 1].Alignment = pNtHdrs->OptionalHeader.SectionAlignment;
 | 
|---|
| 479 |                 break;
 | 
|---|
| 480 |             case IMAGE_SCN_ALIGN_1BYTES:        pMod->aSegments[i + 1].Alignment = 1; break;
 | 
|---|
| 481 |             case IMAGE_SCN_ALIGN_2BYTES:        pMod->aSegments[i + 1].Alignment = 2; break;
 | 
|---|
| 482 |             case IMAGE_SCN_ALIGN_4BYTES:        pMod->aSegments[i + 1].Alignment = 4; break;
 | 
|---|
| 483 |             case IMAGE_SCN_ALIGN_8BYTES:        pMod->aSegments[i + 1].Alignment = 8; break;
 | 
|---|
| 484 |             case IMAGE_SCN_ALIGN_16BYTES:       pMod->aSegments[i + 1].Alignment = 16; break;
 | 
|---|
| 485 |             case IMAGE_SCN_ALIGN_32BYTES:       pMod->aSegments[i + 1].Alignment = 32; break;
 | 
|---|
| 486 |             case IMAGE_SCN_ALIGN_64BYTES:       pMod->aSegments[i + 1].Alignment = 64; break;
 | 
|---|
| 487 |             case IMAGE_SCN_ALIGN_128BYTES:      pMod->aSegments[i + 1].Alignment = 128; break;
 | 
|---|
| 488 |             case IMAGE_SCN_ALIGN_256BYTES:      pMod->aSegments[i + 1].Alignment = 256; break;
 | 
|---|
| 489 |             case IMAGE_SCN_ALIGN_512BYTES:      pMod->aSegments[i + 1].Alignment = 512; break;
 | 
|---|
| 490 |             case IMAGE_SCN_ALIGN_1024BYTES:     pMod->aSegments[i + 1].Alignment = 1024; break;
 | 
|---|
| 491 |             case IMAGE_SCN_ALIGN_2048BYTES:     pMod->aSegments[i + 1].Alignment = 2048; break;
 | 
|---|
| 492 |             case IMAGE_SCN_ALIGN_4096BYTES:     pMod->aSegments[i + 1].Alignment = 4096; break;
 | 
|---|
| 493 |             case IMAGE_SCN_ALIGN_8192BYTES:     pMod->aSegments[i + 1].Alignment = 8192; break;
 | 
|---|
| 494 |             default: kldrHlpAssert(0);          pMod->aSegments[i + 1].Alignment = 0; break;
 | 
|---|
| 495 |         }
 | 
|---|
| 496 |     }
 | 
|---|
| 497 | 
 | 
|---|
| 498 | #elif defined(__DARWIN__)
 | 
|---|
| 499 |     /** @todo Figure out the Mac OS X dynamic loader. */
 | 
|---|
| 500 | 
 | 
|---|
| 501 | #else
 | 
|---|
| 502 | # error "Port me"
 | 
|---|
| 503 | #endif
 | 
|---|
| 504 | 
 | 
|---|
| 505 |     /*
 | 
|---|
| 506 |      * We're done.
 | 
|---|
| 507 |      */
 | 
|---|
| 508 |     *ppMod = pMod;
 | 
|---|
| 509 |     return 0;
 | 
|---|
| 510 | }
 | 
|---|
| 511 | 
 | 
|---|
| 512 | 
 | 
|---|
| 513 | /** @copydoc KLDRMODOPS::pfnDestroy */
 | 
|---|
| 514 | static int kldrModNativeDestroy(PKLDRMOD pMod)
 | 
|---|
| 515 | {
 | 
|---|
| 516 |     PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
 | 
|---|
| 517 |     int rc;
 | 
|---|
| 518 | 
 | 
|---|
| 519 | #ifdef __OS2__
 | 
|---|
| 520 |     rc = DosFreeModule(pModNative->hmod);
 | 
|---|
| 521 | 
 | 
|---|
| 522 | #elif defined(__WIN__)
 | 
|---|
| 523 |     if (FreeLibrary(pModNative->hmod))
 | 
|---|
| 524 |         rc = 0;
 | 
|---|
| 525 |     else
 | 
|---|
| 526 |         rc = GetLastError();
 | 
|---|
| 527 | 
 | 
|---|
| 528 | #elif defined(__DARWIN__)
 | 
|---|
| 529 |     dlclose(pModNative->pvMod);
 | 
|---|
| 530 | 
 | 
|---|
| 531 | #else
 | 
|---|
| 532 | # error "Port me"
 | 
|---|
| 533 | #endif
 | 
|---|
| 534 | 
 | 
|---|
| 535 |     pMod->u32Magic = 0;
 | 
|---|
| 536 |     pMod->pOps = NULL;
 | 
|---|
| 537 |     kldrHlpFree(pModNative);
 | 
|---|
| 538 |     return rc;
 | 
|---|
| 539 | }
 | 
|---|
| 540 | 
 | 
|---|
| 541 | 
 | 
|---|
| 542 | /** @copydoc kLdrModQuerySymbol */
 | 
|---|
| 543 | static int kldrModNativeQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t iSymbol,
 | 
|---|
| 544 |                                     const char *pchSymbol, size_t cchSymbol, const char *pszVersion,
 | 
|---|
| 545 |                                     PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind)
 | 
|---|
| 546 | {
 | 
|---|
| 547 |     PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
 | 
|---|
| 548 |     const char *pszSymbol = pchSymbol;
 | 
|---|
| 549 | #ifdef __OS2__
 | 
|---|
| 550 |     APIRET rc;
 | 
|---|
| 551 |     PFN pfn;
 | 
|---|
| 552 | #elif defined(__WIN__)
 | 
|---|
| 553 |     FARPROC pfn;
 | 
|---|
| 554 | #elif defined(__DARWIN__)
 | 
|---|
| 555 |     void *pfn;
 | 
|---|
| 556 | #else
 | 
|---|
| 557 | # error "Port me"
 | 
|---|
| 558 | #endif
 | 
|---|
| 559 | 
 | 
|---|
| 560 |     /* make stack copy of the symbol if it isn't zero terminated. */
 | 
|---|
| 561 |     if (pszSymbol && pszSymbol[cchSymbol])
 | 
|---|
| 562 |     {
 | 
|---|
| 563 |         char *pszCopy = kLdrHlpAllocA(cchSymbol + 1);
 | 
|---|
| 564 |         kLdrHlpMemCopy(pszCopy, pchSymbol, cchSymbol);
 | 
|---|
| 565 |         pszCopy[cchSymbol] = '\0';
 | 
|---|
| 566 |         pszSymbol = pszCopy;
 | 
|---|
| 567 |     }
 | 
|---|
| 568 | 
 | 
|---|
| 569 | #ifdef __OS2__
 | 
|---|
| 570 |     if (!pchSymbol && iSymbol >= 0x10000)
 | 
|---|
| 571 |         return KLDR_ERR_SYMBOL_NOT_FOUND;
 | 
|---|
| 572 | 
 | 
|---|
| 573 |     if (puValue)
 | 
|---|
| 574 |     {
 | 
|---|
| 575 |         rc = DosQueryProcAddr(pModNative->hmod,
 | 
|---|
| 576 |                               pszSymbol ? 0 : iSymbol,
 | 
|---|
| 577 |                               (PCSZ)pszSymbol,
 | 
|---|
| 578 |                               &pfn);
 | 
|---|
| 579 |         if (rc)
 | 
|---|
| 580 |             return rc == ERROR_PROC_NOT_FOUND ? KLDR_ERR_SYMBOL_NOT_FOUND : rc;
 | 
|---|
| 581 |         *puValue = (uintptr_t)pfn;
 | 
|---|
| 582 |     }
 | 
|---|
| 583 |     if (pfKind)
 | 
|---|
| 584 |     {
 | 
|---|
| 585 |         ULONG ulProcType;
 | 
|---|
| 586 |         rc = DosQueryProcType(pModNative->hmod,
 | 
|---|
| 587 |                               pszSymbol ? 0 : iSymbol,
 | 
|---|
| 588 |                               (PCSZ)pszSymbol,
 | 
|---|
| 589 |                               &ulProcType);
 | 
|---|
| 590 |         if (rc)
 | 
|---|
| 591 |         {
 | 
|---|
| 592 |             if (puValue)
 | 
|---|
| 593 |                 *puValue = 0;
 | 
|---|
| 594 |             return rc == ERROR_PROC_NOT_FOUND ? KLDR_ERR_SYMBOL_NOT_FOUND : rc;
 | 
|---|
| 595 |         }
 | 
|---|
| 596 |         *pfKind = (ulProcType & PT_32BIT ? KLDRSYMKIND_32BIT : KLDRSYMKIND_16BIT)
 | 
|---|
| 597 |                 | KLDRSYMKIND_NO_TYPE;
 | 
|---|
| 598 |     }
 | 
|---|
| 599 | 
 | 
|---|
| 600 | #elif defined(__WIN__)
 | 
|---|
| 601 |     if (!pszSymbol && iSymbol >= 0x10000)
 | 
|---|
| 602 |         return KLDR_ERR_SYMBOL_NOT_FOUND;
 | 
|---|
| 603 | 
 | 
|---|
| 604 |     pfn = GetProcAddress(pModNative->hmod, pszSymbol ? pszSymbol : (const char *)(uintptr_t)iSymbol);
 | 
|---|
| 605 |     if (puValue)
 | 
|---|
| 606 |         *puValue = (uintptr_t)pfn;
 | 
|---|
| 607 |     if (pfKind)
 | 
|---|
| 608 |         *pfKind = (pModNative->pNtHdrs->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
 | 
|---|
| 609 |                    ? KLDRSYMKIND_32BIT : KLDRSYMKIND_16BIT)
 | 
|---|
| 610 |                 | KLDRSYMKIND_NO_TYPE;
 | 
|---|
| 611 | 
 | 
|---|
| 612 | #elif defined(__DARWIN__)
 | 
|---|
| 613 |     if (!pszSymbol && iSymbol != NIL_KLDRMOD_SYM_ORDINAL)
 | 
|---|
| 614 |         return KLDR_ERR_SYMBOL_NOT_FOUND;
 | 
|---|
| 615 | 
 | 
|---|
| 616 |     pfn = dlsym(pModNative->pvMod, pszSymbol);
 | 
|---|
| 617 |     if (!pfn)
 | 
|---|
| 618 |         return KLDR_ERR_SYMBOL_NOT_FOUND;
 | 
|---|
| 619 |     if (puValue)
 | 
|---|
| 620 |         *puValue = (uintptr_t)pfn;
 | 
|---|
| 621 |     if (pfKind)
 | 
|---|
| 622 |         *pfKind = (sizeof(uintptr_t) == 4 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT)
 | 
|---|
| 623 |                 | KLDRSYMKIND_NO_TYPE;
 | 
|---|
| 624 | 
 | 
|---|
| 625 | #else
 | 
|---|
| 626 | # error "Port me"
 | 
|---|
| 627 | #endif
 | 
|---|
| 628 | 
 | 
|---|
| 629 |     return 0;
 | 
|---|
| 630 | }
 | 
|---|
| 631 | 
 | 
|---|
| 632 | 
 | 
|---|
| 633 | /** @copydoc kLdrModEnumSymbols */
 | 
|---|
| 634 | static int kldrModNativeEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress,
 | 
|---|
| 635 |                                     uint32_t fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
 | 
|---|
| 636 | {
 | 
|---|
| 637 |     PKLDRMODNATIVE                  pModNative = (PKLDRMODNATIVE)pMod->pvData;
 | 
|---|
| 638 | #ifdef __OS2__
 | 
|---|
| 639 | 
 | 
|---|
| 640 |     /** @todo implement export enumeration on OS/2. */
 | 
|---|
| 641 |     (void)pModNative;
 | 
|---|
| 642 |     return ERROR_NOT_SUPPORTED;
 | 
|---|
| 643 | 
 | 
|---|
| 644 | #elif defined(__WIN__) || defined(__NT__)
 | 
|---|
| 645 |     const uint32_t                 *paFunctions;
 | 
|---|
| 646 |     const IMAGE_EXPORT_DIRECTORY   *pExpDir;
 | 
|---|
| 647 |     const uint32_t                 *paRVANames;
 | 
|---|
| 648 |     const uint16_t                 *paOrdinals;
 | 
|---|
| 649 |     uint32_t                        iFunction;
 | 
|---|
| 650 |     uint32_t                        cFunctions;
 | 
|---|
| 651 |     uint32_t                        cNames;
 | 
|---|
| 652 |     int                             rc;
 | 
|---|
| 653 | 
 | 
|---|
| 654 |     /*
 | 
|---|
| 655 |      * Make sure we've got mapped bits and resolve any base address aliases.
 | 
|---|
| 656 |      */
 | 
|---|
| 657 |     if (    pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size
 | 
|---|
| 658 |         <   sizeof(IMAGE_EXPORT_DIRECTORY))
 | 
|---|
| 659 |         return 0; /* no exports to enumerate, return success. */
 | 
|---|
| 660 | 
 | 
|---|
| 661 |     pExpDir = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
 | 
|---|
| 662 |                                      pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
 | 
|---|
| 663 |                                      PIMAGE_EXPORT_DIRECTORY);
 | 
|---|
| 664 | 
 | 
|---|
| 665 |     /*
 | 
|---|
| 666 |      * Enumerate the ordinal exports.
 | 
|---|
| 667 |      */
 | 
|---|
| 668 |     paRVANames = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfNames, const uint32_t *);
 | 
|---|
| 669 |     paOrdinals = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfNameOrdinals, const uint16_t *);
 | 
|---|
| 670 |     paFunctions = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pExpDir->AddressOfFunctions, const uint32_t *);
 | 
|---|
| 671 |     cFunctions = pExpDir->NumberOfFunctions;
 | 
|---|
| 672 |     cNames = pExpDir->NumberOfNames;
 | 
|---|
| 673 |     for (iFunction = 0; iFunction < cFunctions; iFunction++)
 | 
|---|
| 674 |     {
 | 
|---|
| 675 |         unsigned        fFoundName;
 | 
|---|
| 676 |         uint32_t        iName;
 | 
|---|
| 677 |         const uint32_t  uRVA = paFunctions[iFunction];
 | 
|---|
| 678 |         const KLDRADDR  uValue = BaseAddress + uRVA;
 | 
|---|
| 679 |         uint32_t        fKind = (pModNative->pNtHdrs->FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
 | 
|---|
| 680 |                               ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT)
 | 
|---|
| 681 |                               | KLDRSYMKIND_NO_TYPE;
 | 
|---|
| 682 |         if (    uRVA - pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
 | 
|---|
| 683 |             <   pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
 | 
|---|
| 684 |             fKind |= KLDRSYMKIND_FORWARDER;
 | 
|---|
| 685 | 
 | 
|---|
| 686 |         /*
 | 
|---|
| 687 |          * Any symbol names?
 | 
|---|
| 688 |          */
 | 
|---|
| 689 |         fFoundName = 0;
 | 
|---|
| 690 |         for (iName = 0; iName < cNames; iName++)
 | 
|---|
| 691 |         {
 | 
|---|
| 692 |             const char *pszName;
 | 
|---|
| 693 |             if (paOrdinals[iName] != iFunction)
 | 
|---|
| 694 |                 continue;
 | 
|---|
| 695 |             fFoundName = 1;
 | 
|---|
| 696 | 
 | 
|---|
| 697 |             pszName = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, paRVANames[iName], const char *);
 | 
|---|
| 698 |             rc = pfnCallback(pMod, iFunction + pExpDir->Base, pszName, strlen(pszName), NULL,
 | 
|---|
| 699 |                              uValue, fKind, pvUser);
 | 
|---|
| 700 |             if (rc)
 | 
|---|
| 701 |                 return rc;
 | 
|---|
| 702 |         }
 | 
|---|
| 703 | 
 | 
|---|
| 704 |         /*
 | 
|---|
| 705 |          * If no names, call once with the ordinal only.
 | 
|---|
| 706 |          */
 | 
|---|
| 707 |         if (!fFoundName)
 | 
|---|
| 708 |         {
 | 
|---|
| 709 |             rc = pfnCallback(pMod, iFunction + pExpDir->Base, NULL, 0, NULL, uValue, fKind, pvUser);
 | 
|---|
| 710 |             if (rc)
 | 
|---|
| 711 |                 return rc;
 | 
|---|
| 712 |         }
 | 
|---|
| 713 |     }
 | 
|---|
| 714 |     return 0;
 | 
|---|
| 715 | 
 | 
|---|
| 716 | #elif defined(__DARWIN__)
 | 
|---|
| 717 |     /** @todo implement enumeration on darwin. */
 | 
|---|
| 718 |     (void)pModNative;
 | 
|---|
| 719 |     return KLDR_ERR_TODO;
 | 
|---|
| 720 | 
 | 
|---|
| 721 | #else
 | 
|---|
| 722 | # error "Port me"
 | 
|---|
| 723 | #endif
 | 
|---|
| 724 | 
 | 
|---|
| 725 | }
 | 
|---|
| 726 | 
 | 
|---|
| 727 | 
 | 
|---|
| 728 | /** @copydoc kLdrModGetImport */
 | 
|---|
| 729 | static int kldrModNativeGetImport(PKLDRMOD pMod, const void *pvBits, uint32_t iImport, char *pszName, size_t cchName)
 | 
|---|
| 730 | {
 | 
|---|
| 731 |     PKLDRMODNATIVE                  pModNative = (PKLDRMODNATIVE)pMod->pvData;
 | 
|---|
| 732 | #ifdef __OS2__
 | 
|---|
| 733 | 
 | 
|---|
| 734 |     /** @todo implement import enumeration on OS/2. */
 | 
|---|
| 735 |     (void)pModNative;
 | 
|---|
| 736 |     return ERROR_NOT_SUPPORTED;
 | 
|---|
| 737 | 
 | 
|---|
| 738 | #elif defined(__WIN__) || defined(__NT__)
 | 
|---|
| 739 |     const IMAGE_IMPORT_DESCRIPTOR  *pImpDesc;
 | 
|---|
| 740 |     const char                     *pszImportName;
 | 
|---|
| 741 |     size_t                          cchImportName;
 | 
|---|
| 742 |     int                             rc;
 | 
|---|
| 743 | 
 | 
|---|
| 744 |     /*
 | 
|---|
| 745 |      * Simple bounds check.
 | 
|---|
| 746 |      */
 | 
|---|
| 747 |     if (iImport >= (uint32_t)kldrModNativeNumberOfImports(pMod, pvBits))
 | 
|---|
| 748 |         return KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS;
 | 
|---|
| 749 | 
 | 
|---|
| 750 |     /*
 | 
|---|
| 751 |      * Get the name.
 | 
|---|
| 752 |      */
 | 
|---|
| 753 |     pImpDesc = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
 | 
|---|
| 754 |                                       pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
 | 
|---|
| 755 |                                       + sizeof(IMAGE_IMPORT_DESCRIPTOR) * iImport,
 | 
|---|
| 756 |                                       const IMAGE_IMPORT_DESCRIPTOR *);
 | 
|---|
| 757 |     pszImportName = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod, pImpDesc->Name, const char *);
 | 
|---|
| 758 |     cchImportName = kLdrHlpStrLen(pszImportName);
 | 
|---|
| 759 |     if (cchImportName < cchName)
 | 
|---|
| 760 |     {
 | 
|---|
| 761 |         kLdrHlpMemCopy(pszName, pszImportName, cchImportName + 1);
 | 
|---|
| 762 |         rc = 0;
 | 
|---|
| 763 |     }
 | 
|---|
| 764 |     else
 | 
|---|
| 765 |     {
 | 
|---|
| 766 |         kLdrHlpMemCopy(pszName, pszImportName, cchName);
 | 
|---|
| 767 |         if (cchName)
 | 
|---|
| 768 |             pszName[cchName - 1] = '\0';
 | 
|---|
| 769 |         rc = KLDR_ERR_BUFFER_OVERFLOW;
 | 
|---|
| 770 |     }
 | 
|---|
| 771 | 
 | 
|---|
| 772 |     return rc;
 | 
|---|
| 773 | 
 | 
|---|
| 774 | #elif defined(__DARWIN__)
 | 
|---|
| 775 |     /** @todo Implement import enumeration on darwin. */
 | 
|---|
| 776 |     (void)pModNative;
 | 
|---|
| 777 |     return KLDR_ERR_TODO;
 | 
|---|
| 778 | 
 | 
|---|
| 779 | #else
 | 
|---|
| 780 | # error "Port me"
 | 
|---|
| 781 | #endif
 | 
|---|
| 782 | }
 | 
|---|
| 783 | 
 | 
|---|
| 784 | 
 | 
|---|
| 785 | /** @copydoc kLdrModNumberOfImports */
 | 
|---|
| 786 | static int32_t kldrModNativeNumberOfImports(PKLDRMOD pMod, const void *pvBits)
 | 
|---|
| 787 | {
 | 
|---|
| 788 |     PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
 | 
|---|
| 789 | #ifdef __OS2__
 | 
|---|
| 790 | 
 | 
|---|
| 791 |     /** @todo implement import counting on OS/2. */
 | 
|---|
| 792 |     (void)pModNative;
 | 
|---|
| 793 |     return -1;
 | 
|---|
| 794 | 
 | 
|---|
| 795 | #elif defined(__WIN__) || defined(__NT__)
 | 
|---|
| 796 |     if (pModNative->cImportModules == ~(uint32_t)0)
 | 
|---|
| 797 |     {
 | 
|---|
| 798 |         /*
 | 
|---|
| 799 |          * We'll have to walk the import descriptors to figure out their number.
 | 
|---|
| 800 |          */
 | 
|---|
| 801 |         pModNative->cImportModules = 0;
 | 
|---|
| 802 |         if (    pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size
 | 
|---|
| 803 |             &&  pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
 | 
|---|
| 804 |         {
 | 
|---|
| 805 |             const IMAGE_IMPORT_DESCRIPTOR  *pImpDesc;
 | 
|---|
| 806 | 
 | 
|---|
| 807 |             pImpDesc = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
 | 
|---|
| 808 |                                               pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
 | 
|---|
| 809 |                                               const IMAGE_IMPORT_DESCRIPTOR *);
 | 
|---|
| 810 |             while (pImpDesc->Name && pImpDesc->FirstThunk)
 | 
|---|
| 811 |             {
 | 
|---|
| 812 |                 pModNative->cImportModules++;
 | 
|---|
| 813 |                 pImpDesc++;
 | 
|---|
| 814 |             }
 | 
|---|
| 815 |         }
 | 
|---|
| 816 |     }
 | 
|---|
| 817 |     return pModNative->cImportModules;
 | 
|---|
| 818 | 
 | 
|---|
| 819 | #elif defined(__DARWIN__)
 | 
|---|
| 820 |     /** @todo Implement import counting on Darwin. */
 | 
|---|
| 821 |     (void)pModNative;
 | 
|---|
| 822 |     return -1;
 | 
|---|
| 823 | 
 | 
|---|
| 824 | #else
 | 
|---|
| 825 | # error "Port me"
 | 
|---|
| 826 | #endif
 | 
|---|
| 827 | }
 | 
|---|
| 828 | 
 | 
|---|
| 829 | 
 | 
|---|
| 830 | /** @copydoc kLdrModGetStackInfo */
 | 
|---|
| 831 | static int kldrModNativeGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
 | 
|---|
| 832 | {
 | 
|---|
| 833 |     PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
 | 
|---|
| 834 | #ifdef __OS2__
 | 
|---|
| 835 | 
 | 
|---|
| 836 |     /** @todo implement stack info on OS/2. */
 | 
|---|
| 837 |     (void)pModNative;
 | 
|---|
| 838 |     return ERROR_NOT_SUPPORTED;
 | 
|---|
| 839 | 
 | 
|---|
| 840 | #elif defined(__WIN__) || defined(__NT__)
 | 
|---|
| 841 |     pStackInfo->Address = NIL_KLDRADDR;
 | 
|---|
| 842 |     pStackInfo->LinkAddress = NIL_KLDRADDR;
 | 
|---|
| 843 |     pStackInfo->cbStack = pStackInfo->cbStackThread = pModNative->pNtHdrs->OptionalHeader.SizeOfStackReserve;
 | 
|---|
| 844 | 
 | 
|---|
| 845 |     return 0;
 | 
|---|
| 846 | 
 | 
|---|
| 847 | #elif defined(__DARWIN__)
 | 
|---|
| 848 |     /** @todo Implement stack info on Darwin. */
 | 
|---|
| 849 |     (void)pModNative;
 | 
|---|
| 850 |     return KLDR_ERR_TODO;
 | 
|---|
| 851 | 
 | 
|---|
| 852 | #else
 | 
|---|
| 853 | # error "Port me"
 | 
|---|
| 854 | #endif
 | 
|---|
| 855 | }
 | 
|---|
| 856 | 
 | 
|---|
| 857 | 
 | 
|---|
| 858 | /** @copydoc kLdrModQueryMainEntrypoint */
 | 
|---|
| 859 | static int kldrModNativeQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
 | 
|---|
| 860 | {
 | 
|---|
| 861 |     PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
 | 
|---|
| 862 | #ifdef __OS2__
 | 
|---|
| 863 | 
 | 
|---|
| 864 |     /** @todo implement me on OS/2. */
 | 
|---|
| 865 |     (void)pModNative;
 | 
|---|
| 866 |     return ERROR_NOT_SUPPORTED;
 | 
|---|
| 867 | 
 | 
|---|
| 868 | #elif defined(__WIN__) || defined(__NT__)
 | 
|---|
| 869 |     /*
 | 
|---|
| 870 |      * Convert the address from the header.
 | 
|---|
| 871 |      */
 | 
|---|
| 872 |     *pMainEPAddress = pModNative->pNtHdrs->OptionalHeader.AddressOfEntryPoint
 | 
|---|
| 873 |         ? BaseAddress + pModNative->pNtHdrs->OptionalHeader.AddressOfEntryPoint
 | 
|---|
| 874 |         : NIL_KLDRADDR;
 | 
|---|
| 875 |     return 0;
 | 
|---|
| 876 | 
 | 
|---|
| 877 | #elif defined(__DARWIN__)
 | 
|---|
| 878 |     /** @todo Implement me on Darwin. */
 | 
|---|
| 879 |     (void)pModNative;
 | 
|---|
| 880 |     return KLDR_ERR_TODO;
 | 
|---|
| 881 | 
 | 
|---|
| 882 | #else
 | 
|---|
| 883 | # error "Port me"
 | 
|---|
| 884 | #endif
 | 
|---|
| 885 | }
 | 
|---|
| 886 | 
 | 
|---|
| 887 | 
 | 
|---|
| 888 | /** @copydoc kLdrModEnumDbgInfo */
 | 
|---|
| 889 | static int kldrModNativeEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser)
 | 
|---|
| 890 | {
 | 
|---|
| 891 |     PKLDRMODNATIVE                  pModNative = (PKLDRMODNATIVE)pMod->pvData;
 | 
|---|
| 892 | #ifdef __OS2__
 | 
|---|
| 893 | 
 | 
|---|
| 894 |     /** @todo implement me on OS/2. */
 | 
|---|
| 895 |     (void)pModNative;
 | 
|---|
| 896 |     return ERROR_NOT_SUPPORTED;
 | 
|---|
| 897 | 
 | 
|---|
| 898 | #elif defined(__WIN__) || defined(__NT__)
 | 
|---|
| 899 |     const IMAGE_DEBUG_DIRECTORY    *pDbgDir;
 | 
|---|
| 900 |     uint32_t                        iDbgInfo;
 | 
|---|
| 901 |     uint32_t                        cb;
 | 
|---|
| 902 |     int                             rc;
 | 
|---|
| 903 | 
 | 
|---|
| 904 |     /*
 | 
|---|
| 905 |      * Check that there is a debug directory first.
 | 
|---|
| 906 |      */
 | 
|---|
| 907 |     cb = pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
 | 
|---|
| 908 |     if (    cb < sizeof(IMAGE_DEBUG_DIRECTORY) /* screw borland linkers */
 | 
|---|
| 909 |         ||  !pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress)
 | 
|---|
| 910 |         return 0;
 | 
|---|
| 911 | 
 | 
|---|
| 912 |     /*
 | 
|---|
| 913 |      * Enumerate the debug directory.
 | 
|---|
| 914 |      */
 | 
|---|
| 915 |     pDbgDir = KLDRMODNATIVE_RVA2TYPE(pModNative->hmod,
 | 
|---|
| 916 |                                      pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
 | 
|---|
| 917 |                                      const IMAGE_DEBUG_DIRECTORY *);
 | 
|---|
| 918 |     for (iDbgInfo = 0;; iDbgInfo++, pDbgDir++, cb -= sizeof(IMAGE_DEBUG_DIRECTORY))
 | 
|---|
| 919 |     {
 | 
|---|
| 920 |         KLDRDBGINFOTYPE     enmDbgInfoType;
 | 
|---|
| 921 | 
 | 
|---|
| 922 |         /* convert the type. */
 | 
|---|
| 923 |         switch (pDbgDir->Type)
 | 
|---|
| 924 |         {
 | 
|---|
| 925 |             case IMAGE_DEBUG_TYPE_UNKNOWN:
 | 
|---|
| 926 |             case IMAGE_DEBUG_TYPE_FPO:
 | 
|---|
| 927 |             case IMAGE_DEBUG_TYPE_COFF: /*stabs dialect??*/
 | 
|---|
| 928 |             case IMAGE_DEBUG_TYPE_MISC:
 | 
|---|
| 929 |             case IMAGE_DEBUG_TYPE_EXCEPTION:
 | 
|---|
| 930 |             case IMAGE_DEBUG_TYPE_FIXUP:
 | 
|---|
| 931 |             case IMAGE_DEBUG_TYPE_BORLAND:
 | 
|---|
| 932 |             default:
 | 
|---|
| 933 |                 enmDbgInfoType = KLDRDBGINFOTYPE_UNKNOWN;
 | 
|---|
| 934 |                 break;
 | 
|---|
| 935 |             case IMAGE_DEBUG_TYPE_CODEVIEW:
 | 
|---|
| 936 |                 enmDbgInfoType = KLDRDBGINFOTYPE_CODEVIEW;
 | 
|---|
| 937 |                 break;
 | 
|---|
| 938 |         }
 | 
|---|
| 939 | 
 | 
|---|
| 940 |         rc = pfnCallback(pMod, iDbgInfo,
 | 
|---|
| 941 |                          enmDbgInfoType, pDbgDir->MajorVersion, pDbgDir->MinorVersion,
 | 
|---|
| 942 |                          pDbgDir->PointerToRawData ? pDbgDir->PointerToRawData : -1,
 | 
|---|
| 943 |                          pDbgDir->AddressOfRawData ? pDbgDir->AddressOfRawData : NIL_KLDRADDR,
 | 
|---|
| 944 |                          pDbgDir->SizeOfData,
 | 
|---|
| 945 |                          NULL,
 | 
|---|
| 946 |                          pvUser);
 | 
|---|
| 947 |         if (rc)
 | 
|---|
| 948 |             break;
 | 
|---|
| 949 | 
 | 
|---|
| 950 |         /* next */
 | 
|---|
| 951 |         if (cb <= sizeof(IMAGE_DEBUG_DIRECTORY))
 | 
|---|
| 952 |             break;
 | 
|---|
| 953 |     }
 | 
|---|
| 954 | 
 | 
|---|
| 955 |     return rc;
 | 
|---|
| 956 | 
 | 
|---|
| 957 | #elif defined(__DARWIN__)
 | 
|---|
| 958 |     /** @todo Implement me on Darwin. */
 | 
|---|
| 959 |     (void)pModNative;
 | 
|---|
| 960 |     return KLDR_ERR_TODO;
 | 
|---|
| 961 | 
 | 
|---|
| 962 | #else
 | 
|---|
| 963 | # error "Port me"
 | 
|---|
| 964 | #endif
 | 
|---|
| 965 | }
 | 
|---|
| 966 | 
 | 
|---|
| 967 | 
 | 
|---|
| 968 | /** @copydoc kLdrModHasDbgInfo */
 | 
|---|
| 969 | static int kldrModNativeHasDbgInfo(PKLDRMOD pMod, const void *pvBits)
 | 
|---|
| 970 | {
 | 
|---|
| 971 |     PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
 | 
|---|
| 972 | #ifdef __OS2__
 | 
|---|
| 973 | 
 | 
|---|
| 974 |     /** @todo implement me on OS/2. */
 | 
|---|
| 975 |     (void)pModNative;
 | 
|---|
| 976 |     return KLDR_ERR_NO_DEBUG_INFO;
 | 
|---|
| 977 | 
 | 
|---|
| 978 | #elif defined(__WIN__) || defined(__NT__)
 | 
|---|
| 979 |     /*
 | 
|---|
| 980 |      * Base this entirely on the presence of a debug directory.
 | 
|---|
| 981 |      */
 | 
|---|
| 982 |     if (    pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size
 | 
|---|
| 983 |             < sizeof(IMAGE_DEBUG_DIRECTORY) /* screw borland linkers */
 | 
|---|
| 984 |         ||  !pModNative->pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress)
 | 
|---|
| 985 |         return KLDR_ERR_NO_DEBUG_INFO;
 | 
|---|
| 986 |     return 0;
 | 
|---|
| 987 | 
 | 
|---|
| 988 | #elif defined(__DARWIN__)
 | 
|---|
| 989 |     /** @todo Implement me on Darwin. */
 | 
|---|
| 990 |     (void)pModNative;
 | 
|---|
| 991 |     return KLDR_ERR_NO_DEBUG_INFO;
 | 
|---|
| 992 | 
 | 
|---|
| 993 | #else
 | 
|---|
| 994 | # error "Port me"
 | 
|---|
| 995 | #endif
 | 
|---|
| 996 | }
 | 
|---|
| 997 | 
 | 
|---|
| 998 | 
 | 
|---|
| 999 | /** @copydoc kLdrModMap */
 | 
|---|
| 1000 | static int kldrModNativeMap(PKLDRMOD pMod)
 | 
|---|
| 1001 | {
 | 
|---|
| 1002 |     return 0;
 | 
|---|
| 1003 | }
 | 
|---|
| 1004 | 
 | 
|---|
| 1005 | 
 | 
|---|
| 1006 | /** @copydoc kLdrModUnmap */
 | 
|---|
| 1007 | static int kldrModNativeUnmap(PKLDRMOD pMod)
 | 
|---|
| 1008 | {
 | 
|---|
| 1009 |     return 0;
 | 
|---|
| 1010 | }
 | 
|---|
| 1011 | 
 | 
|---|
| 1012 | 
 | 
|---|
| 1013 | /** @copydoc kLdrModAllocTLS */
 | 
|---|
| 1014 | static int kldrModNativeAllocTLS(PKLDRMOD pMod)
 | 
|---|
| 1015 | {
 | 
|---|
| 1016 |     return 0;
 | 
|---|
| 1017 | }
 | 
|---|
| 1018 | 
 | 
|---|
| 1019 | 
 | 
|---|
| 1020 | /** @copydoc kLdrModFreeTLS */
 | 
|---|
| 1021 | static void kldrModNativeFreeTLS(PKLDRMOD pMod)
 | 
|---|
| 1022 | {
 | 
|---|
| 1023 | }
 | 
|---|
| 1024 | 
 | 
|---|
| 1025 | 
 | 
|---|
| 1026 | /** @copydoc kLdrModReload */
 | 
|---|
| 1027 | static int kldrModNativeReload(PKLDRMOD pMod)
 | 
|---|
| 1028 | {
 | 
|---|
| 1029 |     return 0;
 | 
|---|
| 1030 | }
 | 
|---|
| 1031 | 
 | 
|---|
| 1032 | 
 | 
|---|
| 1033 | /** @copydoc kLdrModFixupMapping */
 | 
|---|
| 1034 | static int kldrModNativeFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
 | 
|---|
| 1035 | {
 | 
|---|
| 1036 |     return 0;
 | 
|---|
| 1037 | }
 | 
|---|
| 1038 | 
 | 
|---|
| 1039 | 
 | 
|---|
| 1040 | /** @copydoc kLdrModCallInit */
 | 
|---|
| 1041 | static int kldrModNativeCallInit(PKLDRMOD pMod, uintptr_t uHandle)
 | 
|---|
| 1042 | {
 | 
|---|
| 1043 |     return 0;
 | 
|---|
| 1044 | }
 | 
|---|
| 1045 | 
 | 
|---|
| 1046 | 
 | 
|---|
| 1047 | /** @copydoc kLdrModCallTerm */
 | 
|---|
| 1048 | static int kldrModNativeCallTerm(PKLDRMOD pMod, uintptr_t uHandle)
 | 
|---|
| 1049 | {
 | 
|---|
| 1050 |     return 0;
 | 
|---|
| 1051 | }
 | 
|---|
| 1052 | 
 | 
|---|
| 1053 | 
 | 
|---|
| 1054 | /** @copydoc kLdrModCallThread */
 | 
|---|
| 1055 | static int kldrModNativeCallThread(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching)
 | 
|---|
| 1056 | {
 | 
|---|
| 1057 |     return 0;
 | 
|---|
| 1058 | }
 | 
|---|
| 1059 | 
 | 
|---|
| 1060 | 
 | 
|---|
| 1061 | /** @copydoc kLdrModSize */
 | 
|---|
| 1062 | static KLDRADDR kldrModNativeSize(PKLDRMOD pMod)
 | 
|---|
| 1063 | {
 | 
|---|
| 1064 | #ifdef __OS2__
 | 
|---|
| 1065 |     return 0; /* don't bother */
 | 
|---|
| 1066 | 
 | 
|---|
| 1067 | #elif defined(__WIN__) || defined(__NT__)
 | 
|---|
| 1068 |     /* just because we can. */
 | 
|---|
| 1069 |     PKLDRMODNATIVE pModNative = (PKLDRMODNATIVE)pMod->pvData;
 | 
|---|
| 1070 |     return pModNative->pNtHdrs->OptionalHeader.SizeOfImage;
 | 
|---|
| 1071 | 
 | 
|---|
| 1072 | #elif defined(__DARWIN__)
 | 
|---|
| 1073 |     /** @todo Implement me on Darwin. */
 | 
|---|
| 1074 |     return 0;
 | 
|---|
| 1075 | 
 | 
|---|
| 1076 | #else
 | 
|---|
| 1077 | # error "Port me"
 | 
|---|
| 1078 | #endif
 | 
|---|
| 1079 | }
 | 
|---|
| 1080 | 
 | 
|---|
| 1081 | 
 | 
|---|
| 1082 | /** @copydoc kLdrModGetBits */
 | 
|---|
| 1083 | static int kldrModNativeGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
 | 
|---|
| 1084 | {
 | 
|---|
| 1085 | #ifdef __OS2__
 | 
|---|
| 1086 |     return ERROR_NOT_SUPPORTED; /* don't bother */
 | 
|---|
| 1087 | 
 | 
|---|
| 1088 | #elif defined(__WIN__) || defined(__NT__)
 | 
|---|
| 1089 |     return ERROR_NOT_SUPPORTED; /* don't bother even if we could implement this. */
 | 
|---|
| 1090 | 
 | 
|---|
| 1091 | #elif defined(__DARWIN__)
 | 
|---|
| 1092 |     return KLDR_ERR_TODO; /* don't bother. */
 | 
|---|
| 1093 | 
 | 
|---|
| 1094 | #else
 | 
|---|
| 1095 | # error "Port me"
 | 
|---|
| 1096 | #endif
 | 
|---|
| 1097 | }
 | 
|---|
| 1098 | 
 | 
|---|
| 1099 | 
 | 
|---|
| 1100 | /** @copydoc kLdrModRelocateBits */
 | 
|---|
| 1101 | static int kldrModNativeRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
 | 
|---|
| 1102 |                                      PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
 | 
|---|
| 1103 | {
 | 
|---|
| 1104 | #ifdef __OS2__
 | 
|---|
| 1105 |     return ERROR_NOT_SUPPORTED; /* don't bother */
 | 
|---|
| 1106 | 
 | 
|---|
| 1107 | #elif defined(__WIN__) || defined(__NT__)
 | 
|---|
| 1108 |     return ERROR_NOT_SUPPORTED; /* don't bother even if we could implement this. */
 | 
|---|
| 1109 | 
 | 
|---|
| 1110 | #elif defined(__DARWIN__)
 | 
|---|
| 1111 |     return KLDR_ERR_TODO; /* don't bother. */
 | 
|---|
| 1112 | 
 | 
|---|
| 1113 | #else
 | 
|---|
| 1114 | # error "Port me"
 | 
|---|
| 1115 | #endif
 | 
|---|
| 1116 | }
 | 
|---|
| 1117 | 
 | 
|---|
| 1118 | 
 | 
|---|
| 1119 | /**
 | 
|---|
| 1120 |  * The native module interpreter method table.
 | 
|---|
| 1121 |  */
 | 
|---|
| 1122 | KLDRMODOPS g_kLdrModNativeOps =
 | 
|---|
| 1123 | {
 | 
|---|
| 1124 |     "Native",
 | 
|---|
| 1125 |     NULL,
 | 
|---|
| 1126 |     kldrModNativeCreate,
 | 
|---|
| 1127 |     kldrModNativeDestroy,
 | 
|---|
| 1128 |     kldrModNativeQuerySymbol,
 | 
|---|
| 1129 |     kldrModNativeEnumSymbols,
 | 
|---|
| 1130 |     kldrModNativeGetImport,
 | 
|---|
| 1131 |     kldrModNativeNumberOfImports,
 | 
|---|
| 1132 |     NULL /* can execute one is optional */,
 | 
|---|
| 1133 |     kldrModNativeGetStackInfo,
 | 
|---|
| 1134 |     kldrModNativeQueryMainEntrypoint,
 | 
|---|
| 1135 |     NULL /* fixme */,
 | 
|---|
| 1136 |     NULL /* fixme */,
 | 
|---|
| 1137 |     kldrModNativeEnumDbgInfo,
 | 
|---|
| 1138 |     kldrModNativeHasDbgInfo,
 | 
|---|
| 1139 |     kldrModNativeMap,
 | 
|---|
| 1140 |     kldrModNativeUnmap,
 | 
|---|
| 1141 |     kldrModNativeAllocTLS,
 | 
|---|
| 1142 |     kldrModNativeFreeTLS,
 | 
|---|
| 1143 |     kldrModNativeReload,
 | 
|---|
| 1144 |     kldrModNativeFixupMapping,
 | 
|---|
| 1145 |     kldrModNativeCallInit,
 | 
|---|
| 1146 |     kldrModNativeCallTerm,
 | 
|---|
| 1147 |     kldrModNativeCallThread,
 | 
|---|
| 1148 |     kldrModNativeSize,
 | 
|---|
| 1149 |     kldrModNativeGetBits,
 | 
|---|
| 1150 |     kldrModNativeRelocateBits,
 | 
|---|
| 1151 |     NULL /* fixme */,
 | 
|---|
| 1152 |     42 /* the end */
 | 
|---|
| 1153 | };
 | 
|---|
| 1154 | 
 | 
|---|