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