1 /* 2 * Copyright (c) 2019 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 /* IOSymbol.h created by gvdl on Fri 1998-10-30 */ 29 /* OSSymbol must be created through the factory methods and thus is not subclassable. */ 30 31 #ifndef _OS_OSSYMBOL_H 32 #define _OS_OSSYMBOL_H 33 34 #include <kern/smr_types.h> 35 #include <libkern/c++/OSString.h> 36 #include <libkern/c++/OSPtr.h> 37 38 class OSSymbol; 39 40 typedef OSSymbol* OSSymbolPtr; 41 typedef OSSymbol const* OSSymbolConstPtr; 42 43 /*! 44 * @header 45 * 46 * @abstract 47 * This header declares the OSSymbol container class. 48 */ 49 50 // xx-review: OSSymbol does not override setChar 51 52 /*! 53 * @class OSSymbol 54 * 55 * @abstract 56 * OSSymbol wraps a C string in a unique C++ object 57 * for use as keys in Libkern collections. 58 * 59 * @discussion 60 * OSSymbol is a container class for managing uniqued strings, 61 * for example, those used as dictionary keys. 62 * Its static instance-creation functions check 63 * for an existing instance of OSSymbol 64 * with the requested C string value before creating a new object. 65 * If an instance already exists in the pool of unique symbols, 66 * its reference count is incremented 67 * and the existing instance is returned. 68 * 69 * While OSSymbol provides for uniquing of a given string value, 70 * it makes no effort to enforce immutability of that value. 71 * Altering the contents of an OSSymbol should be avoided. 72 * 73 * <b>Use Restrictions</b> 74 * 75 * With very few exceptions in the I/O Kit, all Libkern-based C++ 76 * classes, functions, and macros are <b>unsafe</b> 77 * to use in a primary interrupt context. 78 * Consult the I/O Kit documentation related to primary interrupts 79 * for more information. 80 * 81 * OSSymbol provides no concurrency protection; 82 * it's up to the usage context to provide any protection necessary. 83 * Some portions of the I/O Kit, such as 84 * @link //apple_ref/doc/class/IORegistryEntry IORegistryEntry@/link, 85 * handle synchronization via defined member functions for setting 86 * properties. 87 */ 88 class OSSymbol final : public OSString 89 { 90 friend class OSSymbolPool; 91 92 OSDeclareDefaultStructors(OSSymbol); 93 94 private: 95 struct smrq_slink hashlink; 96 97 static void initialize(); 98 99 /*! 100 * @function initWithString 101 * 102 * @abstract 103 * Overridden to prevent creation of duplicate symbols. 104 * 105 * @param aString Unused. 106 * 107 * @result 108 * <code>false</code>. 109 * 110 * @discussion 111 * Overrides OSString's implementation to prevent creation 112 * of distinct OSSymbols with the same string value. 113 */ 114 virtual bool initWithString(const OSString * aString) APPLE_KEXT_OVERRIDE; 115 116 117 /*! 118 * @function initWithCString 119 * 120 * @abstract 121 * Overridden to prevent creation of duplicate symbols. 122 * 123 * @param cString Unused. 124 * 125 * @result 126 * <code>false</code>. 127 * 128 * @discussion 129 * Overrides OSString's implementation to prevent creation 130 * of distinct OSSymbols with the same string value. 131 */ 132 virtual bool initWithCString(const char * cString) APPLE_KEXT_OVERRIDE; 133 134 135 /*! 136 * @function initWithCStringNoCopy 137 * 138 * @abstract 139 * Overridden to prevent creation of duplicate symbols. 140 * 141 * @param cString Unused. 142 * 143 * @result 144 * <code>false</code>. 145 * 146 * @discussion 147 * Overrides OSString's implementation to prevent creation 148 * of distinct OSSymbols with the same string value. 149 */ 150 virtual bool initWithCStringNoCopy(const char *cString) APPLE_KEXT_OVERRIDE; 151 152 protected: 153 154 /*! 155 * @function taggedRetain 156 * 157 * @abstract 158 * Overrides 159 * <code>@link 160 * //apple_ref/cpp/instm/OSObject/taggedRetain/virtualvoid/(constvoid*) 161 * OSObject::taggedRetain(const void *) const@/link</code> 162 * to synchronize with the symbol pool. 163 * 164 * @param tag Used for tracking collection references. 165 */ 166 virtual void taggedRetain( 167 const void * tag) const APPLE_KEXT_OVERRIDE; 168 169 /*! 170 * @function taggedRelease 171 * 172 * @abstract 173 * Overrides 174 * <code>@link 175 * //apple_ref/cpp/instm/OSObject/taggedRelease/virtualvoid/(constvoid*,constint) 176 * OSObject::taggedRelease(const void *, const int)@/link</code> 177 * to synchronize with the symbol pool. 178 * 179 * @param tag Used for tracking collection references. 180 * @param freeWhen If decrementing the reference count makes it 181 * >= <code>freeWhen</code>, the object is immediately freed. 182 * 183 * @discussion 184 * Because OSSymbol shares instances, the reference-counting functions 185 * must synchronize access to the class-internal tables 186 * used to track those instances. 187 */ 188 virtual void taggedRelease( 189 const void * tag, 190 const int freeWhen) const APPLE_KEXT_OVERRIDE; 191 192 193 // xx-review: should we just omit this from headerdoc? 194 /*! 195 * @function free 196 * 197 * @abstract 198 * Overrides 199 * <code>@link 200 * //apple_ref/cpp/instm/OSObject/free/virtualvoid/() 201 * OSObject::free@/link</code> 202 * to synchronize with the symbol pool. 203 * 204 * @discussion 205 * Because OSSymbol shares instances, the reference-counting functions 206 * must synchronize access to the class-internal tables 207 * used to track those instances. 208 */ 209 virtual void free() APPLE_KEXT_OVERRIDE; 210 211 public: 212 213 // xx-review: should we just omit this from headerdoc? 214 /*! 215 * @function taggedRelease 216 * 217 * @abstract 218 * Overrides 219 * <code>@link 220 * //apple_ref/cpp/instm/OSObject/taggedRelease/virtualvoid/(constvoid*) 221 * OSObject::taggedRelease(const void *)@/link</code> 222 * to synchronize with the symbol pool. 223 * 224 * @param tag Used for tracking collection references. 225 * 226 * @discussion 227 * Because OSSymbol shares instances, the reference-counting functions 228 * must synchronize access to the class-internal tables 229 * used to track those instances. 230 */ 231 232 /* Original note (not for headerdoc): 233 * The C++ language has forced me to override this method 234 * even though I have implemented it as 235 * <code>{ super::taggedRelease(tag) }</code>. 236 * It seems that C++ is confused about the appearance of the protected 237 * taggedRelease with 2 parameters and refuses to only inherit one function. 238 * See 239 * <code>@link 240 * //apple_ref/cpp/instm/OSObject/taggedRelease/virtualvoid/(constvoid*,constint) 241 * OSObject::taggedRelease(const void *, const int)@/link</code>. 242 */ 243 virtual void taggedRelease(const void * tag) const APPLE_KEXT_OVERRIDE; 244 245 246 /*! 247 * @function withString 248 * 249 * @abstract 250 * Returns an OSSymbol created from an OSString, 251 * or the existing unique instance of the same value. 252 * 253 * @param aString The OSString object to look up or copy. 254 * 255 * @result 256 * An instance of OSSymbol 257 * representing the same characters as <code>aString</code>; 258 * <code>NULL</code> on failure. 259 * 260 * @discussion 261 * This function creates or returns the unique OSSymbol instance 262 * representing the string value of <code>aString</code>. 263 * You can compare it with other OSSymbols using the <code>==</code> operator. 264 * 265 * OSSymbols are reference-counted normally. 266 * This function either returns a 267 * new OSSymbol with a retain count of 1, 268 * or increments the retain count of the existing instance. 269 */ 270 static OSPtr<const OSSymbol> withString(const OSString * aString); 271 272 273 /*! 274 * @function withCString 275 * 276 * @abstract 277 * Returns an OSSymbol created from a C string, 278 * or the existing unique instance of the same value. 279 * 280 * @param cString The C string to look up or copy. 281 * 282 * @result 283 * An instance of OSSymbol representing 284 * the same characters as <code>cString</code>; 285 * <code>NULL</code> on failure. 286 * 287 * @discussion 288 * This function returns the unique OSSymbol instance 289 * representing the string value of <code>cString</code>. 290 * You can compare it with other OSSymbols using the <code>==</code> operator. 291 * 292 * OSSymbols are reference-counted normally. 293 * This function either returns a 294 * new OSSymbol with a retain count of 1, 295 * or increments the retain count of the existing instance. 296 */ 297 static OSPtr<const OSSymbol> withCString(const char * cString); 298 299 300 /*! 301 * @function withCStringNoCopy 302 * 303 * @abstract 304 * Returns an OSSymbol created from a C string, 305 * without copying that string, 306 * or the existing unique instance of the same value. 307 * 308 * @param cString The C string to look up or use. 309 * @result 310 * An instance of OSSymbol representing 311 * the same characters as <code>cString</code>; 312 * <code>NULL</code>. 313 * 314 * @discussion 315 * Avoid using this function; 316 * OSSymbols should own their internal string buffers. 317 * 318 * This function returns the unique OSSymbol instance 319 * representing the string value of <code>cString</code>. 320 * You can compare it with other OSSymbols using the <code>==</code> operator. 321 * 322 * OSSymbols are reference-counted normally. 323 * This function either returns a 324 * new OSSymbol with a retain count of 1, 325 * or increments the retain count of the existing instance. 326 */ 327 static OSPtr<const OSSymbol> withCStringNoCopy(const char * cString); 328 329 /*! 330 * @function existingSymbolForString 331 * 332 * @abstract 333 * Returns an existing OSSymbol for the given OSString. 334 * 335 * @param aString The OSString Object to look up. 336 * 337 * @result 338 * An existing instance of OSSymbol representing 339 * the same characters as <code>aString</code>; 340 * <code>NULL</code> if none is found. 341 * 342 * @discussion 343 * The returned OSSymbol object is returned with an incremented refcount 344 * that needs to be released. 345 */ 346 static OSPtr<const OSSymbol> existingSymbolForString(const OSString *aString); 347 348 /*! 349 * @function existingSymbolForCString 350 * 351 * @abstract 352 * Returns an existing OSSymbol for the given C string. 353 * 354 * @param aCString The C string to look up. 355 * 356 * @result 357 * An existing instance of OSSymbol representing 358 * the same characters as <code>aString</code>; 359 * <code>NULL</code> if none is found. 360 * 361 * @discussion 362 * The returned OSSymbol object is returned with an incremented refcount 363 * that needs to be released. 364 */ 365 static OSPtr<const OSSymbol> existingSymbolForCString(const char *aCString); 366 367 /*! 368 * @function isEqualTo 369 * 370 * @abstract 371 * Tests the equality of two OSSymbol objects. 372 * 373 * @param aSymbol The OSSymbol object being compared against the receiver. 374 * 375 * @result 376 * <code>true</code> if the two OSSymbol objects are equivalent, 377 * <code>false</code> otherwise. 378 * 379 * @discussion 380 * Two OSSymbol objects are considered equal if they have the same address; 381 * that is, this function is equivalent to the <code>==</code> operator. 382 */ 383 virtual bool isEqualTo(const OSSymbol * aSymbol) const; 384 385 386 /*! 387 * @function isEqualTo 388 * 389 * @abstract Tests the equality of an OSSymbol object with a C string. 390 * 391 * @param cString The C string to compare against the receiver. 392 * 393 * @result 394 * <code>true</code> if the OSSymbol's characters 395 * are equivalent to the C string's, 396 * <code>false</code> otherwise. 397 */ 398 virtual bool isEqualTo(const char * cString) const APPLE_KEXT_OVERRIDE; 399 400 401 /*! 402 * @function isEqualTo 403 * 404 * @abstract Tests the equality of an OSSymbol object to an arbitrary object. 405 * 406 * @param anObject The object to be compared against the receiver. 407 * @result Returns <code>true</code> if the two objects are equivalent, 408 * <code>false</code> otherwise. 409 * 410 * @discussion 411 * An OSSymbol is considered equal to another object 412 * if that object is derived from 413 * @link //apple_ref/doc/class/OSMetaClassBase OSString@/link 414 * and contains the equivalent bytes of the same length. 415 */ 416 virtual bool isEqualTo(const OSMetaClassBase * anObject) const APPLE_KEXT_OVERRIDE; 417 418 419 #ifdef XNU_KERNEL_PRIVATE 420 /* OSRuntime only INTERNAL API - DO NOT USE */ 421 /* Not to be included in headerdoc. */ 422 // xx-review: this should be removed from the symbol set. 423 424 static void checkForPageUnload( 425 void * startAddr, 426 void * endAddr); 427 428 static unsigned int bsearch( 429 const void * key, 430 const void * array, 431 unsigned int arrayCount, 432 size_t memberSize); 433 434 inline void smr_free(); 435 436 inline uint32_t hash() const; 437 438 #endif /* XNU_KERNEL_PRIVATE */ 439 440 OSMetaClassDeclareReservedUnused(OSSymbol, 0); 441 OSMetaClassDeclareReservedUnused(OSSymbol, 1); 442 OSMetaClassDeclareReservedUnused(OSSymbol, 2); 443 OSMetaClassDeclareReservedUnused(OSSymbol, 3); 444 OSMetaClassDeclareReservedUnused(OSSymbol, 4); 445 OSMetaClassDeclareReservedUnused(OSSymbol, 5); 446 OSMetaClassDeclareReservedUnused(OSSymbol, 6); 447 OSMetaClassDeclareReservedUnused(OSSymbol, 7); 448 }; 449 450 #endif /* !_OS_OSSYMBOL_H */ 451