Logo Search packages:      
Sourcecode: virtualbox-ose version File versions  Download package

static int kldrModOpenFromRdrSelectImageFromFAT ( PKRDR  pRdr,
KU32  fFlags,
KCPUARCH  enmCpuArch,
KU32  u32Magic,
KLDRFOFF poffHdr 
) [static]

Select image from the FAT according to the enmCpuArch and fFlag.

Returns:
0 on success and *poffHdr set to the image header. On failure, a non-zero error code is returned.
Parameters:
pRdr The file provider instance to use.
fFlags Flags, MBZ.
enmCpuArch The desired CPU architecture. KCPUARCH_UNKNOWN means anything goes, but with a preference for the current host architecture.
u32Magic The FAT magic.
poffHdr Where to store the offset of the selected image.

Definition at line 146 of file kLdrMod.c.

References fat_arch::align, fat_arch::cpusubtype, fat_arch::cputype, IMAGE_FAT_SIGNATURE_OE, K_E2E_U32, KCPUARCH_AMD64, KCPUARCH_UNKNOWN, KCPUARCH_X86_32, KLDR_ERR_CPU_ARCH_MISMATCH, KLDR_ERR_FAT_INVALID, KLDR_ERR_FAT_UNSUPPORTED_CPU_SUBTYPE, fat_arch::offset, and fat_arch::size.

Referenced by kLdrModOpenFromRdr().

{
    int         rcRet = KLDR_ERR_CPU_ARCH_MISMATCH;
    KLDRFOFF    off = *poffHdr + sizeof(KU32);
    KLDRFOFF    offEndFAT;
    KBOOL       fCpuArchWhatever;
    KU32        cArchs;
    KU32        iArch;
    int         rc;

    /* Read fat_header_t::nfat_arch. */
    rc = kRdrRead(pRdr, &cArchs, sizeof(cArchs), off);
    if (rc)
        return rc;
    off += sizeof(KU32);
    if (u32Magic == IMAGE_FAT_SIGNATURE_OE)
        cArchs = K_E2E_U32(cArchs);
    if (cArchs == 0)
        return KLDR_ERR_FAT_INVALID;

    /* Deal with KCPUARCH_UNKNOWN. */
    fCpuArchWhatever = enmCpuArch == KCPUARCH_UNKNOWN;
    if (fCpuArchWhatever)
    {
        KCPU enmCpuIgnored;
        kCpuGetArchAndCpu(&enmCpuArch, &enmCpuIgnored);
    }

    /*
     * Iterate the architecture list.
     */
    offEndFAT = off + cArchs * sizeof(fat_arch_t);
    for (iArch = 0; iArch < cArchs; iArch++)
    {
        KCPUARCH    enmEntryArch;
        fat_arch_t  Arch;
        rc = kRdrRead(pRdr, &Arch, sizeof(Arch), off);
        if (rc)
            return rc;
        off += sizeof(Arch);

        if (u32Magic == IMAGE_FAT_SIGNATURE_OE)
        {
            Arch.cputype    = K_E2E_U32(Arch.cputype);
            Arch.cpusubtype = K_E2E_U32(Arch.cpusubtype);
            Arch.offset     = K_E2E_U32(Arch.offset);
            Arch.size       = K_E2E_U32(Arch.size);
            Arch.align      = K_E2E_U32(Arch.align);
        }

        /* Simple validation. */
        if (    (KLDRFOFF)Arch.offset < offEndFAT
            ||  (KLDRFOFF)Arch.offset >= kRdrSize(pRdr)
            ||  Arch.align >= 32
            ||  Arch.offset & ((KU32_C(1) << Arch.align) - KU32_C(1)))
            return KLDR_ERR_FAT_INVALID;

        /* deal with the cputype and cpusubtype. (See similar code in kLdrModMachO.c.) */
        switch (Arch.cputype)
        {
            case CPU_TYPE_X86:
                enmEntryArch = KCPUARCH_X86_32;
                switch (Arch.cpusubtype)
                {
                    case CPU_SUBTYPE_I386_ALL:
                    /*case CPU_SUBTYPE_386: ^^ ;*/
                    case CPU_SUBTYPE_486:
                    case CPU_SUBTYPE_486SX:
                    /*case CPU_SUBTYPE_586: vv */
                    case CPU_SUBTYPE_PENT:
                    case CPU_SUBTYPE_PENTPRO:
                    case CPU_SUBTYPE_PENTII_M3:
                    case CPU_SUBTYPE_PENTII_M5:
                    case CPU_SUBTYPE_CELERON:
                    case CPU_SUBTYPE_CELERON_MOBILE:
                    case CPU_SUBTYPE_PENTIUM_3:
                    case CPU_SUBTYPE_PENTIUM_3_M:
                    case CPU_SUBTYPE_PENTIUM_3_XEON:
                    case CPU_SUBTYPE_PENTIUM_M:
                    case CPU_SUBTYPE_PENTIUM_4:
                    case CPU_SUBTYPE_PENTIUM_4_M:
                    case CPU_SUBTYPE_XEON:
                    case CPU_SUBTYPE_XEON_MP:
                        break;
                    default:
                        return KLDR_ERR_FAT_UNSUPPORTED_CPU_SUBTYPE;
                }
                break;

            case CPU_TYPE_X86_64:
                enmEntryArch = KCPUARCH_AMD64;
                switch (Arch.cpusubtype & ~CPU_SUBTYPE_MASK)
                {
                    case CPU_SUBTYPE_X86_64_ALL:
                        break;
                    default:
                        return KLDR_ERR_FAT_UNSUPPORTED_CPU_SUBTYPE;
                }
                break;

            default:
                enmEntryArch = KCPUARCH_UNKNOWN;
                break;
        }

        /*
         * Finally the actual image selecting.
         *
         * Return immediately on a perfect match. Otherwise continue looking,
         * if we're none too picky, remember the first image in case we don't
         * get lucky.
         */
        if (enmEntryArch == enmCpuArch)
        {
            *poffHdr = Arch.offset;
            return 0;
        }

        if (    fCpuArchWhatever
            &&  rcRet == KLDR_ERR_CPU_ARCH_MISMATCH)
        {
            *poffHdr = Arch.offset;
            rcRet = 0;
        }
    }

    return rcRet;
}


Generated by  Doxygen 1.6.0   Back to index