]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IORegistryEntry.cpp
xnu-3789.31.2.tar.gz
[apple/xnu.git] / iokit / Kernel / IORegistryEntry.cpp
index f10f82d6a959aee0e311f5789bbc27c7805de128..f07b4231805428004c7417c315a87b4d645e3730 100644 (file)
@@ -1,49 +1,43 @@
 /*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * This file contains Original Code and/or Modifications of Original Code 
- * as defined in and that are subject to the Apple Public Source License 
- * Version 2.0 (the 'License'). You may not use this file except in 
- * compliance with the License.  The rights granted to you under the 
- * License may not be used to create, or enable the creation or 
- * redistribution of, unlawful or unlicensed copies of an Apple operating 
- * system, or to circumvent, violate, or enable the circumvention or 
- * violation of, any terms of an Apple operating system software license 
- * agreement.
- *
- * Please obtain a copy of the License at 
- * http://www.opensource.apple.com/apsl/ and read it before using this 
- * file.
- *
- * The Original Code and all software distributed under the License are 
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
- * Please see the License for the specific language governing rights and 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
  * limitations under the License.
- *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
- */
-/*
- * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved. 
- *
- * HISTORY
- * 12 Nov 98 sdouglas created.
- *
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 #include <IOKit/IORegistryEntry.h>
 #include <libkern/c++/OSContainers.h>
 #include <IOKit/IOService.h>
 #include <IOKit/IOKitKeys.h>
+#include <IOKit/IOTimeStamp.h>
 
 #include <IOKit/IOLib.h>
 
 #include <IOKit/assert.h>
 
+#include "IOKitKernelInternal.h"
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 #define super OSObject
@@ -56,13 +50,29 @@ OSDefineMetaClassAndStructors(IORegistryEntry, OSObject)
 #define kIORegPlaneChildSuffix         "ChildLinks"
 #define kIORegPlaneNameSuffix          "Name"
 #define kIORegPlaneLocationSuffix      "Location"
+
 #define kIORegPlaneParentSuffixLen     (sizeof(kIORegPlaneParentSuffix) - 1)
+#define kIORegPlaneChildSuffixLen      (sizeof(kIORegPlaneChildSuffix) - 1)
+#define kIORegPlaneNameSuffixLen       (sizeof(kIORegPlaneNameSuffix) - 1)
+#define kIORegPlaneLocationSuffixLen   (sizeof(kIORegPlaneLocationSuffix) - 1)
+
+#define KASLR_IOREG_DEBUG 0
+
+struct IORegistryEntry::ExpansionData
+{
+    IORecursiveLock * fLock;
+    uint64_t         fRegistryEntryID;
+    SInt32            fRegistryEntryGenerationCount;
+};
+
 
 static IORegistryEntry * gRegistryRoot;
 static OSDictionary *   gIORegistryPlanes;
 
 const OSSymbol *       gIONameKey;
 const OSSymbol *       gIOLocationKey;
+const OSSymbol *       gIORegistryEntryIDKey;
+const OSSymbol *       gIORegistryEntryPropertyKeysKey;
 
 enum {
     kParentSetIndex    = 0,
@@ -73,6 +83,10 @@ enum {
     kIOMaxPlaneName    = 32
 };
 
+enum { kIORegistryIDReserved = (1ULL << 32) + 255 };
+
+static uint64_t gIORegistryLastID = kIORegistryIDReserved;
+
 class IORegistryPlane : public OSObject {
 
     friend class IORegistryEntry;
@@ -86,7 +100,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)
@@ -101,8 +115,8 @@ static SInt32                       gIORegistryGenerationCount;
                gIORegistryGenerationCount++
                // make atomic
 
-#define PUNLOCK        IORecursiveLockUnlock( gPropertiesLock )
-#define PLOCK  IORecursiveLockLock( gPropertiesLock )
+#define PUNLOCK        IORecursiveLockUnlock( reserved->fLock )
+#define PLOCK  IORecursiveLockLock( reserved->fLock )
 
 #define IOREGSPLITTABLES
 
@@ -147,8 +161,13 @@ 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 );
+        gIORegistryEntryPropertyKeysKey = OSSymbol::withCStringNoCopy( kIORegistryEntryPropertyKeysKey );
 
        assert( ok && gIONameKey && gIOLocationKey );
 
@@ -169,6 +188,10 @@ SInt32 IORegistryEntry::getGenerationCount( void )
     return( gIORegistryGenerationCount );
 }
 
+SInt32 IORegistryEntry::getRegistryEntryGenerationCount(void) const
+{
+    return (reserved->fRegistryEntryGenerationCount);
+}
 
 const IORegistryPlane * IORegistryEntry::makePlane( const char * name )
 {
@@ -181,22 +204,21 @@ const IORegistryPlane * IORegistryEntry::makePlane( const char * name )
     char               key[ kIOMaxPlaneName + 16 ];
     char *             end;
 
-    strncpy( key, name, kIOMaxPlaneName );
-    key[ kIOMaxPlaneName ] = 0;
-    end = key + strlen( name );
+    strlcpy( key, name, kIOMaxPlaneName + 1 );
+    end = key + strlen( key );
 
     nameKey = OSSymbol::withCString( key);
 
-    strcpy( end, kIORegPlaneParentSuffix );
+    strlcpy( end, kIORegPlaneParentSuffix, kIORegPlaneParentSuffixLen + 1 );
     parentKey = OSSymbol::withCString( key);
 
-    strcpy( end, kIORegPlaneChildSuffix );
+    strlcpy( end, kIORegPlaneChildSuffix, kIORegPlaneChildSuffixLen + 1 );
     childKey = OSSymbol::withCString( key);
 
-    strcpy( end, kIORegPlaneNameSuffix );
+    strlcpy( end, kIORegPlaneNameSuffix, kIORegPlaneNameSuffixLen + 1 );
     pathNameKey = OSSymbol::withCString( key);
 
-    strcpy( end, kIORegPlaneLocationSuffix );
+    strlcpy( end, kIORegPlaneLocationSuffix, kIORegPlaneLocationSuffixLen + 1 );
     pathLocationKey = OSSymbol::withCString( key);
 
     plane = new IORegistryPlane;
@@ -260,8 +282,22 @@ bool IORegistryEntry::init( OSDictionary * dict )
     if( !super::init())
        return( false);
 
+    if (!reserved)
+    {
+       reserved = IONew(ExpansionData, 1);
+       if (!reserved)
+           return (false);
+       bzero(reserved, sizeof(ExpansionData));
+       reserved->fLock = IORecursiveLockAlloc();
+       if (!reserved->fLock) return (false);
+    }
     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;
@@ -304,13 +340,23 @@ bool IORegistryEntry::init( IORegistryEntry * old,
     if( !super::init())
        return( false);
 
+    if (!reserved)
+    {
+       reserved = IONew(ExpansionData, 1);
+       if (!reserved) return (false);
+       bzero(reserved, sizeof(ExpansionData));
+       reserved->fLock = IORecursiveLockAlloc();
+       if (!reserved->fLock) return (false);
+    }
+
     WLOCK;
 
-    fPropertyTable = old->getPropertyTable();
-    fPropertyTable->retain();
+    reserved->fRegistryEntryID = old->reserved->fRegistryEntryID;
+
+    fPropertyTable = old->dictionaryWithProperties();
 #ifdef IOREGSPLITTABLES
     fRegistryTable = old->fRegistryTable;
-    old->fRegistryTable = OSDictionary::withDictionary( fRegistryTable );
+    old->fRegistryTable = (OSDictionary *) fRegistryTable->copyCollection();
 #endif /* IOREGSPLITTABLES */
 
     old->registryTable()->removeObject( plane->keys[ kParentSetIndex ] );
