Loading...
iokit/Kernel/IODeviceTreeSupport.cpp xnu-12377.121.6 xnu-6153.11.26
--- xnu/xnu-12377.121.6/iokit/Kernel/IODeviceTreeSupport.cpp
+++ xnu/xnu-6153.11.26/iokit/Kernel/IODeviceTreeSupport.cpp
@@ -28,7 +28,6 @@
 
 #include <IOKit/IODeviceTreeSupport.h>
 #include <libkern/c++/OSContainers.h>
-#include <libkern/c++/OSSharedPtr.h>
 #include <IOKit/IODeviceMemory.h>
 #include <IOKit/IOService.h>
 #include <IOKit/IOCatalogue.h>
@@ -56,30 +55,17 @@
 
 #define IODTSUPPORTDEBUG 0
 
-struct IODTPersistent {
-	IODTCompareAddressCellFunc  compareFunc;
-};
-
-struct IODTResolvers {
-	unsigned int     alloc;
-	unsigned int     count;
-	IOLock         * lock;
-	IODTPersistent * resolvers;
-};
-
 const IORegistryPlane * gIODTPlane;
 
 static OSArray *    gIODTPHandles;
 static OSArray *    gIODTPHandleMap;
-
-static IODTResolvers *  gIODTResolvers;
+static OSData  *    gIODTResolvers;
 
 const OSSymbol *        gIODTNameKey;
 const OSSymbol *        gIODTUnitKey;
 const OSSymbol *        gIODTCompatibleKey;
 const OSSymbol *        gIODTTypeKey;
 const OSSymbol *        gIODTModelKey;
-const OSSymbol *        gIODTBridgeModelKey;
 const OSSymbol *        gIODTTargetTypeKey;
 
 const OSSymbol *        gIODTSizeCellKey;
@@ -95,20 +81,15 @@
 const OSSymbol *        gIODTInterruptParentKey;
 const OSSymbol *        gIODTNWInterruptMappingKey;
 
-const OSData *          gIODTAssociatedServiceKey;
-
 OSDictionary   *        gIODTSharedInterrupts;
+
+static IOLock  *    gIODTResolversLock;
 
 static IORegistryEntry * MakeReferenceTable( DTEntry dtEntry, bool copy );
 static void AddPHandle( IORegistryEntry * regEntry );
 static void FreePhysicalMemory( vm_offset_t * range );
 static bool IODTMapInterruptsSharing( IORegistryEntry * regEntry, OSDictionary * allInts );
 
