Changeset 26151 in vbox for trunk/src/VBox/VMM/PDMLdr.cpp
- Timestamp:
- Feb 2, 2010 4:00:15 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PDMLdr.cpp
r25015 r26151 1159 1159 } 1160 1160 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 */ 1171 static 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 */ 1245 VMMR3DECL(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.