]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IORegistryEntry.cpp
xnu-3247.1.106.tar.gz
[apple/xnu.git] / iokit / Kernel / IORegistryEntry.cpp
index f039c28adef3a69569c91ca9391a7c124132efb0..1d9cf8f9d6314ca11eff3bd0649da55eb0a563d0 100644 (file)
@@ -60,11 +60,14 @@ OSDefineMetaClassAndStructors(IORegistryEntry, OSObject)
 #define kIORegPlaneNameSuffixLen       (sizeof(kIORegPlaneNameSuffix) - 1)
 #define kIORegPlaneLocationSuffixLen   (sizeof(kIORegPlaneLocationSuffix) - 1)
 
+#define KASLR_IOREG_DEBUG 0
+
 static IORegistryEntry * gRegistryRoot;
 static OSDictionary *   gIORegistryPlanes;
 
 const OSSymbol *       gIONameKey;
 const OSSymbol *       gIOLocationKey;
+const OSSymbol *       gIORegistryEntryIDKey;
 
 enum {
     kParentSetIndex    = 0,
@@ -75,6 +78,10 @@ enum {
     kIOMaxPlaneName    = 32
 };
 
+enum { kIORegistryIDReserved = (1ULL << 32) + 255 };
+
+static uint64_t gIORegistryLastID = kIORegistryIDReserved;
+
 class IORegistryPlane : public OSObject {
 
     friend class IORegistryEntry;
@@ -88,7 +95,7 @@ class IORegistryPlane : public OSObject {
     int                        reserved[2];
 
 public:
-    virtual bool serialize(OSSerialize *s) const;
+    virtual bool serialize(OSSerialize *s) const APPLE_KEXT_OVERRIDE;
 };
 
 OSDefineMetaClassAndStructors(IORegistryPlane, OSObject)
@@ -149,8 +156,12 @@ IORegistryEntry * IORegistryEntry::initialize( void )
                && gIORegistryPlanes );
         ok = gRegistryRoot->init();
 
+       if (ok)
+           gRegistryRoot->reserved->fRegistryEntryID = ++gIORegistryLastID;
+
        gIONameKey = OSSymbol::withCStringNoCopy( "IOName" );
        gIOLocationKey = OSSymbol::withCStringNoCopy( "IOLocation" );
+       gIORegistryEntryIDKey = OSSymbol::withCStringNoCopy( kIORegistryEntryIDKey );
 
        assert( ok && gIONameKey && gIOLocationKey );
 
@@ -261,8 +272,20 @@ bool IORegistryEntry::init( OSDictionary * dict )
     if( !super::init())
        return( false);
 
+    if (!reserved)
+    {
+       reserved = IONew(ExpansionData, 1);
+       if (!reserved)
+           return (false);
+       bzero(reserved, sizeof(ExpansionData));
+    }
     if( dict) {
-       dict->retain();
+       if (OSCollection::kImmutable & dict->setOptions(0, 0)) {
+           dict = (OSDictionary *) dict->copyCollection();
+           if (!dict)
+               return (false);
+       } else
+           dict->retain();
        if( fPropertyTable)
            fPropertyTable->release();
        fPropertyTable = dict;
@@ -307,11 +330,14 @@ bool IORegistryEntry::init( IORegistryEntry * old,
 
     WLOCK;
 
+    reserved = old->reserved;
+    old->reserved = NULL;
+
     fPropertyTable = old->getPropertyTable();
     fPropertyTable->retain();
 #ifdef IOREGSPLITTABLES
     fRegistryTable = old->fRegistryTable;
-    old->fRegistryTable = OSDictionary::withDictionary( fRegistryTable );
+    old->fRegistryTable = (OSDictionary *) fRegistryTable->copyCollection();
 #endif /* IOREGSPLITTABLES */
 
     old->registryTable()->removeObject( plane->keys[ kParentSetIndex ] );
@@ -340,19 +366,11 @@ bool IORegistryEntry::init( IORegistryEntry * old,
 
 void IORegistryEntry::free( void )
 {
-
 #if DEBUG_FREE
-#define msg ": attached at free()"
-    int len = strlen(msg) + 40;
-    char buf[len];
-
     if( registryTable() && gIOServicePlane) {
         if( getParentSetReference( gIOServicePlane )
             || getChildSetReference( gIOServicePlane )) {
-
-            strlcpy( buf, getName(), 32);
-            strlcat( buf, msg, len );
-            IOPanic( buf );
+            panic("%s: attached at free()", getName());
         }
     }
 #endif
@@ -365,6 +383,9 @@ void IORegistryEntry::free( void )
         registryTable()->release();
 #endif /* IOREGSPLITTABLES */
 
+    if (reserved)
+       IODelete(reserved, ExpansionData, 1);
+
     super::free();
 }
 
@@ -507,6 +528,15 @@ IORegistryEntry::removeProperty( const OSSymbol * aKey)
     PUNLOCK;
 }
 
+#if KASLR_IOREG_DEBUG
+extern "C" {
+    
+bool ScanForAddrInObject(OSObject * theObject, 
+                         int indent);
+    
+}; /* extern "C" */
+#endif
+
 bool
 IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject)
 {
@@ -524,7 +554,18 @@ IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject)
 
     ret = getPropertyTable()->setObject( aKey, anObject );
     PUNLOCK;
-    
+
+#if KASLR_IOREG_DEBUG
+    if ( anObject && strcmp(kIOKitDiagnosticsKey, aKey->getCStringNoCopy()) != 0 ) {
+        if (ScanForAddrInObject(anObject, 0)) {
+            IOLog("%s: IORegistryEntry name %s with key \"%s\" \n",
+                  __FUNCTION__,
+                  getName(0),
+                  aKey->getCStringNoCopy() );        
+        }
+    }
+#endif
+
     return ret;
 }
 
@@ -845,7 +886,7 @@ bool IORegistryEntry::getPath(      char * path, int * length,
     OSArray *          stack;
     IORegistryEntry *  root;
     const IORegistryEntry * entry;
-    IORegistryEntry *  parent;
+    const IORegistryEntry * parent;
     const OSSymbol *   alias;
     int                        index;
     int                        len, maxLength, compLen, aliasLen;
@@ -876,67 +917,62 @@ bool IORegistryEntry::getPath(    char * path, int * length,
        return( ok );
     }
 
-    entry = this;
-    parent = entry->getParentEntry( plane );
-    if( !parent)
-       // Error if not attached in plane
-       return( false);
-
     stack = OSArray::withCapacity( getDepth( plane ));
-    if( !stack)
-       return( false);
+    if (!stack) return( false);
 
     RLOCK;
 
+    parent = entry = this;
     root = gRegistryRoot->getChildEntry( plane );
-    while( parent && (entry != root)) {
+    while (parent && (parent != root))
+    {
        // stop below root
-       stack->setObject( (OSObject *) entry );
        entry = parent;
        parent = entry->getParentEntry( plane );
+       stack->setObject( (OSObject *) entry );
     }
 
-    index = stack->getCount();
-    ok = true;
-
-    if( 0 == index) {
-
-        *nextComp++ = '/';
-        *nextComp = 0;
-        len++;
-
-    } else while( ok && ((--index) >= 0)) {
-
-        entry = (IORegistryEntry *) stack->getObject((unsigned int) index );
-        assert( entry );
-
-        if( (alias = entry->hasAlias( plane ))) {
-            len = plane->nameKey->getLength() + 1;
-            nextComp = path + len;
-
-            compLen = alias->getLength();
-            ok = (maxLength > (len + compLen));
-            if( ok)
-                strlcpy( nextComp, alias->getCStringNoCopy(), compLen + 1);
-        } else {
-            compLen = maxLength - len;
-            ok = entry->getPathComponent( nextComp + 1, &compLen, plane );
-
-            if( ok && compLen) {
-                compLen++;
-                *nextComp = '/';
+    ok = (0 != parent);
+    if (ok)
+    {
+        index = stack->getCount();
+        if( 0 == index) {
+
+            *nextComp++ = '/';
+            *nextComp = 0;
+            len++;
+
+        } else while( ok && ((--index) >= 0)) {
+
+            entry = (IORegistryEntry *) stack->getObject((unsigned int) index );
+            assert( entry );
+
+            if( (alias = entry->hasAlias( plane ))) {
+                len = plane->nameKey->getLength() + 1;
+                nextComp = path + len;
+
+                compLen = alias->getLength();
+                ok = (maxLength > (len + compLen));
+                if( ok)
+                    strlcpy( nextComp, alias->getCStringNoCopy(), compLen + 1);
+            } else {
+                compLen = maxLength - len;
+                ok = entry->getPathComponent( nextComp + 1, &compLen, plane );
+
+                if( ok && compLen) {
+                    compLen++;
+                    *nextComp = '/';
+                }
             }
-        }
 
-        if( ok) {
-            len += compLen;
-            nextComp += compLen;
+            if( ok) {
+                len += compLen;
+                nextComp += compLen;
+            }
         }
+        *length = len;
     }
-    *length = len;
-
     UNLOCK;
-
     stack->release();
 
     return( ok );
@@ -1593,6 +1629,9 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
 
     WLOCK;
 
+    if (!reserved->fRegistryEntryID)
+       reserved->fRegistryEntryID = ++gIORegistryLastID;
+
     ret = makeLink( parent, kParentSetIndex, plane );
 
     if( (links = parent->getChildSetReference( plane )))
@@ -1633,6 +1672,14 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
     return( ret );
 }
 
+uint64_t IORegistryEntry::getRegistryEntryID( void )
+{
+    if (reserved)
+       return (reserved->fRegistryEntryID);
+    else
+       return (0);
+}
+
 bool IORegistryEntry::attachToChild( IORegistryEntry * child,
                                         const IORegistryPlane * plane )
 {
@@ -1717,8 +1764,11 @@ void IORegistryEntry::detachAbove( const IORegistryPlane * plane )
     IORegistryEntry *  parent;
 
     retain();
-    while( (parent = getParentEntry( plane )))
+    while( (parent = copyParentEntry( plane )))
+    {
        detachFromParent( parent, plane );
+       parent->release();
+    }
     release();
 }
 
@@ -2009,13 +2059,21 @@ OSOrderedSet * IORegistryIterator::iterateAll( void )
     return( done);
 }
 
+#if __LP64__
+OSMetaClassDefineReservedUnused(IORegistryEntry, 0);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 1);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 2);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 3);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 4);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 5);
+#else
 OSMetaClassDefineReservedUsed(IORegistryEntry, 0);
 OSMetaClassDefineReservedUsed(IORegistryEntry, 1);
 OSMetaClassDefineReservedUsed(IORegistryEntry, 2);
 OSMetaClassDefineReservedUsed(IORegistryEntry, 3);
 OSMetaClassDefineReservedUsed(IORegistryEntry, 4);
 OSMetaClassDefineReservedUsed(IORegistryEntry, 5);
-
+#endif
 OSMetaClassDefineReservedUnused(IORegistryEntry, 6);
 OSMetaClassDefineReservedUnused(IORegistryEntry, 7);
 OSMetaClassDefineReservedUnused(IORegistryEntry, 8);