Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:31:23

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