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