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

static int kldrModLXQuerySymbol ( PKLDRMOD  pMod,
const void *  pvBits,
KLDRADDR  BaseAddress,
KU32  iSymbol,
const char *  pchSymbol,
KSIZE  cchSymbol,
const char *  pszVersion,
PFNKLDRMODGETIMPORT  pfnGetForwarder,
void *  pvUser,
PKLDRADDR  puValue,
KU32 *  pfKind 
) [static]

Queries a symbol by name or ordinal number.

Returns:
0 and *puValue and *pfKind on success. KLDR_ERR_SYMBOL_NOT_FOUND is returned if the symbol wasn't found. Other failures could stem from bad executable format failures, read failure in case pvBits isn't specified and no mapping should be used.
Parameters:
pMod The module.
pvBits Optional pointer to bits returned by kLdrModGetBits() currently located at BaseAddress. This can be used by some module interpreters to reduce memory consumption.
BaseAddress The module base address to use when calculating the symbol value. There are two special values that can be used: KLDRMOD_BASEADDRESS_LINK and KLDRMOD_BASEADDRESS_MAP.
iSymbol The symbol ordinal. (optional)
pchSymbol The symbol name. (optional) Important, this doesn't have to be a null-terminated string.
cchSymbol The length of the symbol name.
pszVersion The symbol version. NULL if not versioned.
pfnGetForwarder The callback to use when resolving a forwarder symbol. This is optional and if not specified KLDR_ERR_FORWARDER is returned instead.
pvUser The user argument for the pfnGetForwarder callback.
puValue Where to store the symbol value. (optional)
pfKind On input one of the KLDRSYMKIND_REQ_* defines. On output the symbol kind. (optional)

Todo:
figure out TYPEINFO.

Definition at line 580 of file kLdrModLX.c.

References KLDRMOD::aSegments, KLDRMOD::cSegments, e32_exe::e32_enttab, e32_entry::e32_variant, EMPTY, ENTRY16, ENTRY32, ENTRYFWD, GATE16, KLDRMODLX::Hdr, KLDR_ERR_LX_BAD_BUNDLE, KLDR_ERR_SYMBOL_NOT_FOUND, KLDRMODLX_ASSERT, kldrModLXDoForwarderQuery(), kldrModLXDoNameLookup(), kldrModLXResolveBaseAddress(), KLDRSYMKIND_16BIT, KLDRSYMKIND_32BIT, KLDRSYMKIND_CODE, KLDRSYMKIND_NO_TYPE, KSIZE, KLDRMODLX::pbEntryTab, KLDRMOD::pvData, KLDRSEG::RVA, and while().

{
    PKLDRMODLX                  pModLX = (PKLDRMODLX)pMod->pvData;
    KU32                        iOrdinal;
    int                         rc;
    const struct b32_bundle     *pBundle;


    /*
     * Give up at once if there is no entry table.
     */
    if (!pModLX->Hdr.e32_enttab)
        return KLDR_ERR_SYMBOL_NOT_FOUND;

    /*
     * Translate the symbol name into an ordinal.
     */
    if (pchSymbol)
    {
        rc = kldrModLXDoNameLookup(pModLX, pchSymbol, cchSymbol, &iSymbol);
        if (rc)
            return rc;
    }

    /*
     * Iterate the entry table.
     * (The entry table is made up of bundles of similar exports.)
     */
    iOrdinal = 1;
    pBundle = (const struct b32_bundle *)pModLX->pbEntryTab;
    while (pBundle->b32_cnt && iOrdinal <= iSymbol)
    {
        static const KSIZE s_cbEntry[] = { 0, 3, 5, 5, 7 };

        /*
         * Check for a hit first.
         */
        iOrdinal += pBundle->b32_cnt;
        if (iSymbol < iOrdinal)
        {
            KU32 offObject;
            const struct e32_entry *pEntry = (const struct e32_entry *)((KUPTR)(pBundle + 1)
                                                                        +   (iSymbol - (iOrdinal - pBundle->b32_cnt))
                                                                          * s_cbEntry[pBundle->b32_type]);

            /*
             * Calculate the return address.
             */
            kldrModLXResolveBaseAddress(pModLX, &BaseAddress);
            switch (pBundle->b32_type)
            {
                /* empty bundles are place holders unused ordinal ranges. */
                case EMPTY:
                    return KLDR_ERR_SYMBOL_NOT_FOUND;

                /* e32_flags + a 16-bit offset. */
                case ENTRY16:
                    offObject = pEntry->e32_variant.e32_offset.offset16;
                    if (pfKind)
                        *pfKind = KLDRSYMKIND_16BIT | KLDRSYMKIND_NO_TYPE;
                    break;

                /* e32_flags + a 16-bit offset + a 16-bit callgate selector. */
                case GATE16:
                    offObject = pEntry->e32_variant.e32_callgate.offset;
                    if (pfKind)
                        *pfKind = KLDRSYMKIND_16BIT | KLDRSYMKIND_CODE;
                    break;

                /* e32_flags + a 32-bit offset. */
                case ENTRY32:
                    offObject = pEntry->e32_variant.e32_offset.offset32;
                    if (pfKind)
                        *pfKind = KLDRSYMKIND_32BIT;
                    break;

                /* e32_flags + 16-bit import module ordinal + a 32-bit procname or ordinal. */
                case ENTRYFWD:
                    return kldrModLXDoForwarderQuery(pModLX, pEntry, pfnGetForwarder, pvUser, puValue, pfKind);

                default:
                    /* anyone actually using TYPEINFO will end up here. */
                    KLDRMODLX_ASSERT(!"Bad bundle type");
                    return KLDR_ERR_LX_BAD_BUNDLE;
            }

            /*
             * Validate the object number and calc the return address.
             */
            if (    pBundle->b32_obj <= 0
                ||  pBundle->b32_obj > pMod->cSegments)
                return KLDR_ERR_LX_BAD_BUNDLE;
            if (puValue)
                *puValue = BaseAddress
                         + offObject
                         + pMod->aSegments[pBundle->b32_obj - 1].RVA;
            return 0;
        }

        /*
         * Skip the bundle.
         */
        if (pBundle->b32_type > ENTRYFWD)
        {
            KLDRMODLX_ASSERT(!"Bad type"); /** @todo figure out TYPEINFO. */
            return KLDR_ERR_LX_BAD_BUNDLE;
        }
        if (pBundle->b32_type == 0)
            pBundle = (const struct b32_bundle *)((const KU8 *)pBundle + 2);
        else
            pBundle = (const struct b32_bundle *)((const KU8 *)(pBundle + 1) + s_cbEntry[pBundle->b32_type] * pBundle->b32_cnt);
    }

    return KLDR_ERR_SYMBOL_NOT_FOUND;
}


Generated by  Doxygen 1.6.0   Back to index