-// FIXME: Implementation of this function is hidden from the static analyzer.
-// The analyzer doesn't know that the registry holds retains, and gets confused
-// about releases after calls to 'attachToParent'.
-// Feel free to remove the #ifndef and address the warning!
-#ifndef __clang_analyzer__
 IORegistryEntry *
 IODeviceTreeAlloc( void * dtTop )
 {
@@ -124,10 +105,7 @@
 	vm_offset_t *               dtMap;
 	unsigned int                propSize;
 	bool                        intMap;
-	bool                        foundDTNode;
 	bool                        freeDT;
-	char                        exBootArg[64];
-	const char *                found;
 
 	gIODTPlane = IORegistryEntry::makePlane( kIODeviceTreePlane );
 
@@ -136,14 +114,11 @@
 	gIODTCompatibleKey  = OSSymbol::withCStringNoCopy( "compatible" );
 	gIODTTypeKey                = OSSymbol::withCStringNoCopy( "device_type" );
 	gIODTModelKey               = OSSymbol::withCStringNoCopy( "model" );
-	gIODTBridgeModelKey         = OSSymbol::withCStringNoCopy( "bridge-model" );
 	gIODTTargetTypeKey          = OSSymbol::withCStringNoCopy( "target-type" );
 	gIODTSizeCellKey    = OSSymbol::withCStringNoCopy( "#size-cells" );
 	gIODTAddressCellKey = OSSymbol::withCStringNoCopy( "#address-cells" );
 	gIODTRangeKey               = OSSymbol::withCStringNoCopy( "ranges" );
 	gIODTPersistKey             = OSSymbol::withCStringNoCopy( "IODTPersist" );
-	gIODTAssociatedServiceKey   = OSData::withBytesNoCopy((void *) kIODTAssociatedServiceKey, sizeof(kIODTAssociatedServiceKey));
-
 
 	assert(    gIODTPlane && gIODTCompatibleKey
 	    && gIODTTypeKey && gIODTModelKey
@@ -165,16 +140,9 @@
 
 	gIODTPHandles       = OSArray::withCapacity( 1 );
 	gIODTPHandleMap     = OSArray::withCapacity( 1 );
-
-	gIODTResolvers            = zalloc_permanent_type(IODTResolvers);
-	gIODTResolvers->count     = 0;
-	gIODTResolvers->alloc     = 2;
-	gIODTResolvers->resolvers = IONewZero(IODTPersistent, gIODTResolvers->alloc);
-	gIODTResolvers->lock      = IOLockAlloc();
-
-	if (!PE_parse_boot_argn("exp", exBootArg, sizeof(exBootArg))) {
-		exBootArg[0] = '\0';
-	}
+	gIODTResolvers  = OSData::withCapacity(16);
+
+	gIODTResolversLock = IOLockAlloc();
 
 	gIODTInterruptCellKey
 	        = OSSymbol::withCStringNoCopy("#interrupt-cells");
@@ -182,51 +150,32 @@
 	assert(    gIODTDefaultInterruptController && gIODTNWInterruptMappingKey
 	    && gIODTAAPLInterruptsKey
 	    && gIODTPHandleKey && gIODTInterruptParentKey
-	    && gIODTPHandles && gIODTPHandleMap && gIODTInterruptCellKey
-	    && gIODTResolvers && gIODTResolvers->lock && gIODTResolvers->resolvers
+	    && gIODTPHandles && gIODTPHandleMap && gIODTResolvers && gIODTResolversLock
+	    && gIODTInterruptCellKey
 	    );
 
-	foundDTNode = (kSuccess == SecureDTLookupEntry( NULL, "/chosen/memory-map", &mapEntry ))
-	    && (kSuccess == SecureDTGetProperty( mapEntry,
-	    "DeviceTree", (void const **) &dtMap, &propSize ))
+	freeDT = (kSuccess == DTLookupEntry( NULL, "/chosen/memory-map", &mapEntry ))
+	    && (kSuccess == DTGetProperty( mapEntry,
+	    "DeviceTree", (void **) &dtMap, &propSize ))
 	    && ((2 * sizeof(uint32_t)) == propSize);
 
-	freeDT = foundDTNode && !SecureDTIsLockedDown();
-
 	parent = MakeReferenceTable((DTEntry)dtTop, freeDT );
 
 	stack = OSArray::withObjects((const OSObject **) &parent, 1, 10 );
-	SecureDTInitEntryIterator((DTEntry)dtTop, &iter );
+	DTInitEntryIterator((DTEntry)dtTop, &iter );
 
 	do {
 		parent = (IORegistryEntry *)stack->getObject( stack->getCount() - 1);
 		//parent->release();
 		stack->removeObject( stack->getCount() - 1);
 
-		while (kSuccess == SecureDTIterateEntries( &iter, &dtChild)) {
+		while (kSuccess == DTIterateEntries( &iter, &dtChild)) {
 			child = MakeReferenceTable( dtChild, freeDT );
 			child->attachToParent( parent, gIODTPlane);
 
 			AddPHandle( child );
-			// E.g. exp=sgx:3 or exp=sgx:3,5
-			if ((found = strnstr(exBootArg, child->getName(), sizeof(exBootArg)))) {
-				child->setProperty(gIOExclaveAssignedKey, kOSBooleanTrue);
-				uint32_t ep = 0;
-				uint32_t edk_ep = 0;
-				found += strlen(child->getName());
-				if (':' == *found) {
-					char *end;
-					ep = (uint32_t) strtol(found + 1, &end, 0);
-					// Check for optional edk endpoint
-					if (',' == *end) {
-						edk_ep = (uint32_t) strtol(end + 1, &end, 0);
-						child->setProperty("exclave-edk-endpoint", &edk_ep, sizeof(edk_ep));
-					}
-				}
-				child->setProperty("exclave-endpoint", &ep, sizeof(ep));
-			}
-
-			if (kSuccess == SecureDTEnterEntry( &iter, dtChild)) {
+
+			if (kSuccess == DTEnterEntry( &iter, dtChild)) {
 				stack->setObject( parent);
 				parent = child;
 			}
@@ -234,10 +183,10 @@
 			child->release();
 		}
 	} while (stack->getCount()
-	    && (kSuccess == SecureDTExitEntry( &iter, &dtChild)));
+	    && (kSuccess == DTExitEntry( &iter, &dtChild)));
 
 	stack->release();
-	assert(kSuccess != SecureDTExitEntry(&iter, &dtChild));
+	assert(kSuccess != DTExitEntry(&iter, &dtChild));
 
 	// parent is now root of the created tree
 
@@ -253,7 +202,7 @@
 
 	if (freeDT) {
 		// free original device tree
-		SecureDTInit(NULL, 0);
+		DTInit(NULL);
 		IODTFreeLoaderInfo( "DeviceTree",
 		    (void *)dtMap[0], (int) round_page(dtMap[1]));
 	}
@@ -272,12 +221,14 @@
 			if (!intMap && child->getProperty( gIODTInterruptParentKey)) {
 				intMap = true;
 			}
+#if !(defined(RC_HIDE_N144) || defined(RC_HIDE_N146))
 			if (!strcmp("sep", child->getName())
 			    || !strcmp("aop", child->getName())
 			    || !strcmp("disp0", child->getName())) {
 				uint32_t aotFlags = 1;
 				child->setProperty("aot-power", &aotFlags, sizeof(aotFlags));
 			}
+#endif /* !(defined(RC_HIDE_N144) || defined(RC_HIDE_N146)) */
 		}
 		regIter->release();
 	}
@@ -314,7 +265,6 @@
 
 	return parent;
 }