@@ -339,19 +385,11 @@ bool IORegistryEntry::init( IORegistryEntry * old,
 
 void IORegistryEntry::free( void )
 {
-
 #if DEBUG_FREE
-#define msg ": attached at free()"
-    char buf[ strlen(msg) + 40 ];
-
     if( registryTable() && gIOServicePlane) {
         if( getParentSetReference( gIOServicePlane )
             || getChildSetReference( gIOServicePlane )) {
-
-            strncpy( buf, getName(), 32);
-            buf[32] = 0;
-            strcat( buf, msg );
-            IOPanic( buf );
+            panic("%s: attached at free()", getName());
         }
     }
 #endif
@@ -364,15 +402,22 @@ void IORegistryEntry::free( void )
         registryTable()->release();
 #endif /* IOREGSPLITTABLES */
 
+    if (reserved)
+    {
+       if (reserved->fLock) IORecursiveLockFree(reserved->fLock);
+       IODelete(reserved, ExpansionData, 1);
+    }
+
     super::free();
 }
 
 void IORegistryEntry::setPropertyTable( OSDictionary * dict )
 {
-    if( fPropertyTable)
-       fPropertyTable->release();
     if( dict)
        dict->retain();
+    if( fPropertyTable)
+       fPropertyTable->release();
+
     fPropertyTable = dict;
 }
 
@@ -451,11 +496,22 @@ bool IORegistryEntry::serializeProperties( OSSerialize * s ) const
     OSCollection *snapshotProperties = getPropertyTable()->copyCollection();
     PUNLOCK;
 
+    if (!snapshotProperties) return (false);
+
     bool ok =  snapshotProperties->serialize( s );
     snapshotProperties->release();
     return( ok );
 }
 
