]> git.saurik.com Git - apple/xnu.git/blob - iokit/Tests/Tests.cpp
ac67b43b553c8d26d1dd0e23da2800bdad2e7d80
[apple/xnu.git] / iokit / Tests / Tests.cpp
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, 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 /*
29 *
30 */
31
32 #define TEST_HEADERS 0
33
34 #if TEST_HEADERS
35
36 #include <libkern/OSByteOrder.h>
37 #include <libkern/c++/OSArray.h>
38 #include <libkern/c++/OSAllocation.h>
39 #include <libkern/c++/OSBoolean.h>
40 #include <libkern/c++/OSBoundedArray.h>
41 #include <libkern/c++/OSBoundedArrayRef.h>
42 #include <libkern/c++/OSBoundedPtr.h>
43 #include <libkern/c++/OSCollection.h>
44 #include <libkern/c++/OSCollectionIterator.h>
45 #include <libkern/c++/OSContainers.h>
46 #include <libkern/c++/OSCPPDebug.h>
47 #include <libkern/c++/OSData.h>
48 #include <libkern/c++/OSDictionary.h>
49 #include <libkern/c++/OSEndianTypes.h>
50 #include <libkern/c++/OSIterator.h>
51 #include <libkern/c++/OSKext.h>
52 #include <libkern/c++/OSLib.h>
53 #include <libkern/c++/OSMetaClass.h>
54 #include <libkern/c++/OSNumber.h>
55 #include <libkern/c++/OSObject.h>
56 #include <libkern/c++/OSOrderedSet.h>
57 #include <libkern/c++/OSSerialize.h>
58 #include <libkern/c++/OSSet.h>
59 #include <libkern/c++/OSSharedPtr.h>
60 #include <libkern/c++/OSString.h>
61 #include <libkern/c++/OSSymbol.h>
62 #include <libkern/c++/OSUnserialize.h>
63 #include <libkern/crypto/aes.h>
64 #include <libkern/crypto/aesxts.h>
65 #include <libkern/crypto/crypto_internal.h>
66 #include <libkern/crypto/des.h>
67 #include <libkern/crypto/md5.h>
68 #include <libkern/crypto/register_crypto.h>
69 #include <libkern/crypto/sha1.h>
70 #include <libkern/crypto/sha2.h>
71 #include <libkern/kernel_mach_header.h>
72 #include <libkern/kext_request_keys.h>
73 #include <libkern/kxld.h>
74 #include <libkern/kxld_types.h>
75 #include <libkern/locks.h>
76 #include <libkern/mkext.h>
77 #include <libkern/OSAtomic.h>
78 #include <libkern/OSBase.h>
79 #include <libkern/OSDebug.h>
80 #include <libkern/OSKextLib.h>
81 #include <libkern/OSKextLibPrivate.h>
82 #include <libkern/OSReturn.h>
83 #include <libkern/OSSerializeBinary.h>
84 #include <libkern/OSTypes.h>
85 #include <libkern/prelink.h>
86 #include <libkern/stack_protector.h>
87 #include <libkern/sysctl.h>
88 #include <libkern/tree.h>
89 #include <libkern/zconf.h>
90 #include <libkern/zlib.h>
91
92 #include <IOKit/AppleKeyStoreInterface.h>
93 #include <IOKit/assert.h>
94 #include <IOKit/IOBSD.h>
95 #include <IOKit/IOBufferMemoryDescriptor.h>
96 #include <IOKit/IOCatalogue.h>
97 #include <IOKit/IOCommand.h>
98 #include <IOKit/IOCommandGate.h>
99 #include <IOKit/IOCommandPool.h>
100 #include <IOKit/IOCommandQueue.h>
101 #include <IOKit/IOConditionLock.h>
102 #include <IOKit/IOCPU.h>
103 //#include <IOKit/IODataQueue.h>
104 #include <IOKit/IODataQueueShared.h>
105 #include <IOKit/IODeviceMemory.h>
106 #include <IOKit/IODeviceTreeSupport.h>
107 #include <IOKit/IODMACommand.h>
108 #include <IOKit/IODMAController.h>
109 #include <IOKit/IODMAEventSource.h>
110 #include <IOKit/IOEventSource.h>
111 #include <IOKit/IOFilterInterruptEventSource.h>
112 #include <IOKit/IOHibernatePrivate.h>
113 #include <IOKit/IOInterleavedMemoryDescriptor.h>
114 #include <IOKit/IOInterruptAccounting.h>
115 #include <IOKit/IOInterruptAccountingPrivate.h>
116 #include <IOKit/IOInterruptController.h>
117 #include <IOKit/IOInterruptEventSource.h>
118 #include <IOKit/IOInterrupts.h>
119 #include <IOKit/IOKernelReporters.h>
120 #include <IOKit/IOKernelReportStructs.h>
121 #include <IOKit/IOKitDebug.h>
122 #include <IOKit/IOKitDiagnosticsUserClient.h>
123 #include <IOKit/IOKitKeys.h>
124 #include <IOKit/IOKitKeysPrivate.h>
125 #include <IOKit/IOKitServer.h>
126 #include <IOKit/IOLib.h>
127 #include <IOKit/IOLocks.h>
128 #include <IOKit/IOLocksPrivate.h>
129 #include <IOKit/IOMapper.h>
130 #include <IOKit/IOMemoryCursor.h>
131 #include <IOKit/IOMemoryDescriptor.h>
132 #include <IOKit/IOMessage.h>
133 #include <IOKit/IOMultiMemoryDescriptor.h>
134 #include <IOKit/IONotifier.h>
135 #include <IOKit/IONVRAM.h>
136 #include <IOKit/IOPlatformExpert.h>
137 #include <IOKit/IOPolledInterface.h>
138 #include <IOKit/IORangeAllocator.h>
139 #include <IOKit/IORegistryEntry.h>
140 #include <IOKit/IOReportMacros.h>
141 #include <IOKit/IOReportTypes.h>
142 #include <IOKit/IOReturn.h>
143 #include <IOKit/IOService.h>
144 #include <IOKit/IOServicePM.h>
145 #include <IOKit/IOSharedDataQueue.h>
146 #include <IOKit/IOSharedLock.h>
147 #include <IOKit/IOStatistics.h>
148 #include <IOKit/IOStatisticsPrivate.h>
149 #include <IOKit/IOSubMemoryDescriptor.h>
150 #include <IOKit/IOSyncer.h>
151 #include <IOKit/IOTimerEventSource.h>
152 #include <IOKit/IOTimeStamp.h>
153 #include <IOKit/IOTypes.h>
154 #include <IOKit/IOUserClient.h>
155 #include <IOKit/IOWorkLoop.h>
156 #include <IOKit/nvram/IONVRAMController.h>
157 #include <IOKit/OSMessageNotification.h>
158 #include <IOKit/platform/AppleMacIO.h>
159 #include <IOKit/platform/AppleMacIODevice.h>
160 #include <IOKit/platform/AppleNMI.h>
161 #include <IOKit/platform/ApplePlatformExpert.h>
162 #include <IOKit/power/IOPwrController.h>
163 #include <IOKit/pwr_mgt/IOPM.h>
164 #include <IOKit/pwr_mgt/IOPMinformee.h>
165 #include <IOKit/pwr_mgt/IOPMinformeeList.h>
166 #include <IOKit/pwr_mgt/IOPMLibDefs.h>
167 #include <IOKit/pwr_mgt/IOPMlog.h>
168 #include <IOKit/pwr_mgt/IOPMPowerSource.h>
169 #include <IOKit/pwr_mgt/IOPMPowerSourceList.h>
170 #include <IOKit/pwr_mgt/IOPMpowerState.h>
171 #include <IOKit/pwr_mgt/IOPMPrivate.h>
172 #include <IOKit/pwr_mgt/IOPowerConnection.h>
173 #include <IOKit/pwr_mgt/RootDomain.h>
174 #include <IOKit/rtc/IORTCController.h>
175 #include <IOKit/system.h>
176 #include <IOKit/system_management/IOWatchDogTimer.h>
177
178 #endif /* TEST_HEADERS */
179
180 #include <sys/sysctl.h>
181 #include <libkern/c++/OSData.h>
182 #include "Tests.h"
183
184
185 #if DEVELOPMENT || DEBUG
186
187 #include <IOKit/IOWorkLoop.h>
188 #include <IOKit/IOTimerEventSource.h>
189 #include <IOKit/IOInterruptEventSource.h>
190 #include <IOKit/IOCommandGate.h>
191 #include <IOKit/IOPlatformExpert.h>
192 #include <IOKit/IOSharedDataQueue.h>
193 #include <IOKit/IODataQueueShared.h>
194 #include <libkern/Block.h>
195 #include <libkern/Block_private.h>
196 #include <libkern/c++/OSAllocation.h>
197 #include <libkern/c++/OSBoundedArray.h>
198 #include <libkern/c++/OSBoundedArrayRef.h>
199 #include <libkern/c++/OSBoundedPtr.h>
200 #include <libkern/c++/OSSharedPtr.h>
201 #include <os/cpp_util.h>
202
203 static uint64_t gIOWorkLoopTestDeadline;
204
205 static void
206 TESAction(OSObject * owner, IOTimerEventSource * tes)
207 {
208 if (mach_absolute_time() < gIOWorkLoopTestDeadline) {
209 tes->setTimeout(1, kMicrosecondScale);
210 }
211 }
212
213 static int
214 IOWorkLoopTest(int newValue)
215 {
216 IOReturn err;
217 uint32_t idx;
218 IOWorkLoop * wl;
219 IOTimerEventSource * tes;
220 IOInterruptEventSource * ies;
221
222 wl = IOWorkLoop::workLoop();
223 assert(wl);
224 tes = IOTimerEventSource::timerEventSource(kIOTimerEventSourceOptionsPriorityWorkLoop, wl, &TESAction);
225 assert(tes);
226 err = wl->addEventSource(tes);
227 assert(kIOReturnSuccess == err);
228 clock_interval_to_deadline(100, kMillisecondScale, &gIOWorkLoopTestDeadline);
229 for (idx = 0; mach_absolute_time() < gIOWorkLoopTestDeadline; idx++) {
230 tes->setTimeout(idx & 1023, kNanosecondScale);
231 }
232 tes->cancelTimeout();
233 wl->removeEventSource(tes);
234 tes->release();
235
236 int value = 3;
237
238 tes = IOTimerEventSource::timerEventSource(kIOTimerEventSourceOptionsDefault, wl, ^(IOTimerEventSource * tes){
239 kprintf("wl %p, value %d\n", wl, value);
240 });
241 err = wl->addEventSource(tes);
242 assert(kIOReturnSuccess == err);
243
244 value = 2;
245 tes->setTimeout(1, kNanosecondScale);
246 IOSleep(1);
247 wl->removeEventSource(tes);
248 tes->release();
249
250 ies = IOInterruptEventSource::interruptEventSource(wl, NULL, 0, ^void (IOInterruptEventSource *sender, int count){
251 kprintf("ies block %p, %d\n", sender, count);
252 });
253
254 assert(ies);
255 kprintf("ies %p\n", ies);
256 err = wl->addEventSource(ies);
257 assert(kIOReturnSuccess == err);
258 ies->interruptOccurred(NULL, NULL, 0);
259 IOSleep(1);
260 ies->interruptOccurred(NULL, NULL, 0);
261 IOSleep(1);
262 wl->removeEventSource(ies);
263 ies->release();
264
265 wl->release();
266
267 return 0;
268 }
269
270 static int
271 OSCollectionTest(int newValue)
272 {
273 OSArray * array = OSArray::withCapacity(8);
274 array->setObject(kOSBooleanTrue);
275 array->setObject(kOSBooleanFalse);
276 array->setObject(kOSBooleanFalse);
277 array->setObject(kOSBooleanTrue);
278 array->setObject(kOSBooleanFalse);
279 array->setObject(kOSBooleanTrue);
280
281 __block unsigned int index;
282 index = 0;
283 array->iterateObjects(^bool (OSObject * obj) {
284 kprintf("%d:%d ", index, (obj == kOSBooleanTrue) ? 1 : (obj == kOSBooleanFalse) ? 0 : 2);
285 index++;
286 return false;
287 });
288 kprintf("\n");
289 array->release();
290
291 OSDictionary * dict = IOService::resourceMatching("hello");
292 assert(dict);
293 index = 0;
294 dict->iterateObjects(^bool (const OSSymbol * sym, OSObject * obj) {
295 OSString * str = OSDynamicCast(OSString, obj);
296 assert(str);
297 kprintf("%d:%s=%s\n", index, sym->getCStringNoCopy(), str->getCStringNoCopy());
298 index++;
299 return false;
300 });
301 dict->release();
302
303 OSSerializer * serializer = OSSerializer::withBlock(^bool (OSSerialize * s){
304 return gIOBSDUnitKey->serialize(s);
305 });
306 assert(serializer);
307 IOService::getPlatform()->setProperty("OSSerializer_withBlock", serializer);
308 serializer->release();
309
310 return 0;
311 }
312
313 static int
314 OSAllocationTests(int)
315 {
316 OSAllocation<int> ints(100, OSAllocateMemory);
317 assert(ints);
318
319 {
320 int counter = 0;
321 for (int& i : ints) {
322 i = counter++;
323 }
324 }
325
326 {
327 int counter = 0;
328 for (int& i : ints) {
329 assert(i == counter);
330 ++counter;
331 }
332 }
333
334 // Make sure we can have two-level OSAllocations
335 {
336 OSAllocation<OSAllocation<int> > testArray(10, OSAllocateMemory);
337 for (int i = 0; i < 10; i++) {
338 testArray[i] = OSAllocation<int>(10, OSAllocateMemory);
339 for (int j = 0; j < 10; ++j) {
340 testArray[i][j] = i + j;
341 }
342 }
343
344 for (int i = 0; i < 10; i++) {
345 for (int j = 0; j < 10; ++j) {
346 assert(testArray[i][j] == i + j);
347 }
348 }
349 }
350
351 return 0;
352 }
353
354 static int
355 OSBoundedArrayTests(int)
356 {
357 OSBoundedArray<int, 5> ints = {0, 1, 2, 3, 4};
358 assert(ints.size() == 5);
359
360 {
361 int counter = 0;
362 for (int& i : ints) {
363 i = counter++;
364 }
365 }
366
367 {
368 int counter = 0;
369 for (int& i : ints) {
370 assert(i == counter);
371 ++counter;
372 }
373 }
374
375 return 0;
376 }
377
378 static int
379 OSBoundedArrayRefTests(int)
380 {
381 OSBoundedArray<int, 5> storage = {0, 1, 2, 3, 4};
382 OSBoundedArrayRef<int> ints(storage);
383 assert(ints);
384
385 {
386 int counter = 0;
387 for (int& i : ints) {
388 i = counter++;
389 }
390 }
391
392 {
393 int counter = 0;
394 for (int& i : ints) {
395 assert(i == counter);
396 ++counter;
397 }
398 }
399
400 return 0;
401 }
402
403 static int
404 OSBoundedPtrTests(int)
405 {
406 int array[5] = {55, 66, 77, 88, 99};
407 OSBoundedPtr<int> begin(&array[0], &array[0], &array[5]);
408 OSBoundedPtr<int> end(&array[5], &array[0], &array[5]);
409
410 {
411 int counter = 0;
412 for (OSBoundedPtr<int> b = begin; b != end; ++b) {
413 *b = counter++;
414 }
415 }
416
417 {
418 int counter = 0;
419 for (OSBoundedPtr<int> b = begin; b != end; ++b) {
420 assert(*b == counter);
421 ++counter;
422 }
423 }
424
425 return 0;
426 }
427
428 static int
429 IOSharedDataQueue_44636964(__unused int newValue)
430 {
431 IOSharedDataQueue* sd = IOSharedDataQueue::withCapacity(DATA_QUEUE_ENTRY_HEADER_SIZE + sizeof(UInt64));
432 UInt64 data = 0x11223344aa55aa55;
433 UInt32 data2 = 0x44332211;
434 UInt32 size = sizeof(UInt32);
435 /* enqueue moves tail to end */
436 sd->enqueue(&data, sizeof(UInt64));
437 /* dequeue moves head to end */
438 sd->dequeue(&data, &size);
439 /* Tail wraps around, head is still at end */
440 sd->enqueue(&data2, sizeof(UInt32));
441 /* something in the queue so peek() should return non-null */
442 assert(sd->peek() != NULL);
443 return KERN_SUCCESS;
444 }
445
446 #if 0
447 #include <IOKit/IOUserClient.h>
448 class TestUserClient : public IOUserClient
449 {
450 OSDeclareDefaultStructors(TestUserClient);
451 virtual void stop( IOService *provider) APPLE_KEXT_OVERRIDE;
452 virtual bool finalize(IOOptionBits options) APPLE_KEXT_OVERRIDE;
453 virtual IOReturn externalMethod( uint32_t selector,
454 IOExternalMethodArguments * arguments,
455 IOExternalMethodDispatch * dispatch,
456 OSObject * target,
457 void * reference ) APPLE_KEXT_OVERRIDE;
458 };
459
460 void
461 TestUserClient::stop( IOService *provider)
462 {
463 kprintf("TestUserClient::stop\n");
464 }
465 bool
466 TestUserClient::finalize(IOOptionBits options)
467 {
468 kprintf("TestUserClient::finalize\n");
469 return true;
470 }
471 IOReturn
472 TestUserClient::externalMethod( uint32_t selector,
473 IOExternalMethodArguments * arguments,
474 IOExternalMethodDispatch * dispatch,
475 OSObject * target,
476 void * reference )
477 {
478 getProvider()->terminate();
479 IOSleep(500);
480 return 0;
481 }
482 OSDefineMetaClassAndStructors(TestUserClient, IOUserClient);
483 #endif
484
485 static int
486 IOServiceTest(int newValue)
487 {
488 OSDictionary * matching;
489 IONotifier * note;
490 __block IOService * found;
491
492 #if 0
493 found = new IOService;
494 found->init();
495 found->setName("IOTestUserClientProvider");
496 found->attach(IOService::getPlatform());
497 found->setProperty("IOUserClientClass", "TestUserClient");
498 found->registerService();
499 #endif
500
501 matching = IOService::serviceMatching("IOPlatformExpert");
502 assert(matching);
503 found = nullptr;
504 note = IOService::addMatchingNotification(gIOMatchedNotification, matching, 0,
505 ^bool (IOService * newService, IONotifier * notifier) {
506 kprintf("found %s, %d\n", newService->getName(), newService->getRetainCount());
507 found = newService;
508 found->retain();
509 return true;
510 }
511 );
512 assert(note);
513 assert(found);
514 matching->release();
515 note->remove();
516
517 note = found->registerInterest(gIOBusyInterest,
518 ^IOReturn (uint32_t messageType, IOService * provider,
519 void * messageArgument, size_t argSize) {
520 kprintf("%p messageType 0x%08x %p\n", provider, messageType, messageArgument);
521 return kIOReturnSuccess;
522 });
523 assert(note);
524 IOSleep(1 * 1000);
525 note->remove();
526 found->release();
527
528 return 0;
529 }
530
531 static void
532 OSStaticPtrCastTests()
533 {
534 // const& overload
535 {
536 OSSharedPtr<OSDictionary> const dict = OSMakeShared<OSDictionary>();
537 OSSharedPtr<OSCollection> collection = OSStaticPtrCast<OSCollection>(dict);
538 assert(collection == dict);
539 }
540 {
541 OSSharedPtr<OSDictionary> const dict = nullptr;
542 OSSharedPtr<OSCollection> collection = OSStaticPtrCast<OSCollection>(dict);
543 assert(collection == nullptr);
544 }
545 // && overload
546 {
547 OSSharedPtr<OSDictionary> dict = OSMakeShared<OSDictionary>();
548 OSDictionary* oldDict = dict.get();
549 OSSharedPtr<OSCollection> collection = OSStaticPtrCast<OSCollection>(os::move(dict));
550 assert(collection.get() == oldDict);
551 assert(dict == nullptr);
552 }
553 {
554 OSSharedPtr<OSDictionary> dict = nullptr;
555 OSSharedPtr<OSCollection> collection = OSStaticPtrCast<OSCollection>(os::move(dict));
556 assert(collection == nullptr);
557 assert(dict == nullptr);
558 }
559 }
560
561 static void
562 OSConstPtrCastTests()
563 {
564 // const& overload
565 {
566 OSSharedPtr<OSDictionary const> const dict = OSMakeShared<OSDictionary>();
567 OSSharedPtr<OSDictionary> dict2 = OSConstPtrCast<OSDictionary>(dict);
568 assert(dict2 == dict);
569 }
570 {
571 OSSharedPtr<OSDictionary const> const dict = OSMakeShared<OSDictionary>();
572 OSSharedPtr<OSDictionary const> dict2 = OSConstPtrCast<OSDictionary const>(dict);
573 assert(dict2 == dict);
574 }
575 {
576 OSSharedPtr<OSDictionary const> const dict = nullptr;
577 OSSharedPtr<OSDictionary> dict2 = OSConstPtrCast<OSDictionary>(dict);
578 assert(dict2 == nullptr);
579 }
580 {
581 OSSharedPtr<OSDictionary const> const dict = nullptr;
582 OSSharedPtr<OSDictionary const> dict2 = OSConstPtrCast<OSDictionary const>(dict);
583 assert(dict2 == nullptr);
584 }
585
586 // && overload
587 {
588 OSSharedPtr<OSDictionary const> dict = OSMakeShared<OSDictionary>();
589 OSDictionary const* oldDict = dict.get();
590 OSSharedPtr<OSDictionary> dict2 = OSConstPtrCast<OSDictionary>(os::move(dict));
591 assert(dict == nullptr);
592 assert(dict2 == oldDict);
593 }
594 {
595 OSSharedPtr<OSDictionary const> dict = nullptr;
596 OSSharedPtr<OSDictionary> dict2 = OSConstPtrCast<OSDictionary>(os::move(dict));
597 assert(dict == nullptr);
598 assert(dict2 == nullptr);
599 }
600 }
601
602 static void
603 OSDynamicPtrCastTests()
604 {
605 OSSharedPtr<OSDictionary> const dict = OSMakeShared<OSDictionary>();
606 {
607 OSSharedPtr<OSCollection> collection = OSDynamicPtrCast<OSCollection>(dict);
608 assert(collection != nullptr);
609 }
610 {
611 OSSharedPtr<OSArray> array = OSDynamicPtrCast<OSArray>(dict);
612 assert(array == nullptr);
613 assert(dict != nullptr);
614 }
615 {
616 OSTaggedSharedPtr<OSCollection, OSCollection> taggedDict(dict.get(), OSRetain);
617 OSTaggedSharedPtr<OSCollection, OSCollection> collection = OSDynamicPtrCast<OSCollection>(taggedDict);
618 assert(collection != nullptr);
619 }
620 {
621 OSTaggedSharedPtr<OSCollection, OSCollection> taggedDict(dict.get(), OSRetain);
622 OSTaggedSharedPtr<OSArray, OSCollection> array = OSDynamicPtrCast<OSArray>(taggedDict);
623 assert(array == nullptr);
624 assert(dict != nullptr);
625 }
626 {
627 OSSharedPtr<OSCollection> collection = OSDynamicPtrCast<OSCollection>(dict);
628 assert(collection.get() == OSDynamicCast(OSDictionary, dict.get()));
629 OSSharedPtr<OSDictionary> newDict = OSDynamicPtrCast<OSDictionary>(os::move(collection));
630 assert(collection == nullptr);
631 assert(newDict != nullptr);
632 assert(newDict.get() == dict.get());
633 }
634 }
635
636 static int
637 OSSharedPtrTests(int)
638 {
639 OSDynamicPtrCastTests();
640 OSConstPtrCastTests();
641 OSStaticPtrCastTests();
642 return 0;
643 }
644
645 #endif /* DEVELOPMENT || DEBUG */
646
647 #ifndef __clang_analyzer__
648 // All the scary things that this function is doing, such as the intentional
649 // overrelease of an OSData, are hidden from the static analyzer.
650 static int
651 sysctl_iokittest(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
652 {
653 int error;
654 int newValue, changed;
655
656 error = sysctl_io_number(req, 0, sizeof(int), &newValue, &changed);
657 if (error) {
658 return error;
659 }
660
661 #if DEVELOPMENT || DEBUG
662 if (changed && (66 == newValue)) {
663 IOReturn ret;
664 IOWorkLoop * wl = IOWorkLoop::workLoop();
665 IOCommandGate * cg = IOCommandGate::commandGate(wl);
666 ret = wl->addEventSource(cg);
667
668 struct x {
669 uint64_t h;
670 uint64_t l;
671 };
672 struct x y;
673
674 y.h = 0x1111111122222222;
675 y.l = 0x3333333344444444;
676
677 kprintf("ret1 %d\n", ret);
678 ret = cg->runActionBlock(^(){
679 printf("hello %d 0x%qx\n", wl->inGate(), y.h);
680 return 99;
681 });
682 kprintf("ret %d\n", ret);
683 }
684
685 if (changed && (999 == newValue)) {
686 OSData * data = OSData::withCapacity(16);
687 data->release();
688 data->release();
689 }
690
691 if (changed && (newValue >= 6666) && (newValue <= 6669)) {
692 OSIterator * iter;
693 IOService * service;
694
695 service = NULL;
696 iter = IOService::getMatchingServices(IOService::nameMatching("XHC1"));
697 if (iter && (service = (IOService *) iter->getNextObject())) {
698 if (newValue == 6666) {
699 IOLog("terminating 0x%qx\n", service->getRegistryEntryID());
700 service->terminate();
701 } else if (newValue == 6667) {
702 IOLog("register 0x%qx\n", service->getRegistryEntryID());
703 service->registerService();
704 }
705 }
706 OSSafeReleaseNULL(iter);
707 if (service) {
708 return 0;
709 }
710 }
711
712
713 if (changed && newValue) {
714 error = IOWorkLoopTest(newValue);
715 assert(KERN_SUCCESS == error);
716 error = IOServiceTest(newValue);
717 assert(KERN_SUCCESS == error);
718 error = OSCollectionTest(newValue);
719 assert(KERN_SUCCESS == error);
720 error = OSAllocationTests(newValue);
721 assert(KERN_SUCCESS == error);
722 error = OSBoundedArrayTests(newValue);
723 assert(KERN_SUCCESS == error);
724 error = OSBoundedArrayRefTests(newValue);
725 assert(KERN_SUCCESS == error);
726 error = OSBoundedPtrTests(newValue);
727 assert(KERN_SUCCESS == error);
728 error = IOMemoryDescriptorTest(newValue);
729 assert(KERN_SUCCESS == error);
730 error = OSSharedPtrTests(newValue);
731 assert(KERN_SUCCESS == error);
732 error = IOSharedDataQueue_44636964(newValue);
733 assert(KERN_SUCCESS == error);
734 }
735 #endif /* DEVELOPMENT || DEBUG */
736
737 return error;
738 }
739
740 SYSCTL_PROC(_kern, OID_AUTO, iokittest,
741 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
742 NULL, 0, sysctl_iokittest, "I", "");
743 #endif // __clang_analyzer__