+ return;
+}
+
+/*********************************************************************
+* FIXME: This function invalidates the globals gStartupExtensions and
+* FIXME: ...gBootLoaderObjects without setting them to NULL. Since
+* FIXME: ...the code itself is immediately unloaded, there may not be
+* FIXME: ...any reason to worry about that!
+*********************************************************************/
+void clearStartupExtensionsAndLoaderInfo(void)
+{
+ OSDictionary * startupExtensions = NULL; // must release
+ OSArray * bootLoaderObjects = NULL; // must release
+
+ IORegistryEntry * bootxMemoryMap = NULL; // must release
+ OSDictionary * propertyDict = NULL; // must release
+ OSCollectionIterator * keyIterator = NULL; // must release
+ OSString * key = NULL; // don't release
+
+ /*****
+ * Drop any temporarily held data objects.
+ */
+ bootLoaderObjects = getBootLoaderObjects();
+ if (bootLoaderObjects) {
+ bootLoaderObjects->release();
+ }
+
+ /****
+ * If any "code" entries in driver dictionaries are accompanied
+ * by "compressedCode" entries, then those data objects were
+ * created based of of kmem_alloc()'ed memory, which must be
+ * freed specially.
+ */
+ startupExtensions = getStartupExtensions();
+ if (startupExtensions) {
+ keyIterator =
+ OSCollectionIterator::withCollection(startupExtensions);
+ if (!keyIterator) {
+ IOLog("Error: Couldn't allocate iterator for startup "
+ "extensions.\n");
+ LOG_DELAY();
+ goto memory_map; // bail to the memory_map label
+ }
+
+ while ( (key = OSDynamicCast(OSString,
+ keyIterator->getNextObject())) ) {
+
+ OSDictionary * driverDict = 0;
+ OSData * codeData = 0;
+
+ driverDict = OSDynamicCast(OSDictionary,
+ startupExtensions->getObject(key));
+ if (driverDict) {
+ codeData = OSDynamicCast(OSData,
+ driverDict->getObject("code"));
+
+ if (codeData &&
+ driverDict->getObject("compressedCode")) {
+
+ kmem_free(kernel_map,
+ (unsigned int)codeData->getBytesNoCopy(),
+ codeData->getLength());
+ }
+ }
+ }
+
+ keyIterator->release();
+ startupExtensions->release();
+ }
+
+memory_map:
+
+ /****
+ * Go through the device tree's memory map and remove any driver
+ * data entries.
+ */
+ bootxMemoryMap =
+ IORegistryEntry::fromPath(
+ "/chosen/memory-map", // path
+ gIODTPlane // plane
+ );
+ // return value is retained so be sure to release it
+
+ if (!bootxMemoryMap) {
+ IOLog("Error: Couldn't read booter memory map.\n");
+ LOG_DELAY();
+ goto finish;
+ }
+
+ propertyDict = bootxMemoryMap->dictionaryWithProperties();
+ if (!propertyDict) {
+ IOLog("Error: Couldn't get property dictionary "
+ "from memory map.\n");
+ LOG_DELAY();
+ goto finish;
+ }
+
+ keyIterator = OSCollectionIterator::withCollection(propertyDict);
+ if (!keyIterator) {
+ IOLog("Error: Couldn't allocate iterator for driver images.\n");
+ LOG_DELAY();
+ goto finish;
+ }
+
+ while ( (key = OSDynamicCast(OSString,
+ keyIterator->getNextObject())) ) {
+
+ const char * keyValue = key->getCStringNoCopy();
+
+ if ( !strncmp(keyValue, BOOTX_KEXT_PREFIX,
+ strlen(BOOTX_KEXT_PREFIX)) ||
+ !strncmp(keyValue, BOOTX_MULTIKEXT_PREFIX,
+ strlen(BOOTX_MULTIKEXT_PREFIX)) ) {
+
+ OSData * bootxDriverDataObject = NULL;
+ MemoryMapFileInfo * driverInfo = 0;
+
+ bootxDriverDataObject = OSDynamicCast(OSData,
+ propertyDict->getObject(keyValue));
+ // don't release bootxDriverDataObject
+
+ if (!bootxDriverDataObject) {
+ continue;
+ }
+ driverInfo = (MemoryMapFileInfo *)
+ bootxDriverDataObject->getBytesNoCopy(0,
+ sizeof(MemoryMapFileInfo));
+ IODTFreeLoaderInfo((char *)keyValue,
+ (void *)driverInfo->paddr,
+ (int)driverInfo->length);
+ }
+ }
+
+finish:
+ if (bootxMemoryMap) bootxMemoryMap->release();
+ if (propertyDict) propertyDict->release();
+ if (keyIterator) keyIterator->release();