]> git.saurik.com Git - apple/xnu.git/blob - libkern/libkern/c++/OSKext.h
d3f0fa23296c12ac8da996204ed4fd265608934a
[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/kernel_mach_header.h>
36 #include <libkern/kxld.h>
37 #include <mach/kmod.h>
38
39 #ifdef XNU_KERNEL_PRIVATE
40 #include <kern/thread_call.h>
41 #endif /* XNU_KERNEL_PRIVATE */
42 }
43
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>
49
50 /*********************************************************************
51 * C functions used for callbacks.
52 *********************************************************************/
53 #ifdef XNU_KERNEL_PRIVATE
54 extern "C" {
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);
58 };
59 #endif /* XNU_KERNEL_PRIVATE */
60
61 /*********************************************************************
62 * C Function Prototypes for Friend Declarations.
63 *********************************************************************/
64 class OSKext;
65
66 extern "C" {
67
68 void OSKextLog(
69 OSKext * aKext,
70 OSKextLogSpec msgLogSpec,
71 const char * format, ...)
72 __attribute__((format(printf, 3, 4)));
73
74 void OSKextVLog(
75 OSKext * aKext,
76 OSKextLogSpec msgLogSpec,
77 const char * format,
78 va_list srcArgList);
79
80 #ifdef XNU_KERNEL_PRIVATE
81 void OSKextRemoveKextBootstrap(void);
82 void IOSystemShutdownNotification(void);
83
84 kern_return_t OSRuntimeInitializeCPP(
85 kmod_info_t * kmodInfo,
86 void * data);
87 kern_return_t OSRuntimeFinalizeCPP(
88 kmod_info_t * kmodInfo,
89 void * data);
90
91 kern_return_t is_io_catalog_send_data(
92 mach_port_t masterPort,
93 uint32_t flag,
94 io_buf_ptr_t inData,
95 mach_msg_type_number_t inDataCount,
96 kern_return_t * result);
97
98 void kmod_dump_log(vm_offset_t*, unsigned int);
99
100 #if __i386__
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__ */
105
106 #endif /* XNU_KERNEL_PRIVATE */
107 };
108
109 /********************************************************************/
110 #if PRAGMA_MARK
111 #pragma mark -
112 #endif
113 /*
114 * @class OSKext
115 */
116 /********************************************************************/
117 class OSKext : public OSObject
118 {
119 OSDeclareDefaultStructors(OSKext)
120
121 #if PRAGMA_MARK
122 /**************************************/
123 #pragma mark Friend Declarations
124 /**************************************/
125 #endif
126 friend class IOCatalogue;
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 __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 /* __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 OSString * executableRelPath; // relative to bundle
204
205 OSKextVersion version; // parsed
206 OSKextVersion compatibleVersion; // parsed
207
208 /* These fields are required for tracking loaded kexts and
209 * will always have values for a loaded kext.
210 */
211 OSKextLoadTag loadTag; // 'id' from old kmod_info;
212 // kOSKextInvalidLoadTag invalid
213 kmod_info_t * kmod_info; // address into linkedExec./alloced for interface
214
215 OSArray * dependencies; // kernel resource does not have any;
216 // links directly to kernel
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; non-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 unsigned int hasBleedthrough:1;
233
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;
243
244 unsigned int autounloadEnabled:1;
245 unsigned int delayAutounload:1; // for development
246
247 unsigned int CPPInitialized:1;
248 } flags;
249
250 #if PRAGMA_MARK
251 /**************************************/
252 #pragma mark Private Functions
253 /**************************************/
254 #endif
255
256 #ifdef XNU_KERNEL_PRIVATE
257 /* Startup/shutdown phases.
258 */
259 public:
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 */
265
266 private:
267 /* Called by power management at sleep/shutdown.
268 */
269 static bool setLoadEnabled(bool flag);
270 static bool setUnloadEnabled(bool flag);
271 static bool setAutounloadsEnabled(bool flag);
272 static bool setKernelRequestsEnabled(bool flag);
273
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);
279
280 /* Instance life cycle.
281 */
282 static OSKext * withBooterData(
283 OSString * deviceTreeName,
284 OSData * booterData);
285 virtual bool initWithBooterData(
286 OSString * deviceTreeName,
287 OSData * booterData);
288
289 static OSKext * withPrelinkedInfoDict(
290 OSDictionary * infoDict);
291 virtual bool initWithPrelinkedInfoDict(
292 OSDictionary * infoDict);
293
294 static OSKext * withMkext2Info(
295 OSDictionary * anInfoDict,
296 OSData * mkextData);
297 virtual bool initWithMkext2Info(
298 OSDictionary * anInfoDict,
299 OSData * mkextData);
300
301 virtual bool setInfoDictionaryAndPath(
302 OSDictionary * aDictionary,
303 OSString * aPath);
304 virtual bool setExecutable(
305 OSData * anExecutable,
306 OSData * externalData = NULL,
307 bool externalDataIsMkext = false);
308 virtual bool registerIdentifier(void);
309
310 virtual void free(void);
311
312 static OSReturn removeKext(
313 OSKext * aKext,
314 bool terminateServicesAndRemovePersonalitiesFlag = false);
315
316 /* Mkexts.
317 */
318 static OSReturn readMkextArchive(
319 OSData * mkextData,
320 uint32_t * checksumPtr = NULL);
321 static OSReturn readMkext2Archive(
322 OSData * mkextData,
323 OSDictionary ** mkextPlistOut,
324 uint32_t * checksumPtr = NULL);
325 virtual OSData * createMkext2FileEntry(
326 OSData * mkextData,
327 OSNumber * offsetNum,
328 const char * entryName);
329 virtual OSData * extractMkext2FileData(
330 UInt8 * data,
331 const char * name,
332 uint32_t compressedSize,
333 uint32_t fullSize);
334
335 static OSReturn readMkext1Archive(
336 OSData * mkextData,
337 uint32_t * checksumPtr);
338 bool initWithMkext1Info(
339 OSDictionary * anInfoDict,
340 OSData * executableWrapper,
341 OSData * mkextData);
342 static OSData * extractMkext1Entry(
343 const void * mkextFileBase,
344 const void * entry);
345
346 /* Dependencies.
347 */
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);
354
355 /* User-space requests (load/generic).
356 */
357 static OSReturn loadFromMkext(
358 OSKextLogSpec clientLogSpec,
359 char * mkextBuffer,
360 uint32_t mkextBufferLength,
361 char ** logInfoOut,
362 uint32_t * logInfoLengthOut);
363 static OSReturn handleRequest(
364 host_priv_t hostPriv,
365 OSKextLogSpec clientLogSpec,
366 char * requestBuffer,
367 uint32_t requestLength,
368 char ** responseOut,
369 uint32_t * responseLengthOut,
370 char ** logInfoOut,
371 uint32_t * logInfoLengthOut);
372 static OSReturn serializeLogInfo(
373 OSArray * logInfoArray,
374 char ** logInfoOut,
375 uint32_t * logInfoLengthOut);
376
377 /* Loading.
378 */
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);
387
388 static void recordIdentifierRequest(
389 OSString * kextIdentifier);
390
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);
397
398 #if CONFIG_DTRACE
399 friend void OSKextRegisterKextsWithDTrace(void);
400 static void registerKextsWithDTrace(void);
401 virtual void registerWithDTrace(void);
402 virtual void unregisterWithDTrace(void);
403 #endif /* CONFIG_DTRACE */
404
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);
411
412 static OSArray * copyAllKextPersonalities(
413 bool filterSafeBootFlag = false);
414
415 static void setPrelinkedPersonalities(OSArray * personalitiesArray);
416
417 static void sendAllKextPersonalitiesToCatalog(
418 bool startMatching = false);
419 virtual OSReturn sendPersonalitiesToCatalog(
420 bool startMatching = false,
421 OSArray * personalityNames = NULL);
422
423 static bool canUnloadKextWithIdentifier(
424 OSString * kextIdentifier,
425 bool checkClassesFlag = true);
426
427 static OSReturn autounloadKext(OSKext * aKext);
428
429 /* Sync with user space.
430 */
431 static OSReturn pingKextd(void);
432
433 /* Getting info about loaded kexts (kextstat).
434 */
435 static OSDictionary * copyLoadedKextInfo(
436 OSArray * kextIdentifiers = NULL,
437 OSArray * keys = NULL);
438 virtual OSDictionary * copyInfo(OSArray * keys = NULL);
439
440 static OSData * copySanitizedKernelImage(void);
441
442 /* Logging to user space.
443 */
444 static OSKextLogSpec setUserSpaceLogFilter(
445 OSKextLogSpec userLogSpec,
446 bool captureFlag = false);
447 static OSArray * clearUserSpaceLogFilter(void);
448 static OSKextLogSpec getUserSpaceLogFilter(void);
449
450 /* OSMetaClasses defined by kext.
451 */
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);
464
465 /* Resource requests and other callback stuff.
466 */
467 static OSReturn dispatchResource(OSDictionary * requestDict);
468
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);
482
483 /* panic() support.
484 */
485 static void printKextsInBacktrace(
486 vm_offset_t * addr,
487 unsigned int cnt,
488 int (* printf_func)(const char *fmt, ...),
489 bool lockFlag);
490 static boolean_t summaryIsInBacktrace(
491 OSKextLoadedKextSummary * summary,
492 vm_offset_t * addr,
493 unsigned int cnt);
494 static void printSummary(
495 OSKextLoadedKextSummary * summary,
496 int (* printf_func)(const char *fmt, ...));
497
498 static uint32_t saveLoadedKextPanicListTyped(
499 const char * prefix,
500 int invertFlag,
501 int libsFlag,
502 char * paniclist,
503 uint32_t list_size,
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, ...));
508
509 /* Kext summary support.
510 */
511 static void updateLoadedKextSummaries(void);
512 void updateLoadedKextSummary(OSKextLoadedKextSummary *summary);
513
514 /* C++ Initialization.
515 */
516 virtual void setCPPInitialized(bool initialized=true);
517
518 #if __i386__
519 /* Backward compatibility for kmod_get_info() MIG call.
520 */
521 static kern_return_t getKmodInfo(
522 kmod_info_array_t * kmodList,
523 mach_msg_type_number_t * kmodCount);
524 #endif /* __i386__ */
525
526
527 #if PRAGMA_MARK
528 /**************************************/
529 #pragma mark Public Functions
530 /**************************************/
531 #endif
532 public:
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);
538
539 static bool isKextWithIdentifierLoaded(const char * kextIdentifier);
540
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);
561
562 static OSReturn requestResource(
563 const char * kextIdentifier,
564 const char * resourceName,
565 OSKextRequestResourceCallback callback,
566 void * context,
567 OSKextRequestTag * requestTagOut);
568 static OSReturn cancelRequest(
569 OSKextRequestTag requestTag,
570 void ** contextOut);
571
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);
577
578 virtual bool setAutounloadEnabled(bool flag);
579
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);
587
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);
592
593 /* This removes personalities naming the kext (by CFBundleIdentifier),
594 * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier).
595 */
596 virtual void removePersonalitiesFromCatalog(void);
597
598 /* Converts common string-valued properties to OSSymbols for lower memory consumption.
599 */
600 static void uniquePersonalityProperties(OSDictionary * personalityDict);
601
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);
612 };
613
614
615 #endif /* !_LIBKERN_OSKEXT_H */