-#endif
 
 int
 IODTGetLoaderInfo( const char *key, void **infoAddr, int *infoSize )
@@ -388,21 +338,17 @@
 	}
 
 	defaultObj = OSDynamicCast( OSData, defaults->getProperty(key));
-
 	if (defaultObj == NULL) {
-		defaults->release();
 		return -1;
 	}
 
 	defaultSize = defaultObj->getLength();
 	if (defaultSize > infoSize) {
-		defaults->release();
 		return -1;
 	}
 
 	memcpy( infoAddr, defaultObj->getBytesNoCopy(), defaultSize );
 
-	defaults->release();
 	return 0;
 }
 
@@ -426,9 +372,9 @@
 	OSData                              *data;
 	const OSSymbol              *sym;
 	OpaqueDTPropertyIterator    dtIter;
-	void const                  *prop;
+	void                                *prop;
 	unsigned int                propSize;
-	char const                                      *name;
+	char                                *name;
 	char                                location[32];
 	bool                                noLocation = true;
 	bool                                kernelOnly;
@@ -441,12 +387,12 @@
 	}
 
 	if (regEntry &&
-	    (kSuccess == SecureDTInitPropertyIterator( dtEntry, &dtIter))) {
-		kernelOnly = (kSuccess == SecureDTGetProperty(dtEntry, "kernel-only", &prop, &propSize));
+	    (kSuccess == DTInitPropertyIterator( dtEntry, &dtIter))) {
+		kernelOnly = (kSuccess == DTGetProperty(dtEntry, "kernel-only", &prop, &propSize));
 		propTable = regEntry->getPropertyTable();
 
-		while (kSuccess == SecureDTIterateProperties( &dtIter, &name)) {
-			if (kSuccess != SecureDTGetProperty( dtEntry, name, &prop, &propSize )) {
+		while (kSuccess == DTIterateProperties( &dtIter, &name)) {
+			if (kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize )) {
 				continue;
 			}
 
@@ -455,20 +401,13 @@
 				data = OSData::withBytes(prop, propSize);
 			} else {
 				nameKey = OSSymbol::withCStringNoCopy(name);
-				/* There is no OSDataConst or other way to indicate
-				 * that the OSData is actually immutable. But CTRR
-				 * will catch any write attempts. */
-				data = OSData::withBytesNoCopy((void**)(uintptr_t)prop, propSize);
+				data = OSData::withBytesNoCopy(prop, propSize);
 			}
 			assert( nameKey && data );
 
-#if DEVELOPMENT || DEBUG
-#pragma unused(kernelOnly)
-#else
 			if (kernelOnly) {
 				data->setSerializable(false);
 			}
-#endif
 
 			propTable->setObject( nameKey, data);
 			data->release();
@@ -516,7 +455,7 @@
 	}
 }
 
