diff options
author | Vitaly Takmazov <vitalyster@gmail.com> | 2022-01-26 11:50:43 +0300 |
---|---|---|
committer | Vitaly Takmazov <vitalyster@gmail.com> | 2022-01-26 11:53:50 +0300 |
commit | 3a91a6b2e604a0d24ccf4b25d63b0f8d731cf55e (patch) | |
tree | 71162b83905b0104ad5020a5497f4154de69e94d | |
parent | a60c228a6760b624711573c180730c12e14d5d10 (diff) |
WIPnoswiften
45 files changed, 74 insertions, 3790 deletions
diff --git a/backends/libcommuni/CMakeLists.txt b/backends/libcommuni/CMakeLists.txt index 47b591ba..94a8dea0 100644 --- a/backends/libcommuni/CMakeLists.txt +++ b/backends/libcommuni/CMakeLists.txt @@ -13,15 +13,15 @@ add_executable(spectrum2_libcommuni_backend ${SRC}) if(NOT WIN32) if(ENABLE_QT4) - target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt4::QtNetwork Qt4::QtCore transport pthread) + target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt4::QtNetwork Qt4::QtCore transport-plugin pthread) else() - target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt5::Network Qt5::Core transport pthread) + target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt5::Network Qt5::Core transport-plugin pthread) endif() else() if(ENABLE_QT4) - target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt4::QtNetwork Qt4::QtCore transport) + target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt4::QtNetwork Qt4::QtCore transport-plugin) else() - target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt5::Network Qt5::Core transport) + target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt5::Network Qt5::Core transport-plugin) endif() endif() diff --git a/backends/swiften/CMakeLists.txt b/backends/swiften/CMakeLists.txt index 411fc8ad..b4a6e1c6 100644 --- a/backends/swiften/CMakeLists.txt +++ b/backends/swiften/CMakeLists.txt @@ -3,9 +3,9 @@ file(GLOB SRC *.cpp) add_executable(spectrum2_swiften_backend ${SRC}) if(NOT WIN32) - target_link_libraries(spectrum2_swiften_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) + target_link_libraries(spectrum2_swiften_backend transport-plugin pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) else() - target_link_libraries(spectrum2_swiften_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) + target_link_libraries(spectrum2_swiften_backend transport-plugin ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) endif() install(TARGETS spectrum2_swiften_backend RUNTIME DESTINATION bin) diff --git a/backends/swiften/main.cpp b/backends/swiften/main.cpp index 4d89170c..ff3ece8b 100644 --- a/backends/swiften/main.cpp +++ b/backends/swiften/main.cpp @@ -80,36 +80,15 @@ class SwiftenPlugin : public NetworkPlugin, Swift::XMPPParserClient { Swift::XMPPParser *m_xmppParser; Swift::FullPayloadParserFactoryCollection m_collection2; - SwiftenPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() { + SwiftenPlugin(Config *config, const std::string &host, int port) : NetworkPlugin() { this->config = config; m_firstPing = true; - m_factories = new Swift::BoostNetworkFactories(loop); - m_conn = m_factories->getConnectionFactory()->createConnection(); - m_conn->onDataRead.connect(boost::bind(&SwiftenPlugin::_handleDataRead, this, _1)); - m_conn->connect(Swift::HostAddressPort(*(Swift::HostAddress::fromString(host)), port)); serializer = new Swift::XMPPSerializer(&collection, Swift::ClientStreamType, false); m_xmppParser = new Swift::XMPPParser(this, &m_collection2, m_factories->getXMLParserFactory()); m_xmppParser->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>"); LOG4CXX_INFO(logger, "Starting the plugin."); - } - - // NetworkPlugin uses this method to send the data to networkplugin server - void sendData(const std::string &string) { - m_conn->write(Swift::createSafeByteArray(string)); - } - - // This method has to call handleDataRead with all received data from network plugin server - void _handleDataRead(std::shared_ptr<Swift::SafeByteArray> data) { - if (m_firstPing) { - m_firstPing = false; - NetworkPlugin::PluginConfig cfg; - cfg.setRawXML(true); - cfg.setNeedRegistration(false); - sendConfig(cfg); - } - std::string d(data->begin(), data->end()); - handleDataRead(d); + connect(host, std::to_string(port)); } void handleStreamStart(const Swift::ProtocolHeader&) {} @@ -446,10 +425,7 @@ int main (int argc, char* argv[]) { Logging::initBackendLogging(cfg); - Swift::SimpleEventLoop eventLoop; - loop_ = &eventLoop; - np = new SwiftenPlugin(cfg, &eventLoop, host, port); - loop_->run(); + np = new SwiftenPlugin(cfg, host, port); return 0; } diff --git a/backends/template/CMakeLists.txt b/backends/template/CMakeLists.txt index 26fcde1b..66490e63 100644 --- a/backends/template/CMakeLists.txt +++ b/backends/template/CMakeLists.txt @@ -4,12 +4,12 @@ add_executable(spectrum2_template_backend ${SRC}) if(CMAKE_COMPILER_IS_GNUCXX) if(NOT WIN32) - target_link_libraries(spectrum2_template_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) + target_link_libraries(spectrum2_template_backend transport-plugin pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) else() - target_link_libraries(spectrum2_template_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) + target_link_libraries(spectrum2_template_backend transport-plugin ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) endif() else() - target_link_libraries(spectrum2_template_backend transport ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) + target_link_libraries(spectrum2_template_backend transport-plugin ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) endif() #install(TARGETS spectrum2_template_backend RUNTIME DESTINATION bin) diff --git a/backends/template/main.cpp b/backends/template/main.cpp index 5f9df1a8..1a7324d8 100644 --- a/backends/template/main.cpp +++ b/backends/template/main.cpp @@ -5,9 +5,6 @@ #include "transport/NetworkPlugin.h" #include "transport/Logging.h" -// Swiften -#include "Swiften/Swiften.h" - #ifndef _WIN32 // for signal handler #include "unistd.h" @@ -17,6 +14,7 @@ #endif // Boost #include <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> using namespace boost::filesystem; using namespace boost::program_options; using namespace Transport; @@ -60,9 +58,7 @@ int main (int argc, char* argv[]) { Logging::initBackendLogging(cfg); - Swift::SimpleEventLoop eventLoop; - Plugin p(cfg, &eventLoop, host, port); - eventLoop.run(); + Plugin p(cfg, host, port); return 0; } diff --git a/backends/template/plugin.cpp b/backends/template/plugin.cpp index 45ca5256..0f25b41c 100644 --- a/backends/template/plugin.cpp +++ b/backends/template/plugin.cpp @@ -4,36 +4,19 @@ #include "transport/NetworkPlugin.h" #include "transport/Logging.h" -// Swiften -#include "Swiften/Swiften.h" - // Boost #include <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> using namespace boost::filesystem; using namespace boost::program_options; using namespace Transport; DEFINE_LOGGER(logger, "Backend Template"); -Plugin::Plugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() { +Plugin::Plugin(Config *config, const std::string &host, int port) : NetworkPlugin() { this->config = config; - m_factories = new Swift::BoostNetworkFactories(loop); - m_conn = m_factories->getConnectionFactory()->createConnection(); - m_conn->onDataRead.connect(boost::bind(&Plugin::_handleDataRead, this, _1)); - m_conn->connect(Swift::HostAddressPort(*(Swift::HostAddress::fromString(host)), port)); - LOG4CXX_INFO(logger, "Starting the plugin."); -} - -// NetworkPlugin uses this method to send the data to networkplugin server -void Plugin::sendData(const std::string &string) { - m_conn->write(Swift::createSafeByteArray(string)); -} - -// This method has to call handleDataRead with all received data from network plugin server -void Plugin::_handleDataRead(std::shared_ptr<Swift::SafeByteArray> data) { - std::string d(data->begin(), data->end()); - handleDataRead(d); + connect(host, std::to_string(port)); } void Plugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) { diff --git a/backends/template/plugin.h b/backends/template/plugin.h index 0b4d86a5..b949c52c 100644 --- a/backends/template/plugin.h +++ b/backends/template/plugin.h @@ -1,13 +1,11 @@ #pragma once -#include "Swiften/Swiften.h" - #include "transport/Config.h" #include "transport/NetworkPlugin.h" class Plugin : public Transport::NetworkPlugin { public: - Plugin(Transport::Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port); + Plugin(Transport::Config *config, const std::string &host, int port); // NetworkPlugin uses this method to send the data to networkplugin server void sendData(const std::string &string); @@ -23,12 +21,5 @@ class Plugin : public Transport::NetworkPlugin { void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups); private: - // This method has to call handleDataRead with all received data from network plugin server - void _handleDataRead(std::shared_ptr<Swift::SafeByteArray> data); - - private: - Swift::BoostNetworkFactories *m_factories; - Swift::BoostIOServiceThread m_boostIOServiceThread; - std::shared_ptr<Swift::Connection> m_conn; Transport::Config *config; }; diff --git a/backends/twitter/CMakeLists.txt b/backends/twitter/CMakeLists.txt index 6748305d..14f71e3c 100644 --- a/backends/twitter/CMakeLists.txt +++ b/backends/twitter/CMakeLists.txt @@ -8,7 +8,7 @@ find_package(CURL) if(CURL_FOUND) message(STATUS "Using curl ${CURL_VERSION_STRING}: ${CURL_INCLUDE_DIRS} ${CURL_LIBRARIES}") - target_link_libraries(spectrum2_twitter_backend transport JsonCpp::JsonCpp ${CURL_LIBRARIES} ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) + target_link_libraries(spectrum2_twitter_backend transport-plugin JsonCpp::JsonCpp ${CURL_LIBRARIES} ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) else() message(FATAL_ERROR "curl not found") endif() diff --git a/backends/twitter/TwitterPlugin.cpp b/backends/twitter/TwitterPlugin.cpp index ab9bc5bf..ea43de57 100644 --- a/backends/twitter/TwitterPlugin.cpp +++ b/backends/twitter/TwitterPlugin.cpp @@ -10,12 +10,10 @@ #include "Requests/DestroyFriendRequest.h" #include "Requests/RetweetRequest.h" #include "Requests/ProfileImageRequest.h" -#include "Swiften/StringCodecs/Hexify.h" DEFINE_LOGGER(logger, "Twitter Backend"); TwitterPlugin *np = NULL; -Swift::SimpleEventLoop *loop_; // Event Loop const std::string OLD_APP_KEY = "PCWAdQpyyR12ezp2fVwEhw"; const std::string OLD_APP_SECRET = "EveLmCXJIg2R7BTCpm6OWV8YyX49nI0pxnYXh7JMvDg"; @@ -35,7 +33,7 @@ static int cmp(std::string a, std::string b) } -TwitterPlugin::TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, StorageBackend *storagebackend, const std::string &host, int port) : NetworkPlugin() +TwitterPlugin::TwitterPlugin(Config *config, StorageBackend *storagebackend, const std::string &host, int port) : NetworkPlugin() { this->config = config; this->storagebackend = storagebackend; @@ -68,26 +66,17 @@ TwitterPlugin::TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, Stora OAUTH_SECRET = "twitter_oauth_secret"; MODE = "mode"; - m_factories = new Swift::BoostNetworkFactories(loop); - m_conn = m_factories->getConnectionFactory()->createConnection(); - m_conn->onDataRead.connect(boost::bind(&TwitterPlugin::_handleDataRead, this, _1)); - m_conn->connect(Swift::HostAddressPort(*(Swift::HostAddress::fromString(host)), port)); - - tp = new ThreadPool(loop_, 10); - LOG4CXX_INFO(logger, "Fetch timeout is set to " << CONFIG_INT_DEFAULTED(config, "twitter.fetch_timeout", 90000)); - tweet_timer = m_factories->getTimerFactory()->createTimer(CONFIG_INT_DEFAULTED(config, "twitter.fetch_timeout", 90000)); - message_timer = m_factories->getTimerFactory()->createTimer(CONFIG_INT_DEFAULTED(config, "twitter.fetch_timeout", 90000)); + io = std::make_unique<boost::asio::io_service>(); + tweet_timer = std::make_unique<boost::asio::deadline_timer>(io, boost::posix_time::seconds(CONFIG_INT_DEFAULTED(config, "twitter.fetch_timeout", 90000))); + message_timer = std::make_unique<boost::asio::deadline_timer>(io, boost::posix_time::seconds(CONFIG_INT_DEFAULTED(config, "twitter.fetch_timeout", 90000))); - tweet_timer->onTick.connect(boost::bind(&TwitterPlugin::pollForTweets, this)); - //message_timer->onTick.connect(boost::bind(&TwitterPlugin::pollForDirectMessages, this)); - - tweet_timer->start(); - message_timer->start(); - cryptoProvider = std::shared_ptr<Swift::CryptoProvider>(Swift::PlatformCryptoProvider::create()); + tweet_timer->async_wait(boost::bind(&TwitterPlugin::pollForTweets, this)); + //message_timer->async_wait(boost::bind(&TwitterPlugin::pollForDirectMessages, this)); LOG4CXX_INFO(logger, "Starting the plugin."); + connect(host, std::to_string(port)); } TwitterPlugin::~TwitterPlugin() @@ -95,29 +84,6 @@ TwitterPlugin::~TwitterPlugin() delete storagebackend; std::set<std::string>::iterator it; for (it = onlineUsers.begin() ; it != onlineUsers.end() ; it++) delete userdb[*it].sessions; - delete tp; -} - -// Send data to NetworkPlugin server -void TwitterPlugin::sendData(const std::string &string) -{ - m_conn->write(Swift::createSafeByteArray(string)); -} - -// Receive date from the NetworkPlugin server and invoke the appropirate payload handler (implement in the NetworkPlugin class) -void TwitterPlugin::_handleDataRead(std::shared_ptr<Swift::SafeByteArray> data) -{ - if (m_firstPing) { - m_firstPing = false; - // Users can join the network without registering if we allow - // one user to connect multiple IRC networks. - NetworkPlugin::PluginConfig cfg; - cfg.setNeedPassword(false); - sendConfig(cfg); - } - - std::string d(data->begin(), data->end()); - handleDataRead(d); } // User trying to login into his twitter account diff --git a/backends/twitter/TwitterPlugin.h b/backends/twitter/TwitterPlugin.h index aec182f1..1461cdea 100644 --- a/backends/twitter/TwitterPlugin.h +++ b/backends/twitter/TwitterPlugin.h @@ -7,9 +7,7 @@ #include "transport/MySQLBackend.h" #include "transport/PQXXBackend.h" #include "transport/StorageBackend.h" -#include "transport/ThreadPool.h" -#include <Swiften/Swiften.h> #ifndef _WIN32 #include "unistd.h" #include "signal.h" @@ -17,6 +15,7 @@ #include "sys/signal.h" #endif #include <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> #include <boost/thread.hpp> #include <boost/thread/mutex.hpp> @@ -30,8 +29,7 @@ #include <queue> #include <set> #include <cstdio> -#include <Swiften/Crypto/CryptoProvider.h> -#include <Swiften/Crypto/PlatformCryptoProvider.h> + using namespace boost::filesystem; using namespace boost::program_options; using namespace Transport; @@ -40,27 +38,20 @@ using namespace Transport; class TwitterPlugin; extern TwitterPlugin *np; -extern Swift::SimpleEventLoop *loop_; // Event Loop class TwitterPlugin : public NetworkPlugin { public: - Swift::BoostNetworkFactories *m_factories; - Swift::BoostIOServiceThread m_boostIOServiceThread; - std::shared_ptr<Swift::Connection> m_conn; - std::shared_ptr<Swift::CryptoProvider> cryptoProvider; - Swift::Timer::ref tweet_timer; - Swift::Timer::ref message_timer; + std::unique_ptr<boost::asio::deadline_timer> tweet_timer; + std::unique_ptr<boost::asio::deadline_timer> message_timer; + std::unique_ptr<boost::asio::io_service> io; StorageBackend *storagebackend; - TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, StorageBackend *storagebackend, const std::string &host, int port); + TwitterPlugin(Config *config, StorageBackend *storagebackend, const std::string &host, int port); ~TwitterPlugin(); // Send data to NetworkPlugin server void sendData(const std::string &string); - - // Receive date from the NetworkPlugin server and invoke the appropirate payload handler (implement in the NetworkPlugin class) - void _handleDataRead(std::shared_ptr<Swift::SafeByteArray> data); // User trying to login into his twitter account void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password); @@ -153,7 +144,6 @@ class TwitterPlugin : public NetworkPlugin { boost::mutex dblock, userlock; - ThreadPool *tp; std::set<std::string> onlineUsers; struct UserData { diff --git a/backends/twitter/main.cpp b/backends/twitter/main.cpp index 2ebd389c..4d4cb9cf 100644 --- a/backends/twitter/main.cpp +++ b/backends/twitter/main.cpp @@ -51,11 +51,7 @@ int main (int argc, char* argv[]) { LOG4CXX_ERROR(logger, "Can't connect to database!"); return -1; } - - Swift::SimpleEventLoop eventLoop; - loop_ = &eventLoop; - np = new TwitterPlugin(cfg, &eventLoop, storagebackend, host, port); - loop_->run(); + np = new TwitterPlugin(cfg, storagebackend, host, port); return 0; } diff --git a/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h b/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h index ae00753d..266035f9 100644 --- a/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h +++ b/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h @@ -17,6 +17,7 @@ namespace Swift { +class DiscoInfo; class JingleSessionManager; class IQRouter; class EntityCapsProvider; diff --git a/include/boost/dll.hpp b/include/boost/dll.hpp deleted file mode 100644 index c7357007..00000000 --- a/include/boost/dll.hpp +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef BOOST_DLL_DLL_HPP -#define BOOST_DLL_DLL_HPP - -/// \file boost/dll.hpp -/// \brief Includes all the headers of the Boost.DLL library. - -#include <boost/config.hpp> -#include <boost/dll/shared_library.hpp> -#include <boost/dll/alias.hpp> -#include <boost/dll/import.hpp> -#include <boost/dll/library_info.hpp> -#include <boost/dll/runtime_symbol_info.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -#endif // BOOST_DLL_DLL_HPP - diff --git a/include/boost/dll/alias.hpp b/include/boost/dll/alias.hpp deleted file mode 100755 index 9f2e1685..00000000 --- a/include/boost/dll/alias.hpp +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_ALIAS_HPP -#define BOOST_DLL_ALIAS_HPP - -#include <boost/config.hpp> -#include <boost/static_assert.hpp> -#include <boost/utility/addressof.hpp> -#include <boost/predef/compiler.h> -#include <boost/predef/os.h> -#include <boost/dll/shared_library.hpp> -#include <boost/dll/detail/aggressive_ptr_cast.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - - -/// \file boost/dll/alias.hpp -/// \brief Includes alias methods and macro. You can include this header or -/// boost/dll/shared_library.hpp to reduce dependencies -/// in case you do not use the refcountable functions. - -namespace boost { namespace dll { - -#ifdef BOOST_DLL_DOXYGEN -/// Define this macro to explicitly specify translation unit in which alias must be instantiated. -/// See section 'Limitations' for more info. You may find usage examples in source codes of almost each tutorial. -#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION -#endif - -#if BOOST_COMP_MSVC - -#define BOOST_DLL_SELECTANY __declspec(selectany) - -#define BOOST_DLL_SECTION(SectionName, Permissions) \ - BOOST_STATIC_ASSERT_MSG( \ - sizeof(#SectionName) < 10, \ - "Some platforms require section names to be at most 8 bytest" \ - ); \ - __pragma(section(#SectionName, Permissions)) __declspec(allocate(#SectionName)) \ - /**/ - -#else // #if BOOST_COMP_MSVC - - -#if BOOST_OS_WINDOWS || BOOST_OS_ANDROID || BOOST_COMP_IBM -// There are some problems with mixing `__dllexport__` and `weak` using MinGW -// See https://sourceware.org/bugzilla/show_bug.cgi?id=17480 -// -// Android had an issue with exporting weak symbols -// https://code.google.com/p/android/issues/detail?id=70206 -#define BOOST_DLL_SELECTANY -#else // #if BOOST_OS_WINDOWS -/*! -* \brief Macro that allows linker to select any occurrence of this symbol instead of -* failing with 'multiple definitions' error at linktime. -* -* This macro does not work on Android, IBM XL C/C++ and MinGW+Windows -* because of linker problems with exporting weak symbols -* (See https://code.google.com/p/android/issues/detail?id=70206, https://sourceware.org/bugzilla/show_bug.cgi?id=17480) -*/ -#define BOOST_DLL_SELECTANY __attribute__((weak)) -#endif // #if BOOST_OS_WINDOWS - -// TODO: improve section permissions using following info: -// http://stackoverflow.com/questions/6252812/what-does-the-aw-flag-in-the-section-attribute-mean - -#if !BOOST_OS_MACOS && !BOOST_OS_IOS -/*! -* \brief Macro that puts symbol to a specific section. On MacOS all the sections are put into "__DATA" segment. -* \param SectionName Name of the section. Must be a valid C identifier without quotes not longer than 8 bytes. -* \param Permissions Can be "read" or "write" (without quotes!). -*/ -#define BOOST_DLL_SECTION(SectionName, Permissions) \ - BOOST_STATIC_ASSERT_MSG( \ - sizeof(#SectionName) < 10, \ - "Some platforms require section names to be at most 8 bytest" \ - ); \ - __attribute__ ((section (#SectionName))) \ - /**/ -#else // #if !BOOST_OS_MACOS && !BOOST_OS_IOS - -#define BOOST_DLL_SECTION(SectionName, Permissions) \ - BOOST_STATIC_ASSERT_MSG( \ - sizeof(#SectionName) < 10, \ - "Some platforms require section names to be at most 8 bytest" \ - ); \ - __attribute__ ((section ( "__DATA," #SectionName))) \ - /**/ - -#endif // #if #if !BOOST_OS_MACOS && !BOOST_OS_IOS - -#endif // #if BOOST_COMP_MSVC - - -// Alias - is just a variable that pointers to original data -// -// A few attempts were made to avoid additional indirection: -// 1) -// // Does not work on Windows, work on Linux -// extern "C" BOOST_SYMBOL_EXPORT void AliasName() { -// reinterpret_cast<void (*)()>(Function)(); -// } -// -// 2) -// // Does not work on Linux (changes permissions of .text section and produces incorrect DSO) -// extern "C" BOOST_SYMBOL_EXPORT void* __attribute__ ((section(".text#"))) -// func_ptr = *reinterpret_cast<std::ptrdiff_t**>(&foo::bar); -// -// 3) // requires mangled name of `Function` -// // AliasName() __attribute__ ((weak, alias ("Function"))) -// -// // hard to use -// `#pragma comment(linker, "/alternatename:_pWeakValue=_pDefaultWeakValue")` - -/*! -* \brief Makes an alias name for exported function or variable. -* -* This macro is useful in cases of long mangled C++ names. For example some `void boost::foo(std::sting)` -* function name will change to something like `N5boostN3foosE` after mangling. -* Importing function by `N5boostN3foosE` name does not looks user friendly, especially assuming the fact -* that different compilers have different mangling schemes. AliasName is the name that won't be mangled -* and can be used as a portable import name. -* -* -* Can be used in any namespace, including global. FunctionOrVar must be fully qualified, -* so that address of it could be taken. Multiple different aliases for a single variable/function -* are allowed. -* -* Make sure that AliasNames are unique per library/executable. Functions or variables -* in global namespace must not have names same as AliasNames. -* -* Same AliasName in different translation units must point to the same FunctionOrVar. -* -* Puts all the aliases into the \b "boostdll" read only section of the binary. Equal to -* \forcedmacrolink{BOOST_DLL_ALIAS_SECTIONED}(FunctionOrVar, AliasName, boostdll). -* -* \param FunctionOrVar Function or variable for which an alias must be made. -* \param AliasName Name of the alias. Must be a valid C identifier. -* -* \b Example: -* \code -* namespace foo { -* void bar(std::string&); -* -* BOOST_DLL_ALIAS(foo::bar, foo_bar) -* } -* -* BOOST_DLL_ALIAS(foo::bar, foo_bar_another_alias_name) -* \endcode -* -* \b See: \forcedmacrolink{BOOST_DLL_ALIAS_SECTIONED} for making alias in a specific section. -*/ -#define BOOST_DLL_ALIAS(FunctionOrVar, AliasName) \ - BOOST_DLL_ALIAS_SECTIONED(FunctionOrVar, AliasName, boostdll) \ - /**/ - - -#if ((BOOST_COMP_GNUC && BOOST_OS_WINDOWS) || BOOST_OS_ANDROID || BOOST_COMP_IBM) && !defined(BOOST_DLL_FORCE_ALIAS_INSTANTIATION) - -#define BOOST_DLL_ALIAS_SECTIONED(FunctionOrVar, AliasName, SectionName) \ - namespace _autoaliases { \ - extern "C" BOOST_SYMBOL_EXPORT const void *AliasName; \ - } /* namespace _autoaliases */ \ - /**/ - -#define BOOST_DLL_AUTO_ALIAS(FunctionOrVar) \ - namespace _autoaliases { \ - extern "C" BOOST_SYMBOL_EXPORT const void *FunctionOrVar; \ - } /* namespace _autoaliases */ \ - /**/ -#else -// Note: we can not use `aggressive_ptr_cast` here, because in that case GCC applies -// different permissions to the section and it causes Segmentation fault. -// Note: we can not use `boost::addressof()` here, because in that case GCC -// may optimize away the FunctionOrVar instance and we'll get a pointer to unexisting symbol. -/*! -* \brief Same as \forcedmacrolink{BOOST_DLL_ALIAS} but puts alias name into the user specified section. -* -* \param FunctionOrVar Function or variable for which an alias must be made. -* \param AliasName Name of the alias. Must be a valid C identifier. -* \param SectionName Name of the section. Must be a valid C identifier without quotes not longer than 8 bytes. -* -* \b Example: -* \code -* namespace foo { -* void bar(std::string&); -* -* BOOST_DLL_ALIAS_SECTIONED(foo::bar, foo_bar, sect_1) // section "sect_1" now exports "foo_bar" -* } -* \endcode -* -*/ -#define BOOST_DLL_ALIAS_SECTIONED(FunctionOrVar, AliasName, SectionName) \ - namespace _autoaliases { \ - extern "C" BOOST_SYMBOL_EXPORT const void *AliasName; \ - BOOST_DLL_SECTION(SectionName, read) BOOST_DLL_SELECTANY \ - const void * AliasName = reinterpret_cast<const void*>(reinterpret_cast<intptr_t>( \ - &FunctionOrVar \ - )); \ - } /* namespace _autoaliases */ \ - /**/ - -/*! -* \brief Exports variable or function with unmangled alias name. -* -* This macro is useful in cases of long mangled C++ names. For example some `void boost::foo(std::sting)` -* function name will change to something like `N5boostN3foosE` after mangling. -* Importing function by `N5boostN3foosE` name does not looks user friendly, especially assuming the fact -* that different compilers have different mangling schemes.* -* -* Must be used in scope where FunctionOrVar declared. FunctionOrVar must be a valid C name, which means that -* it must not contain `::`. -* -* Functions or variables -* in global namespace must not have names same as FunctionOrVar. -* -* Puts all the aliases into the \b "boostdll" read only section of the binary. Almost same as -* \forcedmacrolink{BOOST_DLL_ALIAS}(FunctionOrVar, FunctionOrVar). -* -* \param FunctionOrVar Function or variable for which an unmangled alias must be made. -* -* \b Example: -* \code -* namespace foo { -* void bar(std::string&); -* BOOST_DLL_AUTO_ALIAS(bar) -* } -* -* \endcode -* -* \b See: \forcedmacrolink{BOOST_DLL_ALIAS} for making an alias with different names. -*/ - -#define BOOST_DLL_AUTO_ALIAS(FunctionOrVar) \ - namespace _autoaliases { \ - BOOST_DLL_SELECTANY const void * dummy_ ## FunctionOrVar \ - = reinterpret_cast<const void*>(reinterpret_cast<intptr_t>( \ - &FunctionOrVar \ - )); \ - extern "C" BOOST_SYMBOL_EXPORT const void *FunctionOrVar; \ - BOOST_DLL_SECTION(boostdll, read) BOOST_DLL_SELECTANY \ - const void * FunctionOrVar = dummy_ ## FunctionOrVar; \ - } /* namespace _autoaliases */ \ - /**/ - - -#endif - - -}} // namespace boost::dll - - -#endif // BOOST_DLL_ALIAS_HPP - diff --git a/include/boost/dll/detail/aggressive_ptr_cast.hpp b/include/boost/dll/detail/aggressive_ptr_cast.hpp deleted file mode 100644 index 567d102b..00000000 --- a/include/boost/dll/detail/aggressive_ptr_cast.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_DETAIL_AGGRESSIVE_PTR_CAST_HPP -#define BOOST_DLL_DETAIL_AGGRESSIVE_PTR_CAST_HPP - -#include <boost/config.hpp> -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -#include <boost/static_assert.hpp> -#include <boost/type_traits/is_pointer.hpp> -#include <boost/type_traits/is_const.hpp> -#include <boost/cstdint.hpp> // boost::uintptr_t - -namespace boost { namespace dll { namespace detail { - -// GCC warns when reinterpret_cast between function pointer and object pointer occur. -// This method suppress the warnings and ensures that such casts are safe. -template <class To, class From> -BOOST_FORCEINLINE To aggressive_ptr_cast(From* v) BOOST_NOEXCEPT { - BOOST_STATIC_ASSERT_MSG( - boost::is_pointer<To>::value, - "`agressive_ptr_cast` function must be used only for pointer casting." - ); - - BOOST_STATIC_ASSERT_MSG( - sizeof(v) == sizeof(To), - "Pointer to function and pointer to object differ in size on your platform." - ); - - return reinterpret_cast<To>( - reinterpret_cast<boost::uintptr_t>(v) - ); -} - -}}} // boost::dll::detail - -#endif // BOOST_DLL_DETAIL_AGGRESSIVE_PTR_CAST_HPP - diff --git a/include/boost/dll/detail/elf_info.hpp b/include/boost/dll/detail/elf_info.hpp deleted file mode 100644 index 325df9cb..00000000 --- a/include/boost/dll/detail/elf_info.hpp +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_DETAIL_POSIX_ELF_INFO_HPP -#define BOOST_DLL_DETAIL_POSIX_ELF_INFO_HPP - -#include <boost/config.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -#include <cstring> -#include <boost/filesystem/fstream.hpp> -#include <boost/dll/detail/x_info_interface.hpp> - -namespace boost { namespace dll { namespace detail { - -template <class AddressOffsetT> -struct Elf_Ehdr_template { - unsigned char e_ident[16]; /* Magic number and other info */ - boost::uint16_t e_type; /* Object file type */ - boost::uint16_t e_machine; /* Architecture */ - boost::uint32_t e_version; /* Object file version */ - AddressOffsetT e_entry; /* Entry point virtual address */ - AddressOffsetT e_phoff; /* Program header table file offset */ - AddressOffsetT e_shoff; /* Section header table file offset */ - boost::uint32_t e_flags; /* Processor-specific flags */ - boost::uint16_t e_ehsize; /* ELF header size in bytes */ - boost::uint16_t e_phentsize; /* Program header table entry size */ - boost::uint16_t e_phnum; /* Program header table entry count */ - boost::uint16_t e_shentsize; /* Section header table entry size */ - boost::uint16_t e_shnum; /* Section header table entry count */ - boost::uint16_t e_shstrndx; /* Section header string table index */ -}; - -typedef Elf_Ehdr_template<boost::uint32_t> Elf32_Ehdr_; -typedef Elf_Ehdr_template<boost::uint64_t> Elf64_Ehdr_; - -template <class AddressOffsetT> -struct Elf_Shdr_template { - boost::uint32_t sh_name; /* Section name (string tbl index) */ - boost::uint32_t sh_type; /* Section type */ - AddressOffsetT sh_flags; /* Section flags */ - AddressOffsetT sh_addr; /* Section virtual addr at execution */ - AddressOffsetT sh_offset; /* Section file offset */ - AddressOffsetT sh_size; /* Section size in bytes */ - boost::uint32_t sh_link; /* Link to another section */ - boost::uint32_t sh_info; /* Additional section information */ - AddressOffsetT sh_addralign; /* Section alignment */ - AddressOffsetT sh_entsize; /* Entry size if section holds table */ -}; - -typedef Elf_Shdr_template<boost::uint32_t> Elf32_Shdr_; -typedef Elf_Shdr_template<boost::uint64_t> Elf64_Shdr_; - -template <class AddressOffsetT> -struct Elf_Sym_template; - -template <> -struct Elf_Sym_template<boost::uint32_t> { - typedef boost::uint32_t AddressOffsetT; - - boost::uint32_t st_name; /* Symbol name (string tbl index) */ - AddressOffsetT st_value; /* Symbol value */ - AddressOffsetT st_size; /* Symbol size */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* Symbol visibility */ - boost::uint16_t st_shndx; /* Section index */ -}; - -template <> -struct Elf_Sym_template<boost::uint64_t> { - typedef boost::uint64_t AddressOffsetT; - - boost::uint32_t st_name; /* Symbol name (string tbl index) */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* Symbol visibility */ - boost::uint16_t st_shndx; /* Section index */ - AddressOffsetT st_value; /* Symbol value */ - AddressOffsetT st_size; /* Symbol size */ -}; - - -typedef Elf_Sym_template<boost::uint32_t> Elf32_Sym_; -typedef Elf_Sym_template<boost::uint64_t> Elf64_Sym_; - -template <class AddressOffsetT> -class elf_info: public x_info_interface { - boost::filesystem::ifstream& f_; - - typedef boost::dll::detail::Elf_Ehdr_template<AddressOffsetT> header_t; - typedef boost::dll::detail::Elf_Shdr_template<AddressOffsetT> section_t; - typedef boost::dll::detail::Elf_Sym_template<AddressOffsetT> symbol_t; - - BOOST_STATIC_CONSTANT(boost::uint32_t, SHT_SYMTAB_ = 2); - BOOST_STATIC_CONSTANT(boost::uint32_t, SHT_STRTAB_ = 3); - - BOOST_STATIC_CONSTANT(unsigned char, STB_LOCAL_ = 0); /* Local symbol */ - BOOST_STATIC_CONSTANT(unsigned char, STB_GLOBAL_ = 1); /* Global symbol */ - BOOST_STATIC_CONSTANT(unsigned char, STB_WEAK_ = 2); /* Weak symbol */ - - /* Symbol visibility specification encoded in the st_other field. */ - BOOST_STATIC_CONSTANT(unsigned char, STV_DEFAULT_ = 0); /* Default symbol visibility rules */ - BOOST_STATIC_CONSTANT(unsigned char, STV_INTERNAL_ = 1); /* Processor specific hidden class */ - BOOST_STATIC_CONSTANT(unsigned char, STV_HIDDEN_ = 2); /* Sym unavailable in other modules */ - BOOST_STATIC_CONSTANT(unsigned char, STV_PROTECTED_ = 3); /* Not preemptible, not exported */ - -public: - static bool parsing_supported(boost::filesystem::ifstream& f) { - const unsigned char magic_bytes[5] = { - 0x7f, 'E', 'L', 'F', sizeof(boost::uint32_t) == sizeof(AddressOffsetT) ? 1 : 2 - }; - - unsigned char ch; - f.seekg(0); - for (std::size_t i = 0; i < sizeof(magic_bytes); ++i) { - f >> ch; - if (ch != magic_bytes[i]) { - return false; - } - } - - return true; - } - - explicit elf_info(boost::filesystem::ifstream& f) BOOST_NOEXCEPT - : f_(f) - {} - - std::vector<std::string> sections() { - std::vector<std::string> ret; - std::vector<char> names; - sections_names_raw(names); - - const char* name_begin = &names[0]; - const char* const name_end = name_begin + names.size(); - ret.reserve(header().e_shnum); - do { - ret.push_back(name_begin); - name_begin += ret.back().size() + 1; - } while (name_begin != name_end); - - return ret; - } - -private: - template <class T> - inline void read_raw(T& value, std::size_t size = sizeof(T)) const { - f_.read(reinterpret_cast<char*>(&value), size); - } - - inline header_t header() { - header_t elf; - - f_.seekg(0); - read_raw(elf); - - return elf; - } - - void sections_names_raw(std::vector<char>& sections) { - const header_t elf = header(); - - section_t section_names_section; - f_.seekg(elf.e_shoff + elf.e_shstrndx * sizeof(section_t)); - read_raw(section_names_section); - - sections.resize(static_cast<std::size_t>(section_names_section.sh_size)); - f_.seekg(section_names_section.sh_offset); - read_raw(sections[0], static_cast<std::size_t>(section_names_section.sh_size)); - } - - void symbols_text(std::vector<symbol_t>& symbols, std::vector<char>& text) { - const header_t elf = header(); - f_.seekg(elf.e_shoff); - - for (std::size_t i = 0; i < elf.e_shnum; ++i) { - section_t section; - read_raw(section); - - if (section.sh_type == SHT_SYMTAB_) { - symbols.resize(static_cast<std::size_t>(section.sh_size / sizeof(symbol_t))); - - const boost::filesystem::ifstream::pos_type pos = f_.tellg(); - f_.seekg(section.sh_offset); - read_raw(symbols[0], static_cast<std::size_t>(section.sh_size - (section.sh_size % sizeof(symbol_t))) ); - f_.seekg(pos); - } else if (section.sh_type == SHT_STRTAB_) { - text.resize(static_cast<std::size_t>(section.sh_size)); - - const boost::filesystem::ifstream::pos_type pos = f_.tellg(); - f_.seekg(section.sh_offset); - read_raw(text[0], static_cast<std::size_t>(section.sh_size)); - f_.seekg(pos); - } - } - } - - static bool is_visible(const symbol_t& sym) BOOST_NOEXCEPT { - // `(sym.st_info >> 4) != STB_LOCAL_ && !!sym.st_size` check also workarounds the - // GCC's issue https://sourceware.org/bugzilla/show_bug.cgi?id=13621 - return (sym.st_other & 0x03) == STV_DEFAULT_ && (sym.st_info >> 4) != STB_LOCAL_ && !!sym.st_size; - } - -public: - std::vector<std::string> symbols() { - std::vector<std::string> ret; - - std::vector<symbol_t> symbols; - std::vector<char> text; - symbols_text(symbols, text); - - ret.reserve(symbols.size()); - for (std::size_t i = 0; i < symbols.size(); ++i) { - if (is_visible(symbols[i])) { - ret.push_back(&text[0] + symbols[i].st_name); - if (ret.back().empty()) { - ret.pop_back(); // Do not show empty names - } - } - } - - return ret; - } - - std::vector<std::string> symbols(const char* section_name) { - std::vector<std::string> ret; - - std::size_t index = 0; - std::size_t ptrs_in_section_count = 0; - { - std::vector<char> names; - sections_names_raw(names); - - const header_t elf = header(); - - for (; index < elf.e_shnum; ++index) { - section_t section; - f_.seekg(elf.e_shoff + index * sizeof(section_t)); - read_raw(section); - - if (!std::strcmp(&names[0] + section.sh_name, section_name)) { - if (!section.sh_entsize) { - section.sh_entsize = 1; - } - ptrs_in_section_count = static_cast<std::size_t>(section.sh_size / section.sh_entsize); - break; - } - } - } - - std::vector<symbol_t> symbols; - std::vector<char> text; - symbols_text(symbols, text); - - if (ptrs_in_section_count < symbols.size()) { - ret.reserve(ptrs_in_section_count); - } else { - ret.reserve(symbols.size()); - } - - for (std::size_t i = 0; i < symbols.size(); ++i) { - if (symbols[i].st_shndx == index && is_visible(symbols[i])) { - ret.push_back(&text[0] + symbols[i].st_name); - if (ret.back().empty()) { - ret.pop_back(); // Do not show empty names - } - } - } - - return ret; - } -}; - -typedef elf_info<boost::uint32_t> elf_info32; -typedef elf_info<boost::uint64_t> elf_info64; - -}}} // namespace boost::dll::detail - -#endif // BOOST_DLL_DETAIL_POSIX_ELF_INFO_HPP diff --git a/include/boost/dll/detail/macho_info.hpp b/include/boost/dll/detail/macho_info.hpp deleted file mode 100644 index 69119082..00000000 --- a/include/boost/dll/detail/macho_info.hpp +++ /dev/null @@ -1,321 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_DETAIL_MACHO_INFO_HPP -#define BOOST_DLL_DETAIL_MACHO_INFO_HPP - -#include <boost/config.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -#include <boost/filesystem/fstream.hpp> -#include <boost/dll/detail/x_info_interface.hpp> - -namespace boost { namespace dll { namespace detail { - -typedef int integer_t; -typedef int vm_prot_t; -typedef integer_t cpu_type_t; -typedef integer_t cpu_subtype_t; - -template <class AddressOffsetT> -struct mach_header_template { - boost::uint32_t magic; - cpu_type_t cputype; - cpu_subtype_t cpusubtype; - boost::uint32_t filetype; - boost::uint32_t ncmds; - boost::uint32_t sizeofcmds; - boost::uint32_t flags[sizeof(AddressOffsetT) / sizeof(uint32_t)]; // Flags and reserved -}; - -typedef mach_header_template<boost::uint32_t> mach_header_32_; -typedef mach_header_template<boost::uint64_t> mach_header_64_; - -struct load_command_ { - boost::uint32_t cmd; /* type of command */ - boost::uint32_t cmdsize; -}; - -struct load_command_types { - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_SEGMENT_ = 0x1); /* segment of this file to be mapped */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_SYMTAB_ = 0x2); /* link-edit stab symbol table info */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_SYMSEG_ = 0x3); /* link-edit gdb symbol table info (obsolete) */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_THREAD_ = 0x4); /* thread */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_UNIXTHREAD_ = 0x5); /* unix thread (includes a stack) */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_LOADFVMLIB_ = 0x6); /* load a specified fixed VM shared library */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_IDFVMLIB_ = 0x7); /* fixed VM shared library identification */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_IDENT_ = 0x8); /* object identification info (obsolete) */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_FVMFILE_ = 0x9); /* fixed VM file inclusion (internal use) */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_PREPAGE_ = 0xa); /* prepage command (internal use) */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_DYSYMTAB_ = 0xb); /* dynamic link-edit symbol table info */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_LOAD_DYLIB_ = 0xc); /* load a dynamically linked shared library */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_ID_DYLIB_ = 0xd); /* dynamically linked shared lib ident */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_LOAD_DYLINKER_ = 0xe); /* load a dynamic linker */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_ID_DYLINKER_ = 0xf); /* dynamic linker identification */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_PREBOUND_DYLIB_ = 0x10); /* modules prebound for a dynamically linked shared library */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_ROUTINES_ = 0x11); /* image routines */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_SUB_FRAMEWORK_ = 0x12); /* sub framework */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_SUB_UMBRELLA_ = 0x13); /* sub umbrella */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_SUB_CLIENT_ = 0x14); /* sub client */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_SUB_LIBRARY_ = 0x15); /* sub library */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_TWOLEVEL_HINTS_ = 0x16); /* two-level namespace lookup hints */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_PREBIND_CKSUM_ = 0x17); /* prebind checksum */ -/* - * After MacOS X 10.1 when a new load command is added that is required to be - * understood by the dynamic linker for the image to execute properly the - * LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic - * linker sees such a load command it it does not understand will issue a - * "unknown load command required for execution" error and refuse to use the - * image. Other load commands without this bit that are not understood will - * simply be ignored. - */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_REQ_DYLD_ = 0x80000000); - -/* - * load a dynamically linked shared library that is allowed to be missing - * (all symbols are weak imported). - */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_LOAD_WEAK_DYLIB_ = (0x18 | LC_REQ_DYLD_)); - - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_SEGMENT_64_ = 0x19); /* 64-bit segment of this file to be mapped */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_ROUTINES_64_ = 0x1a); /* 64-bit image routines */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_UUID_ = 0x1b); /* the uuid */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_RPATH_ = (0x1c | LC_REQ_DYLD_)); /* runpath additions */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_CODE_SIGNATURE_ = 0x1d); /* local of code signature */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_SEGMENT_SPLIT_INFO_= 0x1e); /* local of info to split segments */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_REEXPORT_DYLIB_ = (0x1f | LC_REQ_DYLD_)); /* load and re-export dylib */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_LAZY_LOAD_DYLIB_ = 0x20); /* delay load of dylib until first use */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_ENCRYPTION_INFO_ = 0x21); /* encrypted segment information */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_DYLD_INFO_ = 0x22); /* compressed dyld information */ - BOOST_STATIC_CONSTANT(boost::uint32_t, LC_DYLD_INFO_ONLY_ = (0x22|LC_REQ_DYLD_)); /* compressed dyld information only */ -}; - -template <class AddressOffsetT> -struct segment_command_template { - boost::uint32_t cmd; /* LC_SEGMENT_ */ - boost::uint32_t cmdsize; /* includes sizeof section structs */ - char segname[16]; /* segment name */ - AddressOffsetT vmaddr; /* memory address of this segment */ - AddressOffsetT vmsize; /* memory size of this segment */ - AddressOffsetT fileoff; /* file offset of this segment */ - AddressOffsetT filesize; /* amount to map from the file */ - vm_prot_t maxprot; /* maximum VM protection */ - vm_prot_t initprot; /* initial VM protection */ - boost::uint32_t nsects; /* number of sections in segment */ - boost::uint32_t flags; /* flags */ -}; - -typedef segment_command_template<boost::uint32_t> segment_command_32_; -typedef segment_command_template<boost::uint64_t> segment_command_64_; - -template <class AddressOffsetT> -struct section_template { - char sectname[16]; /* name of this section */ - char segname[16]; /* segment this section goes in */ - AddressOffsetT addr; /* memory address of this section */ - AddressOffsetT size; /* size in bytes of this section */ - boost::uint32_t offset; /* file offset of this section */ - boost::uint32_t align; /* section alignment (power of 2) */ - boost::uint32_t reloff; /* file offset of relocation entries */ - boost::uint32_t nreloc; /* number of relocation entries */ - boost::uint32_t flags; /* flags (section type and attributes)*/ - boost::uint32_t reserved[1 + sizeof(AddressOffsetT) / sizeof(uint32_t)]; -}; - -typedef section_template<boost::uint32_t> section_32_; -typedef section_template<boost::uint64_t> section_64_; - -struct symtab_command_ { - boost::uint32_t cmd; /* LC_SYMTAB_ */ - boost::uint32_t cmdsize; /* sizeof(struct symtab_command) */ - boost::uint32_t symoff; /* symbol table offset */ - boost::uint32_t nsyms; /* number of symbol table entries */ - boost::uint32_t stroff; /* string table offset */ - boost::uint32_t strsize; /* string table size in bytes */ -}; - -template <class AddressOffsetT> -struct nlist_template { - boost::uint32_t n_strx; - boost::uint8_t n_type; - boost::uint8_t n_sect; - boost::uint16_t n_desc; - AddressOffsetT n_value; -}; - -typedef nlist_template<boost::uint32_t> nlist_32_; -typedef nlist_template<boost::uint64_t> nlist_64_; - -template <class AddressOffsetT> -class macho_info: public x_info_interface { - boost::filesystem::ifstream& f_; - - typedef boost::dll::detail::mach_header_template<AddressOffsetT> header_t; - typedef boost::dll::detail::load_command_ load_command_t; - typedef boost::dll::detail::segment_command_template<AddressOffsetT> segment_t; - typedef boost::dll::detail::section_template<AddressOffsetT> section_t; - typedef boost::dll::detail::symtab_command_ symbol_header_t; - typedef boost::dll::detail::nlist_template<AddressOffsetT> nlist_t; - - BOOST_STATIC_CONSTANT(boost::uint32_t, SEGMENT_CMD_NUMBER = (sizeof(AddressOffsetT) > 4 ? load_command_types::LC_SEGMENT_64_ : load_command_types::LC_SEGMENT_)); - -public: - static bool parsing_supported(boost::filesystem::ifstream& f) { - static const uint32_t magic_bytes = (sizeof(AddressOffsetT) <= sizeof(uint32_t) ? 0xfeedface : 0xfeedfacf); - - uint32_t magic; - f.seekg(0); - f.read(reinterpret_cast<char*>(&magic), sizeof(magic)); - return (magic_bytes == magic); - } - - explicit macho_info(boost::filesystem::ifstream& f) BOOST_NOEXCEPT - : f_(f) - {} - -private: - template <class T> - inline void read_raw(T& value, std::size_t size = sizeof(T)) const { - f_.read(reinterpret_cast<char*>(&value), size); - } - - template <class F> - void command_finder(uint32_t cmd_num, F callback_f) { - const header_t h = header(); - load_command_t command; - f_.seekg(sizeof(header_t)); - for (std::size_t i = 0; i < h.ncmds; ++i) { - const boost::filesystem::ifstream::pos_type pos = f_.tellg(); - read_raw(command); - if (command.cmd != cmd_num) { - f_.seekg(pos + static_cast<boost::filesystem::ifstream::pos_type>(command.cmdsize)); - continue; - } - - f_.seekg(pos); - callback_f(*this); - f_.seekg(pos + static_cast<boost::filesystem::ifstream::pos_type>(command.cmdsize)); - } - } - - struct section_names_gather { - std::vector<std::string>& ret; - - void operator()(const macho_info& f) const { - segment_t segment; - f.read_raw(segment); - - section_t section; - ret.reserve(ret.size() + segment.nsects); - for (std::size_t j = 0; j < segment.nsects; ++j) { - f.read_raw(section); - // `segname` goes right after the `sectname`. - // Forcing `sectname` to end on '\0' - section.segname[0] = '\0'; - ret.push_back(section.sectname); - if (ret.back().empty()) { - ret.pop_back(); // Do not show empty names - } - } - } - }; - - struct symbol_names_gather { - std::vector<std::string>& ret; - std::size_t section_index; - - void operator()(const macho_info& f) const { - symbol_header_t symbh; - f.read_raw(symbh); - ret.reserve(ret.size() + symbh.nsyms); - - nlist_t symbol; - std::string symbol_name; - for (std::size_t j = 0; j < symbh.nsyms; ++j) { - f.f_.seekg(symbh.symoff + j * sizeof(nlist_t)); - f.read_raw(symbol); - if (!symbol.n_strx) { - continue; // Symbol has no name - } - - if ((symbol.n_type & 0x0e) != 0xe || !symbol.n_sect) { - continue; // Symbol has no section - } - - if (section_index && section_index != symbol.n_sect) { - continue; // Not in the required section - } - - f.f_.seekg(symbh.stroff + symbol.n_strx); - getline(f.f_, symbol_name, '\0'); - if (symbol_name.empty()) { - continue; - } - - if (symbol_name[0] == '_') { - // Linker adds additional '_' symbol. Could not find official docs for that case. - ret.push_back(symbol_name.c_str() + 1); - } else { - ret.push_back(symbol_name); - } - } - } - }; - -public: - std::vector<std::string> sections() { - std::vector<std::string> ret; - section_names_gather f = { ret }; - command_finder(SEGMENT_CMD_NUMBER, f); - return ret; - } - -private: - inline header_t header() { - header_t h; - - f_.seekg(0); - read_raw(h); - - return h; - } - -public: - std::vector<std::string> symbols() { - std::vector<std::string> ret; - symbol_names_gather f = { ret, 0 }; - command_finder(load_command_types::LC_SYMTAB_, f); - return ret; - } - - std::vector<std::string> symbols(const char* section_name) { - // Not very optimal solution - std::vector<std::string> ret = sections(); - std::vector<std::string>::iterator it = std::find(ret.begin(), ret.end(), section_name); - if (it == ret.end()) { - // No section with such name - ret.clear(); - return ret; - } - - // section indexes start from 1 - symbol_names_gather f = { ret, static_cast<std::size_t>(1 + (it - ret.begin())) }; - ret.clear(); - command_finder(load_command_types::LC_SYMTAB_, f); - return ret; - } -}; - -typedef macho_info<boost::uint32_t> macho_info32; -typedef macho_info<boost::uint64_t> macho_info64; - -}}} // namespace boost::dll::detail - -#endif // BOOST_DLL_DETAIL_MACHO_INFO_HPP diff --git a/include/boost/dll/detail/pe_info.hpp b/include/boost/dll/detail/pe_info.hpp deleted file mode 100644 index 7f1584a6..00000000 --- a/include/boost/dll/detail/pe_info.hpp +++ /dev/null @@ -1,427 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_DETAIL_WINDOWS_PE_INFO_HPP -#define BOOST_DLL_DETAIL_WINDOWS_PE_INFO_HPP - -#include <boost/config.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -#include <boost/filesystem/fstream.hpp> -#include <boost/dll/detail/x_info_interface.hpp> - -namespace boost { namespace dll { namespace detail { - -// reference: -// http://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/ -// http://msdn.microsoft.com/en-us/magazine/ms809762.aspx -// http://msdn.microsoft.com/en-us/magazine/cc301808.aspx -// - -// Basic Windows typedefs. We can not use <boost/detail/winapi/basic_types.hpp> header -// because that header must be included only on Windows platform -typedef unsigned char BYTE_; -typedef unsigned short WORD_; -typedef unsigned long DWORD_; -typedef long LONG_; -typedef unsigned long ULONG_; -typedef boost::int64_t LONGLONG_; -typedef boost::uint64_t ULONGLONG_; - -struct IMAGE_DOS_HEADER_ { // 32/64 independent header - boost::dll::detail::WORD_ e_magic; // Magic number - boost::dll::detail::WORD_ e_cblp; // Bytes on last page of file - boost::dll::detail::WORD_ e_cp; // Pages in file - boost::dll::detail::WORD_ e_crlc; // Relocations - boost::dll::detail::WORD_ e_cparhdr; // Size of header in paragraphs - boost::dll::detail::WORD_ e_minalloc; // Minimum extra paragraphs needed - boost::dll::detail::WORD_ e_maxalloc; // Maximum extra paragraphs needed - boost::dll::detail::WORD_ e_ss; // Initial (relative) SS value - boost::dll::detail::WORD_ e_sp; // Initial SP value - boost::dll::detail::WORD_ e_csum; // Checksum - boost::dll::detail::WORD_ e_ip; // Initial IP value - boost::dll::detail::WORD_ e_cs; // Initial (relative) CS value - boost::dll::detail::WORD_ e_lfarlc; // File address of relocation table - boost::dll::detail::WORD_ e_ovno; // Overlay number - boost::dll::detail::WORD_ e_res[4]; // Reserved words - boost::dll::detail::WORD_ e_oemid; // OEM identifier (for e_oeminfo) - boost::dll::detail::WORD_ e_oeminfo; // OEM information; e_oemid specific - boost::dll::detail::WORD_ e_res2[10]; // Reserved words - boost::dll::detail::LONG_ e_lfanew; // File address of new exe header -}; - -struct IMAGE_FILE_HEADER_ { // 32/64 independent header - boost::dll::detail::WORD_ Machine; - boost::dll::detail::WORD_ NumberOfSections; - boost::dll::detail::DWORD_ TimeDateStamp; - boost::dll::detail::DWORD_ PointerToSymbolTable; - boost::dll::detail::DWORD_ NumberOfSymbols; - boost::dll::detail::WORD_ SizeOfOptionalHeader; - boost::dll::detail::WORD_ Characteristics; -}; - -struct IMAGE_DATA_DIRECTORY_ { // 32/64 independent header - boost::dll::detail::DWORD_ VirtualAddress; - boost::dll::detail::DWORD_ Size; -}; - -struct IMAGE_EXPORT_DIRECTORY_ { // 32/64 independent header - boost::dll::detail::DWORD_ Characteristics; - boost::dll::detail::DWORD_ TimeDateStamp; - boost::dll::detail::WORD_ MajorVersion; - boost::dll::detail::WORD_ MinorVersion; - boost::dll::detail::DWORD_ Name; - boost::dll::detail::DWORD_ Base; - boost::dll::detail::DWORD_ NumberOfFunctions; - boost::dll::detail::DWORD_ NumberOfNames; - boost::dll::detail::DWORD_ AddressOfFunctions; - boost::dll::detail::DWORD_ AddressOfNames; - boost::dll::detail::DWORD_ AddressOfNameOrdinals; -}; - -struct IMAGE_SECTION_HEADER_ { // 32/64 independent header - static const std::size_t IMAGE_SIZEOF_SHORT_NAME_ = 8; - - boost::dll::detail::BYTE_ Name[IMAGE_SIZEOF_SHORT_NAME_]; - union { - boost::dll::detail::DWORD_ PhysicalAddress; - boost::dll::detail::DWORD_ VirtualSize; - } Misc; - boost::dll::detail::DWORD_ VirtualAddress; - boost::dll::detail::DWORD_ SizeOfRawData; - boost::dll::detail::DWORD_ PointerToRawData; - boost::dll::detail::DWORD_ PointerToRelocations; - boost::dll::detail::DWORD_ PointerToLinenumbers; - boost::dll::detail::WORD_ NumberOfRelocations; - boost::dll::detail::WORD_ NumberOfLinenumbers; - boost::dll::detail::DWORD_ Characteristics; -}; - - -template <class AddressOffsetT> -struct IMAGE_OPTIONAL_HEADER_template { - static const std::size_t IMAGE_NUMBEROF_DIRECTORY_ENTRIES_ = 16; - - boost::dll::detail::WORD_ Magic; - boost::dll::detail::BYTE_ MajorLinkerVersion; - boost::dll::detail::BYTE_ MinorLinkerVersion; - boost::dll::detail::DWORD_ SizeOfCode; - boost::dll::detail::DWORD_ SizeOfInitializedData; - boost::dll::detail::DWORD_ SizeOfUninitializedData; - boost::dll::detail::DWORD_ AddressOfEntryPoint; - union { - boost::dll::detail::DWORD_ BaseOfCode; - unsigned char padding_[sizeof(AddressOffsetT) == 8 ? 4 : 8]; // in x64 version BaseOfData does not exist - } BaseOfCode_and_BaseOfData; - - AddressOffsetT ImageBase; - boost::dll::detail::DWORD_ SectionAlignment; - boost::dll::detail::DWORD_ FileAlignment; - boost::dll::detail::WORD_ MajorOperatingSystemVersion; - boost::dll::detail::WORD_ MinorOperatingSystemVersion; - boost::dll::detail::WORD_ MajorImageVersion; - boost::dll::detail::WORD_ MinorImageVersion; - boost::dll::detail::WORD_ MajorSubsystemVersion; - boost::dll::detail::WORD_ MinorSubsystemVersion; - boost::dll::detail::DWORD_ Win32VersionValue; - boost::dll::detail::DWORD_ SizeOfImage; - boost::dll::detail::DWORD_ SizeOfHeaders; - boost::dll::detail::DWORD_ CheckSum; - boost::dll::detail::WORD_ Subsystem; - boost::dll::detail::WORD_ DllCharacteristics; - AddressOffsetT SizeOfStackReserve; - AddressOffsetT SizeOfStackCommit; - AddressOffsetT SizeOfHeapReserve; - AddressOffsetT SizeOfHeapCommit; - boost::dll::detail::DWORD_ LoaderFlags; - boost::dll::detail::DWORD_ NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY_ DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES_]; -}; - -typedef IMAGE_OPTIONAL_HEADER_template<boost::dll::detail::DWORD_> IMAGE_OPTIONAL_HEADER32_; -typedef IMAGE_OPTIONAL_HEADER_template<boost::dll::detail::ULONGLONG_> IMAGE_OPTIONAL_HEADER64_; - -template <class AddressOffsetT> -struct IMAGE_NT_HEADERS_template { - boost::dll::detail::DWORD_ Signature; - IMAGE_FILE_HEADER_ FileHeader; - IMAGE_OPTIONAL_HEADER_template<AddressOffsetT> OptionalHeader; -}; - -typedef IMAGE_NT_HEADERS_template<boost::dll::detail::DWORD_> IMAGE_NT_HEADERS32_; -typedef IMAGE_NT_HEADERS_template<boost::dll::detail::ULONGLONG_> IMAGE_NT_HEADERS64_; - - -template <class AddressOffsetT> -class pe_info: public x_info_interface { - boost::filesystem::ifstream& f_; - - typedef IMAGE_NT_HEADERS_template<AddressOffsetT> header_t; - typedef IMAGE_EXPORT_DIRECTORY_ exports_t; - typedef IMAGE_SECTION_HEADER_ section_t; - typedef IMAGE_DOS_HEADER_ dos_t; - - template <class T> - inline void read_raw(T& value, std::size_t size = sizeof(T)) const { - f_.read(reinterpret_cast<char*>(&value), size); - } - -public: - static bool parsing_supported(boost::filesystem::ifstream& f) { - dos_t dos; - f.seekg(0); - f.read(reinterpret_cast<char*>(&dos), sizeof(dos)); - - // 'MZ' and 'ZM' according to Wikipedia - if (dos.e_magic != 0x4D5A && dos.e_magic != 0x5A4D) { - return false; - } - - header_t h; - f.seekg(dos.e_lfanew); - f.read(reinterpret_cast<char*>(&h), sizeof(h)); - - return h.Signature == 0x00004550 // 'PE00' - && h.OptionalHeader.Magic == (sizeof(boost::uint32_t) == sizeof(AddressOffsetT) ? 0x10B : 0x20B); - } - - - explicit pe_info(boost::filesystem::ifstream& f) BOOST_NOEXCEPT - : f_(f) - {} - -private: - inline header_t header() { - header_t h; - - dos_t dos; - f_.seekg(0); - read_raw(dos); - - f_.seekg(dos.e_lfanew); - read_raw(h); - - return h; - } - - inline exports_t exports(const header_t& h) { - exports_t exports; - - static const unsigned int IMAGE_DIRECTORY_ENTRY_EXPORT_ = 0; - const std::size_t exp_virtual_address = h.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT_].VirtualAddress; - - const std::size_t real_offset = get_file_offset(exp_virtual_address, h); - BOOST_ASSERT(real_offset); - - f_.seekg(real_offset); - read_raw(exports); - - return exports; - } - - std::size_t get_file_offset(std::size_t virtual_address, const header_t& h) { - section_t image_section_header; - - { // f_.seekg to the beginning on section headers - dos_t dos; - f_.seekg(0); - read_raw(dos); - f_.seekg(dos.e_lfanew + sizeof(header_t)); - } - - for (std::size_t i = 0;i < h.FileHeader.NumberOfSections;++i) { - read_raw(image_section_header); - if (virtual_address >= image_section_header.VirtualAddress - && virtual_address < image_section_header.VirtualAddress + image_section_header.SizeOfRawData) - { - return image_section_header.PointerToRawData + virtual_address - image_section_header.VirtualAddress; - } - } - - return 0; - } - -public: - std::vector<std::string> sections() { - std::vector<std::string> ret; - - const header_t h = header(); - ret.reserve(h.FileHeader.NumberOfSections); - - // get names, e.g: .text .rdata .data .rsrc .reloc - section_t image_section_header; - char name_helper[section_t::IMAGE_SIZEOF_SHORT_NAME_ + 1]; - std::memset(name_helper, 0, sizeof(name_helper)); - for (std::size_t i = 0;i < h.FileHeader.NumberOfSections;++i) { - // There is no terminating null character if the string is exactly eight characters long - read_raw(image_section_header); - std::memcpy(name_helper, image_section_header.Name, section_t::IMAGE_SIZEOF_SHORT_NAME_); - - if (name_helper[0] != '/') { - ret.push_back(name_helper); - } else { - // For longer names, image_section_header.Name contains a slash (/) followed by ASCII representation of a decimal number. - // this number is an offset into the string table. - // TODO: fixme - ret.push_back(name_helper); - } - } - - return ret; - } - - std::vector<std::string> symbols() { - std::vector<std::string> ret; - - const header_t h = header(); - const exports_t exprt = exports(h); - const std::size_t exported_symbols = exprt.NumberOfNames; - const std::size_t fixed_names_addr = get_file_offset(exprt.AddressOfNames, h); - - ret.reserve(exported_symbols); - boost::dll::detail::DWORD_ name_offset; - std::string symbol_name; - for (std::size_t i = 0;i < exported_symbols;++i) { - f_.seekg(fixed_names_addr + i * sizeof(name_offset)); - read_raw(name_offset); - f_.seekg(get_file_offset(name_offset, h)); - getline(f_, symbol_name, '\0'); - ret.push_back(symbol_name); - } - - return ret; - } - - std::vector<std::string> symbols(const char* section_name) { - std::vector<std::string> ret; - - const header_t h = header(); - - std::size_t section_begin_addr = 0; - std::size_t section_end_addr = 0; - - { // getting address range for the section - section_t image_section_header; - char name_helper[section_t::IMAGE_SIZEOF_SHORT_NAME_ + 1]; - std::memset(name_helper, 0, sizeof(name_helper)); - for (std::size_t i = 0;i < h.FileHeader.NumberOfSections;++i) { - // There is no terminating null character if the string is exactly eight characters long - read_raw(image_section_header); - std::memcpy(name_helper, image_section_header.Name, section_t::IMAGE_SIZEOF_SHORT_NAME_); - if (!std::strcmp(section_name, name_helper)) { - section_begin_addr = image_section_header.PointerToRawData; - section_end_addr = section_begin_addr + image_section_header.SizeOfRawData; - } - } - BOOST_ASSERT(section_begin_addr); - BOOST_ASSERT(section_end_addr); - } - - const exports_t exprt = exports(h); - const std::size_t exported_symbols = exprt.NumberOfFunctions; - const std::size_t fixed_names_addr = get_file_offset(exprt.AddressOfNames, h); - const std::size_t fixed_ordinals_addr = get_file_offset(exprt.AddressOfNameOrdinals, h); - const std::size_t fixed_functions_addr = get_file_offset(exprt.AddressOfFunctions, h); - - ret.reserve(exported_symbols); - boost::dll::detail::DWORD_ ptr; - boost::dll::detail::WORD_ ordinal; - std::string symbol_name; - for (std::size_t i = 0;i < exported_symbols;++i) { - // getting ordinal - f_.seekg(fixed_ordinals_addr + i * sizeof(ordinal)); - read_raw(ordinal); - - // getting function addr - f_.seekg(fixed_functions_addr + ordinal * sizeof(ptr)); - read_raw(ptr); - ptr = static_cast<boost::dll::detail::DWORD_>( get_file_offset(ptr, h) ); - - if (ptr >= section_end_addr || ptr < section_begin_addr) { - continue; - } - - f_.seekg(fixed_names_addr + i * sizeof(ptr)); - read_raw(ptr); - f_.seekg(get_file_offset(ptr, h)); - getline(f_, symbol_name, '\0'); - ret.push_back(symbol_name); - } - - return ret; - } - - // a test method to get dependents modules, - // who my plugin imports (1st level only) - /* - e.g. for myself I get: - KERNEL32.dll - MSVCP110D.dll - boost_system-vc-mt-gd-1_56.dll - MSVCR110D.dll - */ - /* - std::vector<std::string> depend_of(boost::system::error_code &ec) BOOST_NOEXCEPT { - std::vector<std::string> ret; - - IMAGE_DOS_HEADER* image_dos_header = (IMAGE_DOS_HEADER*)native(); - if(!image_dos_header) { - // ERROR_BAD_EXE_FORMAT - ec = boost::system::error_code( - boost::system::errc::executable_format_error, - boost::system::generic_category() - ); - - return ret; - } - - IMAGE_OPTIONAL_HEADER* image_optional_header = (IMAGE_OPTIONAL_HEADER*)((boost::dll::detail::BYTE_*)native() + image_dos_header->e_lfanew + 24); - if(!image_optional_header) { - // ERROR_BAD_EXE_FORMAT - ec = boost::system::error_code( - boost::system::errc::executable_format_error, - boost::system::generic_category() - ); - - return ret; - } - - IMAGE_IMPORT_DESCRIPTOR* image_import_descriptor = (IMAGE_IMPORT_DESCRIPTOR*)((boost::dll::detail::BYTE_*)native() + image_optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); - if(!image_import_descriptor) { - // ERROR_BAD_EXE_FORMAT - ec = boost::system::error_code( - boost::system::errc::executable_format_error, - boost::system::generic_category() - ); - - return ret; - } - - while(image_import_descriptor->FirstThunk) { - std::string module_name = reinterpret_cast<char*>((boost::dll::detail::BYTE_*)native() + image_import_descriptor->Name); - - if(module_name.size()) { - ret.push_back(module_name); - } - - image_import_descriptor++; - } - - return ret; - } -*/ -}; - -typedef pe_info<boost::dll::detail::DWORD_> pe_info32; -typedef pe_info<boost::dll::detail::ULONGLONG_> pe_info64; - -}}} // namespace boost::dll::detail - -#endif // BOOST_DLL_DETAIL_WINDOWS_PE_INFO_HPP diff --git a/include/boost/dll/detail/posix/path_from_handle.hpp b/include/boost/dll/detail/posix/path_from_handle.hpp deleted file mode 100644 index aeebc249..00000000 --- a/include/boost/dll/detail/posix/path_from_handle.hpp +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2014-2015 Renato Tegon Forti, Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_DETAIL_POSIX_PATH_FROM_HANDLE_HPP -#define BOOST_DLL_DETAIL_POSIX_PATH_FROM_HANDLE_HPP - -#include <boost/config.hpp> -#include <boost/dll/detail/system_error.hpp> -#include <boost/dll/detail/posix/program_location_impl.hpp> -#include <boost/filesystem/path.hpp> -#include <boost/predef/os.h> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -// for dlinfo -#include <dlfcn.h> - -#if BOOST_OS_MACOS || BOOST_OS_IOS -# include <mach-o/dyld.h> -# include <mach-o/nlist.h> -# include <cstddef> // for std::ptrdiff_t - -namespace boost { namespace dll { namespace detail { - inline void* strip_handle(void* handle) BOOST_NOEXCEPT { - return reinterpret_cast<void*>( - (reinterpret_cast<std::ptrdiff_t>(handle) >> 2) << 2 - ); - } - - inline boost::filesystem::path path_from_handle(void* handle, boost::system::error_code &ec) { - handle = strip_handle(handle); - - // Iterate through all images currently in memory - // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/dyld.3.html - const std::size_t count = _dyld_image_count(); // not thread safe: other thread my [un]load images - for (std::size_t i = 0; i <= count; ++i) { - // on last iteration `i` is equal to `count` which is out of range, so `_dyld_get_image_name` - // will return NULL. `dlopen(NULL, RTLD_LAZY)` call will open the current executable. - const char* image_name = _dyld_get_image_name(i); - void* probe_handle = dlopen(image_name, RTLD_LAZY); - dlclose(probe_handle); - - // If the handle is the same as what was passed in (modulo mode bits), return this image name - if (handle == strip_handle(probe_handle)) { - return image_name; - } - } - - ec = boost::system::error_code( - boost::system::errc::bad_file_descriptor, - boost::system::generic_category() - ); - - return boost::filesystem::path(); - } - -}}} // namespace boost::dll::detail - -#else // #if BOOST_OS_MACOS || BOOST_OS_IOS - -#if BOOST_OS_QNX -// QNX's copy of <elf.h> and <link.h> reside in sys folder -# include <sys/link.h> -#else -# include <link.h> // struct link_map -#endif - -namespace boost { namespace dll { namespace detail { - -#if BOOST_OS_ANDROID || BOOST_OS_QNX - // Android and QNX miss struct link_map. QNX misses ElfW macro, so avoiding it. - struct link_map { - void *l_addr; // Base address shared object is loaded at - char *l_name; // Absolute file name object was found in - // ... // Ignoring remaning parts of the structure - }; -#endif // #if BOOST_OS_ANDROID - - inline boost::filesystem::path path_from_handle(void* handle, boost::system::error_code &ec) { - // RTLD_DI_LINKMAP (RTLD_DI_ORIGIN returns only folder and is not suitable for this case) - // Obtain the Link_map for the handle that is specified. - // The p argument points to a Link_map pointer (Link_map - // **p). The actual storage for the Link_map structure is - // maintained by ld.so.1. - // - // Unfortunately we can not use `dlinfo(handle, RTLD_DI_LINKMAP, &link_map) < 0` - // because it is not supported on MacOS X 10.3, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, - // HP-UX 11, IRIX 6.5, OSF/1 5.1, Cygwin, mingw, Interix 3.5, BeOS. - // Fortunately investigating the sources of open source projects brought the understanding, that - // `handle` is just a `struct link_map*` that contains full library name. - - const struct link_map* link_map = 0; -#if BOOST_OS_BSD_FREE - // FreeBSD has it's own logic http://code.metager.de/source/xref/freebsd/libexec/rtld-elf/rtld.c - // Fortunately it has the dlinfo call. - if (dlinfo(handle, RTLD_DI_LINKMAP, &link_map) < 0) { - link_map = 0; - } -#else - link_map = static_cast<const struct link_map*>(handle); -#endif - if (!link_map) { - ec = boost::system::error_code( - boost::system::errc::bad_file_descriptor, - boost::system::generic_category() - ); - - return boost::filesystem::path(); - } - - if (!link_map->l_name || *link_map->l_name == '\0') { - return program_location_impl(ec); - } - - return boost::filesystem::path(link_map->l_name); - } - -}}} // namespace boost::dll::detail - -#endif // #if BOOST_OS_MACOS || BOOST_OS_IOS - -#endif // BOOST_DLL_DETAIL_POSIX_PATH_FROM_HANDLE_HPP - - diff --git a/include/boost/dll/detail/posix/program_location_impl.hpp b/include/boost/dll/detail/posix/program_location_impl.hpp deleted file mode 100644 index f27641f8..00000000 --- a/include/boost/dll/detail/posix/program_location_impl.hpp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_DETAIL_POSIX_PROGRAM_LOCATION_IMPL_HPP -#define BOOST_DLL_DETAIL_POSIX_PROGRAM_LOCATION_IMPL_HPP - -#include <boost/config.hpp> -#include <boost/dll/detail/system_error.hpp> -#include <boost/filesystem/path.hpp> -#include <boost/predef/os.h> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -#if BOOST_OS_MACOS || BOOST_OS_IOS - -#include <mach-o/dyld.h> - -namespace boost { namespace dll { namespace detail { - inline boost::filesystem::path program_location_impl(boost::system::error_code &ec) { - char path[1024]; - uint32_t size = sizeof(path); - if (_NSGetExecutablePath(path, &size) == 0) - return boost::filesystem::path(path); - - char *p = new char[size]; - if (_NSGetExecutablePath(p, &size) != 0) { - ec = boost::system::error_code( - boost::system::errc::bad_file_descriptor, // TODO: better error report - boost::system::generic_category() - ); - } - - boost::filesystem::path ret(p); - delete[] p; - return ret; - } -}}} // namespace boost::dll::detail - -#elif BOOST_OS_SOLARIS - -#include <stdlib.h> -namespace boost { namespace dll { namespace detail { - inline boost::filesystem::path program_location_impl(boost::system::error_code& ec) { - ec.clear(); - return boost::filesystem::path(getexecname()); - } -}}} // namespace boost::dll::detail - -#elif BOOST_OS_BSD_FREE - -#include <sys/types.h> -#include <sys/sysctl.h> -#include <stdlib.h> - -namespace boost { namespace dll { namespace detail { - inline boost::filesystem::path program_location_impl(boost::system::error_code& ec) { - int mib[4]; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = -1; - char buf[10240]; - size_t cb = sizeof(buf); - sysctl(mib, 4, buf, &cb, NULL, 0); - - ec.clear(); - return boost::filesystem::path(buf); - } -}}} // namespace boost::dll::detail - - - -#elif BOOST_OS_BSD_NET - -#include <boost/filesystem/operations.hpp> -namespace boost { namespace dll { namespace detail { - inline boost::filesystem::path program_location_impl(boost::system::error_code &ec) { - return boost::filesystem::read_symlink("/proc/curproc/exe", ec); - } -}}} // namespace boost::dll::detail - -#elif BOOST_OS_BSD_DRAGONFLY - -#include <boost/filesystem/operations.hpp> -namespace boost { namespace dll { namespace detail { - inline boost::filesystem::path program_location_impl(boost::system::error_code &ec) { - return boost::filesystem::read_symlink("/proc/curproc/file", ec); - } -}}} // namespace boost::dll::detail - -#else // BOOST_OS_LINUX || BOOST_OS_UNIX || BOOST_OS_QNX || BOOST_OS_HPUX || BOOST_OS_ANDROID - -#include <boost/filesystem/operations.hpp> -namespace boost { namespace dll { namespace detail { - inline boost::filesystem::path program_location_impl(boost::system::error_code &ec) { - // We can not use - // boost::dll::detail::path_from_handle(dlopen(NULL, RTLD_LAZY | RTLD_LOCAL), ignore); - // because such code returns empty path. - - return boost::filesystem::read_symlink("/proc/self/exe", ec); // Linux specific - } -}}} // namespace boost::dll::detail - -#endif - -#endif // BOOST_DLL_DETAIL_POSIX_PROGRAM_LOCATION_IMPL_HPP - diff --git a/include/boost/dll/detail/posix/shared_library_impl.hpp b/include/boost/dll/detail/posix/shared_library_impl.hpp deleted file mode 100644 index 8df0ca5c..00000000 --- a/include/boost/dll/detail/posix/shared_library_impl.hpp +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_SHARED_LIBRARY_IMPL_HPP -#define BOOST_DLL_SHARED_LIBRARY_IMPL_HPP - -#include <boost/config.hpp> -#include <boost/dll/shared_library_load_mode.hpp> -#include <boost/dll/detail/posix/path_from_handle.hpp> -#include <boost/dll/detail/posix/program_location_impl.hpp> - -//#include <boost/move/utility.hpp> -#include <boost/swap.hpp> -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/operations.hpp> -#include <boost/predef/os.h> - -#include <dlfcn.h> -#include <cstring> // strncmp -#if !BOOST_OS_MACOS && !BOOST_OS_IOS && !BOOST_OS_QNX -# include <link.h> -#elif BOOST_OS_QNX -// QNX's copy of <elf.h> and <link.h> reside in sys folder -# include <sys/link.h> -#endif - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -namespace boost { namespace dll { namespace detail { - -class shared_library_impl { - - BOOST_MOVABLE_BUT_NOT_COPYABLE(shared_library_impl) - -public: - typedef void* native_handle_t; - - shared_library_impl() BOOST_NOEXCEPT - : handle_(NULL) - {} - - ~shared_library_impl() BOOST_NOEXCEPT { - unload(); - } - - shared_library_impl(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT - : handle_(sl.handle_) - { - sl.handle_ = NULL; - } - - shared_library_impl & operator=(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT { - handle_ = sl.handle_; - sl.handle_ = NULL; - return *this; - } - - void load(const boost::filesystem::path &sl, load_mode::type mode, boost::system::error_code &ec) { - typedef int native_mode_t; - unload(); - - // Do not allow opening NULL paths. User must use program_location() instead - if (sl.empty()) { - ec = boost::system::error_code( - boost::system::errc::bad_file_descriptor, - boost::system::generic_category() - ); - - return; - } - - // Fixing modes - if (!(mode & load_mode::rtld_now)) { - mode |= load_mode::rtld_lazy; - } - - if (!(mode & load_mode::rtld_global)) { - mode |= load_mode::rtld_local; - } - - // Trying to open with appended decorations - if (!!(mode & load_mode::append_decorations)) { - mode = static_cast<load_mode::type>( - static_cast<native_mode_t>(mode) & (~static_cast<native_mode_t>(load_mode::append_decorations)) - ); - - boost::filesystem::path actual_path = ( - std::strncmp(sl.filename().string().c_str(), "lib", 3) - ? (sl.parent_path() / "lib").native() + sl.filename().native() - : sl - ); - actual_path += suffix(); - - handle_ = dlopen(actual_path.c_str(), static_cast<native_mode_t>(mode)); - if (handle_) { - return; - } - } - - // Opening by exactly specified path - handle_ = dlopen(sl.c_str(), static_cast<native_mode_t>(mode)); - if (handle_) { - return; - } - - ec = boost::system::error_code( - boost::system::errc::bad_file_descriptor, - boost::system::generic_category() - ); - - // Maybe user wanted to load the executable itself? Checking... - // We assume that usually user wants to load a dynamic library not the executable itself, that's why - // we try this only after traditional load fails. - boost::system::error_code prog_loc_err; - boost::filesystem::path loc = boost::dll::detail::program_location_impl(prog_loc_err); - if (!prog_loc_err && boost::filesystem::equivalent(sl, loc, prog_loc_err) && !prog_loc_err) { - // As is known the function dlopen() loads the dynamic library file - // named by the null-terminated string filename and returns an opaque - // "handle" for the dynamic library. If filename is NULL, then the - // returned handle is for the main program. - ec.clear(); - handle_ = dlopen(NULL, static_cast<native_mode_t>(mode)); - if (!handle_) { - ec = boost::system::error_code( - boost::system::errc::bad_file_descriptor, - boost::system::generic_category() - ); - } - } - } - - bool is_loaded() const BOOST_NOEXCEPT { - return (handle_ != 0); - } - - void unload() BOOST_NOEXCEPT { - if (!is_loaded()) { - return; - } - - dlclose(handle_); - handle_ = 0; - } - - void swap(shared_library_impl& rhs) BOOST_NOEXCEPT { - boost::swap(handle_, rhs.handle_); - } - - boost::filesystem::path full_module_path(boost::system::error_code &ec) const { - return boost::dll::detail::path_from_handle(handle_, ec); - } - - static boost::filesystem::path suffix() { - // https://sourceforge.net/p/predef/wiki/OperatingSystems/ -#if BOOST_OS_MACOS || BOOST_OS_IOS - return ".dylib"; -#else - return ".so"; -#endif - } - - void* symbol_addr(const char* sb, boost::system::error_code &ec) const BOOST_NOEXCEPT { - // dlsym - obtain the address of a symbol from a dlopen object - void* const symbol = dlsym(handle_, sb); - if (symbol == NULL) { - ec = boost::system::error_code( - boost::system::errc::invalid_seek, - boost::system::generic_category() - ); - } - - // If handle does not refer to a valid object opened by dlopen(), - // or if the named symbol cannot be found within any of the objects - // associated with handle, dlsym() shall return NULL. - // More detailed diagnostic information shall be available through dlerror(). - - return symbol; - } - - native_handle_t native() const BOOST_NOEXCEPT { - return handle_; - } - -private: - native_handle_t handle_; -}; - -}}} // boost::dll::detail - -#endif // BOOST_DLL_SHARED_LIBRARY_IMPL_HPP - diff --git a/include/boost/dll/detail/strip_calling_convention.hpp b/include/boost/dll/detail/strip_calling_convention.hpp deleted file mode 100644 index 70c642eb..00000000 --- a/include/boost/dll/detail/strip_calling_convention.hpp +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_DETAIL_STRIP_CALLING_CONVENTION_HPP -#define BOOST_DLL_DETAIL_STRIP_CALLING_CONVENTION_HPP - -#include <boost/config.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -namespace boost { namespace dll { namespace detail { - -template <class T> -struct strip_calling_convention { - typedef T type; -}; - -#ifdef _MSC_VER - -// stripping __fastcall - -template <class Ret, class Arg1> -struct strip_calling_convention<Ret __fastcall (Arg1)> { - typedef Ret(type)(Arg1); -}; - -template <class Ret, class Arg1, class Arg2> -struct strip_calling_convention<Ret __fastcall (Arg1, Arg2)> { - typedef Ret(type)(Arg1, Arg2); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3> -struct strip_calling_convention<Ret __fastcall (Arg1, Arg2, Arg3)> { - typedef Ret(type)(Arg1, Arg2, Arg3); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4> -struct strip_calling_convention<Ret __fastcall (Arg1, Arg2, Arg3, Arg4)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -struct strip_calling_convention<Ret __fastcall (Arg1, Arg2, Arg3, Arg4, Arg5)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4, Arg5); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6> -struct strip_calling_convention<Ret __fastcall (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7> -struct strip_calling_convention<Ret __fastcall (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8> -struct strip_calling_convention<Ret __fastcall (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9> -struct strip_calling_convention<Ret __fastcall (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); -}; - -// stripping __stdall -template <class Ret, class Arg1> -struct strip_calling_convention<Ret __stdcall (Arg1)> { - typedef Ret(type)(Arg1); -}; - -template <class Ret, class Arg1, class Arg2> -struct strip_calling_convention<Ret __stdcall (Arg1, Arg2)> { - typedef Ret(type)(Arg1, Arg2); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3> -struct strip_calling_convention<Ret __stdcall (Arg1, Arg2, Arg3)> { - typedef Ret(type)(Arg1, Arg2, Arg3); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4> -struct strip_calling_convention<Ret __stdcall (Arg1, Arg2, Arg3, Arg4)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -struct strip_calling_convention<Ret __stdcall (Arg1, Arg2, Arg3, Arg4, Arg5)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4, Arg5); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6> -struct strip_calling_convention<Ret __stdcall (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7> -struct strip_calling_convention<Ret __stdcall (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8> -struct strip_calling_convention<Ret __stdcall (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); -}; - -template <class Ret, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9> -struct strip_calling_convention<Ret __stdcall (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)> { - typedef Ret(type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); -}; - -#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES - -// Some of the MSVC versions have issues in variadic templates implementation. -// So we leave previous specializations visible even if variadic templates are allowed - -template <class Ret, class... Args> -struct strip_calling_convention<Ret __fastcall (Args...)> { - typedef Ret(type)(Args...); -}; - -template <class Ret, class... Args> -struct strip_calling_convention<Ret __stdcall (Args...)> { - typedef Ret(type)(Args...); -}; -#endif // #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES - -#endif // #ifdef _MSC_VER - - -}}} // namespace boost::dll::detail - - -#endif // #ifndef BOOST_DLL_DETAIL_STRIP_CALLING_CONVENTION_HPP diff --git a/include/boost/dll/detail/system_error.hpp b/include/boost/dll/detail/system_error.hpp deleted file mode 100644 index 1f4cabf8..00000000 --- a/include/boost/dll/detail/system_error.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_SYSTEM_ERROR_HPP -#define BOOST_DLL_SYSTEM_ERROR_HPP - -#include <boost/config.hpp> -#include <boost/predef/os.h> -#include <boost/system/error_code.hpp> -#include <boost/system/system_error.hpp> -#include <boost/throw_exception.hpp> - -#if !BOOST_OS_WINDOWS -# include <dlfcn.h> -#endif - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -namespace boost { namespace dll { namespace detail { - - inline void report_error(const boost::system::error_code& ec, const char* message) { -#if !BOOST_OS_WINDOWS - const char* const error_txt = dlerror(); - if (error_txt) { - boost::throw_exception( - boost::system::system_error( - ec, - message + std::string(" (dlerror system message: ") + error_txt + std::string(")") - ) - ); - } -#endif - - boost::throw_exception( - boost::system::system_error( - ec, message - ) - ); - } - -}}} // boost::dll::detail - -#endif // BOOST_DLL_SYSTEM_ERROR_HPP - diff --git a/include/boost/dll/detail/windows/path_from_handle.hpp b/include/boost/dll/detail/windows/path_from_handle.hpp deleted file mode 100644 index 0372b756..00000000 --- a/include/boost/dll/detail/windows/path_from_handle.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_DETAIL_WINDOWS_PATH_FROM_HANDLE_HPP -#define BOOST_DLL_DETAIL_WINDOWS_PATH_FROM_HANDLE_HPP - -#include <boost/config.hpp> -#include <boost/dll/detail/system_error.hpp> -#include <boost/detail/winapi/dll.hpp> -#include <boost/detail/winapi/GetLastError.hpp> -#include <boost/filesystem/path.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -namespace boost { namespace dll { namespace detail { - - - static inline boost::system::error_code last_error_code() BOOST_NOEXCEPT { - return boost::system::error_code( - boost::detail::winapi::GetLastError(), - boost::system::system_category() - ); - } - - inline boost::filesystem::path path_from_handle(boost::detail::winapi::HMODULE_ handle, boost::system::error_code &ec) { - boost::filesystem::path ret; - - BOOST_STATIC_CONSTANT(boost::detail::winapi::DWORD_, ERROR_INSUFFICIENT_BUFFER_ = 0x7A); - BOOST_STATIC_CONSTANT(boost::detail::winapi::DWORD_, DEFAULT_PATH_SIZE_ = 260); - - // A handle to the loaded module whose path is being requested. - // If this parameter is NULL, GetModuleFileName retrieves the path of the - // executable file of the current process. - boost::detail::winapi::WCHAR_ path_hldr[DEFAULT_PATH_SIZE_]; - boost::detail::winapi::LPWSTR_ path = path_hldr; - boost::detail::winapi::GetModuleFileNameW(handle, path, DEFAULT_PATH_SIZE_); - ec = last_error_code(); - - // In case of ERROR_INSUFFICIENT_BUFFER_ trying to get buffer big enough to store the whole path - for (unsigned i = 2; i < 1025 && ec.value() == ERROR_INSUFFICIENT_BUFFER_; i *= 2) { - path = new boost::detail::winapi::WCHAR_[DEFAULT_PATH_SIZE_ * i]; - - boost::detail::winapi::GetModuleFileNameW(handle, path, DEFAULT_PATH_SIZE_ * i); - ec = last_error_code(); - - if (ec) { - delete[] path; - } - } - - if (ec) { - // Error other than ERROR_INSUFFICIENT_BUFFER_ occurred or failed to allocate buffer big enough - return boost::filesystem::path(); - } - - ret = path; - if (path != path_hldr) { - delete[] path; - } - - return ret; - } - -}}} // namespace boost::dll::detail - -#endif // BOOST_DLL_DETAIL_WINDOWS_PATH_FROM_HANDLE_HPP - diff --git a/include/boost/dll/detail/windows/shared_library_impl.hpp b/include/boost/dll/detail/windows/shared_library_impl.hpp deleted file mode 100644 index d25d3364..00000000 --- a/include/boost/dll/detail/windows/shared_library_impl.hpp +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_SHARED_LIBRARY_IMPL_HPP -#define BOOST_DLL_SHARED_LIBRARY_IMPL_HPP - -#include <boost/config.hpp> -#include <boost/dll/shared_library_load_mode.hpp> -#include <boost/dll/detail/aggressive_ptr_cast.hpp> -#include <boost/dll/detail/system_error.hpp> -#include <boost/dll/detail/windows/path_from_handle.hpp> - -//#include <boost/move/utility.hpp> -#include <boost/swap.hpp> -#include <boost/filesystem/path.hpp> - -#include <boost/detail/winapi/dll.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -namespace boost { namespace dll { namespace detail { - -class shared_library_impl { - BOOST_MOVABLE_BUT_NOT_COPYABLE(shared_library_impl) - -public: - typedef boost::detail::winapi::HMODULE_ native_handle_t; - - shared_library_impl() BOOST_NOEXCEPT - : handle_(NULL) - {} - - ~shared_library_impl() BOOST_NOEXCEPT { - unload(); - } - - shared_library_impl(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT - : handle_(sl.handle_) - { - sl.handle_ = NULL; - } - - shared_library_impl & operator=(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT { - handle_ = sl.handle_; - sl.handle_ = NULL; - return *this; - } - - void load(const boost::filesystem::path &sl, load_mode::type mode, boost::system::error_code &ec) { - typedef boost::detail::winapi::DWORD_ native_mode_t; - unload(); - - // Trying to open with appended decorations - if (!!(mode & load_mode::append_decorations)) { - mode = static_cast<load_mode::type>( - static_cast<native_mode_t>(mode) & (~static_cast<native_mode_t>(load_mode::append_decorations)) - ); - - handle_ = boost::detail::winapi::LoadLibraryExW((sl.native() + L".dll").c_str(), 0, static_cast<native_mode_t>(mode)); - if (!handle_) { - // MinGW loves 'lib' prefix and puts it even on Windows platform - handle_ = boost::detail::winapi::LoadLibraryExW( - ((sl.parent_path() / L"lib").native() + sl.filename().native() + L".dll").c_str(), - 0, - static_cast<native_mode_t>(mode) - ); - } - - if (handle_) { - return; - } - } - - // From MSDN: If the string specifies a module name without a path and the - // file name extension is omitted, the function appends the default library - // extension .dll to the module name. - // - // From experiments: Default library extension appended to the module name even if - // we have some path. So we do not check for path, only for extension. We can not be sure that - // such behavior remain across all platforms, so we add L"." by hand. - if (sl.has_extension()) { - handle_ = boost::detail::winapi::LoadLibraryExW(sl.c_str(), 0, static_cast<native_mode_t>(mode)); - } else { - handle_ = boost::detail::winapi::LoadLibraryExW((sl.native() + L".").c_str(), 0, static_cast<native_mode_t>(mode)); - } - - // LoadLibraryExW method is capable of self loading from program_location() path. No special actions - // must be taken to allow self loading. - - if (!handle_) { - ec = boost::dll::detail::last_error_code(); - } - } - - bool is_loaded() const BOOST_NOEXCEPT { - return (handle_ != 0); - } - - void unload() BOOST_NOEXCEPT { - if (handle_) { - boost::detail::winapi::FreeLibrary(handle_); - handle_ = 0; - } - } - - void swap(shared_library_impl& rhs) BOOST_NOEXCEPT { - boost::swap(handle_, rhs.handle_); - } - - boost::filesystem::path full_module_path(boost::system::error_code &ec) const { - return boost::dll::detail::path_from_handle(handle_, ec); - } - - static boost::filesystem::path suffix() { - return L".dll"; - } - - void* symbol_addr(const char* sb, boost::system::error_code &ec) const BOOST_NOEXCEPT { - if (is_resource()) { - // `GetProcAddress` could not be called for libraries loaded with - // `LOAD_LIBRARY_AS_DATAFILE`, `LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE` - // or `LOAD_LIBRARY_AS_IMAGE_RESOURCE`. - ec = boost::system::error_code( - boost::system::errc::operation_not_supported, - boost::system::generic_category() - ); - - return NULL; - } - - // Judging by the documentation of GetProcAddress - // there is no version for UNICODE, because - // names of functions are stored in narrow characters. - void* const symbol = boost::dll::detail::aggressive_ptr_cast<void*>( - boost::detail::winapi::GetProcAddress(handle_, sb) - ); - if (symbol == NULL) { - ec = boost::dll::detail::last_error_code(); - } - - return symbol; - } - - native_handle_t native() const BOOST_NOEXCEPT { - return handle_; - } - -private: - bool is_resource() const BOOST_NOEXCEPT { - return false; /*!!( - reinterpret_cast<boost::detail::winapi::ULONG_PTR_>(handle_) & static_cast<boost::detail::winapi::ULONG_PTR_>(3) - );*/ - } - - native_handle_t handle_; -}; - -}}} // boost::dll::detail - -#endif // BOOST_DLL_SHARED_LIBRARY_IMPL_HPP - diff --git a/include/boost/dll/detail/x_info_interface.hpp b/include/boost/dll/detail/x_info_interface.hpp deleted file mode 100644 index e53214e1..00000000 --- a/include/boost/dll/detail/x_info_interface.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_DETAIL_X_INFO_INTERFACE_HPP -#define BOOST_DLL_DETAIL_X_INFO_INTERFACE_HPP - -#include <boost/config.hpp> -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -#include <string> -#include <vector> - -namespace boost { namespace dll { namespace detail { - -class x_info_interface { -public: - virtual std::vector<std::string> sections() = 0; - virtual std::vector<std::string> symbols() = 0; - virtual std::vector<std::string> symbols(const char* section_name) = 0; - - virtual ~x_info_interface() BOOST_NOEXCEPT {} -}; - -}}} // namespace boost::dll::detail - -#endif // BOOST_DLL_DETAIL_X_INFO_INTERFACE_HPP diff --git a/include/boost/dll/import.hpp b/include/boost/dll/import.hpp deleted file mode 100644 index f65d353a..00000000 --- a/include/boost/dll/import.hpp +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_IMPORT_HPP -#define BOOST_DLL_IMPORT_HPP - -#include <boost/config.hpp> -#include <boost/utility/enable_if.hpp> -#include <boost/type_traits/is_object.hpp> -#include <boost/function.hpp> -#include <boost/make_shared.hpp> -#include <boost/dll/shared_library.hpp> -#include <boost/dll/detail/strip_calling_convention.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -/// \file boost/dll/import.hpp -/// \brief Contains all the boost::dll::import* reference counting -/// functions that hold a shared pointer to the instance of -/// boost::dll::shared_library. - -namespace boost { namespace dll { - -namespace detail { - template <class T> - class refc_function { - SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<shared_library> lib_; - T* func_ptr_; - - public: - refc_function(const SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<shared_library>& lib, T* func_ptr) BOOST_NOEXCEPT - : lib_(lib) - , func_ptr_(func_ptr) - {} - - operator T*() const BOOST_NOEXCEPT { - return func_ptr_; - } - }; - - template <class T, class = void> - struct import_type; - - template <class T> - struct import_type<T, typename boost::disable_if<boost::is_object<T> >::type> { - typedef boost::dll::detail::refc_function<T> base_type; - typedef boost::function< - typename boost::dll::detail::strip_calling_convention<T>::type - > type; - }; - - template <class T> - struct import_type<T, typename boost::enable_if<boost::is_object<T> >::type> { - typedef SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<T> base_type; - typedef SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<T> type; - }; -} // namespace detail - - -#ifndef BOOST_DLL_DOXYGEN -# define BOOST_DLL_IMPORT_RESULT_TYPE inline typename boost::dll::detail::import_type<T>::type -#endif - - -/*! -* Returns boost::function<T> or SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<T> that holds an imported function or variable -* from the loaded library and refcounts usage -* of the loaded shared library, so that it won't get unload until all copies of return value -* are not destroyed. -* -* This call will succeed if call to \forcedlink{shared_library}`::has(const char* )` -* function with the same symbol name returned `true`. -* -* For importing symbols by \b alias names use \forcedlink{import_alias} method. -* -* \b Examples: -* \code -* boost::function<int(int)> f = import<int(int)>( -* SWIFTEN_SHRPTR_NAMESPACE::make_shared<shared_library>("test_lib.so"), -* "integer_func_name" -* ); -* \endcode -* -* \code -* boost::function<int(int)> f = import<int(int)>("test_lib.so", "integer_func_name"); -* \endcode -* -* \code -* SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<int> i = import<int>("test_lib.so", "integer_name"); -* \endcode -* -* \b Template \b parameter \b T: Type of the symbol that we are going to import. Must be explicitly specified. -* -* \param lib Path or shared pointer to library to load function from. -* \param name Null-terminated C or C++ mangled name of the function to import. Can handle std::string, char*, const char*. -* \param mode An mode that will be used on library load. -* -* \return boost::function<T> if T is a function type, or SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<T> if T is an object type. -* -* \throw boost::system::system_error if symbol does not exist or if the DLL/DSO was not loaded. -* Overload that accepts path also throws std::bad_alloc in case of insufficient memory. -*/ -template <class T> -BOOST_DLL_IMPORT_RESULT_TYPE import(const boost::filesystem::path& lib, const char* name, - load_mode::type mode = load_mode::default_mode); - -//! \overload boost::dll::import(const boost::filesystem::path& lib, const char* name, load_mode::type mode) -template <class T> -BOOST_DLL_IMPORT_RESULT_TYPE import(const boost::filesystem::path& lib, const std::string& name, - load_mode::type mode = load_mode::default_mode) -{ - return boost::dll::import<T>( - SWIFTEN_SHRPTR_NAMESPACE::make_shared<boost::dll::shared_library>(lib, mode), - name.c_str() - ); -} - -//! \overload boost::dll::import(const boost::filesystem::path& lib, const char* name, load_mode::type mode) -template <class T> -BOOST_DLL_IMPORT_RESULT_TYPE import(const SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<shared_library>& lib, const char* name) { - typedef typename boost::dll::detail::import_type<T>::base_type type; - return type(lib, &lib->get<T>(name)); -} - -//! \overload boost::dll::import(const boost::filesystem::path& lib, const char* name, load_mode::type mode) -template <class T> -BOOST_DLL_IMPORT_RESULT_TYPE import(const SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<shared_library>& lib, const std::string& name) { - return boost::dll::import<T>(lib, name.c_str()); -} - -template <class T> -BOOST_DLL_IMPORT_RESULT_TYPE import(const boost::filesystem::path& lib, const char* name, load_mode::type mode) { - return boost::dll::import<T>( - SWIFTEN_SHRPTR_NAMESPACE::make_shared<boost::dll::shared_library>(lib, mode), - name - ); -} - - - - -/*! -* Returns boost::function<T> or SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<T> that holds an imported function or variable -* from the loaded library and refcounts usage -* of the loaded shared library, so that it won't get unload until all copies of return value -* are not destroyed. -* -* This call will succeed if call to \forcedlink{shared_library}`::has(const char* )` -* function with the same symbol name returned `true`. -* -* For importing symbols by \b non \b alias names use \forcedlink{import} method. -* -* \b Examples: -* \code -* boost::function<int(int)> f = import_alias<int(int)>( -* SWIFTEN_SHRPTR_NAMESPACE::make_shared<shared_library>("test_lib.so"), -* "integer_func_alias_name" -* ); -* \endcode -* -* \code -* boost::function<int(int)> f = import_alias<int(int)>("test_lib.so", "integer_func_alias_name"); -* \endcode -* -* \code -* SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<int> i = import_alias<int>("test_lib.so", "integer_alias_name"); -* \endcode -* -* \b Template \b parameter \b T: Type of the symbol alias that we are going to import. Must be explicitly specified. -* -* \param lib Path or shared pointer to library to load function from. -* \param name Null-terminated C or C++ mangled name of the function or variable to import. Can handle std::string, char*, const char*. -* \param mode An mode that will be used on library load. -* -* \return boost::function<T> if T is a function type, or SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<T> if T is an object type. -* -* \throw boost::system::system_error if symbol does not exist or if the DLL/DSO was not loaded. -* Overload that accepts path also throws std::bad_alloc in case of insufficient memory. -*/ -template <class T> -BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const boost::filesystem::path& lib, const char* name, - load_mode::type mode = load_mode::default_mode); - -//! \overload boost::dll::import_alias(const boost::filesystem::path& lib, const char* name, load_mode::type mode) -template <class T> -BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const boost::filesystem::path& lib, const std::string& name, - load_mode::type mode = load_mode::default_mode) -{ - return boost::dll::import_alias<T>( - SWIFTEN_SHRPTR_NAMESPACE::make_shared<boost::dll::shared_library>(lib, mode), - name.c_str() - ); -} - -//! \overload boost::dll::import_alias(const boost::filesystem::path& lib, const char* name, load_mode::type mode) -template <class T> -BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<shared_library>& lib, const std::string& name) { - return boost::dll::import_alias<T>(lib, name.c_str()); -} - -//! \overload boost::dll::import_alias(const boost::filesystem::path& lib, const char* name, load_mode::type mode) -template <class T> -BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<shared_library>& lib, const char* name) { - typedef typename boost::dll::detail::import_type<T>::base_type type; - return type(lib, lib->get<T*>(name)); -} - -template <class T> -BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const boost::filesystem::path& lib, const char* name, load_mode::type mode) { - return boost::dll::import_alias<T>( - SWIFTEN_SHRPTR_NAMESPACE::make_shared<boost::dll::shared_library>(lib, mode), - name - ); -} -#undef BOOST_DLL_IMPORT_RESULT_TYPE - - -}} // boost::dll - -#endif // BOOST_DLL_IMPORT_HPP - diff --git a/include/boost/dll/library_info.hpp b/include/boost/dll/library_info.hpp deleted file mode 100644 index 4666a163..00000000 --- a/include/boost/dll/library_info.hpp +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_LIBRARY_INFO_HPP -#define BOOST_DLL_LIBRARY_INFO_HPP - -#include <boost/config.hpp> -#include <boost/mpl/max_element.hpp> -#include <boost/mpl/vector_c.hpp> -#include <boost/aligned_storage.hpp> -#include <boost/noncopyable.hpp> -#include <boost/predef/os.h> -#include <boost/predef/architecture.h> -#include <boost/type_traits/integral_constant.hpp> - -#include <boost/dll/detail/pe_info.hpp> -#include <boost/dll/detail/elf_info.hpp> -#include <boost/dll/detail/macho_info.hpp> - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -/// \file boost/dll/library_info.hpp -/// \brief Contains only the boost::dll::library_info class that is capable of -/// extracting different information from binaries. - -namespace boost { namespace dll { - -/*! -* \brief Class that is capable of extracting different information from a library or binary file. -* Currently understands ELF, MACH-O and PE formats on all the platforms. -*/ -class library_info: private boost::noncopyable { -private: - boost::filesystem::ifstream f_; - - boost::aligned_storage< // making my own std::aligned_union from scratch. TODO: move to TypeTraits - boost::mpl::deref< - boost::mpl::max_element< - boost::mpl::vector_c<std::size_t, - sizeof(boost::dll::detail::elf_info32), - sizeof(boost::dll::detail::elf_info64), - sizeof(boost::dll::detail::pe_info32), - sizeof(boost::dll::detail::pe_info64), - sizeof(boost::dll::detail::macho_info32), - sizeof(boost::dll::detail::macho_info64) - > - >::type - >::type::value - >::type impl_; - - /// @cond - boost::dll::detail::x_info_interface& impl() BOOST_NOEXCEPT { - return *reinterpret_cast<boost::dll::detail::x_info_interface*>(impl_.address()); - } - - inline static void throw_if_in_32bit_impl(boost::true_type /* is_32bit_platform */) { - boost::throw_exception(std::runtime_error("Not native format: 64bit binary")); - } - - inline static void throw_if_in_32bit_impl(boost::false_type /* is_32bit_platform */) BOOST_NOEXCEPT {} - - - inline static void throw_if_in_32bit() { - throw_if_in_32bit_impl( boost::integral_constant<bool, (sizeof(void*) == 4)>() ); - } - - static void throw_if_in_windows() { -#if BOOST_OS_WINDOWS - boost::throw_exception(std::runtime_error("Not native format: not a PE binary")); -#endif - } - - static void throw_if_in_linux() { -#if !BOOST_OS_WINDOWS && !BOOST_OS_MACOS && !BOOST_OS_IOS - boost::throw_exception(std::runtime_error("Not native format: not an ELF binary")); -#endif - } - - static void throw_if_in_macos() { -#if BOOST_OS_MACOS || BOOST_OS_IOS - boost::throw_exception(std::runtime_error("Not native format: not an Mach-O binary")); -#endif - } - - void init(bool throw_if_not_native) { - - if (boost::dll::detail::elf_info32::parsing_supported(f_)) { - if (throw_if_not_native) { throw_if_in_windows(); throw_if_in_macos(); } - - new (impl_.address()) boost::dll::detail::elf_info32(f_); - } else if (boost::dll::detail::elf_info64::parsing_supported(f_)) { - if (throw_if_not_native) { throw_if_in_windows(); throw_if_in_macos(); throw_if_in_32bit(); } - - new (impl_.address()) boost::dll::detail::elf_info64(f_); - } else if (boost::dll::detail::pe_info32::parsing_supported(f_)) { - if (throw_if_not_native) { throw_if_in_linux(); throw_if_in_macos(); } - - new (impl_.address()) boost::dll::detail::pe_info32(f_); - } else if (boost::dll::detail::pe_info64::parsing_supported(f_)) { - if (throw_if_not_native) { throw_if_in_linux(); throw_if_in_macos(); throw_if_in_32bit(); } - - new (impl_.address()) boost::dll::detail::pe_info64(f_); - } else if (boost::dll::detail::macho_info32::parsing_supported(f_)) { - if (throw_if_not_native) { throw_if_in_linux(); throw_if_in_windows(); } - - new (impl_.address()) boost::dll::detail::macho_info32(f_); - } else if (boost::dll::detail::macho_info64::parsing_supported(f_)) { - if (throw_if_not_native) { throw_if_in_linux(); throw_if_in_windows(); throw_if_in_32bit(); } - - new (impl_.address()) boost::dll::detail::macho_info64(f_); - } else { - boost::throw_exception(std::runtime_error("Unsupported binary format")); - } - } - /// @endcond - -public: - /*! - * Opens file with specified path and prepares for information extraction. - * \param library_path Path to the binary file from which the info must be extracted. - * \param throw_if_not_native_format Throw an exception if this file format is not - * supported by OS. - */ - explicit library_info(const boost::filesystem::path& library_path, bool throw_if_not_native_format = true) - : f_(library_path, std::ios_base::in | std::ios_base::binary) - , impl_() - { - f_.exceptions( - boost::filesystem::ifstream::failbit - | boost::filesystem::ifstream::badbit - | boost::filesystem::ifstream::eofbit - ); - - init(throw_if_not_native_format); - } - - /*! - * \return List of sections that exist in binary file. - */ - std::vector<std::string> sections() { - return impl().sections(); - } - - /*! - * \return List of all the exportable symbols from all the sections that exist in binary file. - */ - std::vector<std::string> symbols() { - return impl().symbols(); - } - - /*! - * \param section_name Name of the section from which symbol names must be returned. - * \return List of symbols from the specified section. - */ - std::vector<std::string> symbols(const char* section_name) { - return impl().symbols(section_name); - } - - - //! \overload std::vector<std::string> symbols(const char* section_name) - std::vector<std::string> symbols(const std::string& section_name) { - return impl().symbols(section_name.c_str()); - } - - /*! - * \throw Nothing. - */ - ~library_info() BOOST_NOEXCEPT { - typedef boost::dll::detail::x_info_interface T; - impl().~T(); - } -}; - -}} // namespace boost::dll -#endif // BOOST_DLL_LIBRARY_INFO_HPP diff --git a/include/boost/dll/runtime_symbol_info.hpp b/include/boost/dll/runtime_symbol_info.hpp deleted file mode 100644 index 58dc467a..00000000 --- a/include/boost/dll/runtime_symbol_info.hpp +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP -#define BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP - -#include <boost/config.hpp> -#include <boost/predef/os.h> -#include <boost/dll/detail/aggressive_ptr_cast.hpp> -#if BOOST_OS_WINDOWS -# include <boost/detail/winapi/dll.hpp> -# include <boost/dll/detail/windows/path_from_handle.hpp> -#else -# include <dlfcn.h> -# include <boost/dll/detail/posix/program_location_impl.hpp> -#endif - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -/// \file boost/dll/runtime_symbol_info.hpp -/// \brief Provides methods for getting acceptable by boost::dll::shared_library location of symbol, source line or program. -namespace boost { namespace dll { - -namespace detail { -#if BOOST_OS_WINDOWS - inline boost::filesystem::path symbol_location_impl(const void* symbol, boost::system::error_code& ec) { - boost::filesystem::path ret; - - boost::detail::winapi::MEMORY_BASIC_INFORMATION_ mbi; - if (!boost::detail::winapi::VirtualQuery(symbol, &mbi, sizeof(mbi))) { - ec = boost::dll::detail::last_error_code(); - return ret; - } - - return boost::dll::detail::path_from_handle(reinterpret_cast<boost::detail::winapi::HMODULE_>(mbi.AllocationBase), ec); - } - - inline boost::filesystem::path program_location_impl(boost::system::error_code& ec) { - return boost::dll::detail::path_from_handle(NULL, ec); - } -#else - inline boost::filesystem::path symbol_location_impl(const void* symbol, boost::system::error_code& ec) { - boost::filesystem::path ret; - Dl_info info; - - // Some of the libc headers miss `const` in `dladdr(const void*, Dl_info*)` - const int res = dladdr(const_cast<void*>(symbol), &info); - - if (res) { - ret = info.dli_fname; - } else { - ec = boost::system::error_code( - boost::system::errc::not_supported, - boost::system::generic_category() - ); - } - - return ret; - } -#endif -} // namespace detail - - /*! - * On success returns full path and name of the binary object that holds symbol. - * \tparam T Type of the symbol, must not be explicitly specified. - * \param symbol Symbol which location is to be determined. - * \param ec Variable that will be set to the result of the operation. - * \return Path to the binary object that holds symbol or empty path in case error. - * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept boost::system::error_code also throws boost::system::system_error. - * - * \b Examples: - * \code - * int var; - * void foo() {} - * - * int main() { - * dll::symbol_location(var); // returns program location - * dll::symbol_location(foo); // returns program location - * dll::symbol_location(std::cerr); // returns location of libstdc++: "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" - * dll::symbol_location(std::placeholders::_1); // returns location of libstdc++: "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" - * dll::symbol_location(std::puts); // returns location of libc: "/lib/x86_64-linux-gnu/libc.so.6" - * } - * \endcode - */ - template <class T> - inline boost::filesystem::path symbol_location(const T& symbol, boost::system::error_code& ec) { - ec.clear(); - return boost::dll::detail::symbol_location_impl( - boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)), - ec - ); - } - - //! \overload symbol_location(const T& symbol, boost::system::error_code& ec) - template <class T> - inline boost::filesystem::path symbol_location(const T& symbol) { - boost::filesystem::path ret; - boost::system::error_code ec; - ret = boost::dll::detail::symbol_location_impl( - boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)), - ec - ); - - if (ec) { - boost::dll::detail::report_error(ec, "boost::dll::symbol_location(const T& symbol) failed"); - } - - return ret; - } - - /// @cond - // We have anonymous namespace here to make sure that `this_line_location()` method is instantiated in - // current translation module and is not shadowed by instantiations from other modules. - namespace { - /// @endcond - - /*! - * On success returns full path and name of the binary object that holds the current line of code - * (the line in which the `this_line_location()` method was called). - * - * \param ec Variable that will be set to the result of the operation. - * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept boost::system::error_code also throws boost::system::system_error. - */ - static inline boost::filesystem::path this_line_location(boost::system::error_code& ec) { - ec.clear(); - return boost::dll::symbol_location<boost::filesystem::path(boost::system::error_code& )>(this_line_location, ec); - } - - //! \overload this_line_location(boost::system::error_code& ec) - static inline boost::filesystem::path this_line_location() { - boost::filesystem::path ret; - boost::system::error_code ec; - ret = boost::dll::symbol_location<boost::filesystem::path()>(this_line_location, ec); - - if (ec) { - boost::dll::detail::report_error(ec, "boost::dll::this_line_location() failed"); - } - - return ret; - } - - /// @cond - } // anonymous namespace - /// @endcond - - /*! - * On success returns full path and name of the currently running program (the one which contains the `main()` function). - * - * Return value can be used as a parameter for shared_library. See Tutorial "Linking plugin into the executable" - * for usage example. Flag '-rdynamic' must be used when linking the plugin into the executable - * on Linux OS. - * - * \param ec Variable that will be set to the result of the operation. - * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept boost::system::error_code also throws boost::system::system_error. - */ - inline boost::filesystem::path program_location(boost::system::error_code& ec) { - return boost::dll::detail::program_location_impl(ec); - } - - //! \overload program_location(boost::system::error_code& ec) { - inline boost::filesystem::path program_location() { - boost::filesystem::path ret; - boost::system::error_code ec; - ret = boost::dll::detail::program_location_impl(ec); - - if (ec) { - boost::dll::detail::report_error(ec, "boost::dll::program_location() failed"); - } - - return ret; - } - -}} // namespace boost::dll - -#endif // BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP - diff --git a/include/boost/dll/shared_library.hpp b/include/boost/dll/shared_library.hpp deleted file mode 100644 index d292c536..00000000 --- a/include/boost/dll/shared_library.hpp +++ /dev/null @@ -1,538 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015 Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_SHARED_LIBRARY_HPP -#define BOOST_DLL_SHARED_LIBRARY_HPP - -/// \file boost/dll/shared_library.hpp -/// \brief Contains the boost::dll::shared_library class, core class for all the -/// DLL/DSO operations. - -// Walkaround for compatibility with boost 1.54 -#include <boost/move/move.hpp> - -#include <boost/config.hpp> -#include <boost/predef/os.h> -#include <boost/utility/explicit_operator_bool.hpp> -#include <boost/dll/detail/system_error.hpp> -#include <boost/dll/detail/aggressive_ptr_cast.hpp> - -#if BOOST_OS_WINDOWS -# include <boost/dll/detail/windows/shared_library_impl.hpp> -#else -# include <boost/dll/detail/posix/shared_library_impl.hpp> -#endif - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -namespace boost { namespace dll { - -/*! -* \brief This class can be used to load a -* Dynamic link libraries (DLL's) or Shared Libraries, also know -* as dynamic shared objects (DSO's) and get their exported -* symbols (functions and variables). -* -* shared_library instances share reference count to an actual loaded DLL/DSO, so it -* is safe and memory efficient to have multiple instances of shared_library referencing the same DLL/DSO -* even if those instances were loaded using different paths (relative + absolute) referencing the same object. -* -* On Linux/POSIX link with library "dl". "-fvisibility=hidden" flag is also recommended for use on Linux/POSIX. -*/ -class shared_library -/// @cond - : private boost::dll::detail::shared_library_impl -/// @endcond -{ - typedef boost::dll::detail::shared_library_impl base_t; - BOOST_COPYABLE_AND_MOVABLE(shared_library) - -public: -#ifdef BOOST_DLL_DOXYGEN - typedef platform_specific native_handle_t; -#else - typedef shared_library_impl::native_handle_t native_handle_t; -#endif - - /*! - * Creates shared_library that does not reference any DLL/DSO. - * - * \post this->is_loaded() returns false. - * \throw Nothing. - */ - shared_library() BOOST_NOEXCEPT {} - - /*! - * Copy constructor that increments the reference count of an underlying shared library. - * Same as calling `shared_library(lib.location())` - * - * \param lib A shared_library to copy. - * \post lib == *this - * \throw boost::system::system_error, std::bad_alloc in case of insufficient memory. - */ - shared_library(const shared_library& lib) - : base_t() - { - assign(lib); - } - - /*! - * Copy constructor that increments the reference count of an underlying shared library. - * Same as calling `shared_library(lib.location(), ec)` - * - * \param lib A shared_library to copy. - * \param ec Variable that will be set to the result of the operation. - * \post lib == *this - * \throw std::bad_alloc in case of insufficient memory. - */ - shared_library(const shared_library& lib, boost::system::error_code& ec) - : base_t() - { - assign(lib, ec); - } - - /*! - * Move constructor. Does not invalidate existing symbols and functions loaded from lib. - * - * \param lib A shared_library to move from. - * \post lib.is_loaded() returns false, this->is_loaded() return true. - * \throw Nothing. - */ - shared_library(BOOST_RV_REF(shared_library) lib) BOOST_NOEXCEPT - : base_t(boost::move(static_cast<base_t&>(lib))) - {} - - /*! - * Creates a shared_library object and loads a library by specified path - * with a specified mode. - * - * \param lib_path Library file name. Can handle std::string, const char*, std::wstring, - * const wchar_t* or boost::filesystem::path. - * \param mode A mode that will be used on library load. - * \throw boost::system::system_error, std::bad_alloc in case of insufficient memory. - */ - explicit shared_library(const boost::filesystem::path& lib_path, load_mode::type mode = load_mode::default_mode) { - load(lib_path, mode); - } - - /*! - * Creates a shared_library object and loads a library by specified path - * with a specified mode. - * - * \param lib_path Library file name. Can handle std::string, const char*, std::wstring, - * const wchar_t* or boost::filesystem::path. - * \param mode A mode that will be used on library load. - * \param ec Variable that will be set to the result of the operation. - * \throw std::bad_alloc in case of insufficient memory. - */ - shared_library(const boost::filesystem::path& lib_path, boost::system::error_code& ec, load_mode::type mode = load_mode::default_mode) { - load(lib_path, mode, ec); - } - - //! \overload shared_library(const boost::filesystem::path& lib_path, boost::system::error_code& ec, load_mode::type mode = load_mode::default_mode) - shared_library(const boost::filesystem::path& lib_path, load_mode::type mode, boost::system::error_code& ec) { - load(lib_path, mode, ec); - } - - /*! - * Copy assign a shared_library object. If this->is_loaded() then calls this->unload(). Does not invalidate existing symbols and functions loaded from lib. - * - * \param lib A shared_library to copy. - * \post lib == *this - * \throw boost::system::system_error, std::bad_alloc in case of insufficient memory. - */ - shared_library& operator=(BOOST_COPY_ASSIGN_REF(shared_library) lib) { - boost::system::error_code ec; - assign(lib, ec); - if (ec) { - boost::dll::detail::report_error(ec, "shared_library::operator= failed"); - } - - return *this; - } - - /*! - * Move assign a shared_library object. If this->is_loaded() then calls this->unload(). Does not invalidate existing symbols and functions loaded from lib. - * - * \param lib A shared_library to move from. - * \post lib.is_loaded() returns false. - * \throw Nothing. - */ - shared_library& operator=(BOOST_RV_REF(shared_library) lib) BOOST_NOEXCEPT { - base_t::operator=(boost::move(static_cast<base_t&>(lib))); - return *this; - } - - /*! - * Destroys the shared_library by calling - * `unload()`. If library was loaded multiple times - * by different instances of shared_library, the actual DLL/DSO won't be unloaded until - * there is at least one instance of shared_library. - * - * \throw Nothing. - */ - ~shared_library() BOOST_NOEXCEPT {} - - /*! - * Makes *this share the same shared object as lib. If *this is loaded, then unloads it. - * - * \post lib.location() == this->location(), lib == *this - * \param lib A shared_library to copy. - * \param ec Variable that will be set to the result of the operation. - * \throw std::bad_alloc in case of insufficient memory. - */ - shared_library& assign(const shared_library& lib, boost::system::error_code& ec) { - ec.clear(); - - if (native() == lib.native()) { - return *this; - } - - if (!lib) { - unload(); - return *this; - } - - boost::filesystem::path loc = lib.location(ec); - if (ec) { - return *this; - } - - shared_library copy(loc, ec); - /*if (ec) { - return *this; - }*/ - - swap(copy); - return *this; - } - - /*! - * Makes *this share the same shared object as lib. If *this is loaded, then unloads it. - * - * \param lib A shared_library instance to share. - * \post lib.location() == this->location() - * \throw boost::system::system_error, std::bad_alloc in case of insufficient memory. - */ - shared_library& assign(const shared_library& lib) { - boost::system::error_code ec; - assign(lib, ec); - if (ec) { - boost::dll::detail::report_error(ec, "assign() failed"); - } - - return *this; - } - - /*! - * Loads a library by specified path with a specified mode. - * - * Note that if some library is already loaded in this shared_library instance, load will - * call unload() and then load the new provided library. - * - * \param lib_path Library file name. Can handle std::string, const char*, std::wstring, - * const wchar_t* or boost::filesystem::path. - * \param mode A mode that will be used on library load. - * \throw boost::system::system_error, std::bad_alloc in case of insufficient memory. - * - */ - void load(const boost::filesystem::path& lib_path, load_mode::type mode = load_mode::default_mode) { - boost::system::error_code ec; - base_t::load(lib_path, mode, ec); - - if (ec) { - boost::dll::detail::report_error(ec, "load() failed"); - } - } - - /*! - * Loads a library by specified path with a specified mode. - * - * Note that if some library is already loaded in this shared_library instance, load will - * call unload() and then load the new provided library. - * - * \param lib_path Library file name. Can handle std::string, const char*, std::wstring, - * const wchar_t* or boost::filesystem::path. - * \param ec Variable that will be set to the result of the operation. - * \param mode A mode that will be used on library load. - * \throw std::bad_alloc in case of insufficient memory. - */ - void load(const boost::filesystem::path& lib_path, boost::system::error_code& ec, load_mode::type mode = load_mode::default_mode) { - ec.clear(); - base_t::load(lib_path, mode, ec); - } - - //! \overload void load(const boost::filesystem::path& lib_path, boost::system::error_code& ec, load_mode::type mode = load_mode::default_mode) - void load(const boost::filesystem::path& lib_path, load_mode::type mode, boost::system::error_code& ec) { - ec.clear(); - base_t::load(lib_path, mode, ec); - } - - /*! - * Unloads a shared library. If library was loaded multiple times - * by different instances of shared_library, the actual DLL/DSO won't be unloaded until - * there is at least one instance of shared_library holding a reference to it. - * - * \post this->is_loaded() returns false. - * \throw Nothing. - */ - void unload() BOOST_NOEXCEPT { - base_t::unload(); - } - - /*! - * Check if an library is loaded. - * - * \return true if a library has been loaded. - * \throw Nothing. - */ - bool is_loaded() const BOOST_NOEXCEPT { - return base_t::is_loaded(); - } - - /*! - * Check if an library is not loaded. - * - * \return true if a library has not been loaded. - * \throw Nothing. - */ - bool operator!() const BOOST_NOEXCEPT { - return !is_loaded(); - } - - /*! - * Check if an library is loaded. - * - * \return true if a library has been loaded. - * \throw Nothing. - */ - BOOST_EXPLICIT_OPERATOR_BOOL() - - /*! - * Search for a given symbol on loaded library. Works for all symbols, including alias names. - * - * \param symbol_name Null-terminated symbol name. Can handle std::string, char*, const char*. - * \return `true` if the loaded library contains a symbol with a given name. - * \throw Nothing. - */ - bool has(const char* symbol_name) const BOOST_NOEXCEPT { - boost::system::error_code ec; - return is_loaded() && !!base_t::symbol_addr(symbol_name, ec) && !ec; - } - - //! \overload bool has(const char* symbol_name) const - bool has(const std::string& symbol_name) const BOOST_NOEXCEPT { - return has(symbol_name.c_str()); - } - - /*! - * Returns reference to the symbol (function or variable) with the given name from the loaded library. - * This call will always succeed and throw nothing if call to `has(const char* )` - * member function with the same symbol name returned `true`. - * - * If using this call for an alias name do not forget to add a pointer to a resulting type. - * - * \b Example: - * \code - * shared_library lib("test_lib.so"); - * int& i0 = lib.get<int>("integer_name"); - * int& i1 = *lib.get<int*>("integer_alias_name"); - * \endcode - * - * \tparam T Type of the symbol that we are going to import. Must be explicitly specified. - * \param symbol_name Null-terminated symbol name. Can handle std::string, char*, const char*. - * \return Reference to the symbol. - * \throw boost::system::system_error if symbol does not exist or if the DLL/DSO was not loaded. - */ - template <typename T> - inline T& get(const char* symbol_name) const { - return *boost::dll::detail::aggressive_ptr_cast<T*>( - get_impl(symbol_name) - ); - } - - //! \overload T& get(const char* symbol_name) const - template <typename T> - inline T& get(const std::string& symbol_name) const { - return get<T>(symbol_name.c_str()); - } - - /*! - * Returns a symbol (function or variable) from a shared library by alias name of the symbol. - * - * \b Example: - * \code - * shared_library lib("test_lib.so"); - * int& i = lib.get_alias<int>("integer_alias_name"); - * \endcode - * - * \tparam T Type of the symbol that we are going to import. Must be explicitly specified.. - * \param alias_name Null-terminated alias symbol name. Can handle std::string, char*, const char*. - * \throw boost::system::system_error if symbol does not exist or if the DLL/DSO was not loaded. - */ - template <typename T> - inline T& get_alias(const char* alias_name) const { - return *get<T*>(alias_name); - } - - //! \overload T& get_alias(const char* alias_name) const - template <typename T> - inline T& get_alias(const std::string& alias_name) const { - return *get<T*>(alias_name.c_str()); - } - -private: - - /// @cond - // get_impl is required to reduce binary size: it does not depend on a template - // parameter and will be instantiated only once. - void* get_impl(const char* sb) const { - boost::system::error_code ec; - - if (!is_loaded()) { - ec = boost::system::error_code( - boost::system::errc::bad_file_descriptor, - boost::system::generic_category() - ); - - // report_error() calls dlsym, do not use it here! - boost::throw_exception( - boost::system::system_error( - ec, "get() failed: no library was loaded" - ) - ); - } - - void* const ret = base_t::symbol_addr(sb, ec); - if (ec || !ret) { - boost::dll::detail::report_error(ec, "get() failed"); - } - - return ret; - } - /// @endcond - -public: - - /*! - * Returns the native handler of the loaded library. - * - * \return Platform-specific handle. - */ - native_handle_t native() const BOOST_NOEXCEPT { - return base_t::native(); - } - - /*! - * Returns full path and name of this shared object. - * - * \b Example: - * \code - * shared_library lib("test_lib.dll"); - * filesystem::path full_path = lib.location(); // C:\Windows\System32\test_lib.dll - * \endcode - * - * \return Full path to the shared library. - * \throw boost::system::system_error, std::bad_alloc. - */ - boost::filesystem::path location() const { - boost::system::error_code ec; - if (!is_loaded()) { - ec = boost::system::error_code( - boost::system::errc::bad_file_descriptor, - boost::system::generic_category() - ); - - boost::throw_exception( - boost::system::system_error( - ec, "location() failed (no library was loaded)" - ) - ); - } - - boost::filesystem::path full_path = base_t::full_module_path(ec); - - if (ec) { - boost::dll::detail::report_error(ec, "location() failed"); - } - - return full_path; - } - - /*! - * Returns full path and name of shared module. - * - * \b Example: - * \code - * shared_library lib("test_lib.dll"); - * filesystem::path full_path = lib.location(); // C:\Windows\System32\test_lib.dll - * \endcode - * - * \param ec Variable that will be set to the result of the operation. - * \return Full path to the shared library. - * \throw std::bad_alloc. - */ - boost::filesystem::path location(boost::system::error_code& ec) const { - if (!is_loaded()) { - ec = boost::system::error_code( - boost::system::errc::bad_file_descriptor, - boost::system::generic_category() - ); - - return boost::filesystem::path(); - } - - return base_t::full_module_path(ec); - } - - /*! - * Returns suffix of shared module: - * in a call to load() or the constructor/load. - * - * \return The suffix od shared module: ".dll" (Windows), ".so" (Unix/Linux/BSD), ".dylib" (MacOS/IOS) - */ - static boost::filesystem::path suffix() { - return base_t::suffix(); - } - - /*! - * Swaps two libraries. Does not invalidate existing symbols and functions loaded from libraries. - * - * \param rhs Library to swap with. - * \throw Nothing. - */ - void swap(shared_library& rhs) BOOST_NOEXCEPT { - base_t::swap(rhs); - } -}; - -/// Very fast equality check that compares the actual DLL/DSO objects. Throws nothing. -inline bool operator==(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT { - return lhs.native() == rhs.native(); -} - -/// Very fast inequality check that compares the actual DLL/DSO objects. Throws nothing. -inline bool operator!=(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT { - return lhs.native() != rhs.native(); -} - -/// Compare the actual DLL/DSO objects without any guarantee to be stable between runs. Throws nothing. -inline bool operator<(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT { - return lhs.native() < rhs.native(); -} - -/// Swaps two shared libraries. Does not invalidate symbols and functions loaded from libraries. Throws nothing. -inline void swap(shared_library& lhs, shared_library& rhs) BOOST_NOEXCEPT { - lhs.swap(rhs); -} - -}} // boost::dll - -#endif // BOOST_DLL_SHARED_LIBRARY_HPP - diff --git a/include/boost/dll/shared_library_load_mode.hpp b/include/boost/dll/shared_library_load_mode.hpp deleted file mode 100644 index cd25ad66..00000000 --- a/include/boost/dll/shared_library_load_mode.hpp +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_DLL_SHARED_LIBRARY_MODE_HPP -#define BOOST_DLL_SHARED_LIBRARY_MODE_HPP - -#include <boost/config.hpp> -#include <boost/predef/os.h> -#include <boost/predef/library/c.h> - -#if BOOST_OS_WINDOWS -//#include <boost/detail/winapi/dll.hpp> -#include <boost/detail/winapi/dll.hpp> -#else -# include <dlfcn.h> -#endif - -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -/// \file boost/dll/shared_library_load_mode.hpp -/// \brief Contains only the boost::dll::load_mode::type enum and operators related to it. - -namespace boost { namespace dll { namespace load_mode { - -/*! Library load modes. -* -* Each of system family provides own modes. Flags not supported by a particular platform will be silently ignored. -* -* For a detailed description of platform specific options see: -* <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx">Windows specific options</a>, -* <a href="http://pubs.opengroup.org/onlinepubs/000095399/functions/dlopen.html">POSIX specific options</a>. -* -*/ - -enum type { -#ifdef BOOST_DLL_DOXYGEN - /*! - * Default open mode. See the \b Default: comments below to find out the flags that are enabled by default. - */ - default_mode, - - /*! - * \b Platforms: Windows - * - * \b Default: disabled - * - * If this value is used, and the executable module is a DLL, the system does - * not call DllMain for process and thread initialization and termination. - * Also, the system does not load additional executable modules that are - * referenced by the specified module. - * - * Note Do not use this value; it is provided only for backward compatibility. - * If you are planning to access only data or resources in the DLL, use - * LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE or LOAD_LIBRARY_AS_IMAGE_RESOURCE - * or both. - */ - dont_resolve_dll_references, - - /*! - * \b Platforms: Windows - * - * \b Default: disabled - * - * If this value is used, the system does not check AppLocker rules or - * apply Software Restriction Policies for the DLL. - */ - load_ignore_code_authz_level, - - /*! - * \b Platforms: Windows - * - * \b Default: disabled - * - * If this value is used and lpFileName specifies an absolute path, - * the system uses the alternate file search strategy. - * - * This value cannot be combined with any LOAD_LIBRARY_SEARCH flag. - */ - load_with_altered_search_path, - - /*! - * \b Platforms: POSIX - * - * \b Default: enabled - * - * Relocations shall be performed at an implementation-defined time, ranging - * from the time of the dlopen() call until the first reference to a given - * symbol occurs. - * - * Specifying RTLD_LAZY should improve performance on implementations - * supporting dynamic symbol binding as a process may not reference all of - * the functions in any given object. And, for systems supporting dynamic - * symbol resolution for normal process execution, this behavior mimics - * the normal handling of process execution. - */ - rtld_lazy, - - /*! - * \b Platforms: POSIX - * - * \b Default: disabled - * - * All necessary relocations shall be performed when the object is first - * loaded. This may waste some processing if relocations are performed for - * functions that are never referenced. This behavior may be useful for - * plugins that need to know as soon as an object is loaded that all - * symbols referenced during execution are available. - */ - rtld_now, - - /*! - * \b Platforms: POSIX - * - * \b Default: disabled - * - * The object's symbols shall be made available for the relocation - * processing of any other object. In addition, symbol lookup using - * dlopen(0, mode) and an associated dlsym() allows objects loaded - * with this mode to be searched. - */ - rtld_global, - - /*! - * \b Platforms: POSIX - * - * \b Default: enabled - * - * The object's symbols shall not be made available for the relocation - * processing of any other object. - * - * This is a default Windows behavior that can not be changed. - */ - rtld_local, - - /*! - * \b Platforms: POSIX (requires glibc >= 2.3.4) - * - * \b Default: disabled - * - * The object will use its own symbols in preference to global symbols - * with the same name contained in libraries that have already been loaded. - * This flag is not specified in POSIX.1-2001. - */ - rtld_deepbind, - - /*! - * \b Platforms: Windows, POSIX - * - * \b Default: disabled - * - * Append a platform specific extension and prefix to shared library filename before trying to load it. - * If load attempt fails, try to load with exactly specified name. - * - * \b Example: - * \code - * // Opens `./my_plugins/plugin1.dll` on Windows, `./my_plugins/libplugin1.so` on Linux, `./my_plugins/libplugin1.dylib` on MacOS. - * // If that fails, loads `./my_plugins/plugin1` - * boost::dll::shared_library lib("./my_plugins/plugin1", load_mode::append_decorations); - * \endcode - */ - append_decorations -#elif BOOST_OS_WINDOWS - default_mode = 0, - dont_resolve_dll_references = boost::detail::winapi::DONT_RESOLVE_DLL_REFERENCES_, - load_ignore_code_authz_level = boost::detail::winapi::LOAD_IGNORE_CODE_AUTHZ_LEVEL_, - load_with_altered_search_path = boost::detail::winapi::LOAD_WITH_ALTERED_SEARCH_PATH_, - rtld_lazy = 0, - rtld_now = 0, - rtld_global = 0, - rtld_local = 0, - rtld_deepbind = 0, - append_decorations = 0x00800000 -#else - default_mode = 0, - dont_resolve_dll_references = 0, - load_ignore_code_authz_level = 0, - load_with_altered_search_path = 0, - rtld_lazy = RTLD_LAZY, - rtld_now = RTLD_NOW, - rtld_global = RTLD_GLOBAL, - rtld_local = RTLD_LOCAL, - -#if BOOST_LIB_C_GNU < BOOST_VERSION_NUMBER(2,3,4) - rtld_deepbind = 0, -#else - rtld_deepbind = RTLD_DEEPBIND, -#endif - - append_decorations = 0x00800000 -#endif -}; - - -/// Free operators for load_mode::type flag manipulation. -inline type operator|(type left, type right) BOOST_NOEXCEPT { - return (static_cast<type>( - static_cast<unsigned int>(left) | static_cast<unsigned int>(right)) - ); -} - -inline type& operator|=(type& left, type right) BOOST_NOEXCEPT { - left = left | right; - return (left); -} - -}}} // boost::dll::load_mode - -#endif // BOOST_DLL_SHARED_LIBRARY_MODE_HPP diff --git a/include/transport/NetworkPlugin.h b/include/transport/NetworkPlugin.h index f8fd3770..873b4d1d 100644 --- a/include/transport/NetworkPlugin.h +++ b/include/transport/NetworkPlugin.h @@ -27,6 +27,8 @@ #include <iostream> #include <list> +#include <boost/asio.hpp> + namespace Transport { /// Represents Spectrum2 legacy network plugin. @@ -50,7 +52,6 @@ class NetworkPlugin { void setExtraFields(const std::vector<std::string> &fields) { m_extraFields = fields; } void setRawXML(bool rawXML = false) { m_rawXML = rawXML; } void disableJIDEscaping() { m_disableJIDEscaping = true; } - private: bool m_needPassword; bool m_needRegistration; @@ -62,15 +63,17 @@ class NetworkPlugin { friend class NetworkPlugin; }; - /// Creates new NetworkPlugin and connects the Spectrum2 NetworkPluginServer. - /// \param loop Event loop. - /// \param host Host where Spectrum2 NetworkPluginServer runs. - /// \param port Port. + /// Creates new NetworkPlugin NetworkPlugin(); /// Destructor. virtual ~NetworkPlugin(); + /// Connects the Spectrum2 NetworkPluginServer. + /// \param host Host where Spectrum2 NetworkPluginServer runs. + /// \param port Port ("http" or "8080") + void connect(const std::string &host, const std::string &port); + void sendConfig(const PluginConfig &cfg); void sendRawXML(std::string &xml); @@ -273,8 +276,8 @@ class NetworkPlugin { virtual void handleMemoryUsage(double &res, double &shared) {res = 0; shared = 0;} virtual void handleExitRequest() { exit(1); } - void handleDataRead(std::string &data); - virtual void sendData(const std::string &string) {} + void handleDataRead(std::istream &data); + void sendData(const std::string& string); void checkPing(); @@ -303,7 +306,7 @@ class NetworkPlugin { std::string m_data; bool m_pingReceived; double m_init_res; - + boost::asio::ip::tcp::iostream stream; }; } diff --git a/libtransport/CMakeLists.txt b/libtransport/CMakeLists.txt index 2e49ca93..ca26c682 100644 --- a/libtransport/CMakeLists.txt +++ b/libtransport/CMakeLists.txt @@ -42,12 +42,10 @@ endif(PROTOBUF_FOUND) endif() # endif() -find_package(CURL) - if(WIN32) - target_link_libraries(transport transport-plugin ${PQXX_LIBRARIES} ${CURL_LIBRARIES} ${PQ_LIBRARY} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY} JsonCpp::JsonCpp psapi.lib bcrypt.lib) + target_link_libraries(transport transport-plugin ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY} JsonCpp::JsonCpp psapi.lib bcrypt.lib) else() - target_link_libraries(transport transport-plugin ${PQXX_LIBRARIES} ${CURL_LIBRARIES} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${POPT_LIBRARY} ${PROTOBUF_LIBRARY} JsonCpp::JsonCpp) + target_link_libraries(transport transport-plugin ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${POPT_LIBRARY} ${PROTOBUF_LIBRARY} JsonCpp::JsonCpp) endif() set_target_properties(transport PROPERTIES diff --git a/plugin/cpp/CMakeLists.txt b/plugin/cpp/CMakeLists.txt index 34b2ba72..0391f4d9 100644 --- a/plugin/cpp/CMakeLists.txt +++ b/plugin/cpp/CMakeLists.txt @@ -1,10 +1,6 @@ file(GLOB SRC *.cpp *.h) file(GLOB HEADERS ../include/transport/*.h) -set(EXTRA_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../../libtransport/MemoryUsage.cpp) -set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../libtransport/Logging.cpp) -set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../libtransport/Config.cpp) -set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../libtransport/Util.cpp) set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc) if(NOT WIN32) @@ -22,10 +18,12 @@ if(CMAKE_COMPILER_IS_GNUCXX) endif() endif() +find_package(CURL) + if(NOT WIN32) - target_link_libraries(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES}) + target_link_libraries(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES} ${PQXX_LIBRARIES} ${CURL_LIBRARIES} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES}) else() - target_link_libraries(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES} ws2_32.lib) + target_link_libraries(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES} ${PQXX_LIBRARIES} ${CURL_LIBRARIES} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ws2_32.lib) endif() set_target_properties(transport-plugin PROPERTIES diff --git a/libtransport/Config.cpp b/plugin/cpp/Config.cpp index 52efed72..52efed72 100644 --- a/libtransport/Config.cpp +++ b/plugin/cpp/Config.cpp diff --git a/libtransport/HTTPRequest.cpp b/plugin/cpp/HTTPRequest.cpp index a3bcdb81..a3bcdb81 100644 --- a/libtransport/HTTPRequest.cpp +++ b/plugin/cpp/HTTPRequest.cpp diff --git a/libtransport/HTTPRequestQueue.cpp b/plugin/cpp/HTTPRequestQueue.cpp index de298806..de298806 100644 --- a/libtransport/HTTPRequestQueue.cpp +++ b/plugin/cpp/HTTPRequestQueue.cpp diff --git a/libtransport/Logging.cpp b/plugin/cpp/Logging.cpp index bfbeab43..bfbeab43 100644 --- a/libtransport/Logging.cpp +++ b/plugin/cpp/Logging.cpp diff --git a/libtransport/MemoryUsage.cpp b/plugin/cpp/MemoryUsage.cpp index e5383f6e..e5383f6e 100644 --- a/libtransport/MemoryUsage.cpp +++ b/plugin/cpp/MemoryUsage.cpp diff --git a/libtransport/MySQLBackend.cpp b/plugin/cpp/MySQLBackend.cpp index 97d781d6..97d781d6 100644 --- a/libtransport/MySQLBackend.cpp +++ b/plugin/cpp/MySQLBackend.cpp diff --git a/libtransport/PQXXBackend.cpp b/plugin/cpp/PQXXBackend.cpp index df148fac..df148fac 100644 --- a/libtransport/PQXXBackend.cpp +++ b/plugin/cpp/PQXXBackend.cpp diff --git a/libtransport/SQLite3Backend.cpp b/plugin/cpp/SQLite3Backend.cpp index 678310af..678310af 100644 --- a/libtransport/SQLite3Backend.cpp +++ b/plugin/cpp/SQLite3Backend.cpp diff --git a/libtransport/StorageBackend.cpp b/plugin/cpp/StorageBackend.cpp index 2ee9171a..2ee9171a 100644 --- a/libtransport/StorageBackend.cpp +++ b/plugin/cpp/StorageBackend.cpp diff --git a/libtransport/Util.cpp b/plugin/cpp/Util.cpp index 92a79cce..92a79cce 100644 --- a/libtransport/Util.cpp +++ b/plugin/cpp/Util.cpp diff --git a/plugin/cpp/networkplugin.cpp b/plugin/cpp/networkplugin.cpp index 8e375f8f..08dc86d3 100644 --- a/plugin/cpp/networkplugin.cpp +++ b/plugin/cpp/networkplugin.cpp @@ -24,14 +24,9 @@ #include <sstream> -#ifndef WIN32 -#include <arpa/inet.h> -#include <sys/types.h> -#include <unistd.h> -#else -#include <winsock2.h> -#include <stdint.h> -#include <process.h> +#include <boost/asio.hpp> + +#ifdef _WIN32 #define getpid _getpid #endif @@ -50,7 +45,7 @@ template <class T> std::string stringOf(T object) { return (os.str()); } -NetworkPlugin::NetworkPlugin() { +NetworkPlugin::NetworkPlugin() : stream() { m_pingReceived = false; double shared; @@ -62,6 +57,12 @@ NetworkPlugin::NetworkPlugin() { NetworkPlugin::~NetworkPlugin() { } +void NetworkPlugin::connect(const std::string& host, const std::string &port) { + stream.expires_after(boost::asio::chrono::seconds(60)); + stream.connect(host, port); + handleDataRead(stream); +} + void NetworkPlugin::sendConfig(const PluginConfig &cfg) { std::string data = "[registration]\n"; data += std::string("needPassword=") + (cfg.m_needPassword ? "1" : "0") + "\n"; @@ -576,30 +577,11 @@ void NetworkPlugin::handleChatStatePayload(const std::string &data, int type) { } } -void NetworkPlugin::handleDataRead(std::string &data) { - m_data.insert(m_data.end(), data.begin(), data.end()); - - while (m_data.size() != 0) { - unsigned int expected_size; - - if (m_data.size() >= 4) { - expected_size = *((unsigned int*) &m_data[0]); - expected_size = ntohl(expected_size); - if (m_data.size() - 4 < expected_size) - return; - } - else { - return; - } - +void NetworkPlugin::handleDataRead(std::istream& data) { + while (true) { pbnetwork::WrapperMessage wrapper; - if (wrapper.ParseFromArray(&m_data[4], expected_size) == false) { - m_data.erase(m_data.begin(), m_data.begin() + 4 + expected_size); - return; - } - m_data.erase(m_data.begin(), m_data.begin() + 4 + expected_size); - - switch(wrapper.type()) { + if (wrapper.ParseFromIstream(&data)) { + switch (wrapper.type()) { case pbnetwork::WrapperMessage_Type_TYPE_LOGIN: handleLoginPayload(wrapper.payload()); break; @@ -665,6 +647,10 @@ void NetworkPlugin::handleDataRead(std::string &data) { break; default: return; + } + } else { + LOG4CXX_ERROR(logger, "Error reading from server"); + break; } } } @@ -675,6 +661,11 @@ void NetworkPlugin::send(const std::string &data) { sendData(std::string(header, 4) + data); } +void NetworkPlugin::sendData(const std::string& data) { + stream << data; + stream.flush(); +} + void NetworkPlugin::checkPing() { if (m_pingReceived == false) { LOG4CXX_ERROR(logger, "PING request not received - exiting..."); |