]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/dll/include/boost/dll/runtime_symbol_info.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / dll / include / boost / dll / runtime_symbol_info.hpp
1 // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
2 // Copyright 2015-2016 Antony Polukhin.
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 #ifndef BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP
9 #define BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP
10
11 #include <boost/config.hpp>
12 #include <boost/predef/os.h>
13 #include <boost/predef/compiler/visualc.h>
14 #include <boost/dll/detail/aggressive_ptr_cast.hpp>
15 #if BOOST_OS_WINDOWS
16 # include <boost/detail/winapi/dll.hpp>
17 # include <boost/dll/detail/windows/path_from_handle.hpp>
18 #else
19 # include <dlfcn.h>
20 # include <boost/dll/detail/posix/program_location_impl.hpp>
21 #endif
22
23 #ifdef BOOST_HAS_PRAGMA_ONCE
24 # pragma once
25 #endif
26
27 /// \file boost/dll/runtime_symbol_info.hpp
28 /// \brief Provides methods for getting acceptable by boost::dll::shared_library location of symbol, source line or program.
29 namespace boost { namespace dll {
30
31 namespace detail {
32 #if BOOST_OS_WINDOWS
33 inline boost::filesystem::path symbol_location_impl(const void* symbol, boost::system::error_code& ec) {
34 boost::filesystem::path ret;
35
36 boost::detail::winapi::MEMORY_BASIC_INFORMATION_ mbi;
37 if (!boost::detail::winapi::VirtualQuery(symbol, &mbi, sizeof(mbi))) {
38 ec = boost::dll::detail::last_error_code();
39 return ret;
40 }
41
42 return boost::dll::detail::path_from_handle(reinterpret_cast<boost::detail::winapi::HMODULE_>(mbi.AllocationBase), ec);
43 }
44
45 inline boost::filesystem::path program_location_impl(boost::system::error_code& ec) {
46 return boost::dll::detail::path_from_handle(NULL, ec);
47 }
48 #else
49 inline boost::filesystem::path symbol_location_impl(const void* symbol, boost::system::error_code& ec) {
50 boost::filesystem::path ret;
51 Dl_info info;
52
53 // Some of the libc headers miss `const` in `dladdr(const void*, Dl_info*)`
54 const int res = dladdr(const_cast<void*>(symbol), &info);
55
56 if (res) {
57 ret = info.dli_fname;
58 } else {
59 boost::dll::detail::reset_dlerror();
60 ec = boost::system::error_code(
61 boost::system::errc::bad_address,
62 boost::system::generic_category()
63 );
64 }
65
66 return ret;
67 }
68 #endif
69 } // namespace detail
70
71 /*!
72 * On success returns full path and name of the binary object that holds symbol.
73 * \tparam T Type of the symbol, must not be explicitly specified.
74 * \param symbol Symbol which location is to be determined.
75 * \param ec Variable that will be set to the result of the operation.
76 * \return Path to the binary object that holds symbol or empty path in case error.
77 * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept boost::system::error_code also throws boost::system::system_error.
78 *
79 * \b Examples:
80 * \code
81 * int var;
82 * void foo() {}
83 *
84 * int main() {
85 * dll::symbol_location(var); // returns program location
86 * dll::symbol_location(foo); // returns program location
87 * dll::symbol_location(std::cerr); // returns location of libstdc++: "/usr/lib/x86_64-linux-gnu/libstdc++.so.6"
88 * dll::symbol_location(std::placeholders::_1); // returns location of libstdc++: "/usr/lib/x86_64-linux-gnu/libstdc++.so.6"
89 * dll::symbol_location(std::puts); // returns location of libc: "/lib/x86_64-linux-gnu/libc.so.6"
90 * }
91 * \endcode
92 */
93 template <class T>
94 inline boost::filesystem::path symbol_location(const T& symbol, boost::system::error_code& ec) {
95 ec.clear();
96 return boost::dll::detail::symbol_location_impl(
97 boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)),
98 ec
99 );
100 }
101
102 #if BOOST_COMP_MSVC < BOOST_VERSION_NUMBER(14,0,0)
103 // Without this MSVC 7.1 fails with:
104 // ..\boost\dll\runtime_symbol_info.hpp(133) : error C2780: 'filesystem::path dll::symbol_location(const T &)' : expects 1 arguments - 2 provided
105 template <class T>
106 inline boost::filesystem::path symbol_location(const T& symbol, const char* /*workaround*/ = 0)
107 #else
108 //! \overload symbol_location(const T& symbol, boost::system::error_code& ec)
109 template <class T>
110 inline boost::filesystem::path symbol_location(const T& symbol)
111 #endif
112 {
113 boost::filesystem::path ret;
114 boost::system::error_code ec;
115 ret = boost::dll::detail::symbol_location_impl(
116 boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)),
117 ec
118 );
119
120 if (ec) {
121 boost::dll::detail::report_error(ec, "boost::dll::symbol_location(const T& symbol) failed");
122 }
123
124 return ret;
125 }
126
127 /// @cond
128 // We have anonymous namespace here to make sure that `this_line_location()` method is instantiated in
129 // current translation module and is not shadowed by instantiations from other modules.
130 namespace {
131 /// @endcond
132
133 /*!
134 * On success returns full path and name of the binary object that holds the current line of code
135 * (the line in which the `this_line_location()` method was called).
136 *
137 * \param ec Variable that will be set to the result of the operation.
138 * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept boost::system::error_code also throws boost::system::system_error.
139 */
140 static inline boost::filesystem::path this_line_location(boost::system::error_code& ec) {
141 typedef boost::filesystem::path(func_t)(boost::system::error_code& );
142 func_t& f = this_line_location;
143 return boost::dll::symbol_location(f, ec);
144 }
145
146 //! \overload this_line_location(boost::system::error_code& ec)
147 static inline boost::filesystem::path this_line_location() {
148 boost::filesystem::path ret;
149 boost::system::error_code ec;
150 ret = this_line_location(ec);
151
152 if (ec) {
153 boost::dll::detail::report_error(ec, "boost::dll::this_line_location() failed");
154 }
155
156 return ret;
157 }
158
159 /// @cond
160 } // anonymous namespace
161 /// @endcond
162
163 /*!
164 * On success returns full path and name of the currently running program (the one which contains the `main()` function).
165 *
166 * Return value can be used as a parameter for shared_library. See Tutorial "Linking plugin into the executable"
167 * for usage example. Flag '-rdynamic' must be used when linking the plugin into the executable
168 * on Linux OS.
169 *
170 * \param ec Variable that will be set to the result of the operation.
171 * \throws std::bad_alloc in case of insufficient memory. Overload that does not accept boost::system::error_code also throws boost::system::system_error.
172 */
173 inline boost::filesystem::path program_location(boost::system::error_code& ec) {
174 ec.clear();
175 return boost::dll::detail::program_location_impl(ec);
176 }
177
178 //! \overload program_location(boost::system::error_code& ec) {
179 inline boost::filesystem::path program_location() {
180 boost::filesystem::path ret;
181 boost::system::error_code ec;
182 ret = boost::dll::detail::program_location_impl(ec);
183
184 if (ec) {
185 boost::dll::detail::report_error(ec, "boost::dll::program_location() failed");
186 }
187
188 return ret;
189 }
190
191 }} // namespace boost::dll
192
193 #endif // BOOST_DLL_RUNTIME_SYMBOL_INFO_HPP
194