Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:30

0001 // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
0002 // Copyright Antony Polukhin, 2015-2023.
0003 //
0004 // Distributed under the Boost Software License, Version 1.0.
0005 // (See accompanying file LICENSE_1_0.txt
0006 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP
0009 #define BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP
0010 
0011 #include <boost/dll/config.hpp>
0012 #include <boost/predef/os.h>
0013 #include <boost/predef/compiler/visualc.h>
0014 #include <boost/dll/detail/aggressive_ptr_cast.hpp>
0015 #if BOOST_OS_WINDOWS
0016 #   include <boost/winapi/dll.hpp>
0017 #   include <boost/dll/detail/windows/path_from_handle.hpp>
0018 #else
0019 #   include <dlfcn.h>
0020 #   include <boost/dll/detail/posix/program_location_impl.hpp>
0021 #endif
0022 
0023 #ifdef BOOST_HAS_PRAGMA_ONCE
0024 # pragma once
0025 #endif
0026 
0027 /// \file boost/dll/runtime_symbol_info.hpp
0028 /// \brief Provides methods for getting acceptable by boost::dll::shared_library location of symbol, source line or program.
0029 namespace boost { namespace dll {
0030 
0031 #if BOOST_OS_WINDOWS
0032 namespace detail {
0033     inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code& ec) {
0034         return boost::dll::detail::path_from_handle(NULL, ec);
0035     }
0036 } // namespace detail
0037 #endif
0038 
0039     /*!
0040     * On success returns full path and name to the binary object that holds symbol pointed by ptr_to_symbol.
0041     *
0042     * \param ptr_to_symbol Pointer to symbol which location is to be determined.
0043     * \param ec Variable that will be set to the result of the operation.
0044     * \return Path to the binary object that holds symbol or empty path in case error.
0045     * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept \forcedlinkfs{error_code} also throws \forcedlinkfs{system_error}.
0046     *
0047     * \b Examples:
0048     * \code
0049     * int main() {
0050     *    dll::symbol_location_ptr(std::set_terminate(0));       // returns "/some/path/libmy_terminate_handler.so"
0051     *    dll::symbol_location_ptr(::signal(SIGSEGV, SIG_DFL));  // returns "/some/path/libmy_symbol_handler.so"
0052     * }
0053     * \endcode
0054     */
0055     template <class T>
0056     inline boost::dll::fs::path symbol_location_ptr(T ptr_to_symbol, boost::dll::fs::error_code& ec) {
0057         static_assert(boost::is_pointer<T>::value, "boost::dll::symbol_location_ptr works only with pointers! `ptr_to_symbol` must be a pointer");
0058         boost::dll::fs::path ret;
0059         if (!ptr_to_symbol) {
0060             ec = boost::dll::fs::make_error_code(
0061                 boost::dll::fs::errc::bad_address
0062             );
0063 
0064             return ret;
0065         }
0066         ec.clear();
0067 
0068         const void* ptr = boost::dll::detail::aggressive_ptr_cast<const void*>(ptr_to_symbol);
0069 
0070 #if BOOST_OS_WINDOWS
0071         boost::winapi::MEMORY_BASIC_INFORMATION_ mbi;
0072         if (!boost::winapi::VirtualQuery(ptr, &mbi, sizeof(mbi))) {
0073             ec = boost::dll::detail::last_error_code();
0074             return ret;
0075         }
0076 
0077         return boost::dll::detail::path_from_handle(reinterpret_cast<boost::winapi::HMODULE_>(mbi.AllocationBase), ec);
0078 #else
0079         Dl_info info;
0080 
0081         // Some of the libc headers miss `const` in `dladdr(const void*, Dl_info*)`
0082         const int res = dladdr(const_cast<void*>(ptr), &info);
0083 
0084         if (res) {
0085             ret = info.dli_fname;
0086         } else {
0087             boost::dll::detail::reset_dlerror();
0088             ec = boost::dll::fs::make_error_code(
0089                 boost::dll::fs::errc::bad_address
0090             );
0091         }
0092 
0093         return ret;
0094 #endif
0095     }
0096 
0097     //! \overload symbol_location_ptr(const void* ptr_to_symbol, boost::dll::fs::error_code& ec)
0098     template <class T>
0099     inline boost::dll::fs::path symbol_location_ptr(T ptr_to_symbol) {
0100         boost::dll::fs::path ret;
0101         boost::dll::fs::error_code ec;
0102         ret = boost::dll::symbol_location_ptr(ptr_to_symbol, ec);
0103 
0104         if (ec) {
0105             boost::dll::detail::report_error(ec, "boost::dll::symbol_location_ptr(T ptr_to_symbol) failed");
0106         }
0107 
0108         return ret;
0109     }
0110 
0111     /*!
0112     * On success returns full path and name of the binary object that holds symbol.
0113     *
0114     * \tparam T Type of the symbol, must not be explicitly specified.
0115     * \param symbol Symbol which location is to be determined.
0116     * \param ec Variable that will be set to the result of the operation.
0117     * \return Path to the binary object that holds symbol or empty path in case error.
0118     * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept \forcedlinkfs{error_code} also throws \forcedlinkfs{system_error}.
0119     *
0120     * \b Examples:
0121     * \code
0122     * int var;
0123     * void foo() {}
0124     *
0125     * int main() {
0126     *    dll::symbol_location(var);                     // returns program location
0127     *    dll::symbol_location(foo);                     // returns program location
0128     *    dll::symbol_location(std::cerr);               // returns location of libstdc++: "/usr/lib/x86_64-linux-gnu/libstdc++.so.6"
0129     *    dll::symbol_location(std::placeholders::_1);   // returns location of libstdc++: "/usr/lib/x86_64-linux-gnu/libstdc++.so.6"
0130     *    dll::symbol_location(std::puts);               // returns location of libc: "/lib/x86_64-linux-gnu/libc.so.6"
0131     * }
0132     * \endcode
0133     */
0134     template <class T>
0135     inline boost::dll::fs::path symbol_location(const T& symbol, boost::dll::fs::error_code& ec) {
0136         ec.clear();
0137         return boost::dll::symbol_location_ptr(
0138             boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)),
0139             ec
0140         );
0141     }
0142 
0143 #if BOOST_COMP_MSVC < BOOST_VERSION_NUMBER(14,0,0)
0144     // Without this MSVC 7.1 fails with:
0145     //  ..\boost\dll\runtime_symbol_info.hpp(133) : error C2780: 'filesystem::path dll::symbol_location(const T &)' : expects 1 arguments - 2 provided
0146     template <class T>
0147     inline boost::dll::fs::path symbol_location(const T& symbol, const char* /*workaround*/ = 0)
0148 #else
0149     //! \overload symbol_location(const T& symbol, boost::dll::fs::error_code& ec)
0150     template <class T>
0151     inline boost::dll::fs::path symbol_location(const T& symbol)
0152 #endif
0153     {
0154         boost::dll::fs::path ret;
0155         boost::dll::fs::error_code ec;
0156         ret = boost::dll::symbol_location_ptr(
0157             boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)),
0158             ec
0159         );
0160 
0161         if (ec) {
0162             boost::dll::detail::report_error(ec, "boost::dll::symbol_location(const T& symbol) failed");
0163         }
0164 
0165         return ret;
0166     }
0167 
0168     /// @cond
0169     // We have anonymous namespace here to make sure that `this_line_location()` method is instantiated in
0170     // current translation unit and is not shadowed by instantiations from other units.
0171     //
0172     // boost-no-inspect
0173     namespace {
0174     /// @endcond
0175 
0176     /*!
0177     * On success returns full path and name of the binary object that holds the current line of code
0178     * (the line in which the `this_line_location()` method was called).
0179     *
0180     * \param ec Variable that will be set to the result of the operation.
0181     * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept \forcedlinkfs{error_code} also throws \forcedlinkfs{system_error}.
0182     */
0183     static inline boost::dll::fs::path this_line_location(boost::dll::fs::error_code& ec) {
0184         typedef boost::dll::fs::path(func_t)(boost::dll::fs::error_code& );
0185         func_t& f = this_line_location;
0186         return boost::dll::symbol_location(f, ec);
0187     }
0188 
0189     //! \overload this_line_location(boost::dll::fs::error_code& ec)
0190     static inline boost::dll::fs::path this_line_location() {
0191         boost::dll::fs::path ret;
0192         boost::dll::fs::error_code ec;
0193         ret = this_line_location(ec);
0194 
0195         if (ec) {
0196             boost::dll::detail::report_error(ec, "boost::dll::this_line_location() failed");
0197         }
0198 
0199         return ret;
0200     }
0201 
0202     /// @cond
0203     } // anonymous namespace
0204     /// @endcond
0205 
0206     /*!
0207     * On success returns full path and name of the currently running program (the one which contains the `main()` function).
0208     * 
0209     * Return value can be used as a parameter for shared_library. See Tutorial "Linking plugin into the executable"
0210     * for usage example. Flag '-rdynamic' must be used when linking the plugin into the executable
0211     * on Linux OS.
0212     *
0213     * \param ec Variable that will be set to the result of the operation.
0214     * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept \forcedlinkfs{error_code} also throws \forcedlinkfs{system_error}.
0215     */
0216     inline boost::dll::fs::path program_location(boost::dll::fs::error_code& ec) {
0217         ec.clear();
0218         return boost::dll::detail::program_location_impl(ec);
0219     }
0220 
0221     //! \overload program_location(boost::dll::fs::error_code& ec) {
0222     inline boost::dll::fs::path program_location() {
0223         boost::dll::fs::path ret;
0224         boost::dll::fs::error_code ec;
0225         ret = boost::dll::detail::program_location_impl(ec);
0226 
0227         if (ec) {
0228             boost::dll::detail::report_error(ec, "boost::dll::program_location() failed");
0229         }
0230 
0231         return ret;
0232     }
0233 
0234 }} // namespace boost::dll
0235 
0236 #endif // BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP
0237