]> git.saurik.com Git - apple/xnu.git/blob - libkern/libkern/c++/OSKext.h
xnu-1456.1.26.tar.gz
[apple/xnu.git] / libkern / libkern / c++ / OSKext.h
1 /*
2 * Copyright (c) 2008-2009 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/kxld.h>
36 #include <mach/kmod.h>
37
38 #ifdef XNU_KERNEL_PRIVATE
39 #include <kern/thread_call.h>
40 #endif /* XNU_KERNEL_PRIVATE */
41 }
42
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>
48
49 /*********************************************************************
50 * C functions used for callbacks.
51 *********************************************************************/
52 #ifdef XNU_KERNEL_PRIVATE
53 extern "C" {
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);
57 };
58 #endif /* XNU_KERNEL_PRIVATE */
59
60 /*********************************************************************
61 * C Function Prototypes for Friend Declarations.
62 *********************************************************************/
63 class OSKext;
64
65 extern "C" {
66
67 void OSKextLog(
68 OSKext * aKext,
69 OSKextLogSpec msgLogSpec,
70 const char * format, ...)
71 __attribute__((format(printf, 3, 4)));
72
73 void OSKextVLog(
74 OSKext * aKext,
75 OSKextLogSpec msgLogSpec,
76 const char * format,
77 va_list srcArgList);
78
79 #ifdef XNU_KERNEL_PRIVATE
80 void OSKextRemoveKextBootstrap(void);
81 void IOSystemShutdownNotification(void);
82
83 kern_return_t OSRuntimeInitializeCPP(
84 kmod_info_t * kmodInfo,
85 void * data);
86 kern_return_t OSRuntimeFinalizeCPP(
87 kmod_info_t * kmodInfo,
88 void * data);
89
90 kern_return_t is_io_catalog_send_data(
91 mach_port_t masterPort,
92 uint32_t flag,
93 io_buf_ptr_t inData,
94 mach_msg_type_number_t inDataCount,
95 kern_return_t * result);
96
97 void kmod_dump_log(vm_offset_t*, unsigned int);
98
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__ */
104
105 #endif /* XNU_KERNEL_PRIVATE */
106 };
107
108 /********************************************************************/
109 #if PRAGMA_MARK
110 #pragma mark -
111 #endif
112 /*
113 * @class OSKext
114 */
115 /********************************************************************/
116 class OSKext : public OSObject
117 {
118 OSDeclareDefaultStructors(OSKext)
119
120 #if PRAGMA_MARK
121 /**************************************/
122 #pragma mark Friend Declarations
123 /**************************************/
124 #endif
125 friend class IOCatalogue;
126 friend class IOPMrootDomain;
127 friend class KLDBootstrap;
128 friend class OSMetaClass;
129
130 #ifdef XNU_KERNEL_PRIVATE
131 friend void OSKextVLog(
132 OSKext * aKext,
133 OSKextLogSpec msgLogSpec,
134 const char * format,
135 va_list srcArgList);
136
137 friend void OSKextRemoveKextBootstrap(void);
138 friend void IOSystemShutdownNotification(void);
139 friend OSReturn OSKextUnloadKextWithLoadTag(uint32_t);
140
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);
151
152 friend kxld_addr_t kern_allocate(
153 u_long size,
154 KXLDAllocateFlags * flags,
155 void * user_data);
156
157 friend void kxld_log_shim(
158 KXLDLogSubsystem subsystem,
159 KXLDLogLevel level,
160 const char * format,
161 va_list argList,
162 void * user_data);
163
164 friend void _OSKextConsiderUnloads(
165 __unused thread_call_param_t p0,
166 __unused thread_call_param_t p1);
167
168 friend kern_return_t OSRuntimeInitializeCPP(
169 kmod_info_t * kmodInfo,
170 void * data);
171 friend kern_return_t OSRuntimeFinalizeCPP(
172 kmod_info_t * kmodInfo,
173 void * data);
174
175 friend kern_return_t is_io_catalog_send_data(
176 mach_port_t masterPort,
177 uint32_t flag,
178 io_buf_ptr_t inData,
179 mach_msg_type_number_t inDataCount,
180 kern_return_t * result);
181
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, ...));
185
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__ */
191
192 #endif /* XNU_KERNEL_PRIVATE */
193
194 private:
195
196 /*************************
197 * Instance variables
198 *************************/
199 OSDictionary * infoDict;
200
201 const OSSymbol * bundleID;
202 OSString * path; // not necessarily correct :-/
203
204 OSKextVersion version; // parsed
205 OSKextVersion compatibleVersion; // parsed
206
207 /* These fields are required for tracking loaded kexts and
208 * will always have values for a loaded kext.
209 */
210 OSKextLoadTag loadTag; // 'id' from old kmod_info;
211 // kOSKextInvalidLoadTag invalid
212 kmod_info_t * kmod_info; // address into linkedExec./alloced for interface
213
214 OSArray * dependencies; // kernel resource does not have any;
215 // links directly to kernel
216 OSData * linkState; // only kept for libraries
217
218 /* Only real kexts have these; interface kexts do not.
219 */
220 OSData * linkedExecutable;
221 OSSet * metaClasses; // for C++/OSMetaClass kexts
222
223 /* Only interface kexts have these; interface kexts can get at them
224 * in the linked Executable.
225 */
226 OSData * interfaceUUID;
227
228 struct {
229 unsigned int loggingEnabled:1;
230
231 unsigned int hasAllDependencies:1;
232
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;
241
242 unsigned int autounloadEnabled:1;
243 unsigned int delayAutounload:1; // for development
244
245 unsigned int CPPInitialized:1;
246 } flags;
247
248 #if PRAGMA_MARK
249 /**************************************/
250 #pragma mark Private Functions
251 /**************************************/
252 #endif
253 private:
254
255 /* Startup/shutdown phases.
256 */
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
261
262 /* Called by power management at sleep/shutdown.
263 */
264 static bool setLoadEnabled(bool flag);
265 static bool setUnloadEnabled(bool flag);
266 static bool setAutounloadsEnabled(bool flag);
267 static bool setKernelRequestsEnabled(bool flag);
268
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);
274
275 /* Instance life cycle.
276 */
277 static OSKext * withBooterData(
278 OSString * deviceTreeName,
279 OSData * booterData);
280 virtual bool initWithBooterData(
281 OSString * deviceTreeName,
282 OSData * booterData);
283
284 static OSKext * withPrelinkedInfoDict(
285 OSDictionary * infoDict);
286 virtual bool initWithPrelinkedInfoDict(
287 OSDictionary * infoDict);
288
289 static OSKext * withMkext2Info(
290 OSDictionary * anInfoDict,
291 OSData * mkextData);
292 virtual bool initWithMkext2Info(
293 OSDictionary * anInfoDict,
294 OSData * mkextData);
295
296 virtual bool setInfoDictionaryAndPath(
297 OSDictionary * aDictionary,
298 OSString * aPath);
299 virtual bool setExecutable(
300 OSData * anExecutable,
301 OSData * externalData = NULL,
302 bool externalDataIsMkext = false);
303 virtual bool registerIdentifier(void);
304
305 virtual void free(void);
306
307 static OSReturn removeKext(
308 OSKext * aKext,
309 bool terminateServicesAndRemovePersonalitiesFlag = false);
310
311 /* Mkexts.
312 */
313 static OSReturn readMkextArchive(
314 OSData * mkextData,
315 uint32_t * checksumPtr = NULL);
316 static OSReturn readMkext2Archive(
317 OSData * mkextData,
318 OSDictionary ** mkextPlistOut,
319 uint32_t * checksumPtr = NULL);
320 virtual OSData * createMkext2FileEntry(
321 OSData * mkextData,
322 OSNumber * offsetNum,
323 const char * entryName);
324 virtual OSData * extractMkext2FileData(
325 UInt8 * data,
326 const char * name,
327 uint32_t compressedSize,
328 uint32_t fullSize);
329
330 static OSReturn readMkext1Archive(
331 OSData * mkextData,
332 uint32_t * checksumPtr);
333 bool initWithMkext1Info(
334 OSDictionary * anInfoDict,
335 OSData * executableWrapper,
336 OSData * mkextData);
337 static OSData * extractMkext1Entry(
338 const void * mkextFileBase,
339 const void * entry);
340
341
342 /* Dependencies.
343 */
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);
350
351 /* User-space requests (load/generic).
352 */
353 static OSReturn loadFromMkext(
354 OSKextLogSpec clientLogSpec,
355 char * mkextBuffer,
356 uint32_t mkextBufferLength,
357 char ** logInfoOut,
358 uint32_t * logInfoLengthOut);
359 static OSReturn handleRequest(
360 host_priv_t hostPriv,
361 OSKextLogSpec clientLogSpec,
362 char * requestBuffer,
363 uint32_t requestLength,
364 char ** responseOut,
365 uint32_t * responseLengthOut,
366 char ** logInfoOut,
367 uint32_t * logInfoLengthOut);
368 static OSReturn serializeLogInfo(
369 OSArray * logInfoArray,
370 char ** logInfoOut,
371 uint32_t * logInfoLengthOut);
372
373 /* Loading.
374 */
375 virtual OSReturn load(
376 OSKextExcludeLevel startOpt = kOSKextExcludeNone,
377 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll,
378 OSArray * personalityNames = NULL); // priv/prot
379 virtual OSReturn unload(void);
380
381 static void recordIdentifierRequest(
382 OSString * kextIdentifier);
383
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);
389
390 virtual OSReturn start(bool startDependenciesFlag = true);
391 virtual OSReturn stop(void);
392 virtual OSReturn setVMProtections(void);
393 virtual OSReturn validateKextMapping(bool startFlag);
394
395 static OSArray * copyAllKextPersonalities(
396 bool filterSafeBootFlag = false);
397
398 static void setPrelinkedPersonalities(OSArray * personalitiesArray);
399
400 static void sendAllKextPersonalitiesToCatalog(
401 bool startMatching = false);
402 virtual void sendPersonalitiesToCatalog(
403 bool startMatching = false,
404 OSArray * personalityNames = NULL);
405
406 static bool canUnloadKextWithIdentifier(
407 OSString * kextIdentifier,
408 bool checkClassesFlag = true);
409
410 static OSReturn autounloadKext(OSKext * aKext);
411
412 /* Getting info about loaded kexts (kextstat).
413 */
414 static OSArray * copyLoadedKextInfo(OSArray * kextIdentifiers);
415 virtual OSDictionary * copyInfo(void);
416
417 /* Logging to user space.
418 */
419 static OSKextLogSpec setUserSpaceLogFilter(
420 OSKextLogSpec userLogSpec,
421 bool captureFlag = false);
422 static OSArray * clearUserSpaceLogFilter(void);
423 static OSKextLogSpec getUserSpaceLogFilter(void);
424
425 /* OSMetaClasses defined by kext.
426 */
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);
439
440 static OSReturn dispatchResource(OSDictionary * requestDict);
441
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);
455
456 /* panic() support.
457 */
458 static void printKextsInBacktrace(
459 vm_offset_t * addr,
460 unsigned int cnt,
461 int (* printf_func)(const char *fmt, ...),
462 bool lockFlag);
463 static uint32_t saveLoadedKextPanicListTyped(
464 const char * prefix,
465 int invertFlag,
466 int libsFlag,
467 char * paniclist,
468 uint32_t list_size,
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, ...));
473
474 /* C++ Initialization.
475 */
476
477 virtual void setCPPInitialized(bool initialized=true);
478
479 #if __ppc__ || __i386__
480 /* Backward compatibility for kmod_get_info() MIG call.
481 */
482 static kern_return_t getKmodInfo(
483 kmod_info_array_t * kmodList,
484 mach_msg_type_number_t * kmodCount);
485 #endif /* __ppc__ || __i386__ */
486
487
488 #if PRAGMA_MARK
489 /**************************************/
490 #pragma mark Public Functions
491 /**************************************/
492 #endif
493 public:
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);
499
500 static bool isKextWithIdentifierLoaded(const char * kextIdentifier);
501
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);
522
523 static OSReturn requestResource(
524 const char * kextIdentifier,
525 const char * resourceName,
526 OSKextRequestResourceCallback callback,
527 void * context,
528 OSKextRequestTag * requestTagOut);
529 static OSReturn cancelRequest(
530 OSKextRequestTag requestTag,
531 void ** contextOut);
532
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);
538
539 virtual bool setAutounloadEnabled(bool flag);
540
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);
547
548 virtual OSKextLoadTag getLoadTag(void);
549 virtual OSData * copyUUID(void);
550 virtual OSArray * copyPersonalitiesArray(void);
551 virtual void removePersonalitiesFromCatalog(void);
552
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);
561 };
562
563
564 #endif /* !_LIBKERN_OSKEXT_H */