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