+OSArray * IORegistryEntry::copyPropertyKeys(void) const
+{
+    PLOCK;
+    OSArray * keys = getPropertyTable()->copyKeys();
+    PUNLOCK;
+
+    return (keys);
+}
+
 OSDictionary * IORegistryEntry::dictionaryWithProperties( void ) const
 {
     OSDictionary *     dict;
@@ -506,6 +562,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)
 {
@@ -523,7 +588,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;
 }
 
@@ -748,6 +824,19 @@ void IORegistryEntry::setName( const OSSymbol * name,
         else
             key = gIONameKey;
 
+        if (gIOKitTrace && reserved && reserved->fRegistryEntryID)
+        {
+            uint64_t str_id = 0;
+            uint64_t __unused regID = getRegistryEntryID();
+            kernel_debug_string(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME_STRING), &str_id, name->getCStringNoCopy());
+            KERNEL_DEBUG_CONSTANT(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME),
+                (uintptr_t) regID,
+                (uintptr_t) (regID >> 32),
+                (uintptr_t) str_id,
+                (uintptr_t) (str_id >> 32),
+                0);
+        }
+
        WLOCK;
         registryTable()->setObject( key, (OSObject *) name);
        UNLOCK;
@@ -844,10 +933,10 @@ 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;
+    int                        len, maxLength, compLen, aliasLen;
     char *             nextComp;
     bool               ok;
 
@@ -861,80 +950,76 @@ bool IORegistryEntry::getPath(    char * path, int * length,
     len = plane->nameKey->getLength();
     if( len >= maxLength)
        return( false);
-    strcpy( nextComp, plane->nameKey->getCStringNoCopy());
+    strlcpy( nextComp, plane->nameKey->getCStringNoCopy(), len + 1);
     nextComp[ len++ ] = ':';
     nextComp += len;
 
     if( (alias = hasAlias( plane ))) {
-       len += alias->getLength();
+       aliasLen = alias->getLength();
+       len += aliasLen;
        ok = (maxLength > len);
        *length = len;
        if( ok)
-           strcpy( nextComp, alias->getCStringNoCopy());
+           strlcpy( nextComp, alias->getCStringNoCopy(), aliasLen + 1);
        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)
-                strcpy( nextComp, alias->getCStringNoCopy());
-        } 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 );
@@ -957,14 +1042,14 @@ bool IORegistryEntry::getPathComponent( char * path, int * length,
     else
        locLen = 0;
 
-    ok = ((len + locLen) < maxLength);
+    ok = ((len + locLen + 1) < maxLength);
     if( ok) {
-        strcpy( path, compName );
+        strlcpy( path, compName, len + 1 );
        if( loc) {
             path += len;
             len += locLen;
             *path++ = '@';
-            strcpy( path, loc );
+            strlcpy( path, loc, locLen );
        }
         *length = len;
     }
@@ -1125,8 +1210,7 @@ const char * IORegistryEntry::dealiasPath(
         {}
     end--;
     if( (end - path) < kIOMaxPlaneName) {
-        strncpy( temp, path, end - path );
-        temp[ end - path ] = 0;
+        strlcpy( temp, path, end - path + 1 );
 
         RLOCK;
         entry = IORegistryEntry::fromPath( "/aliases", plane );
@@ -1169,8 +1253,7 @@ IORegistryEntry * IORegistryEntry::fromPath(
        // get plane name
         end = strchr( path, ':' );
        if( end && ((end - path) < kIOMaxPlaneName)) {
-           strncpy( temp, path, end - path );
-           temp[ end - path ] = 0;
+           strlcpy( temp, path, end - path + 1 );
             plane = getPlane( temp );
            path = end + 1;
        }
@@ -1221,10 +1304,10 @@ IORegistryEntry * IORegistryEntry::fromPath(
 
        if( opath && length) {
             // copy out residual path
-           len2 = len + strlen( path );
-           if( len2 < *length)
-                strcpy( opath + len, path );
-           *length = len2;
+           len2 = strlen( path );
+           if( (len + len2) < *length)
+                strlcpy( opath + len, path, len2 + 1 );
+           *length = (len + len2);
 
        } else if( path[0])
            // no residual path => must be no tail for success
@@ -1298,6 +1381,7 @@ bool IORegistryEntry::makeLink( IORegistryEntry * to,
             links->release();
        }
     }
+    reserved->fRegistryEntryGenerationCount++;
 
     return( result);
 }
@@ -1318,6 +1402,7 @@ void IORegistryEntry::breakLink( IORegistryEntry * to,
                 registryTable()->removeObject( plane->keys[ relation ]);
            }
     }
+    reserved->fRegistryEntryGenerationCount++;
 }
 
 
@@ -1417,6 +1502,18 @@ OSIterator * IORegistryEntry::getChildIterator( const IORegistryPlane * plane )
     return( iter );
 }
 
