| 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 | |