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/kernel_mach_header.h>
36 #include <libkern/kxld.h>
37 #include <mach/kmod.h>
39 #ifdef XNU_KERNEL_PRIVATE
40 #include <kern/thread_call.h>
41 #endif /* XNU_KERNEL_PRIVATE */
44 #include <libkern/OSKextLib.h>
45 #include <libkern/OSKextLibPrivate.h>
46 #include <libkern/c++/OSObject.h>
47 #include <libkern/c++/OSContainers.h>
48 #include <IOKit/IOLocks.h>
50 /*********************************************************************
51 * C functions used for callbacks.
52 *********************************************************************/
53 #ifdef XNU_KERNEL_PRIVATE
55 void osdata_kmem_free(void * ptr
, unsigned int length
);
56 void osdata_phys_free(void * ptr
, unsigned int length
);
57 void osdata_vm_deallocate(void * ptr
, unsigned int length
);
59 #endif /* XNU_KERNEL_PRIVATE */
61 /*********************************************************************
62 * C Function Prototypes for Friend Declarations.
63 *********************************************************************/
70 OSKextLogSpec msgLogSpec
,
71 const char * format
, ...)
72 __attribute__((format(printf
, 3, 4)));
76 OSKextLogSpec msgLogSpec
,
80 #ifdef XNU_KERNEL_PRIVATE
81 void OSKextRemoveKextBootstrap(void);
82 void IOSystemShutdownNotification(void);
84 kern_return_t
OSRuntimeInitializeCPP(
85 kmod_info_t
* kmodInfo
,
87 kern_return_t
OSRuntimeFinalizeCPP(
88 kmod_info_t
* kmodInfo
,
91 kern_return_t
is_io_catalog_send_data(
92 mach_port_t masterPort
,
95 mach_msg_type_number_t inDataCount
,
96 kern_return_t
* result
);
98 void kmod_dump_log(vm_offset_t
*, unsigned int);
101 kern_return_t
kext_get_kmod_info(
102 kmod_info_array_t
* kmod_list
,
103 mach_msg_type_number_t
* kmodCount
);
104 #endif /* __i386__ */
106 #endif /* XNU_KERNEL_PRIVATE */
109 /********************************************************************/
116 /********************************************************************/
117 class OSKext
: public OSObject
119 OSDeclareDefaultStructors(OSKext
)
122 /**************************************/
123 #pragma mark Friend Declarations
124 /**************************************/
126 friend class IOCatalogue
;
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
, ...));
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 /* __i386__ */
192 #endif /* XNU_KERNEL_PRIVATE */
196 /*************************
198 *************************/
199 OSDictionary
* infoDict
;
201 const OSSymbol
* bundleID
;
202 OSString
* path
; // not necessarily correct :-/
203 OSString
* executableRelPath
; // relative to bundle
205 OSKextVersion version
; // parsed
206 OSKextVersion compatibleVersion
; // parsed
208 /* These fields are required for tracking loaded kexts and
209 * will always have values for a loaded kext.
211 OSKextLoadTag loadTag
; // 'id' from old kmod_info;
212 // kOSKextInvalidLoadTag invalid
213 kmod_info_t
* kmod_info
; // address into linkedExec./alloced for interface
215 OSArray
* dependencies
; // kernel resource does not have any;
216 // links directly to kernel
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; non-interface kexts can get at them
224 * in the linked Executable.
226 OSData
* interfaceUUID
;
229 unsigned int loggingEnabled
:1;
231 unsigned int hasAllDependencies
:1;
232 unsigned int hasBleedthrough
:1;
234 unsigned int interface
:1;
235 unsigned int kernelComponent
:1;
236 unsigned int prelinked
:1;
237 unsigned int loaded
:1;
238 unsigned int dtraceInitialized
:1;
239 unsigned int starting
:1;
240 unsigned int started
:1;
241 unsigned int stopping
:1;
242 unsigned int unloading
:1;
244 unsigned int autounloadEnabled
:1;
245 unsigned int delayAutounload
:1; // for development
247 unsigned int CPPInitialized
:1;
248 unsigned int jettisonLinkeditSeg
:1;
252 /**************************************/
253 #pragma mark Private Functions
254 /**************************************/
257 #ifdef XNU_KERNEL_PRIVATE
258 /* Startup/shutdown phases.
261 static void initialize(void);
262 static OSDictionary
* copyKexts(void);
263 static OSReturn
removeKextBootstrap(void);
264 static void willShutdown(void); // called by IOPMrootDomain on shutdown
265 #endif /* XNU_KERNEL_PRIVATE */
268 /* Called by power management at sleep/shutdown.
270 static bool setLoadEnabled(bool flag
);
271 static bool setUnloadEnabled(bool flag
);
272 static bool setAutounloadsEnabled(bool flag
);
273 static bool setKernelRequestsEnabled(bool flag
);
275 // all getters subject to race condition, caller beware
276 static bool getLoadEnabled(void);
277 static bool getUnloadEnabled(void);
278 static bool getAutounloadEnabled(void);
279 static bool getKernelRequestsEnabled(void);
281 /* Instance life cycle.
283 static OSKext
* withBooterData(
284 OSString
* deviceTreeName
,
285 OSData
* booterData
);
286 virtual bool initWithBooterData(
287 OSString
* deviceTreeName
,
288 OSData
* booterData
);
290 static OSKext
* withPrelinkedInfoDict(
291 OSDictionary
* infoDict
);
292 virtual bool initWithPrelinkedInfoDict(
293 OSDictionary
* infoDict
);
295 static OSKext
* withMkext2Info(
296 OSDictionary
* anInfoDict
,
298 virtual bool initWithMkext2Info(
299 OSDictionary
* anInfoDict
,
302 virtual bool setInfoDictionaryAndPath(
303 OSDictionary
* aDictionary
,
305 virtual bool setExecutable(
306 OSData
* anExecutable
,
307 OSData
* externalData
= NULL
,
308 bool externalDataIsMkext
= false);
309 virtual bool registerIdentifier(void);
311 virtual void free(void);
313 static OSReturn
removeKext(
315 bool terminateServicesAndRemovePersonalitiesFlag
= false);
319 static OSReturn
readMkextArchive(
321 uint32_t * checksumPtr
= NULL
);
322 static OSReturn
readMkext2Archive(
324 OSDictionary
** mkextPlistOut
,
325 uint32_t * checksumPtr
= NULL
);
326 virtual OSData
* createMkext2FileEntry(
328 OSNumber
* offsetNum
,
329 const char * entryName
);
330 virtual OSData
* extractMkext2FileData(
333 uint32_t compressedSize
,
336 static OSReturn
readMkext1Archive(
338 uint32_t * checksumPtr
);
339 bool initWithMkext1Info(
340 OSDictionary
* anInfoDict
,
341 OSData
* executableWrapper
,
343 static OSData
* extractMkext1Entry(
344 const void * mkextFileBase
,
349 virtual bool resolveDependencies(
350 OSArray
* loopStack
= NULL
); // priv/prot
351 virtual bool addBleedthroughDependencies(OSArray
* anArray
);
352 virtual bool flushDependencies(bool forceFlag
= false); // priv/prot
353 virtual uint32_t getNumDependencies(void);
354 virtual OSArray
* getDependencies(void);
356 /* User-space requests (load/generic).
358 static OSReturn
loadFromMkext(
359 OSKextLogSpec clientLogSpec
,
361 uint32_t mkextBufferLength
,
363 uint32_t * logInfoLengthOut
);
364 static OSReturn
handleRequest(
365 host_priv_t hostPriv
,
366 OSKextLogSpec clientLogSpec
,
367 char * requestBuffer
,
368 uint32_t requestLength
,
370 uint32_t * responseLengthOut
,
372 uint32_t * logInfoLengthOut
);
373 static OSReturn
serializeLogInfo(
374 OSArray
* logInfoArray
,
376 uint32_t * logInfoLengthOut
);
380 virtual OSReturn
load(
381 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
382 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
383 OSArray
* personalityNames
= NULL
); // priv/prot
384 virtual OSReturn
unload(void);
385 virtual OSReturn
queueKextNotification(
386 const char * notificationName
,
387 OSString
* kextIdentifier
);
389 static void recordIdentifierRequest(
390 OSString
* kextIdentifier
);
392 virtual OSReturn
slidePrelinkedExecutable(void);
393 virtual OSReturn
loadExecutable(void);
394 virtual void jettisonLinkeditSegment(void);
395 static void considerDestroyingLinkContext(void);
396 virtual OSData
* getExecutable(void);
397 virtual void setLinkedExecutable(OSData
* anExecutable
);
400 friend void OSKextRegisterKextsWithDTrace(void);
401 static void registerKextsWithDTrace(void);
402 virtual void registerWithDTrace(void);
403 virtual void unregisterWithDTrace(void);
404 #endif /* CONFIG_DTRACE */
406 virtual OSReturn
start(bool startDependenciesFlag
= true);
407 virtual OSReturn
stop(void);
408 virtual OSReturn
setVMProtections(void);
409 virtual boolean_t
segmentShouldBeWired(kernel_segment_command_t
*seg
);
410 virtual OSReturn
validateKextMapping(bool startFlag
);
411 virtual boolean_t
verifySegmentMapping(kernel_segment_command_t
*seg
);
413 static OSArray
* copyAllKextPersonalities(
414 bool filterSafeBootFlag
= false);
416 static void setPrelinkedPersonalities(OSArray
* personalitiesArray
);
418 static void sendAllKextPersonalitiesToCatalog(
419 bool startMatching
= false);
420 virtual OSReturn
sendPersonalitiesToCatalog(
421 bool startMatching
= false,
422 OSArray
* personalityNames
= NULL
);
424 static bool canUnloadKextWithIdentifier(
425 OSString
* kextIdentifier
,
426 bool checkClassesFlag
= true);
428 static OSReturn
autounloadKext(OSKext
* aKext
);
430 /* Sync with user space.
432 static OSReturn
pingKextd(void);
434 /* Getting info about loaded kexts (kextstat).
436 static OSDictionary
* copyLoadedKextInfo(
437 OSArray
* kextIdentifiers
= NULL
,
438 OSArray
* keys
= NULL
);
439 virtual OSDictionary
* copyInfo(OSArray
* keys
= NULL
);
441 /* Logging to user space.
443 static OSKextLogSpec
setUserSpaceLogFilter(
444 OSKextLogSpec userLogSpec
,
445 bool captureFlag
= false);
446 static OSArray
* clearUserSpaceLogFilter(void);
447 static OSKextLogSpec
getUserSpaceLogFilter(void);
449 /* OSMetaClasses defined by kext.
451 virtual OSReturn
addClass(
452 OSMetaClass
* aClass
,
453 uint32_t numClasses
);
454 virtual OSReturn
removeClass(
455 OSMetaClass
* aClass
);
456 virtual bool hasOSMetaClassInstances(void);
457 virtual OSSet
* getMetaClasses(void);
458 static void reportOSMetaClassInstances(
459 const char * kextIdentifier
,
460 OSKextLogSpec msgLogSpec
);
461 virtual void reportOSMetaClassInstances(
462 OSKextLogSpec msgLogSpec
);
464 /* Resource requests and other callback stuff.
466 static OSReturn
dispatchResource(OSDictionary
* requestDict
);
468 static OSReturn
dequeueCallbackForRequestTag(
469 OSKextRequestTag requestTag
,
470 OSDictionary
** callbackRecordOut
);
471 static OSReturn
dequeueCallbackForRequestTag(
472 OSNumber
* requestTagNum
,
473 OSDictionary
** callbackRecordOut
);
474 static void invokeRequestCallback(
475 OSDictionary
* callbackRecord
,
476 OSReturn requestResult
);
477 virtual void invokeOrCancelRequestCallbacks(
478 OSReturn callbackResult
,
479 bool invokeFlag
= true);
480 virtual uint32_t countRequestCallbacks(void);
484 static void printKextsInBacktrace(
487 int (* printf_func
)(const char *fmt
, ...),
489 static boolean_t
summaryIsInBacktrace(
490 OSKextLoadedKextSummary
* summary
,
493 static void printSummary(
494 OSKextLoadedKextSummary
* summary
,
495 int (* printf_func
)(const char *fmt
, ...));
497 static uint32_t saveLoadedKextPanicListTyped(
503 uint32_t * list_length_ptr
);
504 static void saveLoadedKextPanicList(void);
505 void savePanicString(bool isLoading
);
506 static void printKextPanicLists(int (*printf_func
)(const char *fmt
, ...));
508 /* Kext summary support.
510 static void updateLoadedKextSummaries(void);
511 void updateLoadedKextSummary(OSKextLoadedKextSummary
*summary
);
513 /* C++ Initialization.
515 virtual void setCPPInitialized(bool initialized
=true);
518 /* Backward compatibility for kmod_get_info() MIG call.
520 static kern_return_t
getKmodInfo(
521 kmod_info_array_t
* kmodList
,
522 mach_msg_type_number_t
* kmodCount
);
523 #endif /* __i386__ */
527 /**************************************/
528 #pragma mark Public Functions
529 /**************************************/
532 // caller must release
533 static OSKext
* lookupKextWithIdentifier(const char * kextIdentifier
);
534 static OSKext
* lookupKextWithIdentifier(OSString
* kextIdentifier
);
535 static OSKext
* lookupKextWithLoadTag(OSKextLoadTag aTag
);
536 static OSKext
* lookupKextWithAddress(vm_address_t address
);
538 static bool isKextWithIdentifierLoaded(const char * kextIdentifier
);
540 static OSReturn
loadKextWithIdentifier(
541 const char * kextIdentifier
,
542 Boolean allowDeferFlag
= true,
543 Boolean delayAutounloadFlag
= false,
544 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
545 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
546 OSArray
* personalityNames
= NULL
);
547 static OSReturn
loadKextWithIdentifier(
548 OSString
* kextIdentifier
,
549 Boolean allowDeferFlag
= true,
550 Boolean delayAutounloadFlag
= false,
551 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
552 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
553 OSArray
* personalityNames
= NULL
);
554 static OSReturn
removeKextWithIdentifier(
555 const char * kextIdentifier
,
556 bool terminateServicesAndRemovePersonalitiesFlag
= false);
557 static OSReturn
removeKextWithLoadTag(
558 OSKextLoadTag loadTag
,
559 bool terminateServicesAndRemovePersonalitiesFlag
= false);
561 static OSReturn
requestResource(
562 const char * kextIdentifier
,
563 const char * resourceName
,
564 OSKextRequestResourceCallback callback
,
566 OSKextRequestTag
* requestTagOut
);
567 static OSReturn
cancelRequest(
568 OSKextRequestTag requestTag
,
571 static void considerUnloads(Boolean rescheduleOnlyFlag
= false);
572 static void flushNonloadedKexts(Boolean flushPrelinkedKexts
);
573 static void setKextdActive(Boolean active
= true);
574 static void setDeferredLoadSucceeded(Boolean succeeded
= true);
575 static void considerRebuildOfPrelinkedKernel(void);
577 virtual bool setAutounloadEnabled(bool flag
);
579 virtual const OSSymbol
* getIdentifier(void);
580 virtual const char * getIdentifierCString(void);
581 virtual OSKextVersion
getVersion(void);
582 virtual OSKextVersion
getCompatibleVersion(void);
583 virtual bool isLibrary(void);
584 virtual bool isCompatibleWithVersion(OSKextVersion aVersion
);
585 virtual OSObject
* getPropertyForHostArch(const char * key
);
587 virtual OSKextLoadTag
getLoadTag(void);
588 virtual void getSizeInfo(uint32_t *loadSize
, uint32_t *wiredSize
);
589 virtual OSData
* copyUUID(void);
590 virtual OSArray
* copyPersonalitiesArray(void);
592 /* This removes personalities naming the kext (by CFBundleIdentifier),
593 * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier).
595 virtual void removePersonalitiesFromCatalog(void);
597 /* Converts common string-valued properties to OSSymbols for lower memory consumption.
599 static void uniquePersonalityProperties(OSDictionary
* personalityDict
);
601 virtual bool declaresExecutable(void); // might be missing
602 virtual bool isInterface(void);
603 virtual bool isKernel(void);
604 virtual bool isKernelComponent(void);
605 virtual bool isExecutable(void);
606 virtual bool isLoadableInSafeBoot(void);
607 virtual bool isPrelinked(void);
608 virtual bool isLoaded(void);
609 virtual bool isStarted(void);
610 virtual bool isCPPInitialized(void);
614 #endif /* !_LIBKERN_OSKEXT_H */