1 /* 2 * Copyright (C) 2007 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #import <wtf/Assertions.h> 30 #import <dlfcn.h> 31 32 #define SOFT_LINK_LIBRARY(lib) \ 33 static void* lib##Library() \ 34 { \ 35 static void* dylib = dlopen("/usr/lib/" #lib ".dylib", RTLD_NOW); \ 36 ASSERT(dylib); \ 37 return dylib; \ 38 } 39 40 #define SOFT_LINK_FRAMEWORK(framework) \ 41 static void* framework##Library() \ 42 { \ 43 static void* frameworkLibrary = dlopen("/System/Library/Frameworks/" #framework ".framework/" #framework, RTLD_NOW); \ 44 ASSERT(frameworkLibrary); \ 45 return frameworkLibrary; \ 46 } 47 48 #define SOFT_LINK_FRAMEWORK_IN_CORESERVICES_UMBRELLA(framework) \ 49 static void* framework##Library() \ 50 { \ 51 static void* frameworkLibrary = dlopen("/System/Library/Frameworks/CoreServices.framework/Frameworks/" #framework ".framework/" #framework, RTLD_NOW); \ 52 ASSERT(frameworkLibrary); \ 53 return frameworkLibrary; \ 54 } 55 56 #define SOFT_LINK(framework, functionName, resultType, parameterDeclarations, parameterNames) \ 57 static resultType init##functionName parameterDeclarations; \ 58 static resultType (*softLink##functionName) parameterDeclarations = init##functionName; \ 59 \ 60 static resultType init##functionName parameterDeclarations \ 61 { \ 62 softLink##functionName = (resultType (*) parameterDeclarations) dlsym(framework##Library(), #functionName); \ 63 ASSERT(softLink##functionName); \ 64 return softLink##functionName parameterNames; \ 65 }\ 66 \ 67 inline resultType functionName parameterDeclarations \ 68 {\ 69 return softLink##functionName parameterNames; \ 70 } 71 72 /* callingConvention is unused on Mac but is here to keep the macro prototype the same between Mac and Windows. */ 73 #define SOFT_LINK_OPTIONAL(framework, functionName, resultType, callingConvention, parameterDeclarations) \ 74 typedef resultType (*functionName##PtrType) parameterDeclarations; \ 75 \ 76 static functionName##PtrType functionName##Ptr() \ 77 { \ 78 static functionName##PtrType ptr = reinterpret_cast<functionName##PtrType>(dlsym(framework##Library(), #functionName)); \ 79 return ptr; \ 80 } 81 82 #define SOFT_LINK_CLASS(framework, className) \ 83 static Class init##className(); \ 84 static Class (*get##className##Class)() = init##className; \ 85 static Class class##className; \ 86 \ 87 static Class className##Function() \ 88 { \ 89 return class##className; \ 90 }\ 91 \ 92 static Class init##className() \ 93 { \ 94 framework##Library(); \ 95 class##className = objc_getClass(#className); \ 96 ASSERT(class##className); \ 97 get##className##Class = className##Function; \ 98 return class##className; \ 99 } 100 101 #define SOFT_LINK_POINTER(framework, name, type) \ 102 static type init##name(); \ 103 static type (*get##name)() = init##name; \ 104 static type pointer##name; \ 105 \ 106 static type name##Function() \ 107 { \ 108 return pointer##name; \ 109 }\ 110 \ 111 static type init##name() \ 112 { \ 113 void** pointer = static_cast<void**>(dlsym(framework##Library(), #name)); \ 114 ASSERT(pointer); \ 115 pointer##name = static_cast<type>(*pointer); \ 116 get##name = name##Function; \ 117 return pointer##name; \ 118 } 119 120 #define SOFT_LINK_CONSTANT(framework, name, type) \ 121 static type init##name(); \ 122 static type (*get##name)() = init##name; \ 123 static type constant##name; \ 124 \ 125 static type name##Function() \ 126 { \ 127 return constant##name; \ 128 }\ 129 \ 130 static type init##name() \ 131 { \ 132 void* constant = dlsym(framework##Library(), #name); \ 133 ASSERT(constant); \ 134 constant##name = *static_cast<type*>(constant); \ 135 get##name = name##Function; \ 136 return constant##name; \ 137 } 138