Changeset 2981 for trunk


Ignore:
Timestamp:
Mar 4, 2007, 3:10:18 AM (18 years ago)
Author:
bird
Message:

Implemented symbol enumeration.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdrModLX.c

    r2979 r2981  
    380380     * (The table entry consists of a pascal string followed by a 16-bit ordinal.)
    381381     */
    382     pMod->pszName = (const char *)kldrModLXDoNameTableLookupByOrdinal(pModLX->pbResNameTab,
    383                                                                       pModLX->pbLoaderSectionLast - pModLX->pbResNameTab + 1,
    384                                                                       0);
     382    if (pModLX->pbResNameTab)
     383        pMod->pszName = (const char *)kldrModLXDoNameTableLookupByOrdinal(pModLX->pbResNameTab,
     384                                                                          pModLX->pbLoaderSectionLast - pModLX->pbResNameTab + 1,
     385                                                                          0);
    385386    if (!pMod->pszName)
    386387        return KLDR_ERR_LX_NO_SONAME;
     
    970971                                uint32_t fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
    971972{
    972     PKLDRMODLX                      pModLX = (PKLDRMODLX)pMod->pvData;
    973 /*    int                             rc; */
     973    PKLDRMODLX pModLX = (PKLDRMODLX)pMod->pvData;
     974    const struct b32_bundle *pBundle;
     975    uint32_t iOrdinal;
     976    int rc = 0;
    974977
    975978    kldrModLXResolveBaseAddress(pModLX, &BaseAddress);
     979
     980    /*
     981     * Enumerate the entry table.
     982     * (The entry table is made up of bundles of similar exports.)
     983     */
     984    iOrdinal = 1;
     985    pBundle = (const struct b32_bundle *)pModLX->pbEntryTab;
     986    while (pBundle->b32_cnt && iOrdinal)
     987    {
     988        static const size_t s_cbEntry[] = { 0, 3, 5, 5, 7 };
     989
     990        /*
     991         * Enum the entries in the bundle.
     992         */
     993        if (pBundle->b32_type != EMPTY)
     994        {
     995            const struct e32_entry *pEntry;
     996            size_t cbEntry;
     997            KLDRADDR BundleRVA;
     998            unsigned cLeft;
     999
     1000
     1001            /* Validate the bundle. */
     1002            switch (pBundle->b32_type)
     1003            {
     1004                case ENTRY16:
     1005                case GATE16:
     1006                case ENTRY32:
     1007                    if (    pBundle->b32_obj <= 0
     1008                        ||  pBundle->b32_obj > pMod->cSegments)
     1009                        return KLDR_ERR_LX_BAD_BUNDLE;
     1010                    BundleRVA = pMod->aSegments[pBundle->b32_obj - 1].RVA;
     1011                    break;
     1012
     1013                case ENTRYFWD:
     1014                    BundleRVA = 0;
     1015                    break;
     1016
     1017                default:
     1018                    /* anyone actually using TYPEINFO will end up here. */
     1019                    KLDRMODLX_ASSERT(!"Bad bundle type");
     1020                    return KLDR_ERR_LX_BAD_BUNDLE;
     1021            }
     1022
     1023            /* iterate the bundle entries. */
     1024            cbEntry = s_cbEntry[pBundle->b32_type];
     1025            pEntry = (const struct e32_entry *)(pBundle + 1);
     1026            cLeft = pBundle->b32_cnt;
     1027            while (cLeft-- > 0)
     1028            {
     1029                KLDRADDR uValue;
     1030                uint32_t fKind;
     1031                int fFoundName;
     1032                const uint8_t *pbName;
     1033
     1034                /*
     1035                 * Calc the symbol value and kind.
     1036                 */
     1037                switch (pBundle->b32_type)
     1038                {
     1039                    /* e32_flags + a 16-bit offset. */
     1040                    case ENTRY16:
     1041                        uValue = BaseAddress + BundleRVA + pEntry->e32_variant.e32_offset.offset16;
     1042                        fKind = KLDRSYMKIND_16BIT | KLDRSYMKIND_NO_TYPE;
     1043                        break;
     1044
     1045                    /* e32_flags + a 16-bit offset + a 16-bit callgate selector. */
     1046                    case GATE16:
     1047                        uValue = BaseAddress + BundleRVA + pEntry->e32_variant.e32_callgate.offset;
     1048                        fKind = KLDRSYMKIND_16BIT | KLDRSYMKIND_CODE;
     1049                        break;
     1050
     1051                    /* e32_flags + a 32-bit offset. */
     1052                    case ENTRY32:
     1053                        uValue = BaseAddress + BundleRVA + pEntry->e32_variant.e32_offset.offset32;
     1054                        fKind = KLDRSYMKIND_32BIT;
     1055                        break;
     1056
     1057                    /* e32_flags + 16-bit import module ordinal + a 32-bit procname or ordinal. */
     1058                    case ENTRYFWD:
     1059                        uValue = 0; /** @todo implement enumeration of forwarders properly. */
     1060                        fKind = KLDRSYMKIND_FORWARDER;
     1061                        break;
     1062                }
     1063
     1064                /*
     1065                 * Any symbol names?
     1066                 */
     1067                fFoundName = 0;
     1068
     1069                /* resident name table. */
     1070                pbName = pModLX->pbResNameTab;
     1071                if (pbName)
     1072                {
     1073                    do
     1074                    {
     1075                        pbName = kldrModLXDoNameTableLookupByOrdinal(pbName, pModLX->pbLoaderSectionLast - pbName + 1, iOrdinal);
     1076                        if (!pbName)
     1077                            break;
     1078                        fFoundName = 1;
     1079                        rc = pfnCallback(pMod, iOrdinal, (const char *)pbName + 1, *pbName, NULL, uValue, fKind, pvUser);
     1080                        if (rc)
     1081                            return rc;
     1082
     1083                        /* skip to the next entry */
     1084                        pbName += 1 + *pbName + 2;
     1085                    } while (pbName < pModLX->pbLoaderSectionLast);
     1086                }
     1087
     1088                /* resident name table. */
     1089                pbName = pModLX->pbNonResNameTab;
     1090                /** @todo lazy load the non-resident name table. */
     1091                if (pbName)
     1092                {
     1093                    do
     1094                    {
     1095                        pbName = kldrModLXDoNameTableLookupByOrdinal(pbName, pModLX->pbNonResNameTabLast - pbName + 1, iOrdinal);
     1096                        if (!pbName)
     1097                            break;
     1098                        fFoundName = 1;
     1099                        rc = pfnCallback(pMod, iOrdinal, (const char *)pbName + 1, *pbName, NULL, uValue, fKind, pvUser);
     1100                        if (rc)
     1101                            return rc;
     1102
     1103                        /* skip to the next entry */
     1104                        pbName += 1 + *pbName + 2;
     1105                    } while (pbName < pModLX->pbLoaderSectionLast);
     1106                }
     1107
     1108                /*
     1109                 * If no names, call once with the ordinal only.
     1110                 */
     1111                if (!fFoundName)
     1112                {
     1113                    rc = pfnCallback(pMod, iOrdinal, NULL, 0, NULL, uValue, fKind, pvUser);
     1114                    if (rc)
     1115                        return rc;
     1116                }
     1117
     1118                /* next */
     1119                iOrdinal++;
     1120                pEntry = (const struct e32_entry *)((uintptr_t)pEntry + cbEntry);
     1121            }
     1122        }
     1123
     1124        /*
     1125         * The next bundle.
     1126         */
     1127        if (pBundle->b32_type > ENTRYFWD)
     1128        {
     1129            KLDRMODLX_ASSERT(!"Bad type"); /** @todo figure out TYPEINFO. */
     1130            return KLDR_ERR_LX_BAD_BUNDLE;
     1131        }
     1132        if (pBundle->b32_type == 0)
     1133            pBundle = (const struct b32_bundle *)((const uint8_t *)pBundle + 2);
     1134        else
     1135            pBundle = (const struct b32_bundle *)((const uint8_t *)(pBundle + 1) + s_cbEntry[pBundle->b32_type] * pBundle->b32_cnt);
     1136    }
    9761137
    9771138    return 0;
Note: See TracChangeset for help on using the changeset viewer.