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