+uint32_t IORegistryEntry::getChildCount( const IORegistryPlane * plane ) const
+{
+    OSArray * links;
+    uint32_t  count = 0;
+
+    RLOCK;
+    links = getChildSetReference( plane );
+    if (links) count = links->getCount();
+    UNLOCK;
+
+    return (count);
+}
 
 IORegistryEntry * IORegistryEntry::copyChildEntry(
                                const IORegistryPlane * plane ) const
@@ -1558,12 +1655,16 @@ bool IORegistryEntry::inPlane( const IORegistryPlane * plane ) const
            const OSSymbol *key;
 
             while( (key = (OSSymbol *) iter->getNextObject()) ) {
-               const char *keysuffix;
+               size_t keysuffix;
 
                // Get a pointer to this keys suffix
-               keysuffix = key->getCStringNoCopy()
-                         + key->getLength() - kIORegPlaneParentSuffixLen;
-               if( !strcmp(keysuffix, kIORegPlaneParentSuffix) ) {
+               keysuffix = key->getLength();
+               if (keysuffix <= kIORegPlaneParentSuffixLen)
+                   continue;
+               keysuffix -= kIORegPlaneParentSuffixLen;
+               if( !strncmp(key->getCStringNoCopy() + keysuffix, 
+                               kIORegPlaneParentSuffix, 
+                               kIORegPlaneParentSuffixLen + 1) ) {
                    ret = true;
                    break;
                }
@@ -1583,12 +1684,19 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
     OSArray *  links;
     bool       ret;
     bool       needParent;
+    bool        traceName = false;
 
     if( this == parent)
        return( false );
 
     WLOCK;
 
+    if (!reserved->fRegistryEntryID)
+    {
+       reserved->fRegistryEntryID = ++gIORegistryLastID;
+       traceName = (0 != gIOKitTrace);
+    }
+
     ret = makeLink( parent, kParentSetIndex, plane );
 
     if( (links = parent->getChildSetReference( plane )))
@@ -1598,6 +1706,19 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
 
     UNLOCK;
 
+    if (traceName)
+    {
+        uint64_t str_id = 0;
+        uint64_t __unused regID = getRegistryEntryID();
+        kernel_debug_string(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME_STRING), &str_id, getName());
+        KERNEL_DEBUG_CONSTANT(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME),
+            (uintptr_t) regID,
+            (uintptr_t) (regID >> 32),
+            (uintptr_t) str_id,
+            (uintptr_t) (str_id >> 32),
+            0);
+    }
+
     PLOCK;
 
     // Mark any collections in the property list as immutable
@@ -1629,6 +1750,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 )
 {
@@ -1713,8 +1842,11 @@ void IORegistryEntry::detachAbove( const IORegistryPlane * plane )
     IORegistryEntry *  parent;
 
     retain();
-    while( (parent = getParentEntry( plane )))
+    while( (parent = copyParentEntry( plane )))
+    {
        detachFromParent( parent, plane );
+       parent->release();
+    }
     release();
 }
 
@@ -1859,7 +1991,7 @@ void IORegistryIterator::enterEntry( const IORegistryPlane * enterPlane )
     IORegCursor *      prev;
 
     prev = where;
-    where = (IORegCursor *) IOMalloc( sizeof( IORegCursor));
+    where = (IORegCursor *) IOMalloc( sizeof(IORegCursor));
     assert( where);
 
     if( where) {
@@ -1889,7 +2021,7 @@ bool IORegistryIterator::exitEntry( void )
     if( where != &start) {
        gone = where;
         where = gone->next;
-        IOFree( gone, sizeof( IORegCursor));
+        IOFree( gone, sizeof(IORegCursor));
        return( true);
 
     } else
@@ -2005,13 +2137,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);