2 * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #ifndef _LIBKERN_OSKEXT_H
30 #define _LIBKERN_OSKEXT_H
33 #include <kern/thread_call.h>
34 #include <libkern/OSKextLibPrivate.h>
35 #include <libkern/kxld.h>
36 #include <mach/kmod.h>
38 #ifdef XNU_KERNEL_PRIVATE
39 #include <kern/thread_call.h>
40 #endif /* XNU_KERNEL_PRIVATE */
43 #include <libkern/OSKextLib.h>
44 #include <libkern/OSKextLibPrivate.h>
45 #include <libkern/c++/OSObject.h>
46 #include <libkern/c++/OSContainers.h>
47 #include <IOKit/IOLocks.h>
49 /*********************************************************************
50 * C functions used for callbacks.
51 *********************************************************************/
52 #ifdef XNU_KERNEL_PRIVATE
54 void osdata_kmem_free(void * ptr
, unsigned int length
);
55 void osdata_phys_free(void * ptr
, unsigned int length
);
56 void osdata_vm_deallocate(void * ptr
, unsigned int length
);
58 #endif /* XNU_KERNEL_PRIVATE */
60 /*********************************************************************
61 * C Function Prototypes for Friend Declarations.
62 *********************************************************************/
69 OSKextLogSpec msgLogSpec
,
70 const char * format
, ...)
71 __attribute__((format(printf
, 3, 4)));
75 OSKextLogSpec msgLogSpec
,
79 #ifdef XNU_KERNEL_PRIVATE
80 void OSKextRemoveKextBootstrap(void);
81 void IOSystemShutdownNotification(void);
83 kern_return_t
OSRuntimeInitializeCPP(
84 kmod_info_t
* kmodInfo
,
86 kern_return_t
OSRuntimeFinalizeCPP(
87 kmod_info_t
* kmodInfo
,
90 kern_return_t
is_io_catalog_send_data(
91 mach_port_t masterPort
,
94 mach_msg_type_number_t inDataCount
,
95 kern_return_t
* result
);
97 void kmod_dump_log(vm_offset_t
*, unsigned int);
99 #if __ppc__ || __i386__
100 kern_return_t
kext_get_kmod_info(
101 kmod_info_array_t
* kmod_list
,
102 mach_msg_type_number_t
* kmodCount
);
103 #endif /* __ppc__ || __i386__ */
105 #endif /* XNU_KERNEL_PRIVATE */
108 /********************************************************************/
115 /********************************************************************/
116 class OSKext
: public OSObject
118 OSDeclareDefaultStructors(OSKext
)
121 /**************************************/
122 #pragma mark Friend Declarations
123 /**************************************/
125 friend class IOCatalogue
;
126 friend class IOPMrootDomain
;
127 friend class KLDBootstrap
;
128 friend class OSMetaClass
;
130 #ifdef XNU_KERNEL_PRIVATE
131 friend void OSKextVLog(
133 OSKextLogSpec msgLogSpec
,
137 friend void OSKextRemoveKextBootstrap(void);
138 friend void IOSystemShutdownNotification(void);
139 friend OSReturn
OSKextUnloadKextWithLoadTag(uint32_t);
141 friend kern_return_t
kext_request(
142 host_priv_t hostPriv
,
143 /* in only */ uint32_t clientLogSpec
,
144 /* in only */ vm_offset_t requestIn
,
145 /* in only */ mach_msg_type_number_t requestLengthIn
,
146 /* out only */ vm_offset_t
* responseOut
,
147 /* out only */ mach_msg_type_number_t
* responseLengthOut
,
148 /* out only */ vm_offset_t
* logDataOut
,
149 /* out only */ mach_msg_type_number_t
* logDataLengthOut
,
150 /* out only */ kern_return_t
* op_result
);
152 friend kxld_addr_t
kern_allocate(
154 KXLDAllocateFlags
* flags
,
157 friend void kxld_log_shim(
158 KXLDLogSubsystem subsystem
,
164 friend void _OSKextConsiderUnloads(
165 __unused thread_call_param_t p0
,
166 __unused thread_call_param_t p1
);
168 friend kern_return_t
OSRuntimeInitializeCPP(
169 kmod_info_t
* kmodInfo
,
171 friend kern_return_t
OSRuntimeFinalizeCPP(
172 kmod_info_t
* kmodInfo
,
175 friend kern_return_t
is_io_catalog_send_data(
176 mach_port_t masterPort
,
179 mach_msg_type_number_t inDataCount
,
180 kern_return_t
* result
);
182 friend void kmod_panic_dump(vm_offset_t
*, unsigned int);
183 friend void kmod_dump_log(vm_offset_t
*, unsigned int);
184 friend void kext_dump_panic_lists(int (*printf_func
)(const char * fmt
, ...));
186 #if __ppc__ || __i386__
187 friend kern_return_t
kext_get_kmod_info(
188 kmod_info_array_t
* kmod_list
,
189 mach_msg_type_number_t
* kmodCount
);
190 #endif /* __ppc__ || __i386__ */
192 #endif /* XNU_KERNEL_PRIVATE */
196 /*************************
198 *************************/
199 OSDictionary
* infoDict
;
201 const OSSymbol
* bundleID
;
202 OSString
* path
; // not necessarily correct :-/
204 OSKextVersion version
; // parsed
205 OSKextVersion compatibleVersion
; // parsed
207 /* These fields are required for tracking loaded kexts and
208 * will always have values for a loaded kext.
210 OSKextLoadTag loadTag
; // 'id' from old kmod_info;
211 // kOSKextInvalidLoadTag invalid
212 kmod_info_t
* kmod_info
; // address into linkedExec./alloced for interface
214 OSArray
* dependencies
; // kernel resource does not have any;
215 // links directly to kernel
216 OSData
* linkState
; // only kept for libraries
218 /* Only real kexts have these; interface kexts do not.
220 OSData
* linkedExecutable
;
221 OSSet
* metaClasses
; // for C++/OSMetaClass kexts
223 /* Only interface kexts have these; interface kexts can get at them
224 * in the linked Executable.
226 OSData
* interfaceUUID
;
229 unsigned int loggingEnabled
:1;
231 unsigned int hasAllDependencies
:1;
233 unsigned int interface
:1;
234 unsigned int kernelComponent
:1;
235 unsigned int prelinked
:1;
236 unsigned int loaded
:1;
237 unsigned int starting
:1;
238 unsigned int started
:1;
239 unsigned int stopping
:1;
240 unsigned int unloading
:1;
242 unsigned int autounloadEnabled
:1;
243 unsigned int delayAutounload
:1; // for development
245 unsigned int CPPInitialized
:1;
249 /**************************************/
250 #pragma mark Private Functions
251 /**************************************/
255 /* Startup/shutdown phases.
257 static void initialize(void);
258 static OSDictionary
* copyKexts(void);
259 static OSReturn
removeKextBootstrap(void);
260 static void willShutdown(void); // called by IOPMrootDomain on shutdown
262 /* Called by power management at sleep/shutdown.
264 static bool setLoadEnabled(bool flag
);
265 static bool setUnloadEnabled(bool flag
);
266 static bool setAutounloadsEnabled(bool flag
);
267 static bool setKernelRequestsEnabled(bool flag
);
269 // all getters subject to race condition, caller beware
270 static bool getLoadEnabled(void);
271 static bool getUnloadEnabled(void);
272 static bool getAutounloadEnabled(void);
273 static bool getKernelRequestsEnabled(void);
275 /* Instance life cycle.
277 static OSKext
* withBooterData(
278 OSString
* deviceTreeName
,
279 OSData
* booterData
);
280 virtual bool initWithBooterData(
281 OSString
* deviceTreeName
,
282 OSData
* booterData
);
284 static OSKext
* withPrelinkedInfoDict(
285 OSDictionary
* infoDict
);
286 virtual bool initWithPrelinkedInfoDict(
287 OSDictionary
* infoDict
);
289 static OSKext
* withMkext2Info(
290 OSDictionary
* anInfoDict
,
292 virtual bool initWithMkext2Info(
293 OSDictionary
* anInfoDict
,
296 virtual bool setInfoDictionaryAndPath(
297 OSDictionary
* aDictionary
,
299 virtual bool setExecutable(
300 OSData
* anExecutable
,
301 OSData
* externalData
= NULL
,
302 bool externalDataIsMkext
= false);
303 virtual bool registerIdentifier(void);
305 virtual void free(void);
307 static OSReturn
removeKext(
309 bool terminateServicesAndRemovePersonalitiesFlag
= false);
313 static OSReturn
readMkextArchive(
315 uint32_t * checksumPtr
= NULL
);
316 static OSReturn
readMkext2Archive(
318 OSDictionary
** mkextPlistOut
,
319 uint32_t * checksumPtr
= NULL
);
320 virtual OSData
* createMkext2FileEntry(
322 OSNumber
* offsetNum
,
323 const char * entryName
);
324 virtual OSData
* extractMkext2FileData(
327 uint32_t compressedSize
,
330 static OSReturn
readMkext1Archive(
332 uint32_t * checksumPtr
);
333 bool initWithMkext1Info(
334 OSDictionary
* anInfoDict
,
335 OSData
* executableWrapper
,
337 static OSData
* extractMkext1Entry(
338 const void * mkextFileBase
,
344 virtual bool resolveDependencies(
345 OSArray
* loopStack
= NULL
); // priv/prot
346 virtual bool addBleedthroughDependencies(OSArray
* anArray
);
347 virtual bool flushDependencies(bool forceFlag
= false); // priv/prot
348 virtual uint32_t getNumDependencies(void);
349 virtual OSArray
* getDependencies(void);
351 /* User-space requests (load/generic).
353 static OSReturn
loadFromMkext(
354 OSKextLogSpec clientLogSpec
,
356 uint32_t mkextBufferLength
,
358 uint32_t * logInfoLengthOut
);
359 static OSReturn
handleRequest(
360 host_priv_t hostPriv
,
361 OSKextLogSpec clientLogSpec
,
362 char * requestBuffer
,
363 uint32_t requestLength
,
365 uint32_t * responseLengthOut
,
367 uint32_t * logInfoLengthOut
);
368 static OSReturn
serializeLogInfo(
369 OSArray
* logInfoArray
,
371 uint32_t * logInfoLengthOut
);
375 virtual OSReturn
load(
376 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
377 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
378 OSArray
* personalityNames
= NULL
); // priv/prot
379 virtual OSReturn
unload(void);
381 static void recordIdentifierRequest(
382 OSString
* kextIdentifier
);
384 virtual OSReturn
loadExecutable(void);
385 static void considerDestroyingLinkContext(void);
386 static OSData
* getKernelLinkState(void);
387 virtual OSData
* getExecutable(void);
388 virtual void setLinkedExecutable(OSData
* anExecutable
);
390 virtual OSReturn
start(bool startDependenciesFlag
= true);
391 virtual OSReturn
stop(void);
392 virtual OSReturn
setVMProtections(void);
393 virtual OSReturn
validateKextMapping(bool startFlag
);
395 static OSArray
* copyAllKextPersonalities(
396 bool filterSafeBootFlag
= false);
398 static void setPrelinkedPersonalities(OSArray
* personalitiesArray
);
400 static void sendAllKextPersonalitiesToCatalog(
401 bool startMatching
= false);
402 virtual void sendPersonalitiesToCatalog(
403 bool startMatching
= false,
404 OSArray
* personalityNames
= NULL
);
406 static bool canUnloadKextWithIdentifier(
407 OSString
* kextIdentifier
,
408 bool checkClassesFlag
= true);
410 static OSReturn
autounloadKext(OSKext
* aKext
);
412 /* Getting info about loaded kexts (kextstat).
414 static OSArray
* copyLoadedKextInfo(OSArray
* kextIdentifiers
);
415 virtual OSDictionary
* copyInfo(void);
417 /* Logging to user space.
419 static OSKextLogSpec
setUserSpaceLogFilter(
420 OSKextLogSpec userLogSpec
,
421 bool captureFlag
= false);
422 static OSArray
* clearUserSpaceLogFilter(void);
423 static OSKextLogSpec
getUserSpaceLogFilter(void);
425 /* OSMetaClasses defined by kext.
427 virtual OSReturn
addClass(
428 OSMetaClass
* aClass
,
429 uint32_t numClasses
);
430 virtual OSReturn
removeClass(
431 OSMetaClass
* aClass
);
432 virtual bool hasOSMetaClassInstances(void);
433 virtual OSSet
* getMetaClasses(void);
434 static void reportOSMetaClassInstances(
435 const char * kextIdentifier
,
436 OSKextLogSpec msgLogSpec
);
437 virtual void reportOSMetaClassInstances(
438 OSKextLogSpec msgLogSpec
);
440 static OSReturn
dispatchResource(OSDictionary
* requestDict
);
442 static OSReturn
dequeueCallbackForRequestTag(
443 OSKextRequestTag requestTag
,
444 OSDictionary
** callbackRecordOut
);
445 static OSReturn
dequeueCallbackForRequestTag(
446 OSNumber
* requestTagNum
,
447 OSDictionary
** callbackRecordOut
);
448 static void invokeRequestCallback(
449 OSDictionary
* callbackRecord
,
450 OSReturn requestResult
);
451 virtual void invokeOrCancelRequestCallbacks(
452 OSReturn callbackResult
,
453 bool invokeFlag
= true);
454 virtual uint32_t countRequestCallbacks(void);
458 static void printKextsInBacktrace(
461 int (* printf_func
)(const char *fmt
, ...),
463 static uint32_t saveLoadedKextPanicListTyped(
469 uint32_t * list_length_ptr
);
470 static void saveLoadedKextPanicList(void);
471 static void saveUnloadedKextPanicList(OSKext
* aKext
);
472 static void printKextPanicLists(int (*printf_func
)(const char *fmt
, ...));
474 /* C++ Initialization.
477 virtual void setCPPInitialized(bool initialized
=true);
479 #if __ppc__ || __i386__
480 /* Backward compatibility for kmod_get_info() MIG call.
482 static kern_return_t
getKmodInfo(
483 kmod_info_array_t
* kmodList
,
484 mach_msg_type_number_t
* kmodCount
);
485 #endif /* __ppc__ || __i386__ */
489 /**************************************/
490 #pragma mark Public Functions
491 /**************************************/
494 // caller must release
495 static OSKext
* lookupKextWithIdentifier(const char * kextIdentifier
);
496 static OSKext
* lookupKextWithIdentifier(OSString
* kextIdentifier
);
497 static OSKext
* lookupKextWithLoadTag(OSKextLoadTag aTag
);
498 static OSKext
* lookupKextWithAddress(vm_address_t address
);
500 static bool isKextWithIdentifierLoaded(const char * kextIdentifier
);
502 static OSReturn
loadKextWithIdentifier(
503 const char * kextIdentifier
,
504 Boolean allowDeferFlag
= true,
505 Boolean delayAutounloadFlag
= false,
506 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
507 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
508 OSArray
* personalityNames
= NULL
);
509 static OSReturn
loadKextWithIdentifier(
510 OSString
* kextIdentifier
,
511 Boolean allowDeferFlag
= true,
512 Boolean delayAutounloadFlag
= false,
513 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
514 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
515 OSArray
* personalityNames
= NULL
);
516 static OSReturn
removeKextWithIdentifier(
517 const char * kextIdentifier
,
518 bool terminateServicesAndRemovePersonalitiesFlag
= false);
519 static OSReturn
removeKextWithLoadTag(
520 OSKextLoadTag loadTag
,
521 bool terminateServicesAndRemovePersonalitiesFlag
= false);
523 static OSReturn
requestResource(
524 const char * kextIdentifier
,
525 const char * resourceName
,
526 OSKextRequestResourceCallback callback
,
528 OSKextRequestTag
* requestTagOut
);
529 static OSReturn
cancelRequest(
530 OSKextRequestTag requestTag
,
533 static void considerUnloads(Boolean rescheduleOnlyFlag
= false);
534 static void flushNonloadedKexts(Boolean flushPrelinkedKexts
);
535 static void setKextdActive(Boolean active
= true);
536 static void setDeferredLoadSucceeded(Boolean succeeded
= true);
537 static void considerRebuildOfPrelinkedKernel(void);
539 virtual bool setAutounloadEnabled(bool flag
);
541 virtual const OSSymbol
* getIdentifier(void);
542 virtual const char * getIdentifierCString(void);
543 virtual OSKextVersion
getVersion(void);
544 virtual OSKextVersion
getCompatibleVersion(void);
545 virtual bool isCompatibleWithVersion(OSKextVersion aVersion
);
546 virtual OSObject
* getPropertyForHostArch(const char * key
);
548 virtual OSKextLoadTag
getLoadTag(void);
549 virtual OSData
* copyUUID(void);
550 virtual OSArray
* copyPersonalitiesArray(void);
551 virtual void removePersonalitiesFromCatalog(void);
553 virtual bool declaresExecutable(void); // might be missing
554 virtual bool isInterface(void);
555 virtual bool isKernelComponent(void);
556 virtual bool isLoadableInSafeBoot(void);
557 virtual bool isPrelinked(void);
558 virtual bool isLoaded(void);
559 virtual bool isStarted(void);
560 virtual bool isCPPInitialized(void);
564 #endif /* !_LIBKERN_OSKEXT_H */