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, functionName, resultType, parameterDeclarations, parameterNames) \ 49 static resultType init##functionName parameterDeclarations; \ 50 static resultType (*softLink##functionName) parameterDeclarations = init##functionName; \ 51 \ 52 static resultType init##functionName parameterDeclarations \ 53 { \ 54 softLink##functionName = (resultType (*) parameterDeclarations) dlsym(framework##Library(), #functionName); \ 55 ASSERT(softLink##functionName); \ 56 return softLink##functionName parameterNames; \ 57 }\ 58 \ 59 inline resultType functionName parameterDeclarations \ 60 {\ 61 return softLink##functionName parameterNames; \ 62 } 63 64 #define SOFT_LINK_CLASS(framework, className) \ 65 static Class init##className(); \ 66 static Class (*get##className##Class)() = init##className; \ 67 static Class class##className; \ 68 \ 69 static Class className##Function() \ 70 { \ 71 return class##className; \ 72 }\ 73 \ 74 static Class init##className() \ 75 { \ 76 framework##Library(); \ 77 class##className = objc_getClass(#className); \ 78 ASSERT(class##className); \ 79 get##className##Class = className##Function; \ 80 return class##className; \ 81 } 82 83 #define SOFT_LINK_POINTER(framework, name, type) \ 84 static type init##name(); \ 85 static type (*get##name)() = init##name; \ 86 static type pointer##name; \ 87 \ 88 static type name##Function() \ 89 { \ 90 return pointer##name; \ 91 }\ 92 \ 93 static type init##name() \ 94 { \ 95 void** pointer = static_cast<void**>(dlsym(framework##Library(), #name)); \ 96 ASSERT(pointer); \ 97 pointer##name = static_cast<type>(*pointer); \ 98 get##name = name##Function; \ 99 return pointer##name; \ 100 } 101 102 #define SOFT_LINK_CONSTANT(framework, name, type) \ 103 static type init##name(); \ 104 static type (*get##name)() = init##name; \ 105 static type constant##name; \ 106 \ 107 static type name##Function() \ 108 { \ 109 return constant##name; \ 110 }\ 111 \ 112 static type init##name() \ 113 { \ 114 void* constant = dlsym(framework##Library(), #name); \ 115 ASSERT(constant); \ 116 constant##name = *static_cast<type*>(constant); \ 117 get##name = name##Function; \ 118 return constant##name; \ 119 } 120