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