X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/2d21ac55c334faf3a56e5634905ed6987fc787d4..d190cdc3f5544636abb56dc1874be391d3e1b148:/iokit/Kernel/IORegistryEntry.cpp diff --git a/iokit/Kernel/IORegistryEntry.cpp b/iokit/Kernel/IORegistryEntry.cpp index f039c28ad..f07b42318 100644 --- a/iokit/Kernel/IORegistryEntry.cpp +++ b/iokit/Kernel/IORegistryEntry.cpp @@ -25,23 +25,19 @@ * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ -/* - * Copyright (c) 1998 Apple Computer, Inc. All rights reserved. - * - * HISTORY - * 12 Nov 98 sdouglas created. - * - */ #include #include #include #include +#include #include #include +#include "IOKitKernelInternal.h" + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define super OSObject @@ -60,11 +56,23 @@ OSDefineMetaClassAndStructors(IORegistryEntry, OSObject) #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, @@ -75,6 +83,10 @@ enum { kIOMaxPlaneName = 32 }; +enum { kIORegistryIDReserved = (1ULL << 32) + 255 }; + +static uint64_t gIORegistryLastID = kIORegistryIDReserved; + class IORegistryPlane : public OSObject { friend class IORegistryEntry; @@ -88,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) @@ -103,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 @@ -149,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 ); @@ -171,6 +188,10 @@ SInt32 IORegistryEntry::getGenerationCount( void ) return( gIORegistryGenerationCount ); } +SInt32 IORegistryEntry::getRegistryEntryGenerationCount(void) const +{ + return (reserved->fRegistryEntryGenerationCount); +} const IORegistryPlane * IORegistryEntry::makePlane( const char * name ) { @@ -261,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; @@ -305,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 ] ); @@ -340,19 +385,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,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; } @@ -452,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; @@ -507,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) { @@ -524,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; } @@ -749,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; @@ -845,7 +933,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 +964,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 ); @@ -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 @@ -1587,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 ))) @@ -1602,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 @@ -1633,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 ) { @@ -1717,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(); } @@ -2009,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);