Changeset 25


Ignore:
Timestamp:
Feb 19, 2009, 1:56:15 AM (16 years ago)
Author:
bird
Message:

A blind shot at FAT Mach-O images.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/k/kErrors.h

    r21 r25  
    196196/** Not implemented yet. */
    197197#define KLDR_ERR_TODO                                   (KLDR_ERR_BASE + 34)
     198/** No image matching the requested CPU. */
     199#define KLDR_ERR_CPU_ARCH_MISMATCH                      (KLDR_ERR_BASE + 35)
     200/** Invalid FAT image header. */
     201#define KLDR_ERR_FAT_INVALID                            (KLDR_ERR_BASE + 36)
     202/** Unsupported CPU subtype found in a FAT entry. */
     203#define KLDR_ERR_FAT_UNSUPPORTED_CPU_SUBTYPE            (KLDR_ERR_BASE + 37)
    198204/** @} */
    199205
     
    202208 */
    203209/** The base of the kLdrModPE specific status codes. */
    204 #define KLDR_ERR_PE_BASE                                (KLDR_ERR_BASE + 35)
     210#define KLDR_ERR_PE_BASE                                (KLDR_ERR_BASE + 38)
    205211/** The machine isn't supported by the interpreter. */
    206212#define KLDR_ERR_PE_UNSUPPORTED_MACHINE                 (KLDR_ERR_PE_BASE + 0)
  • trunk/include/k/kLdr.h

    r19 r25  
    582582
    583583
    584 int     kLdrModOpen(const char *pszFilename, PPKLDRMOD ppMod);
    585 int     kLdrModOpenFromRdr(PKRDR pRdr, PPKLDRMOD ppMod);
     584int     kLdrModOpen(const char *pszFilename, KU32 fFlags, KCPUARCH enmCpuArch, PPKLDRMOD ppMod);
     585int     kLdrModOpenFromRdr(PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, PPKLDRMOD ppMod);
    586586int     kLdrModOpenNative(const char *pszFilename, PPKLDRMOD ppMod);
    587587int     kLdrModOpenNativeByHandle(KUPTR uHandle, PPKLDRMOD ppMod);
     
    647647     * @param   pOps            Pointer to the registered method table.
    648648     * @param   pRdr            The file provider instance to use.
     649     * @param   fFlags          Flags, MBZ.
     650     * @param   enmCpuArch      The desired CPU architecture. KCPUARCH_UNKNOWN means
     651     *                          anything goes, but with a preference for the current
     652     *                          host architecture.
    649653     * @param   offNewHdr       The offset of the new header in MZ files. -1 if not found.
    650654     * @param   ppMod           Where to store the module instance pointer.
    651655     */
    652     int (* pfnCreate)(PCKLDRMODOPS pOps, PKRDR pRdr, KLDRFOFF offNewHdr, PPKLDRMOD ppMod);
     656    int (* pfnCreate)(PCKLDRMODOPS pOps, PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, KLDRFOFF offNewHdr, PPKLDRMOD ppMod);
    653657    /**
    654658     * Destroys an loader module instance.
  • trunk/kLdr/kLdrMod.c

    r2 r25  
    110110 *          On failure, a non-zero OS specific error code is returned.
    111111 * @param   pszFilename     The filename to open.
     112 * @param   fFlags          Flags, MBZ.
     113 * @param   enmCpuArch      The desired CPU architecture. KCPUARCH_UNKNOWN means
     114 *                          anything goes, but with a preference for the current
     115 *                          host architecture.
    112116 * @param   ppMod           Where to store the module handle.
    113117 */
    114 int kLdrModOpen(const char *pszFilename, PPKLDRMOD ppMod)
     118int kLdrModOpen(const char *pszFilename, KU32 fFlags, KCPUARCH enmCpuArch, PPKLDRMOD ppMod)
    115119{
    116120    /*
     
    121125    if (!rc)
    122126    {
    123         rc = kLdrModOpenFromRdr(pRdr, ppMod);
     127        rc = kLdrModOpenFromRdr(pRdr, fFlags, enmCpuArch, ppMod);
    124128        if (!rc)
    125129            return 0;
     
    127131    }
    128132    return rc;
     133}
     134
     135
     136/**
     137 * Select image from the FAT according to the enmCpuArch and fFlag.
     138 *
     139 * @returns 0 on success and *poffHdr set to the image header.
     140 *          On failure, a non-zero error code is returned.
     141 *
     142 * @param   pRdr            The file provider instance to use.
     143 * @param   fFlags          Flags, MBZ.
     144 * @param   enmCpuArch      The desired CPU architecture. KCPUARCH_UNKNOWN means
     145 *                          anything goes, but with a preference for the current
     146 *                          host architecture.
     147 * @param   u32Magic        The FAT magic.
     148 * @param   poffHdr         Where to store the offset of the selected image.
     149 */
     150static int kldrModOpenFromRdrSelectImageFromFAT(PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, KU32 u32Magic, KLDRFOFF *poffHdr)
     151{
     152    int         rcRet = KLDR_ERR_CPU_ARCH_MISMATCH;
     153    KLDRFOFF    off = *poffHdr + sizeof(KU32);
     154    KLDRFOFF    offEndFAT;
     155    KBOOL       fCpuArchWhatever;
     156    KU32        cArchs;
     157    KU32        iArch;
     158    int         rc;
     159
     160    /* Read fat_header_t::nfat_arch. */
     161    rc = kRdrRead(pRdr, &cArchs, sizeof(cArchs), off);
     162    if (rc)
     163        return rc;
     164    off += sizeof(KU32);
     165    if (u32Magic == IMAGE_FAT_SIGNATURE_OE)
     166        cArchs = K_E2E_U32(cArchs);
     167    if (cArchs == 0)
     168        return KLDR_ERR_FAT_INVALID;
     169
     170    /* Deal with KCPUARCH_UNKNOWN. */
     171    fCpuArchWhatever = enmCpuArch == KCPUARCH_UNKNOWN;
     172    if (fCpuArchWhatever)
     173    {
     174        KCPU enmCpuIgnored;
     175        kCpuGetArchAndCpu(&enmCpuArch, &enmCpuIgnored);
     176    }
     177
     178    /*
     179     * Iterate the architecture list.
     180     */
     181    offEndFAT = off + cArchs * sizeof(fat_arch_t);
     182    for (iArch = 0; iArch < cArchs; iArch++)
     183    {
     184        KCPUARCH    enmEntryArch;
     185        fat_arch_t  Arch;
     186        rc = kRdrRead(pRdr, &Arch, sizeof(Arch), off);
     187        if (rc)
     188            return rc;
     189        off += sizeof(Arch);
     190
     191        if (u32Magic == IMAGE_FAT_SIGNATURE_OE)
     192        {
     193            Arch.cputype    = K_E2E_U32(Arch.cputype);
     194            Arch.cpusubtype = K_E2E_U32(Arch.cpusubtype);
     195            Arch.offset     = K_E2E_U32(Arch.offset);
     196            Arch.size       = K_E2E_U32(Arch.size);
     197            Arch.align      = K_E2E_U32(Arch.align);
     198        }
     199
     200        /* Simple validation. */
     201        if (    (KLDRFOFF)Arch.offset < offEndFAT
     202            ||  (KLDRFOFF)Arch.offset >= kRdrSize(pRdr)
     203            ||  Arch.align >= 32
     204            ||  Arch.offset & ((KU32_C(1) << Arch.align) - KU32_C(1)))
     205            return KLDR_ERR_FAT_INVALID;
     206
     207        /* deal with the cputype and cpusubtype. (See similar code in kLdrModMachO.c.) */
     208        switch (Arch.cputype)
     209        {
     210            case CPU_TYPE_X86:
     211                enmEntryArch = KCPUARCH_X86_32;
     212                switch (Arch.cpusubtype)
     213                {
     214                    case CPU_SUBTYPE_I386_ALL:
     215                    /*case CPU_SUBTYPE_386: ^^ ;*/
     216                    case CPU_SUBTYPE_486:
     217                    case CPU_SUBTYPE_486SX:
     218                    /*case CPU_SUBTYPE_586: vv */
     219                    case CPU_SUBTYPE_PENT:
     220                    case CPU_SUBTYPE_PENTPRO:
     221                    case CPU_SUBTYPE_PENTII_M3:
     222                    case CPU_SUBTYPE_PENTII_M5:
     223                    case CPU_SUBTYPE_CELERON:
     224                    case CPU_SUBTYPE_CELERON_MOBILE:
     225                    case CPU_SUBTYPE_PENTIUM_3:
     226                    case CPU_SUBTYPE_PENTIUM_3_M:
     227                    case CPU_SUBTYPE_PENTIUM_3_XEON:
     228                    case CPU_SUBTYPE_PENTIUM_M:
     229                    case CPU_SUBTYPE_PENTIUM_4:
     230                    case CPU_SUBTYPE_PENTIUM_4_M:
     231                    case CPU_SUBTYPE_XEON:
     232                    case CPU_SUBTYPE_XEON_MP:
     233                        break;
     234                    default:
     235                        return KLDR_ERR_FAT_UNSUPPORTED_CPU_SUBTYPE;
     236                }
     237                break;
     238
     239            case CPU_TYPE_X86_64:
     240                enmEntryArch = KCPUARCH_AMD64;
     241                switch (Arch.cpusubtype & ~CPU_SUBTYPE_MASK)
     242                {
     243                    case CPU_SUBTYPE_X86_64_ALL:
     244                        break;
     245                    default:
     246                        return KLDR_ERR_FAT_UNSUPPORTED_CPU_SUBTYPE;
     247                }
     248                break;
     249
     250            default:
     251                enmCpuArch = KCPUARCH_UNKNOWN;
     252                break;
     253        }
     254
     255        /*
     256         * Finally the actual image selecting.
     257         *
     258         * Return immediately on a perfect match. Otherwise continue looking,
     259         * if we're none too picky, remember the first image in case we don't
     260         * get lucky.
     261         */
     262        if (enmCpuArch == KCPUARCH_X86_32)
     263        {
     264            *poffHdr = Arch.offset;
     265            return 0;
     266        }
     267
     268        if (    fCpuArchWhatever
     269            &&  rcRet == KLDR_ERR_CPU_ARCH_MISMATCH)
     270        {
     271            *poffHdr = Arch.offset;
     272            rcRet = 0;
     273        }
     274    }
     275
     276    return rcRet;
    129277}
    130278
     
    139287 *                          module and the caller must not ever touch it again.
    140288 *                          (The instance is not closed on failure, the call has to do that.)
     289 * @param   fFlags          Flags, MBZ.
     290 * @param   enmCpuArch      The desired CPU architecture. KCPUARCH_UNKNOWN means
     291 *                          anything goes, but with a preference for the current
     292 *                          host architecture.
    141293 * @param   ppMod           Where to store the module handle.
    142294 */
    143 int kLdrModOpenFromRdr(PKRDR pRdr, PPKLDRMOD ppMod)
     295int kLdrModOpenFromRdr(PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, PPKLDRMOD ppMod)
    144296{
    145297    union
     
    153305    int         rc;
    154306
    155     /*
    156      * Try figure out what kind of image this is.
    157      * Always read the 'new header' if we encounter MZ.
    158      */
    159     rc = kRdrRead(pRdr, &u, sizeof(u), 0);
    160     if (rc)
    161         return rc;
    162     if (    u.u16 == IMAGE_DOS_SIGNATURE
    163         &&  kRdrSize(pRdr) > sizeof(IMAGE_DOS_HEADER))
     307    for (;;)
    164308    {
    165         rc = kRdrRead(pRdr, &u, sizeof(u.u32), K_OFFSETOF(IMAGE_DOS_HEADER, e_lfanew));
     309        /*
     310         * Try figure out what kind of image this is.
     311         * Always read the 'new header' if we encounter MZ.
     312         */
     313        rc = kRdrRead(pRdr, &u, sizeof(u), offHdr);
    166314        if (rc)
    167315            return rc;
    168         if ((KLDRFOFF)u.u32 < kRdrSize(pRdr))
     316        if (    u.u16 == IMAGE_DOS_SIGNATURE
     317            &&  kRdrSize(pRdr) > sizeof(IMAGE_DOS_HEADER))
    169318        {
    170             offHdr = u.u32;
    171             rc = kRdrRead(pRdr, &u, sizeof(u.u32), offHdr);
     319            rc = kRdrRead(pRdr, &u, sizeof(u.u32), K_OFFSETOF(IMAGE_DOS_HEADER, e_lfanew));
     320            if (rc)
     321                return rc;
     322            if ((KLDRFOFF)u.u32 < kRdrSize(pRdr))
     323            {
     324                offHdr = u.u32;
     325                rc = kRdrRead(pRdr, &u, sizeof(u.u32), offHdr);
     326                if (rc)
     327                    return rc;
     328            }
     329            else
     330                u.u16 = IMAGE_DOS_SIGNATURE;
     331        }
     332
     333        /*
     334         * Handle FAT images too here (one only).
     335         */
     336        if (    (   u.u32 == IMAGE_FAT_SIGNATURE
     337                 || u.u32 == IMAGE_FAT_SIGNATURE_OE)
     338            &&  offHdr == 0)
     339        {
     340            rc = kldrModOpenFromRdrSelectImageFromFAT(pRdr, fFlags, enmCpuArch, u.u32, &offHdr);
    172341            if (rc)
    173342                return rc;
    174343        }
    175         else
    176             u.u16 = IMAGE_DOS_SIGNATURE;
    177344    }
     345
    178346
    179347    /*
     
    185353        rc = KLDR_ERR_NE_NOT_SUPPORTED;
    186354    else if (u.u16 == IMAGE_LX_SIGNATURE)
    187         rc = g_kLdrModLXOps.pfnCreate(&g_kLdrModLXOps, pRdr, offHdr, ppMod);
     355        rc = g_kLdrModLXOps.pfnCreate(&g_kLdrModLXOps, pRdr, fFlags, enmCpuArch, offHdr, ppMod);
    188356    else if (u.u16 == IMAGE_LE_SIGNATURE)
    189357        rc = KLDR_ERR_LE_NOT_SUPPORTED;
    190358    else if (u.u32 == IMAGE_NT_SIGNATURE)
    191         rc = g_kLdrModPEOps.pfnCreate(&g_kLdrModPEOps, pRdr, offHdr, ppMod);
     359        rc = g_kLdrModPEOps.pfnCreate(&g_kLdrModPEOps, pRdr, fFlags, enmCpuArch, offHdr, ppMod);
    192360    else if (   u.u32 == IMAGE_MACHO32_SIGNATURE
    193361             || u.u32 == IMAGE_MACHO32_SIGNATURE_OE
    194362             || u.u32 == IMAGE_MACHO64_SIGNATURE
    195363             || u.u32 == IMAGE_MACHO64_SIGNATURE_OE)
    196         rc = g_kLdrModMachOOps.pfnCreate(&g_kLdrModMachOOps, pRdr, offHdr, ppMod);
     364        rc = g_kLdrModMachOOps.pfnCreate(&g_kLdrModMachOOps, pRdr, fFlags, enmCpuArch, offHdr, ppMod);
    197365    else if (u.u32 == IMAGE_ELF_SIGNATURE)
    198366        rc = KLDR_ERR_ELF_NOT_SUPPORTED;
    199     else if (   u.u32 == IMAGE_FAT_SIGNATURE
    200              || u.u32 == IMAGE_FAT_SIGNATURE_OE)
    201         rc = KLDR_ERR_FAT_NOT_SUPPORTED;
    202367    else
    203368        rc = KLDR_ERR_UNKNOWN_FORMAT;
     
    211376        for (pOps = g_pModInterpreterHead; pOps; pOps = pOps->pNext)
    212377        {
    213             int rc2 = pOps->pfnCreate(pOps, pRdr, offHdr, ppMod);
     378            int rc2 = pOps->pfnCreate(pOps, pRdr, fFlags, enmCpuArch, offHdr, ppMod);
    214379            if (!rc2)
    215380                return rc;
  • trunk/kLdr/kLdrModLX.c

    r24 r25  
    147147 * @param   pOps            Pointer to the registered method table.
    148148 * @param   pRdr            The file provider instance to use.
     149 * @param   fFlags          Flags, MBZ.
     150 * @param   enmCpuArch      The desired CPU architecture. KCPUARCH_UNKNOWN means
     151 *                          anything goes, but with a preference for the current
     152 *                          host architecture.
    149153 * @param   offNewHdr       The offset of the new header in MZ files. -1 if not found.
    150154 * @param   ppMod           Where to store the module instance pointer.
    151155 */
    152 static int kldrModLXCreate(PCKLDRMODOPS pOps, PKRDR pRdr, KLDRFOFF offNewHdr, PPKLDRMOD ppMod)
     156static int kldrModLXCreate(PCKLDRMODOPS pOps, PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, KLDRFOFF offNewHdr, PPKLDRMOD ppMod)
    153157{
    154158    PKLDRMODLX pModLX;
     
    161165    if (!rc)
    162166    {
    163         pModLX->pMod->pOps = pOps;
    164         pModLX->pMod->u32Magic = KLDRMOD_MAGIC;
    165         *ppMod = pModLX->pMod;
    166         return 0;
     167        /*
     168         * Match up against the requested CPU architecture.
     169         */
     170        if (    enmCpuArch == KCPUARCH_UNKNOWN
     171            ||  pModLX->pMod->enmArch == enmCpuArch)
     172        {
     173            pModLX->pMod->pOps = pOps;
     174            pModLX->pMod->u32Magic = KLDRMOD_MAGIC;
     175            *ppMod = pModLX->pMod;
     176            return 0;
     177        }
     178        rc = KLDR_ERR_CPU_ARCH_MISMATCH;
    167179    }
    168180    kHlpFree(pModLX);
  • trunk/kLdr/kLdrModMachO.c

    r23 r25  
    127127    void                   *pvMapping;
    128128
     129    /** The offset of the image. (FAT fun.) */
     130    KLDRFOFF                offImage;
    129131    /** The link address. */
    130132    KLDRADDR                LinkAddress;
     
    184186                                    PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
    185187
    186 static int  kldrModMachODoCreate(PKRDR pRdr, PKLDRMODMACHO *ppMod);
    187 static int  kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_header_32_t *pHdr, PKRDR pRdr,
     188static int  kldrModMachODoCreate(PKRDR pRdr, KLDRFOFF offImage, PKLDRMODMACHO *ppMod);
     189static int  kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_header_32_t *pHdr, PKRDR pRdr, KLDRFOFF offImage,
    188190                                             KU32 *pcSegments, KU32 *pcSections, KU32 *pcbStringPool);
    189191static int  kldrModMachOParseLoadCommands(PKLDRMODMACHO pModMachO, char *pbStringPool, KU32 cbStringPool);
     
    228230 * @param   pOps            Pointer to the registered method table.
    229231 * @param   pRdr            The file provider instance to use.
     232 * @param   fFlags          Flags, MBZ.
     233 * @param   enmCpuArch      The desired CPU architecture. KCPUARCH_UNKNOWN means
     234 *                          anything goes, but with a preference for the current
     235 *                          host architecture.
    230236 * @param   offNewHdr       The offset of the new header in MZ files. -1 if not found.
    231237 * @param   ppMod           Where to store the module instance pointer.
    232238 */
    233 static int kldrModMachOCreate(PCKLDRMODOPS pOps, PKRDR pRdr, KLDRFOFF offNewHdr, PPKLDRMOD ppMod)
     239static int kldrModMachOCreate(PCKLDRMODOPS pOps, PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, KLDRFOFF offNewHdr, PPKLDRMOD ppMod)
    234240{
    235241    PKLDRMODMACHO pModMachO;
     
    239245     * Create the instance data and do a minimal header validation.
    240246     */
    241     rc = kldrModMachODoCreate(pRdr, &pModMachO);
     247    rc = kldrModMachODoCreate(pRdr, offNewHdr == -1 ? 0 : offNewHdr, &pModMachO);
    242248    if (!rc)
    243249    {
    244         pModMachO->pMod->pOps = pOps;
    245         pModMachO->pMod->u32Magic = KLDRMOD_MAGIC;
    246         *ppMod = pModMachO->pMod;
    247         return 0;
     250
     251        /*
     252         * Match up against the requested CPU architecture.
     253         */
     254        if (    enmCpuArch == KCPUARCH_UNKNOWN
     255            ||  pModMachO->pMod->enmArch == enmCpuArch)
     256        {
     257            pModMachO->pMod->pOps = pOps;
     258            pModMachO->pMod->u32Magic = KLDRMOD_MAGIC;
     259            *ppMod = pModMachO->pMod;
     260            return 0;
     261        }
     262        rc = KLDR_ERR_CPU_ARCH_MISMATCH;
    248263    }
    249264    if (pModMachO)
     
    260275 * simplify cleanup on failure.
    261276 */
    262 static int kldrModMachODoCreate(PKRDR pRdr, PKLDRMODMACHO *ppModMachO)
     277static int kldrModMachODoCreate(PKRDR pRdr, KLDRFOFF offImage, PKLDRMODMACHO *ppModMachO)
    263278{
    264279    union
     
    286301     * Read the Mach-O header.
    287302     */
    288     rc = kRdrRead(pRdr, &s, sizeof(s), 0);
     303    rc = kRdrRead(pRdr, &s, sizeof(s), offImage);
    289304    if (rc)
    290305        return rc;
     
    327342        return KERR_NO_MEMORY;
    328343    rc = kRdrRead(pRdr, pbLoadCommands, s.Hdr32.sizeofcmds,
    329                         s.Hdr32.magic == IMAGE_MACHO32_SIGNATURE
    330                      || s.Hdr32.magic == IMAGE_MACHO32_SIGNATURE_OE
    331                      ? sizeof(mach_header_32_t) : sizeof(mach_header_64_t));
     344                     s.Hdr32.magic == IMAGE_MACHO32_SIGNATURE
     345                  || s.Hdr32.magic == IMAGE_MACHO32_SIGNATURE_OE
     346                  ? sizeof(mach_header_32_t) + offImage
     347                  : sizeof(mach_header_64_t) + offImage);
    332348    if (!rc)
    333         rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, pRdr, &cSegments, &cSections, &cbStringPool);
     349        rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, pRdr, offImage, &cSegments, &cSections, &cbStringPool);
    334350    if (rc)
    335351    {
     
    354370    *ppModMachO = pModMachO;
    355371    pModMachO->pbLoadCommands = pbLoadCommands;
     372    pModMachO->offImage = offImage;
    356373
    357374    /* KLDRMOD */
     
    475492 * @param   pHdr            The header.
    476493 * @param   pRdr            The file reader.
     494 * @param   offImage        The image header (FAT fun).
    477495 * @param   pcSegments      Where to store the segment count.
    478496 * @param   pcSegments      Where to store the section count.
    479497 * @param   pcbStringPool   Where to store the string pool size.
    480498 */
    481 static int  kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_header_32_t *pHdr, PKRDR pRdr,
     499static int  kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_header_32_t *pHdr, PKRDR pRdr, KLDRFOFF offImage,
    482500                                             KU32 *pcSegments, KU32 *pcSections, KU32 *pcbStringPool)
    483501{
     
    492510        uuid_command_t       *pUuid;
    493511    } u;
    494     const KU64 cbFile = kRdrSize(pRdr);
     512    const KU64 cbFile = kRdrSize(pRdr) - offImage;
    495513    KU32 cSegments = 0;
    496514    KU32 cSections = 0;
     
    10621080                            pSectExtra->RVA = pSect->addr;
    10631081                            pSectExtra->LinkAddress = pSect->addr;
    1064                             pSectExtra->offFile = pSect->offset ? pSect->offset : -1;
     1082                            pSectExtra->offFile = pSect->offset ? pSect->offset + pModMachO->offImage : -1;
    10651083                            pSectExtra->cFixups = pSect->nreloc;
    10661084                            pSectExtra->paFixups = NULL;
    1067                             pSectExtra->offFixups = pSect->nreloc ? pSect->reloff : -1;
     1085                            pSectExtra->offFixups = pSect->nreloc ? pSect->reloff + pModMachO->offImage : -1;
    10681086                            pSectExtra->fFlags = pSect->flags;
    10691087                            pSectExtra->iSegment = pSegExtra - &pModMachO->aSegments[0];
     
    10991117                                pSeg->Alignment = (1 << pSect->align);
    11001118                                pSeg->LinkAddress = pSect->addr;
    1101                                 pSeg->offFile = pSect->offset ? pSect->offset : -1;
     1119                                pSeg->offFile = pSect->offset ? pSect->offset + pModMachO->offImage : -1;
    11021120                                pSeg->cbFile  = pSect->offset ? pSect->size : -1;
    11031121                                pSeg->RVA = pSect->addr - pModMachO->LinkAddress;
     
    11251143                                    &&  pSeg[-1].cbFile == pSeg[-1].cb)
    11261144                                {
    1127                                     int fOk = pSeg[-1].offFile + (pSect->addr - pSeg[-1].LinkAddress) == pSect->offset
     1145                                    int fOk = pSeg[-1].offFile + (pSect->addr - pSeg[-1].LinkAddress) == pSect->offset + pModMachO->offImage
    11281146                                           && pSect[-1].offset
    1129                                            && pSeg[-1].offFile + pSeg[-1].cbFile == pSect[-1].offset + pSect[-1].size;
     1147                                           && pSeg[-1].offFile + pSeg[-1].cbFile == pSect[-1].offset + pModMachO->offImage + pSect[-1].size;
    11301148                                    /* more checks? */
    11311149                                    if (fOk)
     
    11791197                            pSectExtra->RVA = pSect->addr;
    11801198                            pSectExtra->LinkAddress = pSect->addr;
    1181                             pSectExtra->offFile = pSect->offset ? pSect->offset : -1;
     1199                            pSectExtra->offFile = pSect->offset ? pSect->offset + pModMachO->offImage : -1;
    11821200                            pSectExtra->cFixups = pSect->nreloc;
    11831201                            pSectExtra->paFixups = NULL;
    1184                             pSectExtra->offFixups = pSect->nreloc ? pSect->reloff : -1;
     1202                            pSectExtra->offFixups = pSect->nreloc ? pSect->reloff + pModMachO->offImage : -1;
    11851203                            pSectExtra->fFlags = pSect->flags;
    11861204                            pSectExtra->iSegment = pSegExtra - &pModMachO->aSegments[0];
     
    12161234                                pSeg->Alignment = (1 << pSect->align);
    12171235                                pSeg->LinkAddress = pSect->addr;
    1218                                 pSeg->offFile = pSect->offset ? pSect->offset : -1;
     1236                                pSeg->offFile = pSect->offset ? pSect->offset + pModMachO->offImage : -1;
    12191237                                pSeg->cbFile  = pSect->offset ? pSect->size : -1;
    12201238                                pSeg->RVA = pSect->addr - pModMachO->LinkAddress;
     
    12421260                                    &&  pSeg[-1].cbFile == pSeg[-1].cb)
    12431261                                {
    1244                                     int fOk = pSeg[-1].offFile + (pSect->addr - pSeg[-1].LinkAddress) == pSect->offset
     1262                                    int fOk = pSeg[-1].offFile + (pSect->addr - pSeg[-1].LinkAddress) == pSect->offset + pModMachO->offImage
    12451263                                           && pSect[-1].offset
    1246                                            && pSeg[-1].offFile + pSeg[-1].cbFile == pSect[-1].offset + pSect[-1].size;
     1264                                           && pSeg[-1].offFile + pSeg[-1].cbFile == pSect[-1].offset + pModMachO->offImage + pSect[-1].size;
    12471265                                    /* more checks? */
    12481266                                    if (fOk)
     
    12771295                {
    12781296                    case MH_OBJECT:
    1279                         pModMachO->offSymbols = u.pSymTab->symoff;
     1297                        pModMachO->offSymbols = u.pSymTab->symoff + pModMachO->offImage;
    12801298                        pModMachO->cSymbols = u.pSymTab->nsyms;
    1281                         pModMachO->offStrings = u.pSymTab->stroff;
     1299                        pModMachO->offStrings = u.pSymTab->stroff + pModMachO->offImage;
    12821300                        pModMachO->cchStrings = u.pSymTab->strsize;
    12831301                        break;
  • trunk/kLdr/kLdrModPE.c

    r2 r25  
    136136 * @param   pOps            Pointer to the registered method table.
    137137 * @param   pRdr            The file provider instance to use.
     138 * @param   fFlags          Flags, MBZ.
     139 * @param   enmCpuArch      The desired CPU architecture. KCPUARCH_UNKNOWN means
     140 *                          anything goes, but with a preference for the current
     141 *                          host architecture.
    138142 * @param   offNewHdr       The offset of the new header in MZ files. -1 if not found.
    139143 * @param   ppMod           Where to store the module instance pointer.
    140144 */
    141 static int kldrModPECreate(PCKLDRMODOPS pOps, PKRDR pRdr, KLDRFOFF offNewHdr, PPKLDRMOD ppMod)
     145static int kldrModPECreate(PCKLDRMODOPS pOps, PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, KLDRFOFF offNewHdr, PPKLDRMOD ppMod)
    142146{
    143147    PKLDRMODPE pModPE;
     
    150154    if (!rc)
    151155    {
    152         pModPE->pMod->pOps = pOps;
    153         pModPE->pMod->u32Magic = KLDRMOD_MAGIC;
    154         *ppMod = pModPE->pMod;
    155         return 0;
     156        /*
     157         * Match up against the requested CPU architecture.
     158         */
     159        if (    enmCpuArch == KCPUARCH_UNKNOWN
     160            ||  pModPE->pMod->enmArch == enmCpuArch)
     161        {
     162            pModPE->pMod->pOps = pOps;
     163            pModPE->pMod->u32Magic = KLDRMOD_MAGIC;
     164            *ppMod = pModPE->pMod;
     165            return 0;
     166        }
     167        rc = KLDR_ERR_CPU_ARCH_MISMATCH;
    156168    }
    157169    kHlpFree(pModPE);
Note: See TracChangeset for help on using the changeset viewer.