xref: /xnu-8020.140.41/libkern/libkern/c++/OSKext.h (revision 27b03b360a988dfd3dfdf34262bb0042026747cc)
1 /*
2  * Copyright (c) 2008-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 
29 #ifndef _LIBKERN_OSKEXT_H
30 #define _LIBKERN_OSKEXT_H
31 
32 extern "C" {
33 #include <kern/thread_call.h>
34 #include <libkern/OSKextLibPrivate.h>
35 #include <libkern/kernel_mach_header.h>
36 #include <libkern/kxld.h>
37 #include <mach/kmod.h>
38 
39 #ifdef XNU_KERNEL_PRIVATE
40 #include <kern/thread_call.h>
41 #endif /* XNU_KERNEL_PRIVATE */
42 }
43 
44 
45 #include <libkern/OSKextLib.h>
46 #include <libkern/OSKextLibPrivate.h>
47 #include <libkern/c++/OSObject.h>
48 #include <libkern/c++/OSContainers.h>
49 
50 #include <libkern/c++/OSPtr.h>
51 #include <IOKit/IOLocks.h>
52 
53 /*********************************************************************
54 * C functions used for callbacks.
55 *********************************************************************/
56 #ifdef XNU_KERNEL_PRIVATE
57 extern "C" {
58 void osdata_kmem_free(void * ptr, unsigned int length);
59 void osdata_phys_free(void * ptr, unsigned int length);
60 void osdata_vm_deallocate(void * ptr, unsigned int length);
61 void osdata_kext_free(void * ptr, unsigned int length);
62 void kxld_log_callback(
63 	KXLDLogSubsystem    subsystem,
64 	KXLDLogLevel        level,
65 	const char        * format,
66 	va_list             argList,
67 	void              * user_data);
68 };
69 #endif /* XNU_KERNEL_PRIVATE */
70 
71 /*********************************************************************
72 * C Function Prototypes for Friend Declarations.
73 *********************************************************************/
74 class OSKext;
75 
76 extern "C" {
77 void OSKextLog(
78 	OSKext         * aKext,
79 	OSKextLogSpec    msgLogSpec,
80 	const char     * format, ...) __printflike(3, 4);
81 
82 void OSKextVLog(
83 	OSKext         * aKext,
84 	OSKextLogSpec    msgLogSpec,
85 	const char     * format,
86 	va_list          srcArgList) __printflike(3, 0);;
87 
88 #ifdef XNU_KERNEL_PRIVATE
89 void OSKextRemoveKextBootstrap(void);
90 
91 kern_return_t OSRuntimeInitializeCPP(
92 	OSKext * kext);
93 kern_return_t OSRuntimeFinalizeCPP(
94 	OSKext * kext);
95 void OSRuntimeUnloadCPPForSegment(
96 	kernel_segment_command_t * segment);
97 void
98 OSRuntimeSignStructors(
99 	kernel_mach_header_t * header);
100 void
101 OSRuntimeSignStructorsInFileset(
102 	kernel_mach_header_t * fileset_header);
103 
104 kern_return_t is_io_catalog_send_data(
105 	mach_port_t              masterPort,
106 	uint32_t                 flag,
107 	io_buf_ptr_t             inData,
108 	mach_msg_type_number_t   inDataCount,
109 	kern_return_t          * result);
110 
111 void kmod_dump_log(vm_offset_t*, unsigned int, boolean_t);
112 void *OSKextKextForAddress(const void *addr);
113 
114 #endif /* XNU_KERNEL_PRIVATE */
115 };
116 
117 /********************************************************************/
118 #if PRAGMA_MARK
119 #pragma mark -
120 #endif
121 
122 struct list_head {
123 	struct list_head *prev;
124 	struct list_head *next;
125 };
126 
127 struct OSKextGrabPgoStruct {
128 	bool metadata;
129 	uint64_t *pSize;
130 	char *pBuffer;
131 	uint64_t bufferSize;
132 	int err;
133 	struct list_head list_head;
134 };
135 
136 #ifndef container_of
137 #define container_of(ptr, type, member) ((type*)(((uintptr_t)ptr) - offsetof(type, member)))
138 #endif
139 /********************************************************************/
140 
141 #if XNU_KERNEL_PRIVATE
142 
143 struct OSKextAccount {
144 	vm_allocation_site_t site;
145 
146 #if DEVELOPMENT || DEBUG
147 	struct os_refgrp     task_refgrp;
148 	/*
149 	 * '5' for the "task_" prefix. task_refgrp_name can be entirely dropped
150 	 * once we can directly flag the refgrp to be logged.
151 	 */
152 	char                 task_refgrp_name[5 + KMOD_MAX_NAME];
153 #endif /* DEVELOPMENT || DEBUG */
154 	uint32_t             loadTag;
155 	OSKext             * kext;
156 };
157 
158 struct OSKextActiveAccount {
159 	uintptr_t       address;
160 	uintptr_t       address_end;
161 	OSKextAccount * account;
162 };
163 typedef struct OSKextActiveAccount OSKextActiveAccount;
164 
165 class OSKextSavedMutableSegment : public OSObject {
166 	OSDeclareDefaultStructors(OSKextSavedMutableSegment);
167 public:
168 	static OSPtr<OSKextSavedMutableSegment> withSegment(kernel_segment_command_t *seg);
169 	OSReturn restoreContents(kernel_segment_command_t *seg);
170 	vm_offset_t getVMAddr() const;
171 	vm_size_t getVMSize() const;
172 	virtual void free(void) APPLE_KEXT_OVERRIDE;
173 private:
174 	bool initWithSegment(kernel_segment_command_t *seg);
175 	kernel_segment_command_t *savedSegment;
176 	vm_offset_t vmaddr;
177 	vm_size_t   vmsize;
178 	void      * data;
179 };
180 
181 #endif /* XNU_KERNEL_PRIVATE */
182 
183 /*
184  * @class OSKext
185  */
186 /********************************************************************/
187 class OSKext : public OSObject
188 {
189 	OSDeclareDefaultStructors(OSKext);
190 
191 #if PRAGMA_MARK
192 /**************************************/
193 #pragma mark Friend Declarations
194 /**************************************/
195 #endif
196 	friend class IOCatalogue;
197 	friend class KLDBootstrap;
198 	friend class OSMetaClass;
199 
200 	friend int OSKextGrabPgoData(uuid_t uuid,
201 	    uint64_t *pSize,
202 	    char *pBuffer,
203 	    uint64_t bufferSize,
204 	    int wait_for_unload,
205 	    int metadata);
206 
207 #ifdef XNU_KERNEL_PRIVATE
208 	friend void OSKextVLog(
209 		OSKext         * aKext,
210 		OSKextLogSpec    msgLogSpec,
211 		const char     * format,
212 		va_list          srcArgList) __printflike(3, 0);
213 
214 	friend void OSKextRemoveKextBootstrap(void);
215 	friend OSReturn OSKextUnloadKextWithLoadTag(uint32_t);
216 
217 	friend kern_return_t kext_request(
218 		host_priv_t                             hostPriv,
219 		/* in only */ uint32_t                 clientLogSpec,
220 		/* in only */ vm_offset_t              requestIn,
221 		/* in only */ mach_msg_type_number_t   requestLengthIn,
222 		/* out only */ vm_offset_t            * responseOut,
223 		/* out only */ mach_msg_type_number_t * responseLengthOut,
224 		/* out only */ vm_offset_t            * logDataOut,
225 		/* out only */ mach_msg_type_number_t * logDataLengthOut,
226 		/* out only */ kern_return_t          * op_result);
227 
228 	friend kxld_addr_t kern_allocate(
229 		u_long              size,
230 		KXLDAllocateFlags * flags,
231 		void              * user_data);
232 
233 	friend void kxld_log_shim(
234 		KXLDLogSubsystem    subsystem,
235 		KXLDLogLevel        level,
236 		const char        * format,
237 		va_list             argList,
238 		void              * user_data);
239 
240 	friend void _OSKextConsiderUnloads(
241 		__unused thread_call_param_t p0,
242 		__unused thread_call_param_t p1);
243 
244 	friend kern_return_t OSRuntimeInitializeCPP(
245 		OSKext * kext);
246 	friend kern_return_t OSRuntimeFinalizeCPP(
247 		OSKext * kext);
248 	friend void OSRuntimeUnloadCPPForSegment(
249 		kernel_segment_command_t * segment);
250 
251 	friend kern_return_t is_io_catalog_send_data(
252 		mach_port_t              masterPort,
253 		uint32_t                 flag,
254 		io_buf_ptr_t             inData,
255 		mach_msg_type_number_t   inDataCount,
256 		kern_return_t          * result);
257 
258 	friend void kmod_panic_dump(vm_offset_t*, unsigned int);
259 	friend void kmod_dump_log(vm_offset_t*, unsigned int, boolean_t);
260 	friend void kext_dump_panic_lists(int (*printf_func)(const char * fmt, ...));
261 	friend void *OSKextKextForAddress(const void *addr);
262 
263 #endif /* XNU_KERNEL_PRIVATE */
264 
265 private:
266 
267 /*************************
268 * Instance variables
269 *************************/
270 	OSPtr<OSDictionary>  infoDict;
271 
272 	OSPtr<const OSSymbol>    bundleID;
273 	OSPtr<OSString>    path;           // not necessarily correct :-/
274 	OSPtr<OSString>    executableRelPath;// relative to bundle
275 	OSPtr<OSString>    userExecutableRelPath;// relative to bundle
276 
277 	OSKextVersion    version;        // parsed
278 	OSKextVersion    compatibleVersion;// parsed
279 
280 /* These fields are required for tracking loaded kexts and
281  * will always have values for a loaded kext.
282  */
283 	OSKextLoadTag    loadTag;        // 'id' from old kmod_info;
284 	                                 // kOSKextInvalidLoadTag invalid
285 	kmod_info_t    * kmod_info;      // address into linkedExec./alloced for interface
286 
287 	OSPtr<OSArray>     dependencies;   // kernel resource does not have any;
288 	// links directly to kernel
289 
290 /* Only real kexts have these; interface kexts do not.
291  */
292 	OSPtr<OSData>       linkedExecutable;
293 	OSPtr<OSSet>        metaClasses;       // for C++/OSMetaClass kexts
294 
295 /* Only interface kexts have these; non-interface kexts can get at them
296  * in the linked Executable.
297  */
298 	OSPtr<OSData>       interfaceUUID;
299 	OSPtr<OSData>       driverKitUUID;
300 
301 	struct {
302 		unsigned int loggingEnabled:1;
303 
304 		unsigned int hasAllDependencies:1;
305 		unsigned int hasBleedthrough:1;
306 
307 		unsigned int interface:1;
308 		unsigned int kernelComponent:1;
309 		unsigned int prelinked:1;
310 		unsigned int builtin:1;
311 		unsigned int loaded:1;
312 		unsigned int dtraceInitialized:1;
313 		unsigned int starting:1;
314 		unsigned int started:1;
315 		unsigned int stopping:1;
316 		unsigned int unloading:1;
317 		unsigned int resetSegmentsFromVnode:1;
318 
319 		unsigned int requireExplicitLoad:1;
320 		unsigned int autounloadEnabled:1;
321 		unsigned int delayAutounload:1; // for development
322 
323 		unsigned int CPPInitialized:1;
324 		unsigned int jettisonLinkeditSeg:1;
325 		unsigned int resetSegmentsFromImmutableCopy:1;
326 		unsigned int unloadUnsupported:1;
327 	} flags;
328 
329 	uint32_t matchingRefCount;
330 	kc_kind_t kc_type;
331 
332 	struct list_head pendingPgoHead;
333 	uuid_t instance_uuid;
334 	OSKextAccount * account;
335 	uint32_t builtinKmodIdx;
336 	OSPtr<OSArray> savedMutableSegments;
337 
338 #if PRAGMA_MARK
339 /**************************************/
340 #pragma mark Private Functions
341 /**************************************/
342 #endif
343 
344 #ifdef XNU_KERNEL_PRIVATE
345 /* Startup/shutdown phases.
346  */
347 public:
348 	static void           initialize(void);
349 	static OSPtr<OSDictionary> copyKexts(void);
350 	static OSReturn       removeKextBootstrap(void);
351 	static void           willShutdown(void);// called by IOPMrootDomain on shutdown
352 	static void           willUserspaceReboot(void);
353 	static void           resetAfterUserspaceReboot(void);
354 	static  void reportOSMetaClassInstances(
355 		const char     * kextIdentifier,
356 		OSKextLogSpec    msgLogSpec);
357 	static void OSKextLogDriverKitInfoLoad(OSKext *kext);
358 #endif /* XNU_KERNEL_PRIVATE */
359 
360 private:
361 /* Called by power management at sleep/shutdown.
362  */
363 	static bool setLoadEnabled(bool flag);
364 	static bool setUnloadEnabled(bool flag);
365 	static bool setAutounloadsEnabled(bool flag);
366 	static bool setKernelRequestsEnabled(bool flag);
367 
368 // all getters subject to race condition, caller beware
369 	static bool getLoadEnabled(void);
370 	static bool getUnloadEnabled(void);
371 	static bool getAutounloadEnabled(void);
372 	static bool getKernelRequestsEnabled(void);
373 
374 /* Instance life cycle.
375  */
376 	static OSPtr<OSKext> withBooterData(
377 		OSString * deviceTreeName,
378 		OSData   * booterData);
379 	virtual bool initWithBooterData(
380 		OSString * deviceTreeName,
381 		OSData   * booterData);
382 
383 	static OSPtr<OSKext> withPrelinkedInfoDict(
384 		OSDictionary * infoDict,
385 		bool doCoalesedSlides, kc_kind_t type);
386 	virtual bool initWithPrelinkedInfoDict(
387 		OSDictionary * infoDict,
388 		bool doCoalesedSlides, kc_kind_t type);
389 
390 	static OSSharedPtr<OSKext> withCodelessInfo(
391 		OSDictionary * infoDict);
392 	virtual bool initWithCodelessInfo(
393 		OSDictionary * infoDict);
394 
395 	static void setAllVMAttributes(void);
396 
397 	virtual bool setInfoDictionaryAndPath(
398 		OSDictionary * aDictionary,
399 		OSString     * aPath);
400 	virtual bool setExecutable(
401 		OSData       * anExecutable,
402 		OSData       * externalData        = NULL,
403 		bool           externalDataIsMkext = false);
404 	virtual bool registerIdentifier(void);
405 
406 	virtual void free(void) APPLE_KEXT_OVERRIDE;
407 
408 	static OSReturn removeKext(
409 		OSKext * aKext,
410 		bool     terminateServicesAndRemovePersonalitiesFlag = false);
411 
412 	virtual bool isInExcludeList(void);
413 	virtual bool isLoadable(void);
414 
415 /* Mkexts.
416  */
417 #if CONFIG_KXLD
418 	static OSPtr<OSKext> withMkext2Info(
419 		OSDictionary * anInfoDict,
420 		OSData       * mkextData);
421 	virtual bool initWithMkext2Info(
422 		OSDictionary * anInfoDict,
423 		OSData       * mkextData);
424 
425 	static OSReturn readMkextArchive(
426 		OSData   * mkextData,
427 		uint32_t * checksumPtr = NULL);
428 	static OSReturn readMkext2Archive(
429 		OSData * mkextData,
430 		OSDictionary ** mkextPlistOut,
431 		uint32_t * checksumPtr = NULL);
432 
433 	static OSReturn readMkext2Archive(
434 		OSData * mkextData,
435 		OSSharedPtr<OSDictionary> &mkextPlistOut,
436 		uint32_t * checksumPtr = NULL);
437 
438 	virtual OSPtr<OSData> createMkext2FileEntry(
439 		OSData * mkextData,
440 		OSNumber * offsetNum,
441 		const char * entryName);
442 	virtual OSPtr<OSData> extractMkext2FileData(
443 		UInt8      * data,
444 		const char * name,
445 		uint32_t     compressedSize,
446 		uint32_t     fullSize);
447 #endif // CONFIG_KXLD
448 
449 /* Dependencies.
450  */
451 	virtual bool resolveDependencies(
452 		OSArray * loopStack = NULL); // priv/prot
453 	virtual bool addBleedthroughDependencies(OSArray * anArray);
454 	virtual bool flushDependencies(bool forceFlag = false); // priv/prot
455 	virtual uint32_t  getNumDependencies(void);
456 	virtual OSArray * getDependencies(void);
457 
458 /* User-space requests (load/generic).
459  */
460 	static OSReturn loadFromMkext(
461 		OSKextLogSpec   clientLogSpec,
462 		char          * mkextBuffer,
463 		uint32_t        mkextBufferLength,
464 		char         ** logInfoOut,
465 		uint32_t      * logInfoLengthOut);
466 	static OSReturn handleRequest(
467 		host_priv_t     hostPriv,
468 		OSKextLogSpec   clientLogSpec,
469 		char          * requestBuffer,
470 		uint32_t        requestLength,
471 		char         ** responseOut,
472 		uint32_t      * responseLengthOut,
473 		char         ** logInfoOut,
474 		uint32_t      * logInfoLengthOut);
475 	static OSReturn loadCodelessKext(
476 		OSString      * kextIdentifier,
477 		OSDictionary  * requestDict);
478 	static OSReturn serializeLogInfo(
479 		OSArray   * logInfoArray,
480 		char     ** logInfoOut,
481 		uint32_t  * logInfoLengthOut);
482 
483 /* Loading.
484  */
485 	static bool addKextsFromKextCollection(kernel_mach_header_t *mh,
486 	    OSDictionary *infoDict, const char *text_seg_name,
487 	    OSData **kcUUID, kc_kind_t type);
488 
489 	static bool addKextsFromKextCollection(kernel_mach_header_t *mh,
490 	    OSDictionary *infoDict, const char *text_seg_name,
491 	    OSSharedPtr<OSData> &kcUUID, kc_kind_t type);
492 
493 	static bool registerDeferredKextCollection(kernel_mach_header_t *mh,
494 	    OSSharedPtr<OSObject> &parsedXML, kc_kind_t type);
495 	static OSSharedPtr<OSObject> consumeDeferredKextCollection(kc_kind_t type);
496 
497 	virtual OSReturn load(
498 		OSKextExcludeLevel   startOpt         = kOSKextExcludeNone,
499 		OSKextExcludeLevel   startMatchingOpt = kOSKextExcludeAll,
500 		OSArray            * personalityNames = NULL);// priv/prot
501 	virtual OSReturn unload(void);
502 	virtual OSReturn queueKextNotification(
503 		const char * notificationName,
504 		OSString   * kextIdentifier);
505 
506 	static void recordIdentifierRequest(
507 		OSString * kextIdentifier);
508 
509 	virtual OSReturn slidePrelinkedExecutable(bool doCoalesedSlides);
510 	virtual OSReturn loadExecutable(void);
511 	virtual void     jettisonLinkeditSegment(void);
512 	virtual void     jettisonDATASegmentPadding(void);
513 	static  void     considerDestroyingLinkContext(void);
514 	virtual OSData * getExecutable(void);
515 	virtual void     setLinkedExecutable(OSData * anExecutable);
516 
517 #if CONFIG_DTRACE
518 	friend  void OSKextRegisterKextsWithDTrace(void);
519 	static  void registerKextsWithDTrace(void);
520 	virtual void registerWithDTrace(void);
521 	virtual void unregisterWithDTrace(void);
522 #endif /* CONFIG_DTRACE */
523 
524 	virtual OSReturn start(bool startDependenciesFlag = true);
525 	virtual OSReturn stop(void);
526 	virtual OSReturn setVMAttributes(bool protect, bool wire);
527 	virtual boolean_t segmentShouldBeWired(kernel_segment_command_t *seg);
528 	virtual OSReturn validateKextMapping(bool startFlag);
529 	virtual boolean_t verifySegmentMapping(kernel_segment_command_t *seg);
530 
531 	static OSPtr<OSArray> copyAllKextPersonalities(
532 		bool filterSafeBootFlag = false);
533 
534 	static  void  setPrelinkedPersonalities(OSArray * personalitiesArray);
535 
536 	static  void  sendAllKextPersonalitiesToCatalog(
537 		bool startMatching = false);
538 	virtual OSReturn  sendPersonalitiesToCatalog(
539 		bool      startMatching    = false,
540 		OSArray * personalityNames = NULL);
541 
542 	static bool canUnloadKextWithIdentifier(
543 		OSString * kextIdentifier,
544 		bool       checkClassesFlag = true);
545 
546 	static OSReturn autounloadKext(OSKext * aKext);
547 
548 /* Sync with user space.
549  */
550 	static OSReturn pingIOKitDaemon(void);
551 
552 /* Getting info about loaded kexts (kextstat).
553  */
554 	static  OSPtr<OSDictionary> copyLoadedKextInfo(
555 		OSArray * kextIdentifiers = NULL,
556 		OSArray * keys = NULL);
557 	static  OSPtr<OSDictionary> copyLoadedKextInfoByUUID(
558 		OSArray * kextIdentifiers = NULL,
559 		OSArray * keys = NULL);
560 	static  OSPtr<OSDictionary> copyKextCollectionInfo(
561 		OSDictionary *requestDict,
562 		OSArray  *infoKeys = NULL);
563 	static OSPtr<OSData> copyKextUUIDForAddress(OSNumber *address = NULL);
564 	virtual OSPtr<OSDictionary> copyInfo(OSArray * keys = NULL);
565 
566 /* Logging to user space.
567  */
568 	static OSKextLogSpec setUserSpaceLogFilter(
569 		OSKextLogSpec  userLogSpec,
570 		bool           captureFlag = false);
571 	static OSPtr<OSArray> clearUserSpaceLogFilter(void);
572 	static OSKextLogSpec getUserSpaceLogFilter(void);
573 
574 /* OSMetaClasses defined by kext.
575  */
576 	virtual OSReturn addClass(
577 		OSMetaClass * aClass,
578 		uint32_t     numClasses);
579 	virtual OSReturn removeClass(
580 		OSMetaClass * aClass);
581 	virtual bool    hasOSMetaClassInstances(void);
582 	virtual OSSet * getMetaClasses(void);
583 
584 	virtual void reportOSMetaClassInstances(
585 		OSKextLogSpec msgLogSpec);
586 
587 /* Resource requests and other callback stuff.
588  */
589 	static OSReturn loadFileSetKexts(OSDictionary * requestDict);
590 
591 	static OSReturn loadKCFileSet(const char *filepath, kc_kind_t type);
592 
593 #if defined(__x86_64__) || defined(__i386__)
594 	static OSReturn mapKCFileSet(
595 		void                 *control,
596 		vm_size_t            fsize,
597 		kernel_mach_header_t **mh,
598 		off_t                file_offset,
599 		uintptr_t            *slide,
600 		bool                 pageable,
601 		void                 *map_entry_buffer);
602 	static OSReturn protectKCFileSet(
603 		kernel_mach_header_t *mh,
604 		kc_kind_t            type);
605 	static OSReturn mapKCTextSegment(
606 		void                 *control,
607 		kernel_mach_header_t **mhp,
608 		off_t                file_offset,
609 		uintptr_t            *slide,
610 		void                 *map_entry_list);
611 	static void freeKCFileSetcontrol(void);
612 	OSReturn resetKCFileSetSegments(void);
613 #endif //(__x86_64__) || defined(__i386__)
614 
615 	static void jettisonFileSetLinkeditSegment(kernel_mach_header_t *mh);
616 	static OSReturn validateKCFileSetUUID(
617 		OSDictionary         *infoDict,
618 		kc_kind_t            type);
619 
620 	static OSReturn validateKCUUIDfromPrelinkInfo(
621 		uuid_t               *loaded_kcuuid,
622 		kc_kind_t             type,
623 		OSDictionary         *infoDict,
624 		const char           *uuid_key);
625 
626 	static OSReturn dispatchResource(OSDictionary * requestDict);
627 
628 	static OSReturn setMissingAuxKCBundles(OSDictionary * requestDict);
629 
630 	static OSReturn setAuxKCBundleAvailable(OSString *kextIdentifier,
631 	    OSDictionary *requestDict);
632 
633 	static OSReturn dequeueCallbackForRequestTag(
634 		OSKextRequestTag    requestTag,
635 		LIBKERN_RETURNS_RETAINED OSDictionary     ** callbackRecordOut);
636 	static OSReturn dequeueCallbackForRequestTag(
637 		OSNumber     *    requestTagNum,
638 		LIBKERN_RETURNS_RETAINED OSDictionary ** callbackRecordOut);
639 
640 	static OSReturn dequeueCallbackForRequestTag(
641 		OSKextRequestTag    requestTag,
642 		OSSharedPtr<OSDictionary> &callbackRecordOut);
643 	static OSReturn dequeueCallbackForRequestTag(
644 		OSNumber     *    requestTagNum,
645 		OSSharedPtr<OSDictionary> &callbackRecordOut);
646 
647 	static void invokeRequestCallback(
648 		OSDictionary * callbackRecord,
649 		OSReturn         requestResult);
650 	virtual void invokeOrCancelRequestCallbacks(
651 		OSReturn callbackResult,
652 		bool     invokeFlag = true);
653 	virtual uint32_t countRequestCallbacks(void);
654 	OSReturn resetMutableSegments(void);
655 
656 /* panic() support.
657  */
658 public:
659 	enum {
660 		kPrintKextsLock    = 0x01,
661 		kPrintKextsUnslide = 0x02,
662 		kPrintKextsTerse   = 0x04
663 	};
664 	static void printKextsInBacktrace(
665 		vm_offset_t   * addr,
666 		unsigned int    cnt,
667 		int          (* printf_func)(const char *fmt, ...),
668 		uint32_t        flags);
669 	bool isDriverKit(void);
670 	bool isInFileset(void);
671 private:
672 	static OSKextLoadedKextSummary *summaryForAddress(const uintptr_t addr);
673 	static void *kextForAddress(const void *addr);
674 	static boolean_t summaryIsInBacktrace(
675 		OSKextLoadedKextSummary * summary,
676 		vm_offset_t             * addr,
677 		unsigned int              cnt);
678 	static void printSummary(
679 		OSKextLoadedKextSummary * summary,
680 		int                    (* printf_func)(const char *fmt, ...),
681 		uint32_t                  flags);
682 
683 	static int saveLoadedKextPanicListTyped(
684 		const char * prefix,
685 		int          invertFlag,
686 		int          libsFlag,
687 		char       * paniclist,
688 		uint32_t     list_size);
689 	static void saveLoadedKextPanicList(void);
690 	void savePanicString(bool isLoading);
691 	static void printKextPanicLists(int (*printf_func)(const char *fmt, ...));
692 
693 /* Kext summary support.
694  */
695 	static void updateLoadedKextSummaries(void);
696 	void updateLoadedKextSummary(OSKextLoadedKextSummary *summary);
697 	void updateActiveAccount(OSKextActiveAccount *accountp);
698 	static void removeDaemonExitRequests(void);
699 
700 #ifdef XNU_KERNEL_PRIVATE
701 public:
702 #endif /* XNU_KERNEL_PRIVATE */
703 
704 /* C++ Initialization.
705  */
706 	virtual void               setCPPInitialized(bool initialized = true);
707 
708 #if PRAGMA_MARK
709 /**************************************/
710 #pragma mark Public Functions
711 /**************************************/
712 #endif
713 public:
714 	// caller must release
715 	static OSPtr<OSKext> lookupKextWithIdentifier(const char * kextIdentifier);
716 	static OSPtr<OSKext> lookupKextWithIdentifier(OSString * kextIdentifier);
717 	static OSPtr<OSKext> lookupKextWithLoadTag(OSKextLoadTag aTag);
718 	static OSPtr<OSKext> lookupKextWithAddress(vm_address_t address);
719 	static OSPtr<OSKext> lookupKextWithUUID(uuid_t uuid);
720 
721 	kernel_section_t *lookupSection(const char *segname, const char*secname);
722 
723 	static bool isKextWithIdentifierLoaded(const char * kextIdentifier);
724 
725 	static OSReturn loadKextWithIdentifier(
726 		const char       * kextIdentifier,
727 		Boolean            allowDeferFlag      = true,
728 		Boolean            delayAutounloadFlag = false,
729 		OSKextExcludeLevel startOpt            = kOSKextExcludeNone,
730 		OSKextExcludeLevel startMatchingOpt    = kOSKextExcludeAll,
731 		OSArray          * personalityNames    = NULL);
732 
733 	static OSReturn loadKextWithIdentifier(
734 		OSString         * kextIdentifier,
735 		LIBKERN_RETURNS_RETAINED_ON_ZERO OSObject        ** kextRef,
736 		Boolean            allowDeferFlag      = true,
737 		Boolean            delayAutounloadFlag = false,
738 		OSKextExcludeLevel startOpt            = kOSKextExcludeNone,
739 		OSKextExcludeLevel startMatchingOpt    = kOSKextExcludeAll,
740 		OSArray          * personalityNames    = NULL);
741 
742 	static OSReturn loadKextWithIdentifier(
743 		OSString         *    kextIdentifier,
744 		OSSharedPtr<OSObject> &kextRef,
745 		Boolean                allowDeferFlag      = true,
746 		Boolean                delayAutounloadFlag = false,
747 		OSKextExcludeLevel     startOpt            = kOSKextExcludeNone,
748 		OSKextExcludeLevel     startMatchingOpt    = kOSKextExcludeAll,
749 		OSArray              * personalityNames    = NULL);
750 
751 	static OSReturn loadKextFromKC(OSKext *theKext, OSDictionary *requestDict);
752 
753 	static void dropMatchingReferences(
754 		OSSet * kexts);
755 
756 	bool hasDependency(const OSSymbol * depID);
757 
758 	static OSReturn removeKextWithIdentifier(
759 		const char * kextIdentifier,
760 		bool         terminateServicesAndRemovePersonalitiesFlag = false);
761 	static OSReturn removeKextWithLoadTag(
762 		OSKextLoadTag loadTag,
763 		bool          terminateServicesAndRemovePersonalitiesFlag = false);
764 	static OSReturn requestDaemonLaunch(
765 		OSString        * kextIdentifier,
766 		OSString        * serverName,
767 		OSNumber        * serverTag,
768 		class IOUserServerCheckInToken * checkInToken);
769 
770 	static OSReturn requestResource(
771 		const char                    * kextIdentifier,
772 		const char                    * resourceName,
773 		OSKextRequestResourceCallback   callback,
774 		void                          * context,
775 		OSKextRequestTag              * requestTagOut);
776 	static OSReturn cancelRequest(
777 		OSKextRequestTag    requestTag,
778 		void             ** contextOut);
779 
780 	static void     considerUnloads(Boolean rescheduleOnlyFlag = false);
781 	static void     flushNonloadedKexts(Boolean flushPrelinkedKexts);
782 	static void     setIOKitDaemonActive(bool active = true);
783 	static void     setDeferredLoadSucceeded(Boolean succeeded = true);
784 	static void     considerRebuildOfPrelinkedKernel(void);
785 	static void     createExcludeListFromBooterData(
786 		OSDictionary * theDictionary,
787 		OSCollectionIterator * theIterator);
788 	static void     createExcludeListFromPrelinkInfo(OSArray * theInfoArray);
789 	static boolean_t updateExcludeList(OSDictionary * infoDict);
790 
791 	static bool     pendingIOKitDaemonRequests(void);
792 
793 	virtual bool    setAutounloadEnabled(bool flag);
794 
795 	virtual const OSSymbol   * getIdentifier(void);
796 	virtual const char       * getIdentifierCString(void);
797 	virtual OSKextVersion      getVersion(void);
798 	virtual OSKextVersion      getCompatibleVersion(void);
799 	virtual bool               isLibrary(void);
800 	virtual bool               isCompatibleWithVersion(OSKextVersion aVersion);
801 	virtual OSObject         * getPropertyForHostArch(const char * key);
802 
803 	virtual OSKextLoadTag      getLoadTag(void);
804 	virtual void               getSizeInfo(uint32_t *loadSize, uint32_t *wiredSize);
805 	virtual OSPtr<OSData>          copyUUID(void);
806 	OSPtr<OSData>                  copyTextUUID(void);
807 	OSPtr<OSData>                  copyMachoUUID(const kernel_mach_header_t * header);
808 	virtual OSPtr<OSArray>         copyPersonalitiesArray(void);
809 	static bool                copyUserExecutablePath(const OSSymbol * bundleID, char * pathResult, size_t pathSize);
810 	virtual void               setDriverKitUUID(LIBKERN_CONSUMED OSData *uuid);
811 /* This removes personalities naming the kext (by CFBundleIdentifier),
812  * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier).
813  */
814 	virtual void               removePersonalitiesFromCatalog(void);
815 
816 /* Converts common string-valued properties to OSSymbols for lower memory consumption.
817  */
818 	static void uniquePersonalityProperties(OSDictionary * personalityDict);
819 #ifdef XNU_KERNEL_PRIVATE
820 	static void uniquePersonalityProperties(OSDictionary * personalityDict, bool defaultAddKernelBundleIdentifier);
821 #endif
822 
823 	virtual bool               declaresExecutable(void); // might be missing
824 	virtual bool               isInterface(void);
825 	virtual bool               isKernel(void);
826 	virtual bool               isKernelComponent(void);
827 	virtual bool               isExecutable(void);
828 	virtual bool               isLoadableInSafeBoot(void);
829 	virtual bool               isPrelinked(void);
830 	virtual bool               isLoaded(void);
831 	virtual bool               isStarted(void);
832 	virtual bool               isCPPInitialized(void);
833 
834 	const char *
getKCTypeString(void)835 	getKCTypeString(void)
836 	{
837 		switch (kc_type) {
838 		case KCKindPrimary:
839 			return kKCTypePrimary;
840 		case KCKindPageable:
841 			return kKCTypeSystem;
842 		case KCKindAuxiliary:
843 			return kKCTypeAuxiliary;
844 		case KCKindNone:
845 			return kKCTypeCodeless;
846 		default:
847 			return "??";
848 		}
849 	}
850 };
851 
852 extern "C" void OSKextResetAfterUserspaceReboot(void);
853 
854 #endif /* !_LIBKERN_OSKEXT_H */
855