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;
251 /**************************************/
252 #pragma mark Private Functions
253 /**************************************/
256 #ifdef XNU_KERNEL_PRIVATE
257 /* Startup/shutdown phases.
260 static void initialize(void);
261 static OSDictionary
* copyKexts(void);
262 static OSReturn
removeKextBootstrap(void);
263 static void willShutdown(void); // called by IOPMrootDomain on shutdown
264 #endif /* XNU_KERNEL_PRIVATE */
267 /* Called by power management at sleep/shutdown.
269 static bool setLoadEnabled(bool flag
);
270 static bool setUnloadEnabled(bool flag
);
271 static bool setAutounloadsEnabled(bool flag
);
272 static bool setKernelRequestsEnabled(bool flag
);
274 // all getters subject to race condition, caller beware
275 static bool getLoadEnabled(void);
276 static bool getUnloadEnabled(void);
277 static bool getAutounloadEnabled(void);
278 static bool getKernelRequestsEnabled(void);
280 /* Instance life cycle.
282 static OSKext
* withBooterData(
283 OSString
* deviceTreeName
,
284 OSData
* booterData
);
285 virtual bool initWithBooterData(
286 OSString
* deviceTreeName
,
287 OSData
* booterData
);
289 static OSKext
* withPrelinkedInfoDict(
290 OSDictionary
* infoDict
);
291 virtual bool initWithPrelinkedInfoDict(
292 OSDictionary
* infoDict
);
294 static OSKext
* withMkext2Info(
295 OSDictionary
* anInfoDict
,
297 virtual bool initWithMkext2Info(
298 OSDictionary
* anInfoDict
,
301 virtual bool setInfoDictionaryAndPath(
302 OSDictionary
* aDictionary
,
304 virtual bool setExecutable(
305 OSData
* anExecutable
,
306 OSData
* externalData
= NULL
,
307 bool externalDataIsMkext
= false);
308 virtual bool registerIdentifier(void);
310 virtual void free(void);
312 static OSReturn
removeKext(
314 bool terminateServicesAndRemovePersonalitiesFlag
= false);
318 static OSReturn
readMkextArchive(
320 uint32_t * checksumPtr
= NULL
);
321 static OSReturn
readMkext2Archive(
323 OSDictionary
** mkextPlistOut
,
324 uint32_t * checksumPtr
= NULL
);
325 virtual OSData
* createMkext2FileEntry(
327 OSNumber
* offsetNum
,
328 const char * entryName
);
329 virtual OSData
* extractMkext2FileData(
332 uint32_t compressedSize
,
335 static OSReturn
readMkext1Archive(
337 uint32_t * checksumPtr
);
338 bool initWithMkext1Info(
339 OSDictionary
* anInfoDict
,
340 OSData
* executableWrapper
,
342 static OSData
* extractMkext1Entry(
343 const void * mkextFileBase
,
348 virtual bool resolveDependencies(
349 OSArray
* loopStack
= NULL
); // priv/prot
350 virtual bool addBleedthroughDependencies(OSArray
* anArray
);
351 virtual bool flushDependencies(bool forceFlag
= false); // priv/prot
352 virtual uint32_t getNumDependencies(void);
353 virtual OSArray
* getDependencies(void);
355 /* User-space requests (load/generic).
357 static OSReturn
loadFromMkext(
358 OSKextLogSpec clientLogSpec
,
360 uint32_t mkextBufferLength
,
362 uint32_t * logInfoLengthOut
);
363 static OSReturn
handleRequest(
364 host_priv_t hostPriv
,
365 OSKextLogSpec clientLogSpec
,
366 char * requestBuffer
,
367 uint32_t requestLength
,
369 uint32_t * responseLengthOut
,
371 uint32_t * logInfoLengthOut
);
372 static OSReturn
serializeLogInfo(
373 OSArray
* logInfoArray
,
375 uint32_t * logInfoLengthOut
);
379 virtual OSReturn
load(
380 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
381 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
382 OSArray
* personalityNames
= NULL
); // priv/prot
383 virtual OSReturn
unload(void);
384 virtual OSReturn
queueKextNotification(
385 const char * notificationName
,
386 OSString
* kextIdentifier
);
388 static void recordIdentifierRequest(
389 OSString
* kextIdentifier
);
391 virtual OSReturn
loadExecutable(void);
392 virtual void jettisonLinkeditSegment(void);
393 virtual OSReturn
removeLinkeditHeaders(kernel_segment_command_t
*linkedit
);
394 static void considerDestroyingLinkContext(void);
395 virtual OSData
* getExecutable(void);
396 virtual void setLinkedExecutable(OSData
* anExecutable
);
399 friend void OSKextRegisterKextsWithDTrace(void);
400 static void registerKextsWithDTrace(void);
401 virtual void registerWithDTrace(void);
402 virtual void unregisterWithDTrace(void);
403 #endif /* CONFIG_DTRACE */
405 virtual OSReturn
start(bool startDependenciesFlag
= true);
406 virtual OSReturn
stop(void);
407 virtual OSReturn
setVMProtections(void);
408 virtual boolean_t
segmentShouldBeWired(kernel_segment_command_t
*seg
);
409 virtual OSReturn
validateKextMapping(bool startFlag
);
410 virtual boolean_t
verifySegmentMapping(kernel_segment_command_t
*seg
);
412 static OSArray
* copyAllKextPersonalities(
413 bool filterSafeBootFlag
= false);
415 static void setPrelinkedPersonalities(OSArray
* personalitiesArray
);
417 static void sendAllKextPersonalitiesToCatalog(
418 bool startMatching
= false);
419 virtual OSReturn
sendPersonalitiesToCatalog(
420 bool startMatching
= false,
421 OSArray
* personalityNames
= NULL
);
423 static bool canUnloadKextWithIdentifier(
424 OSString
* kextIdentifier
,
425 bool checkClassesFlag
= true);
427 static OSReturn
autounloadKext(OSKext
* aKext
);
429 /* Sync with user space.
431 static OSReturn
pingKextd(void);
433 /* Getting info about loaded kexts (kextstat).
435 static OSDictionary
* copyLoadedKextInfo(
436 OSArray
* kextIdentifiers
= NULL
,
437 OSArray
* keys
= NULL
);
438 virtual OSDictionary
* copyInfo(OSArray
* keys
= NULL
);
440 static OSData
* copySanitizedKernelImage(void);
442 /* Logging to user space.
444 static OSKextLogSpec
setUserSpaceLogFilter(
445 OSKextLogSpec userLogSpec
,
446 bool captureFlag
= false);
447 static OSArray
* clearUserSpaceLogFilter(void);
448 static OSKextLogSpec
getUserSpaceLogFilter(void);
450 /* OSMetaClasses defined by kext.
452 virtual OSReturn
addClass(
453 OSMetaClass
* aClass
,
454 uint32_t numClasses
);
455 virtual OSReturn
removeClass(
456 OSMetaClass
* aClass
);
457 virtual bool hasOSMetaClassInstances(void);
458 virtual OSSet
* getMetaClasses(void);
459 static void reportOSMetaClassInstances(
460 const char * kextIdentifier
,
461 OSKextLogSpec msgLogSpec
);
462 virtual void reportOSMetaClassInstances(
463 OSKextLogSpec msgLogSpec
);
465 /* Resource requests and other callback stuff.
467 static OSReturn
dispatchResource(OSDictionary
* requestDict
);
469 static OSReturn
dequeueCallbackForRequestTag(
470 OSKextRequestTag requestTag
,
471 OSDictionary
** callbackRecordOut
);
472 static OSReturn
dequeueCallbackForRequestTag(
473 OSNumber
* requestTagNum
,
474 OSDictionary
** callbackRecordOut
);
475 static void invokeRequestCallback(
476 OSDictionary
* callbackRecord
,
477 OSReturn requestResult
);
478 virtual void invokeOrCancelRequestCallbacks(
479 OSReturn callbackResult
,
480 bool invokeFlag
= true);
481 virtual uint32_t countRequestCallbacks(void);
485 static void printKextsInBacktrace(
488 int (* printf_func
)(const char *fmt
, ...),
490 static boolean_t
summaryIsInBacktrace(
491 OSKextLoadedKextSummary
* summary
,
494 static void printSummary(
495 OSKextLoadedKextSummary
* summary
,
496 int (* printf_func
)(const char *fmt
, ...));
498 static uint32_t saveLoadedKextPanicListTyped(
504 uint32_t * list_length_ptr
);
505 static void saveLoadedKextPanicList(void);
506 void savePanicString(bool isLoading
);
507 static void printKextPanicLists(int (*printf_func
)(const char *fmt
, ...));
509 /* Kext summary support.
511 static void updateLoadedKextSummaries(void);
512 void updateLoadedKextSummary(OSKextLoadedKextSummary
*summary
);
514 /* C++ Initialization.
516 virtual void setCPPInitialized(bool initialized
=true);
519 /* Backward compatibility for kmod_get_info() MIG call.
521 static kern_return_t
getKmodInfo(
522 kmod_info_array_t
* kmodList
,
523 mach_msg_type_number_t
* kmodCount
);
524 #endif /* __i386__ */
528 /**************************************/
529 #pragma mark Public Functions
530 /**************************************/
533 // caller must release
534 static OSKext
* lookupKextWithIdentifier(const char * kextIdentifier
);
535 static OSKext
* lookupKextWithIdentifier(OSString
* kextIdentifier
);
536 static OSKext
* lookupKextWithLoadTag(OSKextLoadTag aTag
);
537 static OSKext
* lookupKextWithAddress(vm_address_t address
);
539 static bool isKextWithIdentifierLoaded(const char * kextIdentifier
);
541 static OSReturn
loadKextWithIdentifier(
542 const char * kextIdentifier
,
543 Boolean allowDeferFlag
= true,
544 Boolean delayAutounloadFlag
= false,
545 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
546 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
547 OSArray
* personalityNames
= NULL
);
548 static OSReturn
loadKextWithIdentifier(
549 OSString
* kextIdentifier
,
550 Boolean allowDeferFlag
= true,
551 Boolean delayAutounloadFlag
= false,
552 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
553 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
554 OSArray
* personalityNames
= NULL
);
555 static OSReturn
removeKextWithIdentifier(
556 const char * kextIdentifier
,
557 bool terminateServicesAndRemovePersonalitiesFlag
= false);
558 static OSReturn
removeKextWithLoadTag(
559 OSKextLoadTag loadTag
,
560 bool terminateServicesAndRemovePersonalitiesFlag
= false);
562 static OSReturn
requestResource(
563 const char * kextIdentifier
,
564 const char * resourceName
,
565 OSKextRequestResourceCallback callback
,
567 OSKextRequestTag
* requestTagOut
);
568 static OSReturn
cancelRequest(
569 OSKextRequestTag requestTag
,
572 static void considerUnloads(Boolean rescheduleOnlyFlag
= false);
573 static void flushNonloadedKexts(Boolean flushPrelinkedKexts
);
574 static void setKextdActive(Boolean active
= true);
575 static void setDeferredLoadSucceeded(Boolean succeeded
= true);
576 static void considerRebuildOfPrelinkedKernel(OSString
* moduleName
);
578 virtual bool setAutounloadEnabled(bool flag
);
580 virtual const OSSymbol
* getIdentifier(void);
581 virtual const char * getIdentifierCString(void);
582 virtual OSKextVersion
getVersion(void);
583 virtual OSKextVersion
getCompatibleVersion(void);
584 virtual bool isLibrary(void);
585 virtual bool isCompatibleWithVersion(OSKextVersion aVersion
);
586 virtual OSObject
* getPropertyForHostArch(const char * key
);
588 virtual OSKextLoadTag
getLoadTag(void);
589 virtual void getSizeInfo(uint32_t *loadSize
, uint32_t *wiredSize
);
590 virtual OSData
* copyUUID(void);
591 virtual OSArray
* copyPersonalitiesArray(void);
593 /* This removes personalities naming the kext (by CFBundleIdentifier),
594 * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier).
596 virtual void removePersonalitiesFromCatalog(void);
598 /* Converts common string-valued properties to OSSymbols for lower memory consumption.
600 static void uniquePersonalityProperties(OSDictionary
* personalityDict
);
602 virtual bool declaresExecutable(void); // might be missing
603 virtual bool isInterface(void);
604 virtual bool isKernel(void);
605 virtual bool isKernelComponent(void);
606 virtual bool isExecutable(void);
607 virtual bool isLoadableInSafeBoot(void);
608 virtual bool isPrelinked(void);
609 virtual bool isLoaded(void);
610 virtual bool isStarted(void);
611 virtual bool isCPPInitialized(void);
615 #endif /* !_LIBKERN_OSKEXT_H */