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_WITH_MESSAGE(dylib, "%s", dlerror()); \ 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_WITH_MESSAGE(frameworkLibrary, "%s", dlerror()); \ 45 return frameworkLibrary; \ 46 } 47 48#define SOFT_LINK_FRAMEWORK_OPTIONAL(framework) \ 49 static void* framework##Library() \ 50 { \ 51 static void* frameworkLibrary = dlopen("/System/Library/Frameworks/" #framework ".framework/" #framework, RTLD_NOW); \ 52 return frameworkLibrary; \ 53 } 54 55#define SOFT_LINK_STAGED_FRAMEWORK(framework, unstagedLocation, version) \ 56 static void* framework##Library() \ 57 { \ 58 static void* frameworkLibrary = ^{ \ 59 void* result = dlopen("/System/Library/" #unstagedLocation "/" #framework ".framework/Versions/" #version "/" #framework, RTLD_LAZY); \ 60 if (!result) \ 61 result = dlopen("/System/Library/StagedFrameworks/Safari/" #framework ".framework/Versions/" #version "/" #framework, RTLD_LAZY); \ 62 return result; \ 63 }(); \ 64 ASSERT_WITH_MESSAGE(frameworkLibrary, "%s", dlerror()); \ 65 return frameworkLibrary; \ 66 } 67 68#define SOFT_LINK_FRAMEWORK_IN_UMBRELLA(umbrella, framework) \ 69 static void* framework##Library() \ 70 { \ 71 static void* frameworkLibrary = dlopen("/System/Library/Frameworks/" #umbrella ".framework/Frameworks/" #framework ".framework/" #framework, RTLD_NOW); \ 72 ASSERT_WITH_MESSAGE(frameworkLibrary, "%s", dlerror()); \ 73 return frameworkLibrary; \ 74 } 75 76#define SOFT_LINK(framework, functionName, resultType, parameterDeclarations, parameterNames) \ 77 static resultType init##functionName parameterDeclarations; \ 78 static resultType (*softLink##functionName) parameterDeclarations = init##functionName; \ 79 \ 80 static resultType init##functionName parameterDeclarations \ 81 { \ 82 softLink##functionName = (resultType (*) parameterDeclarations) dlsym(framework##Library(), #functionName); \ 83 ASSERT_WITH_MESSAGE(softLink##functionName, "%s", dlerror()); \ 84 return softLink##functionName parameterNames; \ 85 }\ 86 \ 87 inline resultType functionName parameterDeclarations \ 88 {\ 89 return softLink##functionName parameterNames; \ 90 } 91 92/* callingConvention is unused on Mac but is here to keep the macro prototype the same between Mac and Windows. */ 93#define SOFT_LINK_OPTIONAL(framework, functionName, resultType, callingConvention, parameterDeclarations) \ 94 typedef resultType (*functionName##PtrType) parameterDeclarations; \ 95 \ 96 static functionName##PtrType functionName##Ptr() \ 97 { \ 98 static functionName##PtrType ptr = reinterpret_cast<functionName##PtrType>(dlsym(framework##Library(), #functionName)); \ 99 return ptr; \ 100 } 101 102#define SOFT_LINK_CLASS(framework, className) \ 103 static Class init##className(); \ 104 static Class (*get##className##Class)() = init##className; \ 105 static Class class##className; \ 106 \ 107 static Class className##Function() \ 108 { \ 109 return class##className; \ 110 }\ 111 \ 112 static Class init##className() \ 113 { \ 114 framework##Library(); \ 115 class##className = objc_getClass(#className); \ 116 ASSERT(class##className); \ 117 get##className##Class = className##Function; \ 118 return class##className; \ 119 } 120 121#define SOFT_LINK_POINTER(framework, name, type) \ 122 static type init##name(); \ 123 static type (*get##name)() = init##name; \ 124 static type pointer##name; \ 125 \ 126 static type name##Function() \ 127 { \ 128 return pointer##name; \ 129 }\ 130 \ 131 static type init##name() \ 132 { \ 133 void** pointer = static_cast<void**>(dlsym(framework##Library(), #name)); \ 134 ASSERT_WITH_MESSAGE(pointer, "%s", dlerror()); \ 135 pointer##name = static_cast<type>(*pointer); \ 136 get##name = name##Function; \ 137 return pointer##name; \ 138 } 139 140#define SOFT_LINK_POINTER_OPTIONAL(framework, name, type) \ 141 static type init##name(); \ 142 static type (*get##name)() = init##name; \ 143 static type pointer##name; \ 144 \ 145 static type name##Function() \ 146 { \ 147 return pointer##name; \ 148 }\ 149 \ 150 static type init##name() \ 151 { \ 152 void** pointer = static_cast<void**>(dlsym(framework##Library(), #name)); \ 153 if (pointer) \ 154 pointer##name = static_cast<type>(*pointer); \ 155 get##name = name##Function; \ 156 return pointer##name; \ 157 } 158 159#define SOFT_LINK_CONSTANT(framework, name, type) \ 160 static type init##name(); \ 161 static type (*get##name)() = init##name; \ 162 static type constant##name; \ 163 \ 164 static type name##Function() \ 165 { \ 166 return constant##name; \ 167 }\ 168 \ 169 static type init##name() \ 170 { \ 171 void* constant = dlsym(framework##Library(), #name); \ 172 ASSERT_WITH_MESSAGE(constant, "%s", dlerror()); \ 173 constant##name = *static_cast<type*>(constant); \ 174 get##name = name##Function; \ 175 return constant##name; \ 176 } 177