X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..3e170ce000f1506b7b5d2c5c7faec85ceabb573d:/iokit/Kernel/IORegistryEntry.cpp diff --git a/iokit/Kernel/IORegistryEntry.cpp b/iokit/Kernel/IORegistryEntry.cpp index f95427287..1d9cf8f9d 100644 --- a/iokit/Kernel/IORegistryEntry.cpp +++ b/iokit/Kernel/IORegistryEntry.cpp @@ -1,16 +1,19 @@ /* - * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @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. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * 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 @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * Copyright (c) 1998 Apple Computer, Inc. All rights reserved. @@ -47,11 +50,24 @@ OSDefineMetaClassAndStructors(IORegistryEntry, OSObject) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#define kIORegPlaneParentSuffix "ParentLinks" +#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 + static IORegistryEntry * gRegistryRoot; static OSDictionary * gIORegistryPlanes; const OSSymbol * gIONameKey; const OSSymbol * gIOLocationKey; +const OSSymbol * gIORegistryEntryIDKey; enum { kParentSetIndex = 0, @@ -62,6 +78,10 @@ enum { kIOMaxPlaneName = 32 }; +enum { kIORegistryIDReserved = (1ULL << 32) + 255 }; + +static uint64_t gIORegistryLastID = kIORegistryIDReserved; + class IORegistryPlane : public OSObject { friend class IORegistryEntry; @@ -75,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) @@ -84,9 +104,9 @@ OSDefineMetaClassAndStructors(IORegistryPlane, OSObject) static IORecursiveLock * gPropertiesLock; static SInt32 gIORegistryGenerationCount; -#define UNLOCK s_lock_done( &gIORegistryLock ) -#define RLOCK s_lock_read( &gIORegistryLock ) -#define WLOCK s_lock_write( &gIORegistryLock ); \ +#define UNLOCK lck_rw_done( &gIORegistryLock ) +#define RLOCK lck_rw_lock_shared( &gIORegistryLock ) +#define WLOCK lck_rw_lock_exclusive( &gIORegistryLock ); \ gIORegistryGenerationCount++ // make atomic @@ -105,173 +125,11 @@ static SInt32 gIORegistryGenerationCount; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -struct s_lock_t { - decl_simple_lock_data(,interlock) /* "hardware" interlock field */ - volatile unsigned int - read_count:16, /* No. of accepted readers */ - want_upgrade:1, /* Read-to-write upgrade waiting */ - want_write:1, /* Writer is waiting, or - locked for write */ - waiting:1, /* Someone is sleeping on lock */ - can_sleep:1; /* Can attempts to lock go to sleep? */ -}; - -static struct s_lock_t gIORegistryLock; - -/* Time we loop without holding the interlock. - * The former is for when we cannot sleep, the latter - * for when our thread can go to sleep (loop less) - * we shouldn't retake the interlock at all frequently - * if we cannot go to sleep, since it interferes with - * any other processors. In particular, 100 is too small - * a number for powerpc MP systems because of cache - * coherency issues and differing lock fetch times between - * the processors - */ -static unsigned int lock_wait_time[2] = { (unsigned int)-1, 100 } ; - -static void -s_lock_init( - s_lock_t *l, - boolean_t can_sleep) -{ - (void) memset((void *) l, 0, sizeof(s_lock_t)); - - simple_lock_init(&l->interlock, 0); - l->want_write = FALSE; - l->want_upgrade = FALSE; - l->read_count = 0; - l->can_sleep = can_sleep; -} - -static void -s_lock_write( - register s_lock_t * l) -{ - register int i; - - simple_lock(&l->interlock); - - /* - * Try to acquire the want_write bit. - */ - while (l->want_write) { - - i = lock_wait_time[l->can_sleep ? 1 : 0]; - if (i != 0) { - simple_unlock(&l->interlock); - while (--i != 0 && l->want_write) - continue; - simple_lock(&l->interlock); - } - - if (l->can_sleep && l->want_write) { - l->waiting = TRUE; - thread_sleep_simple_lock((event_t) l, - simple_lock_addr(l->interlock), - THREAD_UNINT); - /* interlock relocked */ - } - } - l->want_write = TRUE; - - /* Wait for readers (and upgrades) to finish */ - - while ((l->read_count != 0) || l->want_upgrade) { - - i = lock_wait_time[l->can_sleep ? 1 : 0]; - if (i != 0) { - simple_unlock(&l->interlock); - while (--i != 0 && (l->read_count != 0 || - l->want_upgrade)) - continue; - simple_lock(&l->interlock); - } - - if (l->can_sleep && (l->read_count != 0 || l->want_upgrade)) { - l->waiting = TRUE; - thread_sleep_simple_lock((event_t) l, - simple_lock_addr(l->interlock), - THREAD_UNINT); - /* interlock relocked */ - } - } - - simple_unlock(&l->interlock); -} - -static void -s_lock_done( - register s_lock_t * l) -{ - boolean_t do_wakeup = FALSE; - - simple_lock(&l->interlock); - - if (l->read_count != 0) { - l->read_count -= 1; - } - else { - if (l->want_upgrade) { - l->want_upgrade = FALSE; - } - else { - l->want_write = FALSE; - } - } - - /* - * There is no reason to wakeup a waiting thread - * if the read-count is non-zero. Consider: - * we must be dropping a read lock - * threads are waiting only if one wants a write lock - * if there are still readers, they can't proceed - */ - if (l->waiting && (l->read_count == 0)) { - l->waiting = FALSE; - do_wakeup = TRUE; - } - - simple_unlock(&l->interlock); - - if (do_wakeup) - thread_wakeup((event_t) l); -} - -static void -s_lock_read( - register s_lock_t * l) -{ - register int i; - - simple_lock(&l->interlock); - - while ( l->want_upgrade || ((0 == l->read_count) && l->want_write )) { - - i = lock_wait_time[l->can_sleep ? 1 : 0]; +lck_rw_t gIORegistryLock; +lck_grp_t *gIORegistryLockGrp; +lck_grp_attr_t *gIORegistryLockGrpAttr; +lck_attr_t *gIORegistryLockAttr; - if (i != 0) { - simple_unlock(&l->interlock); - while (--i != 0 && - (l->want_upgrade || ((0 == l->read_count) && l->want_write ))) - continue; - simple_lock(&l->interlock); - } - - if (l->can_sleep && - (l->want_upgrade || ((0 == l->read_count) && l->want_write ))) { - l->waiting = TRUE; - thread_sleep_simple_lock((event_t) l, - simple_lock_addr(l->interlock), - THREAD_UNINT); - /* interlock relocked */ - } - } - - l->read_count += 1; - simple_unlock(&l->interlock); - -} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -281,7 +139,15 @@ IORegistryEntry * IORegistryEntry::initialize( void ) if( !gRegistryRoot) { - s_lock_init( &gIORegistryLock, true ); + + gIORegistryLockGrpAttr = lck_grp_attr_alloc_init(); + //lck_grp_attr_setstat(gIORegistryLockGrpAttr); + gIORegistryLockGrp = lck_grp_alloc_init("IORegistryLock", gIORegistryLockGrpAttr); + gIORegistryLockAttr = lck_attr_alloc_init(); + lck_attr_rw_shared_priority(gIORegistryLockAttr); + //lck_attr_setdebug(gIORegistryLockAttr); + lck_rw_init( &gIORegistryLock, gIORegistryLockGrp, gIORegistryLockAttr); + gRegistryRoot = new IORegistryEntry; gPropertiesLock = IORecursiveLockAlloc(); gIORegistryPlanes = OSDictionary::withCapacity( 1 ); @@ -290,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 ); @@ -324,22 +194,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, "ParentLinks" ); + strlcpy( end, kIORegPlaneParentSuffix, kIORegPlaneParentSuffixLen + 1 ); parentKey = OSSymbol::withCString( key); - strcpy( end, "ChildLinks" ); + strlcpy( end, kIORegPlaneChildSuffix, kIORegPlaneChildSuffixLen + 1 ); childKey = OSSymbol::withCString( key); - strcpy( end, "Name" ); + strlcpy( end, kIORegPlaneNameSuffix, kIORegPlaneNameSuffixLen + 1 ); pathNameKey = OSSymbol::withCString( key); - strcpy( end, "Location" ); + strlcpy( end, kIORegPlaneLocationSuffix, kIORegPlaneLocationSuffixLen + 1 ); pathLocationKey = OSSymbol::withCString( key); plane = new IORegistryPlane; @@ -396,15 +265,27 @@ bool IORegistryPlane::serialize(OSSerialize *s) const enum { kIORegCapacityIncrement = 4 }; -bool IORegistryEntry::init( OSDictionary * dict = 0 ) +bool IORegistryEntry::init( OSDictionary * dict ) { OSString * prop; 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; @@ -449,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 ] ); @@ -482,19 +366,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 @@ -507,6 +383,9 @@ void IORegistryEntry::free( void ) registryTable()->release(); #endif /* IOREGSPLITTABLES */ + if (reserved) + IODelete(reserved, ExpansionData, 1); + super::free(); } @@ -523,19 +402,6 @@ void IORegistryEntry::setPropertyTable( OSDictionary * dict ) /* Wrappers to synchronize property table */ -#define wrap1(func, type, constant) \ -OSObject * \ -IORegistryEntry::func ## Property( type * aKey) constant \ -{ \ - OSObject * obj; \ - \ - PLOCK; \ - obj = getPropertyTable()->func ## Object( aKey ); \ - PUNLOCK; \ - \ - return( obj ); \ -} - #define wrap2(type, constant) \ OSObject * \ IORegistryEntry::copyProperty( type * aKey) constant \ @@ -551,15 +417,6 @@ IORegistryEntry::copyProperty( type * aKey) constant \ return( obj ); \ } -#define wrap3(func,type,constant) \ -void \ -IORegistryEntry::func ## Property( type * aKey) constant \ -{ \ - PLOCK; \ - getPropertyTable()->func ## Object( aKey ); \ - PUNLOCK; \ -} - #define wrap4(type,constant) \ OSObject * \ IORegistryEntry::getProperty( type * aKey, \ @@ -610,14 +467,14 @@ IORegistryEntry::copyProperty( type * aKey, \ bool IORegistryEntry::serializeProperties( OSSerialize * s ) const { - bool ok; - // setProperty( getRetainCount(), 32, "__retain" ); PLOCK; - ok = getPropertyTable()->serialize( s ); + OSCollection *snapshotProperties = getPropertyTable()->copyCollection(); PUNLOCK; + bool ok = snapshotProperties->serialize( s ); + snapshotProperties->release(); return( ok ); } @@ -638,18 +495,10 @@ IOReturn IORegistryEntry::setProperties( OSObject * properties ) return( kIOReturnUnsupported ); } -wrap1(get, const OSSymbol, const) // getProperty() definition -wrap1(get, const OSString, const) // getProperty() definition -wrap1(get, const char, const) // getProperty() definition - wrap2(const OSSymbol, const) // copyProperty() definition wrap2(const OSString, const) // copyProperty() definition wrap2(const char, const) // copyProperty() definition -wrap3(remove, const OSSymbol,) // removeProperty() definition -wrap3(remove, const OSString,) // removeProperty() definition -wrap3(remove, const char,) // removeProperty() definition - wrap4(const OSSymbol, const) // getProperty() w/plane definition wrap4(const OSString, const) // getProperty() w/plane definition wrap4(const char, const) // getProperty() w/plane definition @@ -659,36 +508,135 @@ wrap5(const OSString, const) // copyProperty() w/plane definition wrap5(const char, const) // copyProperty() w/plane definition +OSObject * +IORegistryEntry::getProperty( const OSSymbol * aKey) const +{ + OSObject * obj; + + PLOCK; + obj = getPropertyTable()->getObject( aKey ); + PUNLOCK; + + return( obj ); +} + +void +IORegistryEntry::removeProperty( const OSSymbol * aKey) +{ + PLOCK; + getPropertyTable()->removeObject( 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) { bool ret = false; + + // If we are inserting a collection class and the current entry + // is attached into the registry (inPlane()) then mark the collection + // as immutable. + OSCollection *coll = OSDynamicCast(OSCollection, anObject); + bool makeImmutable = (coll && inPlane()); + PLOCK; + if( makeImmutable ) + coll->setOptions( OSCollection::kMASK, OSCollection::kImmutable ); + 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; } -bool -IORegistryEntry::setProperty( const OSString * aKey, OSObject * anObject) +IOReturn IORegistryEntry:: +runPropertyAction(Action inAction, OSObject *target, + void *arg0, void *arg1, void *arg2, void *arg3) { - bool ret = false; + IOReturn res; + + // closeGate is recursive so don't worry if we already hold the lock. PLOCK; - ret = getPropertyTable()->setObject( aKey, anObject ); + res = (*inAction)(target, arg0, arg1, arg2, arg3); PUNLOCK; + return res; +} + +OSObject * +IORegistryEntry::getProperty( const OSString * aKey) const +{ + const OSSymbol * tmpKey = OSSymbol::withString( aKey ); + OSObject * obj = getProperty( tmpKey ); + + tmpKey->release(); + return( obj ); +} + +OSObject * +IORegistryEntry::getProperty( const char * aKey) const +{ + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + OSObject * obj = getProperty( tmpKey ); + + tmpKey->release(); + return( obj ); +} + + +void +IORegistryEntry::removeProperty( const OSString * aKey) +{ + const OSSymbol * tmpKey = OSSymbol::withString( aKey ); + removeProperty( tmpKey ); + tmpKey->release(); +} + +void +IORegistryEntry::removeProperty( const char * aKey) +{ + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + removeProperty( tmpKey ); + tmpKey->release(); +} + +bool +IORegistryEntry::setProperty( const OSString * aKey, OSObject * anObject) +{ + const OSSymbol * tmpKey = OSSymbol::withString( aKey ); + bool ret = setProperty( tmpKey, anObject ); + + tmpKey->release(); return ret; } bool IORegistryEntry::setProperty( const char * aKey, OSObject * anObject) { - bool ret = false; - PLOCK; - ret = getPropertyTable()->setObject( aKey, anObject ); - PUNLOCK; - + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + bool ret = setProperty( tmpKey, anObject ); + + tmpKey->release(); return ret; } @@ -699,9 +647,10 @@ IORegistryEntry::setProperty(const char * aKey, const char * aString) OSSymbol * aSymbol = (OSSymbol *) OSSymbol::withCString( aString ); if( aSymbol) { - PLOCK; - ret = getPropertyTable()->setObject( aKey, aSymbol ); - PUNLOCK; + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + ret = setProperty( tmpKey, aSymbol ); + + tmpKey->release(); aSymbol->release(); } return( ret ); @@ -714,9 +663,10 @@ IORegistryEntry::setProperty(const char * aKey, bool aBoolean) OSBoolean * aBooleanObj = OSBoolean::withBoolean( aBoolean ); if( aBooleanObj) { - PLOCK; - ret = getPropertyTable()->setObject( aKey, aBooleanObj ); - PUNLOCK; + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + ret = setProperty( tmpKey, aBooleanObj ); + + tmpKey->release(); aBooleanObj->release(); } return( ret ); @@ -731,9 +681,10 @@ IORegistryEntry::setProperty( const char * aKey, OSNumber * anOffset = OSNumber::withNumber( aValue, aNumberOfBits ); if( anOffset) { - PLOCK; - ret = getPropertyTable()->setObject( aKey, anOffset ); - PUNLOCK; + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + ret = setProperty( tmpKey, anOffset ); + + tmpKey->release(); anOffset->release(); } return( ret ); @@ -748,9 +699,10 @@ IORegistryEntry::setProperty( const char * aKey, OSData * data = OSData::withBytes( bytes, length ); if( data) { - PLOCK; - ret = getPropertyTable()->setObject( aKey, data ); - PUNLOCK; + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + ret = setProperty( tmpKey, data ); + + tmpKey->release(); data->release(); } return( ret ); @@ -760,7 +712,7 @@ IORegistryEntry::setProperty( const char * aKey, /* Name, location, paths */ -const char * IORegistryEntry::getName( const IORegistryPlane * plane = 0 ) const +const char * IORegistryEntry::getName( const IORegistryPlane * plane ) const { OSSymbol * sym = 0; @@ -778,7 +730,7 @@ const char * IORegistryEntry::getName( const IORegistryPlane * plane = 0 ) const } const OSSymbol * IORegistryEntry::copyName( - const IORegistryPlane * plane = 0 ) const + const IORegistryPlane * plane ) const { OSSymbol * sym = 0; @@ -798,7 +750,7 @@ const OSSymbol * IORegistryEntry::copyName( } const OSSymbol * IORegistryEntry::copyLocation( - const IORegistryPlane * plane = 0 ) const + const IORegistryPlane * plane ) const { OSSymbol * sym = 0; @@ -814,7 +766,7 @@ const OSSymbol * IORegistryEntry::copyLocation( return( sym ); } -const char * IORegistryEntry::getLocation( const IORegistryPlane * plane = 0 ) const +const char * IORegistryEntry::getLocation( const IORegistryPlane * plane ) const { const OSSymbol * sym = copyLocation( plane ); const char * result = 0; @@ -828,7 +780,7 @@ const char * IORegistryEntry::getLocation( const IORegistryPlane * plane = 0 ) c } void IORegistryEntry::setName( const OSSymbol * name, - const IORegistryPlane * plane = 0 ) + const IORegistryPlane * plane ) { const OSSymbol * key; @@ -845,7 +797,7 @@ void IORegistryEntry::setName( const OSSymbol * name, } void IORegistryEntry::setName( const char * name, - const IORegistryPlane * plane = 0 ) + const IORegistryPlane * plane ) { OSSymbol * sym = (OSSymbol *)OSSymbol::withCString( name ); if ( sym ) { @@ -855,7 +807,7 @@ void IORegistryEntry::setName( const char * name, } void IORegistryEntry::setLocation( const OSSymbol * location, - const IORegistryPlane * plane = 0 ) + const IORegistryPlane * plane ) { const OSSymbol * key; @@ -872,7 +824,7 @@ void IORegistryEntry::setLocation( const OSSymbol * location, } void IORegistryEntry::setLocation( const char * location, - const IORegistryPlane * plane = 0 ) + const IORegistryPlane * plane ) { OSSymbol * sym = (OSSymbol *)OSSymbol::withCString( location ); if ( sym ) { @@ -882,7 +834,7 @@ void IORegistryEntry::setLocation( const char * location, } bool -IORegistryEntry::compareName( OSString * name, OSString ** matched = 0 ) const +IORegistryEntry::compareName( OSString * name, OSString ** matched ) const { const OSSymbol * sym = copyName(); bool isEqual; @@ -901,7 +853,7 @@ IORegistryEntry::compareName( OSString * name, OSString ** matched = 0 ) const } bool -IORegistryEntry::compareNames( OSObject * names, OSString ** matched = 0 ) const +IORegistryEntry::compareNames( OSObject * names, OSString ** matched ) const { OSString * string; OSCollection * collection; @@ -934,10 +886,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; @@ -951,80 +903,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) { + ok = (0 != parent); + if (ok) + { + index = stack->getCount(); + if( 0 == index) { - *nextComp++ = '/'; - *nextComp = 0; - len++; + *nextComp++ = '/'; + *nextComp = 0; + len++; - } else while( ok && ((--index) >= 0)) { + } else while( ok && ((--index) >= 0)) { - entry = (IORegistryEntry *) stack->getObject((unsigned int) index ); - assert( entry ); + entry = (IORegistryEntry *) stack->getObject((unsigned int) index ); + assert( entry ); - if( (alias = entry->hasAlias( plane ))) { - len = plane->nameKey->getLength() + 1; - nextComp = path + len; + 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 ); + 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 && compLen) { + compLen++; + *nextComp = '/'; + } } - } - if( ok) { - len += compLen; - nextComp += compLen; + if( ok) { + len += compLen; + nextComp += compLen; + } } + *length = len; } - *length = len; - UNLOCK; - stack->release(); return( ok ); @@ -1047,14 +995,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; } @@ -1068,39 +1016,38 @@ const char * IORegistryEntry::matchPathLocation( const char * cmp, const char * str; const char * result = 0; u_quad_t num1, num2; - char c1, c2; + char lastPathChar, lastLocationChar; str = getLocation( plane ); if( str) { - c2 = str[0]; + lastPathChar = cmp[0]; + lastLocationChar = str[0]; do { - num1 = strtouq( cmp, (char **) &cmp, 16 ); - if( c2) { + if( lastPathChar) { + num1 = strtouq( cmp, (char **) &cmp, 16 ); + lastPathChar = *cmp++; + } else + num1 = 0; + + if( lastLocationChar) { num2 = strtouq( str, (char **) &str, 16 ); - c2 = str[0]; + lastLocationChar = *str++; } else num2 = 0; if( num1 != num2) break; - c1 = *cmp++; - - if( (c2 == ':') && (c2 == c1)) { - str++; - continue; - } - - if( ',' != c1) { + if (!lastPathChar && !lastLocationChar) { result = cmp - 1; break; } - if( c2) { - if( c2 != ',') - break; - str++; - } + if( (',' != lastPathChar) && (':' != lastPathChar)) + lastPathChar = 0; + + if (lastPathChar && lastLocationChar && (lastPathChar != lastLocationChar)) + break; } while( true); } @@ -1156,7 +1103,7 @@ IORegistryEntry * IORegistryEntry::getChildFromComponent( const char ** opath, } const OSSymbol * IORegistryEntry::hasAlias( const IORegistryPlane * plane, - char * opath = 0, int * length = 0 ) const + char * opath, int * length ) const { IORegistryEntry * entry; IORegistryEntry * entry2; @@ -1216,8 +1163,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 ); @@ -1238,10 +1184,10 @@ const char * IORegistryEntry::dealiasPath( IORegistryEntry * IORegistryEntry::fromPath( const char * path, - const IORegistryPlane * plane = 0, - char * opath = 0, - int * length = 0, - IORegistryEntry * fromEntry = 0 ) + const IORegistryPlane * plane, + char * opath, + int * length, + IORegistryEntry * fromEntry ) { IORegistryEntry * where = 0; IORegistryEntry * aliasEntry = 0; @@ -1260,8 +1206,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; } @@ -1312,10 +1257,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 @@ -1334,9 +1279,9 @@ IORegistryEntry * IORegistryEntry::fromPath( IORegistryEntry * IORegistryEntry::childFromPath( const char * path, - const IORegistryPlane * plane = 0, - char * opath = 0, - int * len = 0 ) + const IORegistryPlane * plane, + char * opath, + int * len ) { return( IORegistryEntry::fromPath( path, plane, opath, len, this )); } @@ -1350,7 +1295,7 @@ IORegistryEntry * IORegistryEntry::childFromPath( inline bool IORegistryEntry::arrayMember( OSArray * set, const IORegistryEntry * member, - unsigned int * index = 0 ) const + unsigned int * index ) const { int i; OSObject * probeObject; @@ -1381,7 +1326,7 @@ bool IORegistryEntry::makeLink( IORegistryEntry * to, } else { - links = OSArray::withObjects( & (const OSObject *) to, 1, 1 ); + links = OSArray::withObjects( (const OSObject **) &to, 1, 1 ); result = (links != 0); if( result) { result = registryTable()->setObject( plane->keys[ relation ], @@ -1587,7 +1532,7 @@ void IORegistryEntry::applyToParents( IORegistryEntryApplierFunction applier, bool IORegistryEntry::isChild( IORegistryEntry * child, const IORegistryPlane * plane, - bool onlyChild = false ) const + bool onlyChild ) const { OSArray * links; bool ret = false; @@ -1608,7 +1553,7 @@ bool IORegistryEntry::isChild( IORegistryEntry * child, bool IORegistryEntry::isParent( IORegistryEntry * parent, const IORegistryPlane * plane, - bool onlyParent = false ) const + bool onlyParent ) const { OSArray * links; @@ -1634,7 +1579,38 @@ bool IORegistryEntry::inPlane( const IORegistryPlane * plane ) const RLOCK; - ret = (0 != getParentSetReference( plane )); + if( plane) + ret = (0 != getParentSetReference( plane )); + else { + + // Check to see if this is in any plane. If it is in a plane + // then the registryTable will contain a key with the ParentLinks + // suffix. When we iterate over the keys looking for that suffix + ret = false; + + OSCollectionIterator *iter = + OSCollectionIterator::withCollection( registryTable()); + if( iter) { + const OSSymbol *key; + + while( (key = (OSSymbol *) iter->getNextObject()) ) { + size_t keysuffix; + + // Get a pointer to this keys suffix + keysuffix = key->getLength(); + if (keysuffix <= kIORegPlaneParentSuffixLen) + continue; + keysuffix -= kIORegPlaneParentSuffixLen; + if( !strncmp(key->getCStringNoCopy() + keysuffix, + kIORegPlaneParentSuffix, + kIORegPlaneParentSuffixLen + 1) ) { + ret = true; + break; + } + } + iter->release(); + } + } UNLOCK; @@ -1653,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 ))) @@ -1660,16 +1639,47 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent, else needParent = true; -// ret &= parent->makeLink( this, kChildSetIndex, plane ); - UNLOCK; + PLOCK; + + // Mark any collections in the property list as immutable + OSDictionary *ptable = getPropertyTable(); + OSCollectionIterator *iter = + OSCollectionIterator::withCollection( ptable ); + if( iter) { + const OSSymbol *key; + + while( (key = (OSSymbol *) iter->getNextObject( ))) { + // Is object for key a collection? + OSCollection *coll = + OSDynamicCast( OSCollection, ptable->getObject( key )); + + if( coll) { + // Yup so mark it as immutable + coll->setOptions( OSCollection::kMASK, + OSCollection::kImmutable ); + } + } + iter->release(); + } + + PUNLOCK; + if( needParent) ret &= parent->attachToChild( this, plane ); return( ret ); } +uint64_t IORegistryEntry::getRegistryEntryID( void ) +{ + if (reserved) + return (reserved->fRegistryEntryID); + else + return (0); +} + bool IORegistryEntry::attachToChild( IORegistryEntry * child, const IORegistryPlane * plane ) { @@ -1754,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(); } @@ -1839,7 +1852,7 @@ enum { kIORegistryIteratorInvalidFlag = 0x80000000 }; IORegistryIterator * IORegistryIterator::iterateOver( IORegistryEntry * root, const IORegistryPlane * plane, - IOOptionBits options = 0 ) + IOOptionBits options ) { IORegistryIterator * create; @@ -1869,7 +1882,7 @@ IORegistryIterator::iterateOver( IORegistryEntry * root, IORegistryIterator * IORegistryIterator::iterateOver( const IORegistryPlane * plane, - IOOptionBits options = 0 ) + IOOptionBits options ) { return( iterateOver( gRegistryRoot, plane, options )); } @@ -1900,7 +1913,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) { @@ -1930,7 +1943,7 @@ bool IORegistryIterator::exitEntry( void ) if( where != &start) { gone = where; where = gone->next; - IOFree( gone, sizeof( IORegCursor)); + IOFree( gone, sizeof(IORegCursor)); return( true); } else @@ -2046,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); - -OSMetaClassDefineReservedUnused(IORegistryEntry, 5); +OSMetaClassDefineReservedUsed(IORegistryEntry, 5); +#endif OSMetaClassDefineReservedUnused(IORegistryEntry, 6); OSMetaClassDefineReservedUnused(IORegistryEntry, 7); OSMetaClassDefineReservedUnused(IORegistryEntry, 8);