2 * Copyright (c) 2008-2012 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, boolean_t
);
101 #endif /* XNU_KERNEL_PRIVATE */
104 /********************************************************************/
111 /********************************************************************/
112 class OSKext
: public OSObject
114 OSDeclareDefaultStructors(OSKext
)
117 /**************************************/
118 #pragma mark Friend Declarations
119 /**************************************/
121 friend class IOCatalogue
;
122 friend class KLDBootstrap
;
123 friend class OSMetaClass
;
125 #ifdef XNU_KERNEL_PRIVATE
126 friend void OSKextVLog(
128 OSKextLogSpec msgLogSpec
,
132 friend void OSKextRemoveKextBootstrap(void);
133 friend void IOSystemShutdownNotification(void);
134 friend OSReturn
OSKextUnloadKextWithLoadTag(uint32_t);
136 friend kern_return_t
kext_request(
137 host_priv_t hostPriv
,
138 /* in only */ uint32_t clientLogSpec
,
139 /* in only */ vm_offset_t requestIn
,
140 /* in only */ mach_msg_type_number_t requestLengthIn
,
141 /* out only */ vm_offset_t
* responseOut
,
142 /* out only */ mach_msg_type_number_t
* responseLengthOut
,
143 /* out only */ vm_offset_t
* logDataOut
,
144 /* out only */ mach_msg_type_number_t
* logDataLengthOut
,
145 /* out only */ kern_return_t
* op_result
);
147 friend kxld_addr_t
kern_allocate(
149 KXLDAllocateFlags
* flags
,
152 friend void kxld_log_shim(
153 KXLDLogSubsystem subsystem
,
159 friend void _OSKextConsiderUnloads(
160 __unused thread_call_param_t p0
,
161 __unused thread_call_param_t p1
);
163 friend kern_return_t
OSRuntimeInitializeCPP(
164 kmod_info_t
* kmodInfo
,
166 friend kern_return_t
OSRuntimeFinalizeCPP(
167 kmod_info_t
* kmodInfo
,
170 friend kern_return_t
is_io_catalog_send_data(
171 mach_port_t masterPort
,
174 mach_msg_type_number_t inDataCount
,
175 kern_return_t
* result
);
177 friend void kmod_panic_dump(vm_offset_t
*, unsigned int);
178 friend void kmod_dump_log(vm_offset_t
*, unsigned int, boolean_t
);
179 friend void kext_dump_panic_lists(int (*printf_func
)(const char * fmt
, ...));
182 #endif /* XNU_KERNEL_PRIVATE */
186 /*************************
188 *************************/
189 OSDictionary
* infoDict
;
191 const OSSymbol
* bundleID
;
192 OSString
* path
; // not necessarily correct :-/
193 OSString
* executableRelPath
; // relative to bundle
195 OSKextVersion version
; // parsed
196 OSKextVersion compatibleVersion
; // parsed
198 /* These fields are required for tracking loaded kexts and
199 * will always have values for a loaded kext.
201 OSKextLoadTag loadTag
; // 'id' from old kmod_info;
202 // kOSKextInvalidLoadTag invalid
203 kmod_info_t
* kmod_info
; // address into linkedExec./alloced for interface
205 OSArray
* dependencies
; // kernel resource does not have any;
206 // links directly to kernel
208 /* Only real kexts have these; interface kexts do not.
210 OSData
* linkedExecutable
;
211 OSSet
* metaClasses
; // for C++/OSMetaClass kexts
213 /* Only interface kexts have these; non-interface kexts can get at them
214 * in the linked Executable.
216 OSData
* interfaceUUID
;
219 unsigned int loggingEnabled
:1;
221 unsigned int hasAllDependencies
:1;
222 unsigned int hasBleedthrough
:1;
224 unsigned int interface
:1;
225 unsigned int kernelComponent
:1;
226 unsigned int prelinked
:1;
227 unsigned int loaded
:1;
228 unsigned int dtraceInitialized
:1;
229 unsigned int starting
:1;
230 unsigned int started
:1;
231 unsigned int stopping
:1;
232 unsigned int unloading
:1;
234 unsigned int autounloadEnabled
:1;
235 unsigned int delayAutounload
:1; // for development
237 unsigned int CPPInitialized
:1;
238 unsigned int jettisonLinkeditSeg
:1;
242 /**************************************/
243 #pragma mark Private Functions
244 /**************************************/
247 #ifdef XNU_KERNEL_PRIVATE
248 /* Startup/shutdown phases.
251 static void initialize(void);
252 static OSDictionary
* copyKexts(void);
253 static OSReturn
removeKextBootstrap(void);
254 static void willShutdown(void); // called by IOPMrootDomain on shutdown
255 #endif /* XNU_KERNEL_PRIVATE */
258 /* Called by power management at sleep/shutdown.
260 static bool setLoadEnabled(bool flag
);
261 static bool setUnloadEnabled(bool flag
);
262 static bool setAutounloadsEnabled(bool flag
);
263 static bool setKernelRequestsEnabled(bool flag
);
265 // all getters subject to race condition, caller beware
266 static bool getLoadEnabled(void);
267 static bool getUnloadEnabled(void);
268 static bool getAutounloadEnabled(void);
269 static bool getKernelRequestsEnabled(void);
271 /* Instance life cycle.
273 static OSKext
* withBooterData(
274 OSString
* deviceTreeName
,
275 OSData
* booterData
);
276 virtual bool initWithBooterData(
277 OSString
* deviceTreeName
,
278 OSData
* booterData
);
280 static OSKext
* withPrelinkedInfoDict(
281 OSDictionary
* infoDict
);
282 virtual bool initWithPrelinkedInfoDict(
283 OSDictionary
* infoDict
);
285 static OSKext
* withMkext2Info(
286 OSDictionary
* anInfoDict
,
288 virtual bool initWithMkext2Info(
289 OSDictionary
* anInfoDict
,
292 virtual bool setInfoDictionaryAndPath(
293 OSDictionary
* aDictionary
,
295 virtual bool setExecutable(
296 OSData
* anExecutable
,
297 OSData
* externalData
= NULL
,
298 bool externalDataIsMkext
= false);
299 virtual bool registerIdentifier(void);
301 virtual void free(void);
303 static OSReturn
removeKext(
305 bool terminateServicesAndRemovePersonalitiesFlag
= false);
307 virtual bool isInExcludeList(void);
311 static OSReturn
readMkextArchive(
313 uint32_t * checksumPtr
= NULL
);
314 static OSReturn
readMkext2Archive(
316 OSDictionary
** mkextPlistOut
,
317 uint32_t * checksumPtr
= NULL
);
318 virtual OSData
* createMkext2FileEntry(
320 OSNumber
* offsetNum
,
321 const char * entryName
);
322 virtual OSData
* extractMkext2FileData(
325 uint32_t compressedSize
,
330 virtual bool resolveDependencies(
331 OSArray
* loopStack
= NULL
); // priv/prot
332 virtual bool addBleedthroughDependencies(OSArray
* anArray
);
333 virtual bool flushDependencies(bool forceFlag
= false); // priv/prot
334 virtual uint32_t getNumDependencies(void);
335 virtual OSArray
* getDependencies(void);
337 /* User-space requests (load/generic).
339 static OSReturn
loadFromMkext(
340 OSKextLogSpec clientLogSpec
,
342 uint32_t mkextBufferLength
,
344 uint32_t * logInfoLengthOut
);
345 static OSReturn
handleRequest(
346 host_priv_t hostPriv
,
347 OSKextLogSpec clientLogSpec
,
348 char * requestBuffer
,
349 uint32_t requestLength
,
351 uint32_t * responseLengthOut
,
353 uint32_t * logInfoLengthOut
);
354 static OSReturn
serializeLogInfo(
355 OSArray
* logInfoArray
,
357 uint32_t * logInfoLengthOut
);
361 virtual OSReturn
load(
362 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
363 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
364 OSArray
* personalityNames
= NULL
); // priv/prot
365 virtual OSReturn
unload(void);
366 virtual OSReturn
queueKextNotification(
367 const char * notificationName
,
368 OSString
* kextIdentifier
);
370 static void recordIdentifierRequest(
371 OSString
* kextIdentifier
);
373 virtual OSReturn
slidePrelinkedExecutable(void);
374 virtual OSReturn
loadExecutable(void);
375 virtual void jettisonLinkeditSegment(void);
376 static void considerDestroyingLinkContext(void);
377 virtual OSData
* getExecutable(void);
378 virtual void setLinkedExecutable(OSData
* anExecutable
);
381 friend void OSKextRegisterKextsWithDTrace(void);
382 static void registerKextsWithDTrace(void);
383 virtual void registerWithDTrace(void);
384 virtual void unregisterWithDTrace(void);
385 #endif /* CONFIG_DTRACE */
387 virtual OSReturn
start(bool startDependenciesFlag
= true);
388 virtual OSReturn
stop(void);
389 virtual OSReturn
setVMProtections(void);
390 virtual boolean_t
segmentShouldBeWired(kernel_segment_command_t
*seg
);
391 virtual OSReturn
validateKextMapping(bool startFlag
);
392 virtual boolean_t
verifySegmentMapping(kernel_segment_command_t
*seg
);
394 static OSArray
* copyAllKextPersonalities(
395 bool filterSafeBootFlag
= false);
397 static void setPrelinkedPersonalities(OSArray
* personalitiesArray
);
399 static void sendAllKextPersonalitiesToCatalog(
400 bool startMatching
= false);
401 virtual OSReturn
sendPersonalitiesToCatalog(
402 bool startMatching
= false,
403 OSArray
* personalityNames
= NULL
);
405 static bool canUnloadKextWithIdentifier(
406 OSString
* kextIdentifier
,
407 bool checkClassesFlag
= true);
409 static OSReturn
autounloadKext(OSKext
* aKext
);
411 /* Sync with user space.
413 static OSReturn
pingKextd(void);
415 /* Getting info about loaded kexts (kextstat).
417 static OSDictionary
* copyLoadedKextInfo(
418 OSArray
* kextIdentifiers
= NULL
,
419 OSArray
* keys
= NULL
);
420 virtual OSDictionary
* copyInfo(OSArray
* keys
= NULL
);
422 /* Logging to user space.
424 static OSKextLogSpec
setUserSpaceLogFilter(
425 OSKextLogSpec userLogSpec
,
426 bool captureFlag
= false);
427 static OSArray
* clearUserSpaceLogFilter(void);
428 static OSKextLogSpec
getUserSpaceLogFilter(void);
430 /* OSMetaClasses defined by kext.
432 virtual OSReturn
addClass(
433 OSMetaClass
* aClass
,
434 uint32_t numClasses
);
435 virtual OSReturn
removeClass(
436 OSMetaClass
* aClass
);
437 virtual bool hasOSMetaClassInstances(void);
438 virtual OSSet
* getMetaClasses(void);
439 static void reportOSMetaClassInstances(
440 const char * kextIdentifier
,
441 OSKextLogSpec msgLogSpec
);
442 virtual void reportOSMetaClassInstances(
443 OSKextLogSpec msgLogSpec
);
445 /* Resource requests and other callback stuff.
447 static OSReturn
dispatchResource(OSDictionary
* requestDict
);
449 static OSReturn
dequeueCallbackForRequestTag(
450 OSKextRequestTag requestTag
,
451 OSDictionary
** callbackRecordOut
);
452 static OSReturn
dequeueCallbackForRequestTag(
453 OSNumber
* requestTagNum
,
454 OSDictionary
** callbackRecordOut
);
455 static void invokeRequestCallback(
456 OSDictionary
* callbackRecord
,
457 OSReturn requestResult
);
458 virtual void invokeOrCancelRequestCallbacks(
459 OSReturn callbackResult
,
460 bool invokeFlag
= true);
461 virtual uint32_t countRequestCallbacks(void);
465 static void printKextsInBacktrace(
468 int (* printf_func
)(const char *fmt
, ...),
471 static boolean_t
summaryIsInBacktrace(
472 OSKextLoadedKextSummary
* summary
,
475 static void printSummary(
476 OSKextLoadedKextSummary
* summary
,
477 int (* printf_func
)(const char *fmt
, ...),
480 static int saveLoadedKextPanicListTyped(
486 static void saveLoadedKextPanicList(void);
487 void savePanicString(bool isLoading
);
488 static void printKextPanicLists(int (*printf_func
)(const char *fmt
, ...));
490 /* Kext summary support.
492 static void updateLoadedKextSummaries(void);
493 void updateLoadedKextSummary(OSKextLoadedKextSummary
*summary
);
495 /* C++ Initialization.
497 virtual void setCPPInitialized(bool initialized
=true);
502 /**************************************/
503 #pragma mark Public Functions
504 /**************************************/
507 // caller must release
508 static OSKext
* lookupKextWithIdentifier(const char * kextIdentifier
);
509 static OSKext
* lookupKextWithIdentifier(OSString
* kextIdentifier
);
510 static OSKext
* lookupKextWithLoadTag(OSKextLoadTag aTag
);
511 static OSKext
* lookupKextWithAddress(vm_address_t address
);
513 static bool isKextWithIdentifierLoaded(const char * kextIdentifier
);
515 static OSReturn
loadKextWithIdentifier(
516 const char * kextIdentifier
,
517 Boolean allowDeferFlag
= true,
518 Boolean delayAutounloadFlag
= false,
519 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
520 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
521 OSArray
* personalityNames
= NULL
);
522 static OSReturn
loadKextWithIdentifier(
523 OSString
* kextIdentifier
,
524 Boolean allowDeferFlag
= true,
525 Boolean delayAutounloadFlag
= false,
526 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
527 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
528 OSArray
* personalityNames
= NULL
);
529 static OSReturn
removeKextWithIdentifier(
530 const char * kextIdentifier
,
531 bool terminateServicesAndRemovePersonalitiesFlag
= false);
532 static OSReturn
removeKextWithLoadTag(
533 OSKextLoadTag loadTag
,
534 bool terminateServicesAndRemovePersonalitiesFlag
= false);
536 static OSReturn
requestResource(
537 const char * kextIdentifier
,
538 const char * resourceName
,
539 OSKextRequestResourceCallback callback
,
541 OSKextRequestTag
* requestTagOut
);
542 static OSReturn
cancelRequest(
543 OSKextRequestTag requestTag
,
546 static void considerUnloads(Boolean rescheduleOnlyFlag
= false);
547 static void flushNonloadedKexts(Boolean flushPrelinkedKexts
);
548 static void setKextdActive(Boolean active
= true);
549 static void setDeferredLoadSucceeded(Boolean succeeded
= true);
550 static void considerRebuildOfPrelinkedKernel(void);
551 static void createExcludeListFromBooterData(
552 OSDictionary
* theDictionary
,
553 OSCollectionIterator
* theIterator
);
554 static void createExcludeListFromPrelinkInfo(OSArray
* theInfoArray
);
556 virtual bool setAutounloadEnabled(bool flag
);
558 virtual const OSSymbol
* getIdentifier(void);
559 virtual const char * getIdentifierCString(void);
560 virtual OSKextVersion
getVersion(void);
561 virtual OSKextVersion
getCompatibleVersion(void);
562 virtual bool isLibrary(void);
563 virtual bool isCompatibleWithVersion(OSKextVersion aVersion
);
564 virtual OSObject
* getPropertyForHostArch(const char * key
);
566 virtual OSKextLoadTag
getLoadTag(void);
567 virtual void getSizeInfo(uint32_t *loadSize
, uint32_t *wiredSize
);
568 virtual OSData
* copyUUID(void);
569 virtual OSArray
* copyPersonalitiesArray(void);
571 /* This removes personalities naming the kext (by CFBundleIdentifier),
572 * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier).
574 virtual void removePersonalitiesFromCatalog(void);
576 /* Converts common string-valued properties to OSSymbols for lower memory consumption.
578 static void uniquePersonalityProperties(OSDictionary
* personalityDict
);
580 virtual bool declaresExecutable(void); // might be missing
581 virtual bool isInterface(void);
582 virtual bool isKernel(void);
583 virtual bool isKernelComponent(void);
584 virtual bool isExecutable(void);
585 virtual bool isLoadableInSafeBoot(void);
586 virtual bool isPrelinked(void);
587 virtual bool isLoaded(void);
588 virtual bool isStarted(void);
589 virtual bool isCPPInitialized(void);
593 #endif /* !_LIBKERN_OSKEXT_H */