Back to home page

EIC code displayed by LXR

 
 

    


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