]> git.saurik.com Git - apple/xnu.git/blob - libkern/libkern/c++/OSKext.h
a054c0281061be16b2ca19c8bccc439191bb574b
[apple/xnu.git] / libkern / libkern / c++ / OSKext.h
1 /*
2 * Copyright (c) 2008-2012 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
101 #endif /* XNU_KERNEL_PRIVATE */
102 };
103
104 /********************************************************************/
105 #if PRAGMA_MARK
106 #pragma mark -
107 #endif
108 /*
109 * @class OSKext
110 */
111 /********************************************************************/
112 class OSKext : public OSObject
113 {
114 OSDeclareDefaultStructors(OSKext)
115
116 #if PRAGMA_MARK
117 /**************************************/
118 #pragma mark Friend Declarations
119 /**************************************/
120 #endif
121 friend class IOCatalogue;
122 friend class KLDBootstrap;
123 friend class OSMetaClass;
124
125 #ifdef XNU_KERNEL_PRIVATE
126 friend void OSKextVLog(
127 OSKext * aKext,
128 OSKextLogSpec msgLogSpec,
129 const char * format,
130 va_list srcArgList);
131
132 friend void OSKextRemoveKextBootstrap(void);
133 friend void IOSystemShutdownNotification(void);
134 friend OSReturn OSKextUnloadKextWithLoadTag(uint32_t);
135
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);
146
147 friend kxld_addr_t kern_allocate(
148 u_long size,
149 KXLDAllocateFlags * flags,
150 void * user_data);
151
152 friend void kxld_log_shim(
153 KXLDLogSubsystem subsystem,
154 KXLDLogLevel level,
155 const char * format,
156 va_list argList,
157 void * user_data);
158
159 friend void _OSKextConsiderUnloads(
160 __unused thread_call_param_t p0,
161 __unused thread_call_param_t p1);
162
163 friend kern_return_t OSRuntimeInitializeCPP(
164 kmod_info_t * kmodInfo,
165 void * data);
166 friend kern_return_t OSRuntimeFinalizeCPP(
167 kmod_info_t * kmodInfo,
168 void * data);
169
170 friend kern_return_t is_io_catalog_send_data(
171 mach_port_t masterPort,
172 uint32_t flag,
173 io_buf_ptr_t inData,
174 mach_msg_type_number_t inDataCount,
175 kern_return_t * result);
176
177 friend void kmod_panic_dump(vm_offset_t*, unsigned int);
178 friend void kmod_dump_log(vm_offset_t*, unsigned int);
179 friend void kext_dump_panic_lists(int (*printf_func)(const char * fmt, ...));
180
181
182 #endif /* XNU_KERNEL_PRIVATE */
183
184 private:
185
186 /*************************
187 * Instance variables
188 *************************/
189 OSDictionary * infoDict;
190
191 const OSSymbol * bundleID;
192 OSString * path; // not necessarily correct :-/
193 OSString * executableRelPath; // relative to bundle
194
195 OSKextVersion version; // parsed
196 OSKextVersion compatibleVersion; // parsed
197
198 /* These fields are required for tracking loaded kexts and
199 * will always have values for a loaded kext.
200 */
201 OSKextLoadTag loadTag; // 'id' from old kmod_info;
202 // kOSKextInvalidLoadTag invalid
203 kmod_info_t * kmod_info; // address into linkedExec./alloced for interface
204
205 OSArray * dependencies; // kernel resource does not have any;
206 // links directly to kernel
207
208 /* Only real kexts have these; interface kexts do not.
209 */
210 OSData * linkedExecutable;
211 OSSet * metaClasses; // for C++/OSMetaClass kexts
212
213 /* Only interface kexts have these; non-interface kexts can get at them
214 * in the linked Executable.
215 */
216 OSData * interfaceUUID;
217
218 struct {
219 unsigned int loggingEnabled:1;
220
221 unsigned int hasAllDependencies:1;
222 unsigned int hasBleedthrough:1;
223
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;
233
234 unsigned int autounloadEnabled:1;
235 unsigned int delayAutounload:1; // for development
236
237 unsigned int CPPInitialized:1;
238 unsigned int jettisonLinkeditSeg:1;
239 } flags;
240
241 #if PRAGMA_MARK
242 /**************************************/
243 #pragma mark Private Functions
244 /**************************************/
245 #endif
246
247 #ifdef XNU_KERNEL_PRIVATE
248 /* Startup/shutdown phases.
249 */
250 public:
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 */
256
257 private:
258 /* Called by power management at sleep/shutdown.
259 */
260 static bool setLoadEnabled(bool flag);
261 static bool setUnloadEnabled(bool flag);
262 static bool setAutounloadsEnabled(bool flag);
263 static bool setKernelRequestsEnabled(bool flag);
264
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);
270
271 /* Instance life cycle.
272 */
273 static OSKext * withBooterData(
274 OSString * deviceTreeName,
275 OSData * booterData);
276 virtual bool initWithBooterData(
277 OSString * deviceTreeName,
278 OSData * booterData);
279
280 static OSKext * withPrelinkedInfoDict(
281 OSDictionary * infoDict);
282 virtual bool initWithPrelinkedInfoDict(
283 OSDictionary * infoDict);
284
285 static OSKext * withMkext2Info(
286 OSDictionary * anInfoDict,
287 OSData * mkextData);
288 virtual bool initWithMkext2Info(
289 OSDictionary * anInfoDict,
290 OSData * mkextData);
291
292 virtual bool setInfoDictionaryAndPath(
293 OSDictionary * aDictionary,
294 OSString * aPath);
295 virtual bool setExecutable(
296 OSData * anExecutable,
297 OSData * externalData = NULL,
298 bool externalDataIsMkext = false);
299 virtual bool registerIdentifier(void);
300
301 virtual void free(void);
302
303 static OSReturn removeKext(
304 OSKext * aKext,
305 bool terminateServicesAndRemovePersonalitiesFlag = false);
306
307 virtual bool isInExcludeList(void);
308
309 /* Mkexts.
310 */
311 static OSReturn readMkextArchive(
312 OSData * mkextData,
313 uint32_t * checksumPtr = NULL);
314 static OSReturn readMkext2Archive(
315 OSData * mkextData,
316 OSDictionary ** mkextPlistOut,
317 uint32_t * checksumPtr = NULL);
318 virtual OSData * createMkext2FileEntry(
319 OSData * mkextData,
320 OSNumber * offsetNum,
321 const char * entryName);
322 virtual OSData * extractMkext2FileData(
323 UInt8 * data,
324 const char * name,
325 uint32_t compressedSize,
326 uint32_t fullSize);
327
328 static OSReturn readMkext1Archive(
329 OSData * mkextData,
330 uint32_t * checksumPtr);
331 bool initWithMkext1Info(
332 OSDictionary * anInfoDict,
333 OSData * executableWrapper,
334 OSData * mkextData);
335 static OSData * extractMkext1Entry(
336 const void * mkextFileBase,
337 const void * entry);
338
339 /* Dependencies.
340 */
341 virtual bool resolveDependencies(
342 OSArray * loopStack = NULL); // priv/prot
343 virtual bool addBleedthroughDependencies(OSArray * anArray);
344 virtual bool flushDependencies(bool forceFlag = false); // priv/prot
345 virtual uint32_t getNumDependencies(void);
346 virtual OSArray * getDependencies(void);
347
348 /* User-space requests (load/generic).
349 */
350 static OSReturn loadFromMkext(
351 OSKextLogSpec clientLogSpec,
352 char * mkextBuffer,
353 uint32_t mkextBufferLength,
354 char ** logInfoOut,
355 uint32_t * logInfoLengthOut);
356 static OSReturn handleRequest(
357 host_priv_t hostPriv,
358 OSKextLogSpec clientLogSpec,
359 char * requestBuffer,
360 uint32_t requestLength,
361 char ** responseOut,
362 uint32_t * responseLengthOut,
363 char ** logInfoOut,
364 uint32_t * logInfoLengthOut);
365 static OSReturn serializeLogInfo(
366 OSArray * logInfoArray,
367 char ** logInfoOut,
368 uint32_t * logInfoLengthOut);
369
370 /* Loading.
371 */
372 virtual OSReturn load(
373 OSKextExcludeLevel startOpt = kOSKextExcludeNone,
374 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll,
375 OSArray * personalityNames = NULL); // priv/prot
376 virtual OSReturn unload(void);
377 virtual OSReturn queueKextNotification(
378 const char * notificationName,
379 OSString * kextIdentifier);
380
381 static void recordIdentifierRequest(
382 OSString * kextIdentifier);
383
384 virtual OSReturn slidePrelinkedExecutable(void);
385 virtual OSReturn loadExecutable(void);
386 virtual void jettisonLinkeditSegment(void);
387 static void considerDestroyingLinkContext(void);
388 virtual OSData * getExecutable(void);
389 virtual void setLinkedExecutable(OSData * anExecutable);
390
391 #if CONFIG_DTRACE
392 friend void OSKextRegisterKextsWithDTrace(void);
393 static void registerKextsWithDTrace(void);
394 virtual void registerWithDTrace(void);
395 virtual void unregisterWithDTrace(void);
396 #endif /* CONFIG_DTRACE */
397
398 virtual OSReturn start(bool startDependenciesFlag = true);
399 virtual OSReturn stop(void);
400 virtual OSReturn setVMProtections(void);
401 virtual boolean_t segmentShouldBeWired(kernel_segment_command_t *seg);
402 virtual OSReturn validateKextMapping(bool startFlag);
403 virtual boolean_t verifySegmentMapping(kernel_segment_command_t *seg);
404
405 static OSArray * copyAllKextPersonalities(
406 bool filterSafeBootFlag = false);
407
408 static void setPrelinkedPersonalities(OSArray * personalitiesArray);
409
410 static void sendAllKextPersonalitiesToCatalog(
411 bool startMatching = false);
412 virtual OSReturn sendPersonalitiesToCatalog(
413 bool startMatching = false,
414 OSArray * personalityNames = NULL);
415
416 static bool canUnloadKextWithIdentifier(
417 OSString * kextIdentifier,
418 bool checkClassesFlag = true);
419
420 static OSReturn autounloadKext(OSKext * aKext);
421
422 /* Sync with user space.
423 */
424 static OSReturn pingKextd(void);
425
426 /* Getting info about loaded kexts (kextstat).
427 */
428 static OSDictionary * copyLoadedKextInfo(
429 OSArray * kextIdentifiers = NULL,
430 OSArray * keys = NULL);
431 virtual OSDictionary * copyInfo(OSArray * keys = NULL);
432
433 /* Logging to user space.
434 */
435 static OSKextLogSpec setUserSpaceLogFilter(
436 OSKextLogSpec userLogSpec,
437 bool captureFlag = false);
438 static OSArray * clearUserSpaceLogFilter(void);
439 static OSKextLogSpec getUserSpaceLogFilter(void);
440
441 /* OSMetaClasses defined by kext.
442 */
443 virtual OSReturn addClass(
444 OSMetaClass * aClass,
445 uint32_t numClasses);
446 virtual OSReturn removeClass(
447 OSMetaClass * aClass);
448 virtual bool hasOSMetaClassInstances(void);
449 virtual OSSet * getMetaClasses(void);
450 static void reportOSMetaClassInstances(
451 const char * kextIdentifier,
452 OSKextLogSpec msgLogSpec);
453 virtual void reportOSMetaClassInstances(
454 OSKextLogSpec msgLogSpec);
455
456 /* Resource requests and other callback stuff.
457 */
458 static OSReturn dispatchResource(OSDictionary * requestDict);
459
460 static OSReturn dequeueCallbackForRequestTag(
461 OSKextRequestTag requestTag,
462 OSDictionary ** callbackRecordOut);
463 static OSReturn dequeueCallbackForRequestTag(
464 OSNumber * requestTagNum,
465 OSDictionary ** callbackRecordOut);
466 static void invokeRequestCallback(
467 OSDictionary * callbackRecord,
468 OSReturn requestResult);
469 virtual void invokeOrCancelRequestCallbacks(
470 OSReturn callbackResult,
471 bool invokeFlag = true);
472 virtual uint32_t countRequestCallbacks(void);
473
474 /* panic() support.
475 */
476 static void printKextsInBacktrace(
477 vm_offset_t * addr,
478 unsigned int cnt,
479 int (* printf_func)(const char *fmt, ...),
480 bool lockFlag);
481 static boolean_t summaryIsInBacktrace(
482 OSKextLoadedKextSummary * summary,
483 vm_offset_t * addr,
484 unsigned int cnt);
485 static void printSummary(
486 OSKextLoadedKextSummary * summary,
487 int (* printf_func)(const char *fmt, ...));
488
489 static uint32_t saveLoadedKextPanicListTyped(
490 const char * prefix,
491 int invertFlag,
492 int libsFlag,
493 char * paniclist,
494 uint32_t list_size,
495 uint32_t * list_length_ptr);
496 static void saveLoadedKextPanicList(void);
497 void savePanicString(bool isLoading);
498 static void printKextPanicLists(int (*printf_func)(const char *fmt, ...));
499
500 /* Kext summary support.
501 */
502 static void updateLoadedKextSummaries(void);
503 void updateLoadedKextSummary(OSKextLoadedKextSummary *summary);
504
505 /* C++ Initialization.
506 */
507 virtual void setCPPInitialized(bool initialized=true);
508
509
510
511 #if PRAGMA_MARK
512 /**************************************/
513 #pragma mark Public Functions
514 /**************************************/
515 #endif
516 public:
517 // caller must release
518 static OSKext * lookupKextWithIdentifier(const char * kextIdentifier);
519 static OSKext * lookupKextWithIdentifier(OSString * kextIdentifier);
520 static OSKext * lookupKextWithLoadTag(OSKextLoadTag aTag);
521 static OSKext * lookupKextWithAddress(vm_address_t address);
522
523 static bool isKextWithIdentifierLoaded(const char * kextIdentifier);
524
525 static OSReturn loadKextWithIdentifier(
526 const char * kextIdentifier,
527 Boolean allowDeferFlag = true,
528 Boolean delayAutounloadFlag = false,
529 OSKextExcludeLevel startOpt = kOSKextExcludeNone,
530 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll,
531 OSArray * personalityNames = NULL);
532 static OSReturn loadKextWithIdentifier(
533 OSString * kextIdentifier,
534 Boolean allowDeferFlag = true,
535 Boolean delayAutounloadFlag = false,
536 OSKextExcludeLevel startOpt = kOSKextExcludeNone,
537 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll,
538 OSArray * personalityNames = NULL);
539 static OSReturn removeKextWithIdentifier(
540 const char * kextIdentifier,
541 bool terminateServicesAndRemovePersonalitiesFlag = false);
542 static OSReturn removeKextWithLoadTag(
543 OSKextLoadTag loadTag,
544 bool terminateServicesAndRemovePersonalitiesFlag = false);
545
546 static OSReturn requestResource(
547 const char * kextIdentifier,
548 const char * resourceName,
549 OSKextRequestResourceCallback callback,
550 void * context,
551 OSKextRequestTag * requestTagOut);
552 static OSReturn cancelRequest(
553 OSKextRequestTag requestTag,
554 void ** contextOut);
555
556 static void considerUnloads(Boolean rescheduleOnlyFlag = false);
557 static void flushNonloadedKexts(Boolean flushPrelinkedKexts);
558 static void setKextdActive(Boolean active = true);
559 static void setDeferredLoadSucceeded(Boolean succeeded = true);
560 static void considerRebuildOfPrelinkedKernel(void);
561 static void createExcludeListFromBooterData(
562 OSDictionary * theDictionary,
563 OSCollectionIterator * theIterator);
564 static void createExcludeListFromPrelinkInfo(OSArray * theInfoArray);
565
566 virtual bool setAutounloadEnabled(bool flag);
567
568 virtual const OSSymbol * getIdentifier(void);
569 virtual const char * getIdentifierCString(void);
570 virtual OSKextVersion getVersion(void);
571 virtual OSKextVersion getCompatibleVersion(void);
572 virtual bool isLibrary(void);
573 virtual bool isCompatibleWithVersion(OSKextVersion aVersion);
574 virtual OSObject * getPropertyForHostArch(const char * key);
575
576 virtual OSKextLoadTag getLoadTag(void);
577 virtual void getSizeInfo(uint32_t *loadSize, uint32_t *wiredSize);
578 virtual OSData * copyUUID(void);
579 virtual OSArray * copyPersonalitiesArray(void);
580
581 /* This removes personalities naming the kext (by CFBundleIdentifier),
582 * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier).
583 */
584 virtual void removePersonalitiesFromCatalog(void);
585
586 /* Converts common string-valued properties to OSSymbols for lower memory consumption.
587 */
588 static void uniquePersonalityProperties(OSDictionary * personalityDict);
589
590 virtual bool declaresExecutable(void); // might be missing
591 virtual bool isInterface(void);
592 virtual bool isKernel(void);
593 virtual bool isKernelComponent(void);
594 virtual bool isExecutable(void);
595 virtual bool isLoadableInSafeBoot(void);
596 virtual bool isPrelinked(void);
597 virtual bool isLoaded(void);
598 virtual bool isStarted(void);
599 virtual bool isCPPInitialized(void);
600 };
601
602
603 #endif /* !_LIBKERN_OSKEXT_H */