|
||||
File indexing completed on 2025-01-18 09:30:44
0001 // Copyright 2014 Renato Tegon Forti, Antony Polukhin. 0002 // Copyright Antony Polukhin, 2015-2023. 0003 // 0004 // Distributed under the Boost Software License, Version 1.0. 0005 // (See accompanying file LICENSE_1_0.txt 0006 // or copy at http://www.boost.org/LICENSE_1_0.txt) 0007 0008 #ifndef BOOST_DLL_ALIAS_HPP 0009 #define BOOST_DLL_ALIAS_HPP 0010 0011 #include <boost/dll/config.hpp> 0012 #include <boost/predef/compiler.h> 0013 #include <boost/predef/os.h> 0014 #include <boost/dll/detail/aggressive_ptr_cast.hpp> 0015 0016 #if BOOST_COMP_GNUC // MSVC does not have <stdint.h> and defines it in some other header, MinGW requires that header. 0017 #include <stdint.h> // intptr_t 0018 #endif 0019 0020 #ifdef BOOST_HAS_PRAGMA_ONCE 0021 # pragma once 0022 #endif 0023 0024 /// \file boost/dll/alias.hpp 0025 /// \brief Includes alias methods and macro. You can include this header or 0026 /// boost/dll/shared_library.hpp to reduce dependencies 0027 /// in case you do not use the refcountable functions. 0028 0029 namespace boost { namespace dll { 0030 0031 #ifdef BOOST_DLL_DOXYGEN 0032 /// Define this macro to explicitly specify translation unit in which alias must be instantiated. 0033 /// See section 'Limitations' for more info. You may find usage examples in source codes of almost each tutorial. 0034 /// Must be used in code, when \forcedmacrolink{BOOST_DLL_FORCE_NO_WEAK_EXPORTS} is defined 0035 #define BOOST_DLL_FORCE_ALIAS_INSTANTIATION 0036 0037 /// Define this macro to disable exporting weak symbols and start using the \forcedmacrolink{BOOST_DLL_FORCE_ALIAS_INSTANTIATION}. 0038 /// This may be useful for working around linker problems or to test your program for compatibility with linkers that do not support export of weak symbols. 0039 #define BOOST_DLL_FORCE_NO_WEAK_EXPORTS 0040 #endif 0041 0042 #if defined(_MSC_VER) // MSVC, Clang-cl, and ICC on Windows 0043 0044 #define BOOST_DLL_SELECTANY __declspec(selectany) 0045 0046 #define BOOST_DLL_SECTION(SectionName, Permissions) \ 0047 static_assert( \ 0048 sizeof(#SectionName) < 10, \ 0049 "Some platforms require section names to be at most 8 bytes" \ 0050 ); \ 0051 __pragma(section(#SectionName, Permissions)) __declspec(allocate(#SectionName)) \ 0052 /**/ 0053 0054 #else // #if BOOST_COMP_MSVC 0055 0056 0057 #if BOOST_OS_WINDOWS || BOOST_OS_ANDROID || BOOST_COMP_IBM 0058 // There are some problems with mixing `__dllexport__` and `weak` using MinGW 0059 // See https://sourceware.org/bugzilla/show_bug.cgi?id=17480 0060 // 0061 // Android had an issue with exporting weak symbols 0062 // https://code.google.com/p/android/issues/detail?id=70206 0063 #define BOOST_DLL_SELECTANY 0064 #else // #if BOOST_OS_WINDOWS 0065 /*! 0066 * \brief Macro that allows linker to select any occurrence of this symbol instead of 0067 * failing with 'multiple definitions' error at linktime. 0068 * 0069 * This macro does not work on Android, IBM XL C/C++ and MinGW+Windows 0070 * because of linker problems with exporting weak symbols 0071 * (See https://code.google.com/p/android/issues/detail?id=70206, https://sourceware.org/bugzilla/show_bug.cgi?id=17480) 0072 */ 0073 #define BOOST_DLL_SELECTANY __attribute__((weak)) 0074 #endif // #if BOOST_OS_WINDOWS 0075 0076 // TODO: improve section permissions using following info: 0077 // http://stackoverflow.com/questions/6252812/what-does-the-aw-flag-in-the-section-attribute-mean 0078 0079 #if !BOOST_OS_MACOS && !BOOST_OS_IOS 0080 /*! 0081 * \brief Macro that puts symbol to a specific section. On MacOS all the sections are put into "__DATA" segment. 0082 * \param SectionName Name of the section. Must be a valid C identifier without quotes not longer than 8 bytes. 0083 * \param Permissions Can be "read" or "write" (without quotes!). 0084 */ 0085 #define BOOST_DLL_SECTION(SectionName, Permissions) \ 0086 static_assert( \ 0087 sizeof(#SectionName) < 10, \ 0088 "Some platforms require section names to be at most 8 bytes" \ 0089 ); \ 0090 __attribute__ ((section (#SectionName))) \ 0091 /**/ 0092 #else // #if !BOOST_OS_MACOS && !BOOST_OS_IOS 0093 0094 #define BOOST_DLL_SECTION(SectionName, Permissions) \ 0095 static_assert( \ 0096 sizeof(#SectionName) < 10, \ 0097 "Some platforms require section names to be at most 8 bytes" \ 0098 ); \ 0099 __attribute__ ((section ( "__DATA," #SectionName))) \ 0100 /**/ 0101 0102 #endif // #if #if !BOOST_OS_MACOS && !BOOST_OS_IOS 0103 0104 #endif // #if BOOST_COMP_MSVC 0105 0106 0107 // Alias - is just a variable that pointers to original data 0108 // 0109 // A few attempts were made to avoid additional indirection: 0110 // 1) 0111 // // Does not work on Windows, work on Linux 0112 // extern "C" BOOST_SYMBOL_EXPORT void AliasName() { 0113 // reinterpret_cast<void (*)()>(Function)(); 0114 // } 0115 // 0116 // 2) 0117 // // Does not work on Linux (changes permissions of .text section and produces incorrect DSO) 0118 // extern "C" BOOST_SYMBOL_EXPORT void* __attribute__ ((section(".text#"))) 0119 // func_ptr = *reinterpret_cast<std::ptrdiff_t**>(&foo::bar); 0120 // 0121 // 3) // requires mangled name of `Function` 0122 // // AliasName() __attribute__ ((weak, alias ("Function"))) 0123 // 0124 // // hard to use 0125 // `#pragma comment(linker, "/alternatename:_pWeakValue=_pDefaultWeakValue")` 0126 0127 /*! 0128 * \brief Makes an alias name for exported function or variable. 0129 * 0130 * This macro is useful in cases of long mangled C++ names. For example some `void boost::foo(std::string)` 0131 * function name will change to something like `N5boostN3foosE` after mangling. 0132 * Importing function by `N5boostN3foosE` name does not looks user friendly, especially assuming the fact 0133 * that different compilers have different mangling schemes. AliasName is the name that won't be mangled 0134 * and can be used as a portable import name. 0135 * 0136 * 0137 * Can be used in any namespace, including global. FunctionOrVar must be fully qualified, 0138 * so that address of it could be taken. Multiple different aliases for a single variable/function 0139 * are allowed. 0140 * 0141 * Make sure that AliasNames are unique per library/executable. Functions or variables 0142 * in global namespace must not have names same as AliasNames. 0143 * 0144 * Same AliasName in different translation units must point to the same FunctionOrVar. 0145 * 0146 * Puts all the aliases into the \b "boostdll" read only section of the binary. Equal to 0147 * \forcedmacrolink{BOOST_DLL_ALIAS_SECTIONED}(FunctionOrVar, AliasName, boostdll). 0148 * 0149 * \param FunctionOrVar Function or variable for which an alias must be made. 0150 * \param AliasName Name of the alias. Must be a valid C identifier. 0151 * 0152 * \b Example: 0153 * \code 0154 * namespace foo { 0155 * void bar(std::string&); 0156 * 0157 * BOOST_DLL_ALIAS(foo::bar, foo_bar) 0158 * } 0159 * 0160 * BOOST_DLL_ALIAS(foo::bar, foo_bar_another_alias_name) 0161 * \endcode 0162 * 0163 * \b See: \forcedmacrolink{BOOST_DLL_ALIAS_SECTIONED} for making alias in a specific section. 0164 */ 0165 #define BOOST_DLL_ALIAS(FunctionOrVar, AliasName) \ 0166 BOOST_DLL_ALIAS_SECTIONED(FunctionOrVar, AliasName, boostdll) \ 0167 /**/ 0168 0169 0170 #if ((BOOST_COMP_GNUC && BOOST_OS_WINDOWS) || BOOST_OS_ANDROID || BOOST_COMP_IBM || defined(BOOST_DLL_FORCE_NO_WEAK_EXPORTS)) \ 0171 && !defined(BOOST_DLL_FORCE_ALIAS_INSTANTIATION) && !defined(BOOST_DLL_DOXYGEN) 0172 0173 #define BOOST_DLL_ALIAS_SECTIONED(FunctionOrVar, AliasName, SectionName) \ 0174 namespace _autoaliases { \ 0175 extern "C" BOOST_SYMBOL_EXPORT const void *AliasName; \ 0176 } /* namespace _autoaliases */ \ 0177 /**/ 0178 0179 #define BOOST_DLL_AUTO_ALIAS(FunctionOrVar) \ 0180 namespace _autoaliases { \ 0181 extern "C" BOOST_SYMBOL_EXPORT const void *FunctionOrVar; \ 0182 } /* namespace _autoaliases */ \ 0183 /**/ 0184 #else 0185 // Note: we can not use `aggressive_ptr_cast` here, because in that case GCC applies 0186 // different permissions to the section and it causes Segmentation fault. 0187 // Note: we can not use `boost::addressof()` here, because in that case GCC 0188 // may optimize away the FunctionOrVar instance and we'll get a pointer to unexisting symbol. 0189 /*! 0190 * \brief Same as \forcedmacrolink{BOOST_DLL_ALIAS} but puts alias name into the user specified section. 0191 * 0192 * \param FunctionOrVar Function or variable for which an alias must be made. 0193 * \param AliasName Name of the alias. Must be a valid C identifier. 0194 * \param SectionName Name of the section. Must be a valid C identifier without quotes not longer than 8 bytes. 0195 * 0196 * \b Example: 0197 * \code 0198 * namespace foo { 0199 * void bar(std::string&); 0200 * 0201 * BOOST_DLL_ALIAS_SECTIONED(foo::bar, foo_bar, sect_1) // section "sect_1" now exports "foo_bar" 0202 * } 0203 * \endcode 0204 * 0205 */ 0206 #define BOOST_DLL_ALIAS_SECTIONED(FunctionOrVar, AliasName, SectionName) \ 0207 namespace _autoaliases { \ 0208 extern "C" BOOST_SYMBOL_EXPORT const void *AliasName; \ 0209 BOOST_DLL_SECTION(SectionName, read) BOOST_DLL_SELECTANY \ 0210 const void * AliasName = reinterpret_cast<const void*>(reinterpret_cast<intptr_t>( \ 0211 &FunctionOrVar \ 0212 )); \ 0213 } /* namespace _autoaliases */ \ 0214 /**/ 0215 0216 /*! 0217 * \brief Exports variable or function with unmangled alias name. 0218 * 0219 * This macro is useful in cases of long mangled C++ names. For example some `void boost::foo(std::string)` 0220 * function name will change to something like `N5boostN3foosE` after mangling. 0221 * Importing function by `N5boostN3foosE` name does not looks user friendly, especially assuming the fact 0222 * that different compilers have different mangling schemes.* 0223 * 0224 * Must be used in scope where FunctionOrVar declared. FunctionOrVar must be a valid C name, which means that 0225 * it must not contain `::`. 0226 * 0227 * Functions or variables 0228 * in global namespace must not have names same as FunctionOrVar. 0229 * 0230 * Puts all the aliases into the \b "boostdll" read only section of the binary. Almost same as 0231 * \forcedmacrolink{BOOST_DLL_ALIAS}(FunctionOrVar, FunctionOrVar). 0232 * 0233 * \param FunctionOrVar Function or variable for which an unmangled alias must be made. 0234 * 0235 * \b Example: 0236 * \code 0237 * namespace foo { 0238 * void bar(std::string&); 0239 * BOOST_DLL_AUTO_ALIAS(bar) 0240 * } 0241 * 0242 * \endcode 0243 * 0244 * \b See: \forcedmacrolink{BOOST_DLL_ALIAS} for making an alias with different names. 0245 */ 0246 0247 #define BOOST_DLL_AUTO_ALIAS(FunctionOrVar) \ 0248 namespace _autoaliases { \ 0249 BOOST_DLL_SELECTANY const void * dummy_ ## FunctionOrVar \ 0250 = reinterpret_cast<const void*>(reinterpret_cast<intptr_t>( \ 0251 &FunctionOrVar \ 0252 )); \ 0253 extern "C" BOOST_SYMBOL_EXPORT const void *FunctionOrVar; \ 0254 BOOST_DLL_SECTION(boostdll, read) BOOST_DLL_SELECTANY \ 0255 const void * FunctionOrVar = dummy_ ## FunctionOrVar; \ 0256 } /* namespace _autoaliases */ \ 0257 /**/ 0258 0259 0260 #endif 0261 0262 0263 }} // namespace boost::dll 0264 0265 0266 #endif // BOOST_DLL_ALIAS_HPP 0267
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |