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