-static LIBKERN_RETURNS_NOT_RETAINED IORegistryEntry *
+static IORegistryEntry *
 FindPHandle( UInt32 phandle )
 {
 	OSData                      *data;
@@ -795,7 +734,7 @@
 	UInt32 *            localBits;
 	UInt32 *            localEnd;
 	IOItemCount         index;
-	OSData *            map = NULL;
+	OSData *            map;
 	OSObject *          oneMap;
 	OSArray *           mapped;
 	OSArray *           controllerInts;
@@ -834,8 +773,6 @@
 				if (0 == skip) {
 					IOLog("%s: error mapping interrupt[%d]\n",
 					    regEntry->getName(), mapped->getCount());
-					OSSafeReleaseNULL(map);
-					OSSafeReleaseNULL(controller);
 					break;
 				}
 			} else {
@@ -880,8 +817,8 @@
 				}
 			}
 
-			OSSafeReleaseNULL(map);
-			OSSafeReleaseNULL(controller);
+			map->release();
+			controller->release();
 		} while (localBits < localEnd);
 	}
 
@@ -950,7 +887,7 @@
 
 		do {
 			// for each name in the property
-			nlen = (unsigned int) strnlen(names, lastName - names);
+			nlen = strnlen(names, lastName - names);
 			if (wild) {
 				matched = ((nlen >= (keyLen - 1)) && (0 == strncmp(ckey, names, keyLen - 1)));
 			} else {
@@ -992,16 +929,6 @@
 }
 
 bool
-IODTCompareNubName( const IORegistryEntry * regEntry,
-    OSString * name, OSSharedPtr<OSString>& matchingName )
-{
-	OSString* matchingNameRaw = NULL;
-	bool result = IODTCompareNubName(regEntry, name, &matchingNameRaw);
-	matchingName.reset(matchingNameRaw, OSNoRetain);
-	return result;
-}
-
-bool
 IODTMatchNubWithKeys( IORegistryEntry * regEntry,
     const char * keys )
 {
@@ -1023,7 +950,7 @@
 	return result;
 }
 
-LIBKERN_RETURNS_RETAINED OSCollectionIterator *
+OSCollectionIterator *
 IODTFindMatchingEntries( IORegistryEntry * from,
     IOOptionBits options, const char * keys )
 {
@@ -1050,12 +977,10 @@
 			iter->reset();
 			while ((next = iter->getNextObject())) {
 				// Look for existence of a debug property to skip
-				if (next->propertyExists("AAPL,ignore")) {
+				if (next->getProperty("AAPL,ignore")) {
 					continue;
 				}
-				if (next->propertyHasValue(gIODTTypeKey, gIODTAssociatedServiceKey)) {
-					continue;
-				}
+
 				if (keys) {
 					cmp = IODTMatchNubWithKeys( next, keys );
 					if ((minus && (false == cmp))
@@ -1080,52 +1005,38 @@
 }
 
 
+struct IODTPersistent {
+	IODTCompareAddressCellFunc  compareFunc;
+};
+
 void
 IODTSetResolving( IORegistryEntry *        regEntry,
     IODTCompareAddressCellFunc      compareFunc,
     IODTNVLocationFunc              locationFunc __unused )
 {
+	IODTPersistent       persist;
 	IODTPersistent * entry;
-	IODTPersistent * newResolvers;
 	OSNumber       * num;
-	unsigned int     index;
-
-	IOLockLock(gIODTResolvers->lock);
-
-	entry = gIODTResolvers->resolvers;
-	for (index = 0; index < gIODTResolvers->count; index++) {
+	unsigned int     index, count;
+
+	IOLockLock(gIODTResolversLock);
+
+	count = (gIODTResolvers->getLength() / sizeof(IODTPersistent));
+	entry = (typeof(entry))gIODTResolvers->getBytesNoCopy();
+	for (index = 0; index < count; index++) {
 		if (compareFunc == entry->compareFunc) {
 			break;
 		}
 		entry++;
 	}
-
-	if (index == gIODTResolvers->count) {
-		if (gIODTResolvers->alloc == gIODTResolvers->count) {
-			if (__improbable(os_mul_overflow(gIODTResolvers->alloc, 2,
-			    &gIODTResolvers->alloc))) {
-				panic("IODTSetResolving - gIODTResolvers alloc overflows");
-			}
-
-			newResolvers = IONewZero(IODTPersistent, gIODTResolvers->alloc);
-			if (__improbable(!newResolvers)) {
-				panic("IODTSetResolving - could not allocate new resolvers");
-			}
-
-			bcopy(gIODTResolvers->resolvers, newResolvers,
-			    sizeof(gIODTResolvers->resolvers[0]) * gIODTResolvers->count);
-
-			IODelete(gIODTResolvers->resolvers, IODTPersistent,
-			    gIODTResolvers->count);
-			gIODTResolvers->resolvers = newResolvers;
-		}
-
-		entry = &gIODTResolvers->resolvers[gIODTResolvers->count];
-		entry->compareFunc = compareFunc;
-		gIODTResolvers->count++;
-	}
-
-	IOLockUnlock(gIODTResolvers->lock);
+	if (index == count) {
+		persist.compareFunc = compareFunc;
+		if (!gIODTResolvers->appendBytes(&persist, sizeof(IODTPersistent))) {
+			panic("IODTSetResolving");
+		}
+	}
+
+	IOLockUnlock(gIODTResolversLock);
 
 	num = OSNumber::withNumber(index, 32);
 	regEntry->setProperty(gIODTPersistKey, num);
@@ -1150,7 +1061,7 @@
 
 	return diff;
 }
-#elif defined(__i386__) || defined(__x86_64__)
+#elif defined(__arm__) || defined(__i386__) || defined(__x86_64__)
 static SInt32
 DefaultCompare( UInt32 cellCount, UInt32 left[], UInt32 right[] )
 {
@@ -1167,7 +1078,7 @@
 	if (numCells == 1) {
 		cells[0] += (UInt32)offset;
 	} else {
-#if defined(__arm64__)
+#if defined(__arm64__) || defined(__arm__)
 		UInt64 sum = cells[numCells - 2] + offset;
 		cells[numCells - 2] = (UInt32)sum;
 		if (sum > UINT32_MAX) {
@@ -1221,11 +1132,11 @@
     UInt32 cellsIn[],
     IOPhysicalAddress * phys, IOPhysicalLength * lenOut )
 {
-	IORegistryEntry     * parent = NULL;
+	IORegistryEntry     * parent;
 	IORegistryEntry * regEntry;
 	OSData          * prop;
 	OSNumber    * num;
-	unsigned int  index;
+	unsigned int  index, count;
 	// cells in addresses at regEntry
 	UInt32              sizeCells, addressCells;
 	// cells in addresses below regEntry
@@ -1242,10 +1153,10 @@
 	SInt64              diff, diff2, endDiff;
 	UInt64              len, rangeLen;
 
+	IODTPersistent      *persist;
 	IODTCompareAddressCellFunc  compare;
 
 	regEntry = startEntry;
-	regEntry->retain();
 	IODTGetCellCounts( regEntry, &childSizeCells, &childAddressCells );
 	childCells = childAddressCells + childSizeCells;
 
@@ -1262,6 +1173,9 @@
 			/* end of the road */
 			*phys = CellsValue( childAddressCells, cell );
 			*phys += offset;
+			if (regEntry != startEntry) {
+				regEntry->release();
+			}
 			break;
 		}
 
@@ -1277,12 +1191,14 @@
 			compare = NULL;
 			num = OSDynamicCast(OSNumber, regEntry->getProperty(gIODTPersistKey));
 			if (num) {
-				IOLockLock(gIODTResolvers->lock);
+				IOLockLock(gIODTResolversLock);
 				index = num->unsigned32BitValue();
-				if (index < gIODTResolvers->count) {
-					compare = gIODTResolvers->resolvers[index].compareFunc;
-				}
-				IOLockUnlock(gIODTResolvers->lock);
+				count = gIODTResolvers->getLength() / sizeof(IODTPersistent);
+				if (index < count) {
+					persist = ((IODTPersistent *) gIODTResolvers->getBytesNoCopy()) + index;
+					compare = persist->compareFunc;
+				}
+				IOLockUnlock(gIODTResolversLock);
 			}
 
 			if (!compare && (addressCells == childAddressCells)) {
@@ -1356,15 +1272,14 @@
 			bzero( cell + addressCells, sizeof(UInt32) * sizeCells );
 		} /* else zero length range => pass thru to parent */
 
-		OSSafeReleaseNULL(regEntry);
+		if (regEntry != startEntry) {
+			regEntry->release();
+		}
 		regEntry                = parent;
-		parent = NULL;
 		childSizeCells          = sizeCells;
 		childAddressCells       = addressCells;
 		childCells              = childAddressCells + childSizeCells;
 	}while (ok && regEntry);
-
-	OSSafeReleaseNULL(regEntry);
 
 	return ok;
 }
@@ -1383,6 +1298,7 @@
 	IOPhysicalAddress   phys;
 	IOPhysicalLength    len;
 	OSArray                             *array;
+	IODeviceMemory              *range;
 
 	array = NULL;
 	do{
@@ -1408,7 +1324,6 @@
 
 		for (i = 0; i < num; i++) {
 			if (IODTResolveAddressCell( parentEntry, reg, &phys, &len )) {
-				IODeviceMemory *range;
 				range = NULL;
 				if (parent) {
 					range = IODeviceMemory::withSubRange( parent,
@@ -1419,7 +1334,6 @@
 				}
 				if (range) {
 					array->setObject( range );
-					OSSafeReleaseNULL(range);
 				}
 			}
 			reg += cells;
@@ -1442,7 +1356,7 @@
 	OSData                              *ret = NULL;
 	UInt32                              *bits;
 	UInt32                              i;
-	UInt32              nlen;
+	size_t              nlen;
 	char                                *names;
 	char                                *lastName;
 	UInt32                              mask;
@@ -1477,7 +1391,7 @@
 
 		for (i = 0; (i <= deviceNumber) && (names < lastName); i++) {
 			if (mask & (1 << i)) {
-				nlen = 1 + ((unsigned int) strnlen(names, lastName - names));
+				nlen = 1 + strnlen(names, lastName - names);
 				if (i == deviceNumber) {
 					data = OSData::withBytesNoCopy(names, nlen);
 					if (data) {