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