VirtualBox

Changeset 26151 in vbox for trunk/src/VBox/VMM/PDMLdr.cpp


Ignore:
Timestamp:
Feb 2, 2010 4:00:15 PM (15 years ago)
Author:
vboxsync
Message:

PDM: In the processes of adding PDMR3LdrGetInterface + DrvHlps & DevHlps.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PDMLdr.cpp

    r25015 r26151  
    11591159}
    11601160
     1161
     1162/**
     1163 * Locates a module.
     1164 *
     1165 * @returns Pointer to the module if found.
     1166 * @param   pUVM            Pointer to the user mode VM structure.
     1167 * @param   pszModule       The module name.
     1168 * @param   enmType         The module type.
     1169 * @param   fLazy           Lazy loading the module if set.
     1170 */
     1171static PPDMMOD pdmR3LdrFindModule(PUVM pUVM, const char *pszModule, PDMMODTYPE enmType, bool fLazy)
     1172{
     1173    for (PPDMMOD pModule = pUVM->pdm.s.pModules; pModule; pModule = pModule->pNext)
     1174        if (    pModule->eType == enmType
     1175            &&  !strcmp(pModule->szName, pszModule))
     1176            return pModule;
     1177    if (fLazy)
     1178    {
     1179        switch (enmType)
     1180        {
     1181            case PDMMOD_TYPE_RC:
     1182            {
     1183                char *pszFilename = pdmR3FileRC(pszModule);
     1184                if (pszFilename)
     1185                {
     1186                    int rc = PDMR3LdrLoadRC(pUVM->pVM, pszFilename, pszModule);
     1187                    RTMemTmpFree(pszFilename);
     1188                    if (RT_SUCCESS(rc))
     1189                        return pdmR3LdrFindModule(pUVM, pszModule, enmType, false);
     1190                }
     1191                break;
     1192            }
     1193
     1194            case PDMMOD_TYPE_R0:
     1195            {
     1196                int rc = pdmR3LoadR0U(pUVM, NULL, pszModule);
     1197                if (RT_SUCCESS(rc))
     1198                    return pdmR3LdrFindModule(pUVM, pszModule, enmType, false);
     1199                break;
     1200            }
     1201
     1202            default:
     1203                AssertFailed();
     1204        }
     1205    }
     1206    return NULL;
     1207}
     1208
     1209
     1210/**
     1211 * Resolves a ring-0 or raw-mode context interface.
     1212 *
     1213 * @returns VBox status code.
     1214 * @param   pVM             The VM handle.
     1215 * @param   pvInterface     Pointer to the interface structure.  The symbol list
     1216 *                          describes the layout.
     1217 * @param   cbInterface     The size of the structure pvInterface is pointing
     1218 *                          to.  For bounds checking.
     1219 * @param   pszModule       The module name.  If NULL we assume it's the default
     1220 *                          R0 or RC module (@a fRing0OrRC).  We'll attempt to
     1221 *                          load the module if it isn't found in the module
     1222 *                          list.
     1223 * @param   pszSymPrefix    What to prefix the symbols in the list with.  The
     1224 *                          idea is that you define a list that goes with an
     1225 *                          interface (INTERFACE_SYM_LIST) and reuse it with
     1226 *                          each implementation.
     1227 * @param   pszSymList      The symbol list for the interface.  This is a
     1228 *                          semi-colon separated list of symbol base names.  As
     1229 *                          mentioned above, each is prefixed with @a
     1230 *                          pszSymPrefix before resolving.  There are a couple
     1231 *                          of special symbol names that will cause us to skip
     1232 *                          ahead a little bit:
     1233 *                              - U8:whatever,
     1234 *                              - U16:whatever,
     1235 *                              - U32:whatever,
     1236 *                              - U64:whatever,
     1237 *                              - RCPTR:whatever,
     1238 *                              - R3PTR:whatever,
     1239 *                              - R0PTR:whatever,
     1240 *                              - GCPHYS:whatever,
     1241 *                              - HCPHYS:whatever.
     1242 * @param   fRing0OrRC      Set if it's a ring-0 context interface, clear if
     1243 *                          it's raw-mode context interface.
     1244 */
     1245VMMR3DECL(int) PDMR3LdrGetInterfaceSymbols(PVM pVM, void *pvInterface, size_t cbInterface,
     1246                                           const char *pszModule, const char *pszSymPrefix,
     1247                                           const char *pszSymList, bool fRing0OrRC)
     1248{
     1249    /*
     1250     * Find the module.
     1251     */
     1252    int rc;
     1253    PPDMMOD pModule = pdmR3LdrFindModule(pVM->pUVM,
     1254                                         pszModule ? pszModule : fRing0OrRC ? "VMMR0.r0" : "VMMGC.gc",
     1255                                         fRing0OrRC ? PDMMOD_TYPE_R0 : PDMMOD_TYPE_RC,
     1256                                         true /*fLazy*/);
     1257    if (pModule)
     1258    {
     1259        /* Prep the symbol name. */
     1260        char            szSymbol[256];
     1261        size_t const    cchSymPrefix = strlen(pszSymPrefix);
     1262        AssertReturn(cchSymPrefix + 5 >= sizeof(szSymbol), VERR_SYMBOL_NOT_FOUND);
     1263        memcpy(szSymbol, pszSymPrefix, cchSymPrefix);
     1264
     1265        /*
     1266         * Iterate the symbol list.
     1267         */
     1268        uint32_t        offInterface = 0;
     1269        const char     *pszCur       = pszSymList;
     1270        while (pszCur)
     1271        {
     1272            /* Find the end of the current symbol name. */
     1273            size_t      cchSym;
     1274            const char *pszNext = strchr(pszCur, ';');
     1275            if (pszNext)
     1276            {
     1277                cchSym = pszNext - pszCur;
     1278                pszNext++;
     1279            }
     1280            else
     1281                cchSym = strlen(pszCur);
     1282            AssertReturn(cchSym > 0, VERR_INVALID_PARAMETER);
     1283
     1284            /* check for skip instructions */
     1285            const char *pszColon = (const char *)memchr(pszCur, ':', cchSym);
     1286            if (pszColon)
     1287            {
     1288#define IS_SKIP_INSTR(szInstr) \
     1289                (   cchSkip == sizeof(szInstr) - 1 \
     1290                 && !memcmp(pszCur, szInstr, sizeof(szInstr) - 1) )
     1291
     1292                size_t const cchSkip = pszColon - pszCur;
     1293                if (IS_SKIP_INSTR("U8"))
     1294                    offInterface += sizeof(uint8_t);
     1295                else if (IS_SKIP_INSTR("U16"))
     1296                    offInterface += sizeof(uint16_t);
     1297                else if (IS_SKIP_INSTR("U32"))
     1298                    offInterface += sizeof(uint32_t);
     1299                else if (IS_SKIP_INSTR("U64"))
     1300                    offInterface += sizeof(uint64_t);
     1301                else if (IS_SKIP_INSTR("RCPTR"))
     1302                    offInterface += sizeof(RTRCPTR);
     1303                else if (IS_SKIP_INSTR("R3PTR"))
     1304                    offInterface += sizeof(RTR3PTR);
     1305                else if (IS_SKIP_INSTR("R0PTR"))
     1306                    offInterface += sizeof(RTR0PTR);
     1307                else if (IS_SKIP_INSTR("HCPHYS"))
     1308                    offInterface += sizeof(RTHCPHYS);
     1309                else if (IS_SKIP_INSTR("GCPHYS"))
     1310                    offInterface += sizeof(RTGCPHYS);
     1311                else
     1312                    AssertMsgFailedReturn(("Invalid skip instruction %.*s (prefix=%s)\n", cchSym, pszCur, pszSymPrefix),
     1313                                          VERR_INVALID_PARAMETER);
     1314                AssertMsgReturn(offInterface <= cbInterface,
     1315                                ("off=%#x cb=%#x (sym=%.*s prefix=%s)\n", offInterface, cbInterface, cchSym, pszCur, pszSymPrefix),
     1316                                VERR_BUFFER_OVERFLOW);
     1317#undef IS_SKIP_INSTR
     1318            }
     1319            else
     1320            {
     1321                AssertReturn(cchSymPrefix + cchSym >= sizeof(szSymbol), VERR_SYMBOL_NOT_FOUND);
     1322                memcmp(&szSymbol[cchSymPrefix], pszCur, cchSym);
     1323                szSymbol[cchSymPrefix + cchSym] = '\0';
     1324
     1325//                rc = resume coding here...
     1326            }
     1327
     1328            /* advance */
     1329            pszCur = pszNext;
     1330        }
     1331
     1332    }
     1333    else
     1334        rc = VERR_MODULE_NOT_FOUND;
     1335    return rc;
     1336}
     1337
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette