diff options
Diffstat (limited to 'boost/dll')
-rw-r--r-- | boost/dll/detail/aggressive_ptr_cast.hpp | 31 | ||||
-rw-r--r-- | boost/dll/detail/demangling/msvc.hpp | 2 | ||||
-rw-r--r-- | boost/dll/detail/import_mangled_helpers.hpp | 60 | ||||
-rw-r--r-- | boost/dll/detail/posix/path_from_handle.hpp | 4 | ||||
-rw-r--r-- | boost/dll/import_mangled.hpp | 29 | ||||
-rw-r--r-- | boost/dll/runtime_symbol_info.hpp | 77 | ||||
-rw-r--r-- | boost/dll/smart_library.hpp | 2 |
7 files changed, 131 insertions, 74 deletions
diff --git a/boost/dll/detail/aggressive_ptr_cast.hpp b/boost/dll/detail/aggressive_ptr_cast.hpp index a882cd9b19..8d1ecc112b 100644 --- a/boost/dll/detail/aggressive_ptr_cast.hpp +++ b/boost/dll/detail/aggressive_ptr_cast.hpp @@ -1,5 +1,5 @@ // Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015-2016 Antony Polukhin. +// Copyright 2015-2017 Antony Polukhin. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt @@ -21,9 +21,12 @@ #include <boost/type_traits/remove_pointer.hpp> #include <boost/type_traits/remove_reference.hpp> #include <boost/utility/enable_if.hpp> -#include <boost/cstdint.hpp> // boost::uintptr_t #include <cstring> // std::memcpy +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ * 100 + __GNUC_MINOR__ > 301) +# pragma GCC system_header +#endif + namespace boost { namespace dll { namespace detail { // GCC warns when reinterpret_cast between function pointer and object pointer occur. @@ -48,11 +51,14 @@ BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::val "Pointer to function and pointer to object differ in size on your platform." ); - return reinterpret_cast<To>( - reinterpret_cast<boost::uintptr_t>(v) - ); + return reinterpret_cast<To>(v); } +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4172) // "returning address of local variable or temporary" but **v is not local! +#endif + template <class To, class From> BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_reference<To>::value || boost::is_member_pointer<From>::value, To>::type aggressive_ptr_cast(From v) BOOST_NOEXCEPT @@ -71,18 +77,17 @@ BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_reference<To>::value | sizeof(v) == sizeof(typename boost::remove_reference<To>::type*), "Pointer to function and pointer to object differ in size on your platform." ); - return static_cast<To>( - *reinterpret_cast<typename boost::remove_reference<To>::type*>( - *reinterpret_cast<boost::uintptr_t*>( - reinterpret_cast<unsigned char*>( - v - ) - ) + **reinterpret_cast<typename boost::remove_reference<To>::type**>( + v ) ); } +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + template <class To, class From> BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_member_pointer<To>::value || boost::is_member_pointer<From>::value, To>::type aggressive_ptr_cast(From v) BOOST_NOEXCEPT @@ -98,7 +103,7 @@ BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_member_pointer<To>::va ); To res = 0; - std::memcpy(&res, &v, sizeof(To)); + std::memcpy(&res, &v, sizeof(From)); return res; } diff --git a/boost/dll/detail/demangling/msvc.hpp b/boost/dll/detail/demangling/msvc.hpp index b5d526b581..c1abd6a185 100644 --- a/boost/dll/detail/demangling/msvc.hpp +++ b/boost/dll/detail/demangling/msvc.hpp @@ -185,7 +185,7 @@ namespace parser } template<typename Return> - auto arg_list(const mangled_storage_impl & ms, Return (*)()) + auto arg_list(const mangled_storage_impl& /*ms*/, Return (*)()) { return x3::string("void"); } diff --git a/boost/dll/detail/import_mangled_helpers.hpp b/boost/dll/detail/import_mangled_helpers.hpp index c5942f69a8..b1a22e7012 100644 --- a/boost/dll/detail/import_mangled_helpers.hpp +++ b/boost/dll/detail/import_mangled_helpers.hpp @@ -71,28 +71,32 @@ template <class ...Ts> struct function_tuple; template <class Return, class...Args, class T2, class ...Ts> -struct function_tuple<Return(Args...), T2, Ts...> : function_tuple<T2, Ts...> +struct function_tuple<Return(Args...), T2, Ts...> + : function_tuple<T2, Ts...> { - constexpr function_tuple(Return(* t)(Args...), T2* t2, Ts* ... ts) : function_tuple<T2, Ts...>(t2, ts...), _f(t) {}; - Return(*_f)(Args...); + Return(*f_)(Args...); - Return operator()(Args...args) - { - return (*_f)(static_cast<Args>(args)...); + constexpr function_tuple(Return(* t)(Args...), T2* t2, Ts* ... ts) + : function_tuple<T2, Ts...>(t2, ts...) + , f_(t) + {} + + Return operator()(Args...args) const { + return (*f_)(static_cast<Args>(args)...); } using function_tuple<T2, Ts...>::operator(); - }; template <class Return, class...Args> -struct function_tuple<Return(Args...)> -{ - constexpr function_tuple(Return(* t)(Args...)) : _f(t) {}; - Return(*_f)(Args...); +struct function_tuple<Return(Args...)> { + Return(*f_)(Args...); - Return operator()(Args...args) - { - return (*_f)(static_cast<Args>(args)...); + constexpr function_tuple(Return(* t)(Args...)) + : f_(t) + {} + + Return operator()(Args...args) const { + return (*f_)(static_cast<Args>(args)...); } }; @@ -250,33 +254,35 @@ template <class ...Ts> struct mem_fn_tuple; template <class Class, class Return, class...Args, class T2, class ...Ts> -struct mem_fn_tuple<mem_fn_def<Class, Return(Args...)>, T2, Ts...> : mem_fn_tuple<T2, Ts...> +struct mem_fn_tuple<mem_fn_def<Class, Return(Args...)>, T2, Ts...> + : mem_fn_tuple<T2, Ts...> { typedef typename boost::dll::detail::get_mem_fn_type<Class, Return(Args...)>::mem_fn mem_fn; + mem_fn f_; constexpr mem_fn_tuple(mem_fn f, typename T2::mem_fn t2, typename Ts::mem_fn ... ts) - : mem_fn_tuple<T2, Ts...>(t2, ts...), _f(f) {}; - mem_fn _f; + : mem_fn_tuple<T2, Ts...>(t2, ts...) + , f_(f) + {} - Return operator()(Class* const cl, Args...args) - { - return (cl->*_f)(static_cast<Args>(args)...); + Return operator()(Class* const cl, Args...args) const { + return (cl->*f_)(static_cast<Args>(args)...); } using mem_fn_tuple<T2, Ts...>::operator(); }; template <class Class, class Return, class...Args> -struct mem_fn_tuple<mem_fn_def<Class, Return(Args...)>> -{ +struct mem_fn_tuple<mem_fn_def<Class, Return(Args...)>> { typedef typename boost::dll::detail::get_mem_fn_type<Class, Return(Args...)>::mem_fn mem_fn; + mem_fn f_; - constexpr mem_fn_tuple(mem_fn f) : _f(f) {}; - mem_fn _f; + constexpr mem_fn_tuple(mem_fn f) + : f_(f) + {} - Return operator()(Class * const cl, Args...args) - { - return (cl->*_f)(static_cast<Args>(args)...); + Return operator()(Class * const cl, Args...args) const { + return (cl->*f_)(static_cast<Args>(args)...); } }; diff --git a/boost/dll/detail/posix/path_from_handle.hpp b/boost/dll/detail/posix/path_from_handle.hpp index a2787623d6..65d1a78b96 100644 --- a/boost/dll/detail/posix/path_from_handle.hpp +++ b/boost/dll/detail/posix/path_from_handle.hpp @@ -84,12 +84,12 @@ namespace boost { namespace dll { namespace detail { const struct soinfo* si = reinterpret_cast<const struct soinfo*>( static_cast<const char*>(handle) + work_around_b_24465209__offset ); - boost::filesystem::path ret = boost::dll::detail::symbol_location_impl(si->base, ec); + boost::filesystem::path ret = boost::dll::symbol_location_ptr(si->base, ec); if (ec) { ec.clear(); si = static_cast<const struct soinfo*>(handle); - return boost::dll::detail::symbol_location_impl(si->base, ec); + return boost::dll::symbol_location_ptr(si->base, ec); } return ret; diff --git a/boost/dll/import_mangled.hpp b/boost/dll/import_mangled.hpp index 7463168e10..69490ed19d 100644 --- a/boost/dll/import_mangled.hpp +++ b/boost/dll/import_mangled.hpp @@ -34,11 +34,12 @@ namespace detail template <class ... Ts> class mangled_library_function { // Copying of `boost::dll::shared_library` is very expensive, so we use a `shared_ptr` to make it faster. - boost::shared_ptr<function_tuple<Ts...>> f_; - + boost::shared_ptr<shared_library> lib_; + function_tuple<Ts...> f_; public: - inline mangled_library_function(const boost::shared_ptr<shared_library>& lib, Ts*... func_ptr) BOOST_NOEXCEPT - : f_(lib, new function_tuple<Ts...>(func_ptr...)) + constexpr mangled_library_function(const boost::shared_ptr<shared_library>& lib, Ts*... func_ptr) BOOST_NOEXCEPT + : lib_(lib) + , f_(func_ptr...) {} @@ -51,10 +52,10 @@ public: // f(1, 2); // error: too many arguments to function // f(); // error: too few arguments to function template <class... Args> - inline auto operator()(Args&&... args) const - -> decltype( (*f_)(static_cast<Args&&>(args)...) ) + auto operator()(Args&&... args) const + -> decltype( f_(static_cast<Args&&>(args)...) ) { - return (*f_)(static_cast<Args&&>(args)...); + return f_(static_cast<Args&&>(args)...); } }; @@ -66,18 +67,20 @@ template <class Class, class ... Ts> class mangled_library_mem_fn<Class, sequence<Ts...>> { // Copying of `boost::dll::shared_library` is very expensive, so we use a `shared_ptr` to make it faster. typedef mem_fn_tuple<Ts...> call_tuple_t; - boost::shared_ptr<call_tuple_t> f_; + boost::shared_ptr<shared_library> lib_; + call_tuple_t f_; public: - inline mangled_library_mem_fn(const boost::shared_ptr<shared_library>& lib, - typename Ts::mem_fn... func_ptr) BOOST_NOEXCEPT - : f_(lib, new call_tuple_t(func_ptr...)) + constexpr mangled_library_mem_fn(const boost::shared_ptr<shared_library>& lib, typename Ts::mem_fn... func_ptr) BOOST_NOEXCEPT + : lib_(lib) + , f_(func_ptr...) {} template <class ClassIn, class... Args> - inline auto operator()(ClassIn *cl, Args&&... args) const -> decltype( (*f_)(cl, static_cast<Args&&>(args)...) ) + auto operator()(ClassIn *cl, Args&&... args) const + -> decltype( f_(cl, static_cast<Args&&>(args)...) ) { - return (*f_)(cl, static_cast<Args&&>(args)...); + return f_(cl, static_cast<Args&&>(args)...); } }; diff --git a/boost/dll/runtime_symbol_info.hpp b/boost/dll/runtime_symbol_info.hpp index 80cce510f9..3f94e2ee1b 100644 --- a/boost/dll/runtime_symbol_info.hpp +++ b/boost/dll/runtime_symbol_info.hpp @@ -1,5 +1,5 @@ // Copyright 2014 Renato Tegon Forti, Antony Polukhin. -// Copyright 2015-2016 Antony Polukhin. +// Copyright 2015-2017 Antony Polukhin. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt @@ -28,30 +28,59 @@ /// \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) { +namespace detail { + inline boost::filesystem::path program_location_impl(boost::system::error_code& ec) { + return boost::dll::detail::path_from_handle(NULL, ec); + } +} // namespace detail +#endif + + /*! + * On success returns full path and name to the binary object that holds symbol pointed by ptr_to_symbol. + * + * \param ptr_to_symbol Pointer to 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 main() { + * dll::symbol_location_ptr(std::set_terminate(0)); // returns "/some/path/libmy_terminate_handler.so" + * dll::symbol_location_ptr(::signal(SIGSEGV, SIG_DFL)); // returns "/some/path/libmy_symbol_handler.so" + * } + * \endcode + */ + template <class T> + inline boost::filesystem::path symbol_location_ptr(T ptr_to_symbol, boost::system::error_code& ec) { + BOOST_STATIC_ASSERT_MSG(boost::is_pointer<T>::value, "boost::dll::symbol_location_ptr works only with pointers! `ptr_to_symbol` must be a pointer"); boost::filesystem::path ret; + if (!ptr_to_symbol) { + ec = boost::system::error_code( + boost::system::errc::bad_address, + boost::system::generic_category() + ); + return ret; + } + ec.clear(); + + const void* ptr = boost::dll::detail::aggressive_ptr_cast<const void*>(ptr_to_symbol); + +#if BOOST_OS_WINDOWS boost::detail::winapi::MEMORY_BASIC_INFORMATION_ mbi; - if (!boost::detail::winapi::VirtualQuery(symbol, &mbi, sizeof(mbi))) { + if (!boost::detail::winapi::VirtualQuery(ptr, &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); + const int res = dladdr(const_cast<void*>(ptr), &info); if (res) { ret = info.dli_fname; @@ -64,12 +93,26 @@ namespace detail { } return ret; - } #endif -} // namespace detail + } + + //! \overload symbol_location_ptr(const void* ptr_to_symbol, boost::system::error_code& ec) + template <class T> + inline boost::filesystem::path symbol_location_ptr(T ptr_to_symbol) { + boost::filesystem::path ret; + boost::system::error_code ec; + ret = boost::dll::symbol_location_ptr(ptr_to_symbol, ec); + + if (ec) { + boost::dll::detail::report_error(ec, "boost::dll::symbol_location_ptr(T ptr_to_symbol) failed"); + } + + return ret; + } /*! * 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. @@ -93,7 +136,7 @@ namespace detail { 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( + return boost::dll::symbol_location_ptr( boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)), ec ); @@ -112,7 +155,7 @@ namespace detail { { boost::filesystem::path ret; boost::system::error_code ec; - ret = boost::dll::detail::symbol_location_impl( + ret = boost::dll::symbol_location_ptr( boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)), ec ); @@ -126,7 +169,7 @@ namespace detail { /// @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. + // current translation unit and is not shadowed by instantiations from other units. namespace { /// @endcond diff --git a/boost/dll/smart_library.hpp b/boost/dll/smart_library.hpp index 03bade8100..c5859251de 100644 --- a/boost/dll/smart_library.hpp +++ b/boost/dll/smart_library.hpp @@ -95,7 +95,7 @@ public: //! \copydoc shared_library::shared_library(const boost::filesystem::path& lib_path, load_mode::type mode = load_mode::default_mode) smart_library(const boost::filesystem::path& lib_path, load_mode::type mode = load_mode::default_mode) { _lib.load(lib_path, mode); - _storage.load(lib_path, mode); + _storage.load(lib_path); } //! \copydoc shared_library::shared_library(const boost::filesystem::path& lib_path, boost::system::error_code& ec, load_mode::type mode = load_mode::default_mode) |