diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/dll/test | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/dll/test')
19 files changed, 2553 insertions, 0 deletions
diff --git a/src/boost/libs/dll/test/Jamfile.v2 b/src/boost/libs/dll/test/Jamfile.v2 new file mode 100644 index 00000000..037ab4c5 --- /dev/null +++ b/src/boost/libs/dll/test/Jamfile.v2 @@ -0,0 +1,94 @@ +# +# Copyright Renato Tegon Forti, Antony Polukhin 2011 - 2019. +# 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) +# + +# For more information, see http://www.boost.org + +# bring in rules for testing +import testing ; +import path ; + +local RDYNAMIC = <target-os>freebsd:<linkflags>"-rdynamic" <target-os>solaris:<linkflags>"-Bdynamic" <target-os>aix:<linkflags>"-rdynamic" + <target-os>qnxnto,<toolset>qcc:<linkflags>"-Bdynamic" <target-os>qnxnto,<toolset>gcc:<linkflags>"-rdynamic" + <target-os>android:<linkflags>"-rdynamic" <target-os>linux:<linkflags>"-rdynamic" <target-os>darwin,<toolset>gcc:<linkflags>"-dynamic" + <target-os>darwin,<toolset>clang:<linkflags>"-rdynamic" <target-os>iphone:<linkflags>"-rdynamic" ; + + +# Static library that is not linked with any of the boost libs +lib static_plugin : ../example/tutorial4/static_plugin.cpp : <link>static <define>BOOST_SYSTEM_NO_DEPRECATED $(RDYNAMIC) ; +lib static_refcounting_plugin : ../example/tutorial8/refcounting_plugin.cpp : <link>static <define>BOOST_SYSTEM_NO_DEPRECATED <variant>release $(RDYNAMIC) ; + + +project + : source-location . + : requirements + + # linux + <target-os>linux:<linkflags>"-ldl" + <toolset>gcc:<cxxflags>"-Wall -Wextra -pedantic -Wno-long-long" + + # others + <local-visibility>hidden + <library>/boost/filesystem//boost_filesystem + <library>/boost/system//boost_system + <threading>multi + <define>BOOST_SYSTEM_NO_DEPRECATED + ; +{ + + # our test lib for shared library tests + lib test_library : test_library.cpp : <link>shared ; + lib getting_started_library : ../example/getting_started_library.cpp : <link>shared ; + lib my_plugin_sum : ../example/tutorial1/my_plugin_sum.cpp : <link>shared ; + lib my_plugin_aggregator : ../example/tutorial2/my_plugin_aggregator.cpp : <link>shared ; + lib on_unload_lib : ../example/tutorial6/on_unload_lib.cpp : <link>shared ; + lib library1 : ../example/tutorial7/library1.cpp : <link>shared ; + lib library2 : ../example/tutorial7/library2.cpp : <link>shared ; + lib refcounting_plugin : ../example/tutorial8/refcounting_plugin.cpp : <link>shared ; + lib cpp_plugin : cpp_test_library.cpp : <link>shared ; + + test-suite boostdll + : + [ run link1.cpp link2.cpp : : : : validate_link ] + [ run shared_library_load_test.cpp : : library1 test_library : <link>shared ] + [ run shared_library_search_symbol_test.cpp : : test_library : $(RDYNAMIC) <link>shared ] + [ run shared_library_get_symbol_test.cpp : : test_library : $(RDYNAMIC) <link>shared ] + [ run shared_library_get_symbol_test.cpp + : + : test_library + : $(RDYNAMIC) <target-os>windows:<define>BOOST_USE_WINDOWS_H <link>shared + : get_symbol_windows_h_forced + ] + [ run symbol_runtime_info_test.cpp : : test_library : $(RDYNAMIC) <link>shared ] + [ run shared_library_errors.cpp : : test_library : <test-info>always_show_run_output <link>shared ] + [ run structures_tests.cpp ] + [ run library_info_test.cpp ../example/tutorial4/static_plugin.cpp : : test_library : <test-info>always_show_run_output <link>shared ] + [ run ../example/getting_started.cpp : : getting_started_library : <link>shared ] + [ run ../example/tutorial1/tutorial1.cpp : : my_plugin_sum : <link>shared ] + [ run ../example/tutorial2/tutorial2.cpp : : my_plugin_aggregator : <link>shared ] + [ run ../example/tutorial3/tutorial3.cpp : : my_plugin_aggregator my_plugin_sum : <link>shared ] + [ run ../example/tutorial4/load_self.cpp ../example/tutorial4/static_plugin.cpp + : : : <variant>release $(RDYNAMIC) + ] + [ run ../example/tutorial5/load_all.cpp ../example/tutorial4/static_plugin.cpp + : : getting_started_library my_plugin_aggregator my_plugin_sum : $(RDYNAMIC) <link>shared + ] + [ run ../example/tutorial6/tutorial6.cpp : : on_unload_lib : <link>shared ] + [ run ../example/tutorial7/tutorial7.cpp : : library1 library2 : <link>shared ] + [ run ../example/tutorial8/tutorial8.cpp : : refcounting_plugin : <link>shared ] + [ run ../example/tutorial8/tutorial8_static.cpp : : : <link>static <variant>release $(RDYNAMIC) <test-info>always_show_run_output <library>static_refcounting_plugin + # Known problem: unsupported __dllexport__ with weak symbols + GNU linker features (no non-weak unresolved symbols in executable => no need to link libraries) + <target-os>windows,<toolset>gcc:<build>no + ] + [ run ../example/tutorial9/tutorial9.cpp ] + # test for shared libraries + [ compile-fail section_name_too_big.cpp ] + [ run shared_library_concurrent_load_test.cpp /boost/thread//boost_thread : : library1 library2 my_plugin_aggregator refcounting_plugin : <link>shared ] + [ run cpp_mangle_test.cpp : : cpp_plugin ] + [ run cpp_load_test.cpp : : cpp_plugin ] + [ run cpp_import_test.cpp : : cpp_plugin ] + ; +} diff --git a/src/boost/libs/dll/test/cpp_import_class_test.cpp b/src/boost/libs/dll/test/cpp_import_class_test.cpp new file mode 100644 index 00000000..2b4e0091 --- /dev/null +++ b/src/boost/libs/dll/test/cpp_import_class_test.cpp @@ -0,0 +1,115 @@ +// Copyright 2016 Klemens Morgenstern +// +// 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) + +// For more information, see http://www.boost.org + + +#include <boost/predef.h> + +#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0)) + +#include "../example/b2_workarounds.hpp" + +#include <iostream> + +using namespace std; + +#include <boost/dll/smart_library.hpp> +#include <boost/dll/import_mangled.hpp> +#include <boost/dll/import_class.hpp> + +#include <boost/core/lightweight_test.hpp> +#include <boost/filesystem.hpp> +#include <boost/variant.hpp> +#include <boost/function.hpp> + +#define L cout << __LINE__ << endl; + +int main(int argc, char* argv[]) +{ + using namespace boost::dll; + using namespace boost::dll::experimental; + boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv); + + BOOST_TEST(!pt.empty()); + std::cout << "Library: " << pt << std::endl; + + smart_library sm(pt); + + auto static_val = import_mangled<int>(sm, "some_space::some_class::value"); + + std::cout << "--------------------- Entry Points ------------------------\n" << std::endl; + for (auto &s : sm.symbol_storage().get_storage()) + std::cout << s.demangled << std::endl; + + std::cout << "-----------------------------------------------------------\n\n" << std::endl; + + + auto sp_variable = import_mangled<double>(sm, "some_space::variable"); + + auto unscoped_var = import_mangled<int>(sm, "unscoped_var"); + + std::size_t type_size = *import_mangled<std::size_t>(sm, "some_space::size_of_some_class"); + { + +#if defined(BOOST_MSVC) || defined(BOOST_MSVC_FULL_VER) + class override_class{}; + auto cl = import_class<override_class, int>(sm, "some_space::some_class", type_size, 42); +#else + auto cl = import_class<class override_class, int>(sm, "some_space::some_class", type_size, 42); +#endif + BOOST_TEST(!cl.is_copy_assignable()); + BOOST_TEST(!cl.is_copy_constructible()); + + BOOST_TEST( cl.is_move_assignable()); + BOOST_TEST( cl.is_move_constructible()); + + BOOST_TEST(*static_val == 42); + + auto i = cl.call<const override_class, int()>("get")(); + BOOST_TEST(i == 456); + cl.call<void(int)>("set")(42); + i = 0; + i = cl.call<const override_class, int()>("get")(); + BOOST_TEST(i == 42); + + auto func = import_mangled< + override_class, double(double, double), int(int, int), + volatile override_class, int(int, int), + const volatile override_class, double(double, double)>(sm, "func"); + + + + BOOST_TEST((cl->*func)(3.,2.) == 6.); + BOOST_TEST((cl->*func)(1 ,2 ) == 3 ); + + auto fun2 = cl.import<double(double, double), int(int, int)>("func"); + + BOOST_TEST((cl->*fun2)(3.,2.) == 6.); + BOOST_TEST((cl->*fun2)(5 ,2 ) == 7 ); + + //test if it binds. + boost::function<int(override_class* const, int, int)> mem_fn_obj = func; + + + const std::type_info & ti = cl.get_type_info(); + std::string imp_name = boost::core::demangle(ti.name()); +#if defined(BOOST_MSVC) || defined(BOOST_MSVC_FULL_VER) + std::string exp_name = "struct some_space::some_class"; +#else + std::string exp_name = "some_space::some_class"; +#endif + BOOST_TEST(imp_name == exp_name); + } + + BOOST_TEST(*static_val == 0); + + return boost::report_errors(); +} + +#else +int main() {return 0;} +#endif diff --git a/src/boost/libs/dll/test/cpp_import_test.cpp b/src/boost/libs/dll/test/cpp_import_test.cpp new file mode 100644 index 00000000..b6005d05 --- /dev/null +++ b/src/boost/libs/dll/test/cpp_import_test.cpp @@ -0,0 +1,81 @@ +// Copyright 2016 Klemens Morgenstern +// +// 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) + +// For more information, see http://www.boost.org + +#include <boost/predef.h> + +#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0)) + +#include "../example/b2_workarounds.hpp" + +#include <boost/dll/smart_library.hpp> +#include <boost/dll/import_mangled.hpp> + +#include <boost/core/lightweight_test.hpp> +#include <boost/filesystem.hpp> +#include <boost/variant.hpp> +#include <boost/function.hpp> + +#include <iostream> + +struct override_class +{ + int arr[32]; +}; + + +int main(int argc, char* argv[]) +{ + using namespace boost::dll; + using namespace boost::dll::experimental; + boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv); + + BOOST_TEST(!pt.empty()); + std::cout << "Library: " << pt << std::endl; + + smart_library sm(pt); + + auto sp_variable = import_mangled<double>(sm, "some_space::variable"); + + auto unscoped_var = import_mangled<int>(sm, "unscoped_var"); + + + auto ovl = import_mangled<void(int), void(double)>(sm, "overloaded"); + + ovl(12); + BOOST_TEST(*unscoped_var == 12); + ovl(5.0); + BOOST_TEST(*sp_variable == 5.0); + + boost::function<void(int)> f_test = ovl;//test if it binds + f_test(-2); + BOOST_TEST(*unscoped_var == -2); + + sm.add_type_alias<override_class>("some_space::some_class"); + + auto func = import_mangled< + override_class, double(double, double), int(int, int), + volatile override_class, int(int, int), + const volatile override_class, double(double, double)>(sm, "func"); + + override_class override_class_varible{}; + + override_class *ov = &override_class_varible; + volatile override_class *ovv = ov; + const volatile override_class *ovcv = ov; + + BOOST_TEST(func(ov, 3.,2.) == 6.); + BOOST_TEST(func(ov, 1,2 ) == 3 ); + BOOST_TEST(func(ovv, 10,2) == 8 ); + BOOST_TEST(func(ovcv, 9,2) == 4.5 ); + + return boost::report_errors(); +} + +#else +int main() {return 0;} +#endif diff --git a/src/boost/libs/dll/test/cpp_load_test.cpp b/src/boost/libs/dll/test/cpp_load_test.cpp new file mode 100644 index 00000000..7d6b183a --- /dev/null +++ b/src/boost/libs/dll/test/cpp_load_test.cpp @@ -0,0 +1,226 @@ +// Copyright 2016 Klemens Morgenstern +// +// 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) + +// For more information, see http://www.boost.org + +#include <boost/predef.h> + +#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0)) + +#include "../example/b2_workarounds.hpp" + +#include <boost/dll/smart_library.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/filesystem.hpp> +#include <boost/variant.hpp> + +#include <iostream> + +struct override_class +{ + int arr[32]; +}; + + +int main(int argc, char* argv[]) +{ + using namespace boost::dll; + using namespace boost::dll::experimental; + boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv); + + BOOST_TEST(!pt.empty()); + std::cout << "Library: " << pt << std::endl; + std::cerr << 1 << ' '; + smart_library sm(pt); + + auto& unscoped_var = sm.get_variable<int>("unscoped_var"); + BOOST_TEST(unscoped_var == 42); + std::cerr << 2 << ' '; + auto& unscoped_c_var = sm.get_variable<const double>("unscoped_c_var"); + BOOST_TEST(unscoped_c_var == 1.234); + + std::cerr << 3 << ' '; + auto& sp_variable = sm.get_variable<double>("some_space::variable"); + BOOST_TEST(sp_variable == 0.2); + + std::cerr << 4 << ' '; + auto scoped_fun = sm.get_function<const int&()>("some_space::scoped_fun"); + BOOST_TEST(scoped_fun != nullptr); + { std::cerr << 5 << ' '; + auto &res = scoped_fun(); + const int expected = 0xDEADBEEF; + BOOST_TEST(res == expected); + } + std::cerr << 6 << ' '; + auto ovl1 = sm.get_function<void(int)> ("overloaded"); + auto ovl2 = sm.get_function<void(double)>("overloaded"); + std::cerr << 7 << ' '; + BOOST_TEST(ovl1 != nullptr); + BOOST_TEST(ovl2 != nullptr); + BOOST_TEST(reinterpret_cast<void*>(ovl1) != reinterpret_cast<void*>(ovl2)); + std::cerr << 8 << ' '; + ovl1(12); + BOOST_TEST(unscoped_var == 12); + ovl2(5.0); + BOOST_TEST(sp_variable == 5.0); + std::cerr << 9 << ' '; + + + auto var1 = sm.get_function<void(boost::variant<int, double> &)>("use_variant"); + auto var2 = sm.get_function<void(boost::variant<double, int> &)>("use_variant"); + std::cerr << 10 << ' '; + BOOST_TEST(var1 != nullptr); + BOOST_TEST(var2 != nullptr); + BOOST_TEST(reinterpret_cast<void*>(var1) != reinterpret_cast<void*>(var2)); + + { + boost::variant<int, double> v1 = 232.22; + boost::variant<double, int> v2 = -1; + std::cerr << 11 << ' '; + var1(v1); + var2(v2); + + struct : boost::static_visitor<void> + { + void operator()(double) {BOOST_TEST(false);} + void operator()(int i) {BOOST_TEST(i == 42);} + } vis1; + + struct : boost::static_visitor<void> + { + void operator()(double d) {BOOST_TEST(d == 3.124);} + void operator()(int ) {BOOST_TEST(false);} + } vis2; + + boost::apply_visitor(vis1, v1); + boost::apply_visitor(vis2, v2); + + } + std::cerr << 12 << ' '; + /* now test the class stuff */ + + //first we import and test the global variables + + auto& father_val = sm.get_variable<int>("some_space::father_value"); + auto& static_val = sm.get_variable<int>("some_space::some_class::value"); + BOOST_TEST(father_val == 12); + BOOST_TEST(static_val == -1); + std::cerr << 13 << ' '; + //now get the static function. + auto set_value = sm.get_function<void(const int &)>("some_space::some_class::set_value"); + BOOST_TEST(set_value != nullptr); + std::cerr << 14 << ' '; + set_value(42); + BOOST_TEST(static_val == 42); //alright, static method works. + + + //alright, now import the class members + //first add the type alias. + sm.add_type_alias<override_class>("some_space::some_class"); + std::cerr << 15 << ' '; + auto set = sm.get_mem_fn<override_class, void(int)>("set"); + + std::cerr << 16 << ' '; + try { + sm.get_mem_fn<override_class, int()>("get"); + BOOST_TEST(false); + } catch(boost::dll::fs::system_error &) {} + auto get = sm.get_mem_fn<const override_class, int()>("get"); + std::cerr << 17 << ' '; + BOOST_TEST(get != nullptr); + BOOST_TEST(set != nullptr); + std::cerr << 18 << ' '; + auto func_dd = sm.get_mem_fn<override_class, double(double, double)>("func"); + auto func_ii = sm.get_mem_fn<override_class, int(int, int)> ("func"); + auto func_iiv = sm.get_mem_fn<volatile override_class, int(int, int)> ("func"); + auto func_ddc = sm.get_mem_fn<const volatile override_class, double(double, double)>("func"); + + std::cerr << 19 << ' '; + BOOST_TEST(func_dd != nullptr); + BOOST_TEST(func_ii != nullptr); + + std::cerr << 20 << ' '; + auto ctor_v = sm.get_constructor<override_class()>(); + auto ctor_i = sm.get_constructor<override_class(int)>(); + + auto dtor = sm.get_destructor<override_class>(); + std::cerr << 21 << ' '; + //actually never used. + if (ctor_v.has_allocating()) + { + //allocate + auto p = ctor_v.call_allocating(); + + //assert it works + auto val = (p->*get)(); + BOOST_TEST(val == 123); + //deallocate + dtor.call_deleting(p); + //now i cannot assert that it deletes, since it would crash. + } + //More tests to assure the correct this-ptr + std::cerr << 22 << ' '; + typedef override_class * override_class_p; + override_class_p &this_dll = sm.shared_lib().get<override_class_p>("this_"); + + std::cerr << 23 << ' '; + //ok, now load the ctor/dtor + override_class oc; + + override_class_p this_exe = &oc; + + for (auto& i : oc.arr) { + i = 0; + } + std::cerr << 24 << ' '; + + BOOST_TEST((oc.*get)() == 0); BOOST_TEST(this_dll == this_exe); + + ctor_i.call_standard(&oc, 12); BOOST_TEST(this_dll == this_exe); + + BOOST_TEST(static_val == 12); + BOOST_TEST((oc.*get)() == 456); BOOST_TEST(this_dll == this_exe); + (oc.*set)(42); + BOOST_TEST((oc.*get)() == 42); BOOST_TEST(this_dll == this_exe); + std::cerr << 25 << ' '; + + BOOST_TEST((oc.*func_dd)(3,2) == 6); BOOST_TEST(this_dll == this_exe); + BOOST_TEST((oc.*func_ii)(1,2) == 3); BOOST_TEST(this_dll == this_exe); + BOOST_TEST((oc.*func_ddc)(10,2) == 5); BOOST_TEST(this_dll == this_exe); + BOOST_TEST((oc.*func_iiv)(9,2) == 7); BOOST_TEST(this_dll == this_exe); + std::cerr << 26 << ' '; + dtor.call_standard(&oc); BOOST_TEST(this_dll == this_exe); + BOOST_TEST(static_val == 0); + +// TODO: FIX! +#ifndef BOOST_TRAVISCI_BUILD + const auto& ti = sm.get_type_info<override_class>(); + BOOST_TEST(ti.name() != nullptr); +#endif + std::cerr << 27 << ' '; + //test the ovls helper. + { + namespace ex = boost::dll::experimental; + auto &var = ex::get<double>(sm, "some_space::variable"); + BOOST_TEST(&var == &sp_variable); + + auto fun = ex::get<void(int)>(sm, "overloaded"); + BOOST_TEST(fun == ovl1); + + auto func_ii = sm.get_mem_fn<override_class, int(int, int)> ("func"); + + auto mem_fn = ex::get<override_class, int(int, int)>(sm, "func"); + + BOOST_TEST(mem_fn == func_ii); + } + + std::cerr << 28 << ' '; + return boost::report_errors(); +} + +#else +int main() {return 0;} +#endif diff --git a/src/boost/libs/dll/test/cpp_mangle_test.cpp b/src/boost/libs/dll/test/cpp_mangle_test.cpp new file mode 100644 index 00000000..2aabb3a5 --- /dev/null +++ b/src/boost/libs/dll/test/cpp_mangle_test.cpp @@ -0,0 +1,131 @@ +// Copyright 2016 Klemens Morgenstern +// +// 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) + +// For more information, see http://www.boost.org + +#include <boost/predef.h> + +#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0)) + +#include "../example/b2_workarounds.hpp" + +#include <boost/dll/smart_library.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/filesystem.hpp> +#include <boost/variant.hpp> + +#include <iostream> + + +struct override_class {}; + + +int main(int argc, char* argv[]) +{ + using namespace boost::dll; + using mangled_storage = detail::mangled_storage_impl; + + boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv);; + + std::cout << "Library: " << pt << std::endl; + library_info lib{pt}; + + mangled_storage ms(lib); + + std::cout << "Symbols: " << std::endl; + + for (auto &s : ms.get_storage()) + { + std::cout << s.demangled << std::endl; + } + + std::string v; + v = ms.get_variable<double>("some_space::variable"); + + BOOST_TEST(!v.empty()); //check if a symbols was found. + BOOST_TEST(v != "some_space::variable"); //demangle is different + + v = ms.get_variable<double>("some_space::variable_typo"); + BOOST_TEST(v.empty()); + + + v = ms.get_variable<const double>("unscoped_c_var"); + + BOOST_TEST(!v.empty()); //check if a symbols was found. + + v = ms.get_variable<int>("unscoped_var"); + + BOOST_TEST(!v.empty()); //check if a symbols was found. + + + v = ms.get_function<const int &()>("some_space::scoped_fun"); + + BOOST_TEST(!v.empty()); + BOOST_TEST(v != "some_space::scoped_fun"); + + + auto v1 = ms.get_function<void(const double)>("overloaded"); + auto v2 = ms.get_function<void(const volatile int)>("overloaded"); + BOOST_TEST(!v1.empty()); + BOOST_TEST(!v2.empty()); + BOOST_TEST(v1 != v2); + + v = ms.get_variable<int>("some_space::some_class::value"); + BOOST_TEST(!v.empty()); + BOOST_TEST(v != "some_space::some_class::value"); + + v = ms.get_function<void(const int &)>("some_space::some_class::set_value"); + + BOOST_TEST(!v.empty()); + BOOST_TEST(v != "some_space::some_class::set_value"); + + + + ms.add_alias<override_class>("some_space::some_class"); + + auto ctor1 = ms.get_constructor<override_class()>(); + BOOST_TEST(!ctor1.empty()); + + auto ctor2 = ms.get_constructor<override_class(int)>(); + BOOST_TEST(!ctor2.empty()); + + + v = ms.get_mem_fn<override_class, double(double, double)>("func"); + BOOST_TEST(!v.empty()); + + v = ms.get_mem_fn<override_class, int(int, int)>("func"); + BOOST_TEST(!v.empty()); + + + auto dtor = ms.get_destructor<override_class>(); + + BOOST_TEST(!dtor.empty()); + + auto var1 = ms.get_function<void(boost::variant<int, double> &)>("use_variant"); + auto var2 = ms.get_function<void(boost::variant<double, int> &)>("use_variant"); + + BOOST_TEST(!var1.empty()); + BOOST_TEST(!var2.empty()); + +// TODO: FIX! +#ifndef BOOST_TRAVISCI_BUILD + +#if defined(BOOST_MSVC) || defined(BOOST_MSVC_VER) + auto vtable = ms.get_vtable<override_class>(); + BOOST_TEST(!vtable.empty()); +#else + auto ti = ms.get_type_info<override_class>(); + BOOST_TEST(!ti.empty()); +#endif + +#endif // #ifndef BOOST_TRAVISCI_BUILD + + return boost::report_errors(); +} + +#else +int main() {return 0;} +#endif diff --git a/src/boost/libs/dll/test/cpp_test_library.cpp b/src/boost/libs/dll/test/cpp_test_library.cpp new file mode 100644 index 00000000..d6216477 --- /dev/null +++ b/src/boost/libs/dll/test/cpp_test_library.cpp @@ -0,0 +1,138 @@ +// Copyright 2016 Klemens Morgenstern +// +// 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) + +// For more information, see http://www.boost.org + +#include <boost/predef.h> + +#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0)) + +#include <boost/dll/config.hpp> +#include <boost/variant.hpp> + +BOOST_SYMBOL_EXPORT extern int unscoped_var; +int unscoped_var = 42; + +BOOST_SYMBOL_EXPORT extern const double unscoped_c_var; +const double unscoped_c_var = 1.234; + + +namespace some_space { + +BOOST_SYMBOL_EXPORT extern double variable; +double variable = 0.2; +BOOST_SYMBOL_EXPORT const int & scoped_fun() +{ + static int x = 0xDEADBEEF; + return x; +} + +} + + +BOOST_SYMBOL_EXPORT void overloaded(const volatile int i) +{ + unscoped_var = i; +} + +BOOST_SYMBOL_EXPORT void overloaded(const double d) +{ + some_space::variable = d; +} + +BOOST_SYMBOL_EXPORT void use_variant(boost::variant<int, double> & v) +{ + v = 42; +} + +BOOST_SYMBOL_EXPORT void use_variant(boost::variant<double, int> & v) +{ + v = 3.124; +} + + + +namespace some_space +{ + +BOOST_SYMBOL_EXPORT extern int father_value; +int father_value = 12; + +struct BOOST_SYMBOL_EXPORT some_father +{ + some_father() { father_value = 24; }; + ~some_father() { father_value = 112; }; +}; + + + +struct BOOST_SYMBOL_EXPORT some_class : some_father +{ + static int value ; + static void set_value(const int &i); + + // static some_class* dummy(); + + virtual double func(double i, double j); + virtual int func(int i, int j); + int func(int i, int j) volatile; + double func(double i, double j) const volatile; + + int mem_val; + int get() const ; + void set(int i) ; + + some_class(); + some_class(some_class &&); + some_class(int i); + + some_class& operator=(some_class &&); + + + virtual ~some_class(); +}; + +some_class::some_class(some_class &&){} + + +some_class& some_class::operator=(some_class &&ref) {return ref;} + + +BOOST_SYMBOL_EXPORT extern std::size_t size_of_some_class; +std::size_t size_of_some_class = sizeof(some_space::some_class); + + +extern "C" BOOST_SYMBOL_EXPORT const volatile some_class* this_; +const volatile some_class * this_ = nullptr; + +int some_class::value = -1; + +void some_class::set_value(const int &i) {value = i;} + + +//some_class* some_class::dummy() {return new some_class();}//so it implements an allocating ctor. + +double some_class::func(double i, double j) {this_ = this; return i*j;} +int some_class::func(int i, int j) {this_ = this; return i+j;} +int some_class::func(int i, int j) volatile {this_ = this; return i-j;;} +double some_class::func(double i, double j) const volatile {this_ = this; return i/j;} + +int some_class::get() const {this_ = this; return mem_val;} +void some_class::set(int i) {this_ = this; mem_val = i;} + +some_class::some_class() { this_ = this; value = 23; mem_val = 123;} +some_class::some_class(int i) : mem_val(456) {this_ = this; value = i;} + +some_class::~some_class() +{ + value = 0; + this_ = this; +} + +} + + +#endif diff --git a/src/boost/libs/dll/test/library_info_test.cpp b/src/boost/libs/dll/test/library_info_test.cpp new file mode 100644 index 00000000..e7808e96 --- /dev/null +++ b/src/boost/libs/dll/test/library_info_test.cpp @@ -0,0 +1,65 @@ +// Copyright 2011-2012 Renato Tegon Forti +// Copyright 2015-2019 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) + +// For more information, see http://www.boost.org + +// MinGW related workaround +#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION +#include "../example/b2_workarounds.hpp" + +#include <boost/dll/library_info.hpp> +#include <boost/core/lightweight_test.hpp> +#include "../example/tutorial4/static_plugin.hpp" + +// Unit Tests + +#include <iterator> + +int main(int argc, char* argv[]) +{ + boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv); + BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos); + + boost::dll::library_info lib_info(shared_library_path); + std::vector<std::string> sec = lib_info.sections(); + std::copy(sec.begin(), sec.end(), std::ostream_iterator<std::string>(std::cout, ", ")); + BOOST_TEST(std::find(sec.begin(), sec.end(), "boostdll") != sec.end()); + + + std::cout << "\n\n\n"; + std::vector<std::string> symb = lib_info.symbols(); + std::copy(symb.begin(), symb.end(), std::ostream_iterator<std::string>(std::cout, "\n")); + BOOST_TEST(std::find(symb.begin(), symb.end(), "const_integer_g") != symb.end()); + BOOST_TEST(std::find(symb.begin(), symb.end(), "say_hello") != symb.end()); + + symb = lib_info.symbols("boostdll"); + std::copy(symb.begin(), symb.end(), std::ostream_iterator<std::string>(std::cout, "\n")); + BOOST_TEST(std::find(symb.begin(), symb.end(), "const_integer_g_alias") != symb.end()); + BOOST_TEST(std::find(symb.begin(), symb.end(), "foo_variable") != symb.end()); + BOOST_TEST(std::find(symb.begin(), symb.end(), "const_integer_g") == symb.end()); + BOOST_TEST(std::find(symb.begin(), symb.end(), "say_hello") == symb.end()); + BOOST_TEST(lib_info.symbols(std::string("boostdll")) == symb); + + std::vector<std::string> empty = lib_info.symbols("empty"); + BOOST_TEST(empty.empty() == true); + + BOOST_TEST(lib_info.symbols("section_that_does_not_exist").empty()); + + // Self testing + std::cout << "Self: " << argv[0]; + boost::dll::library_info self_info(argv[0]); + + sec = self_info.sections(); + //std::copy(sec.begin(), sec.end(), std::ostream_iterator<std::string>(std::cout, ", ")); + BOOST_TEST(std::find(sec.begin(), sec.end(), "boostdll") != sec.end()); + + symb = self_info.symbols("boostdll"); + std::copy(symb.begin(), symb.end(), std::ostream_iterator<std::string>(std::cout, "\n")); + BOOST_TEST(std::find(symb.begin(), symb.end(), "create_plugin") != symb.end()); + + return boost::report_errors(); +} diff --git a/src/boost/libs/dll/test/link.hpp b/src/boost/libs/dll/test/link.hpp new file mode 100644 index 00000000..f84d8bd3 --- /dev/null +++ b/src/boost/libs/dll/test/link.hpp @@ -0,0 +1,21 @@ +// Copyright 2018-2019 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) +// +// For more information, see http://www.boost.org + + +#include <boost/predef.h> + +#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0)) + +#include <boost/dll/smart_library.hpp> +#include <boost/dll/import_mangled.hpp> +#include <boost/dll/import_class.hpp> + +#endif + + +#include <boost/dll.hpp> diff --git a/src/boost/libs/dll/test/link1.cpp b/src/boost/libs/dll/test/link1.cpp new file mode 100644 index 00000000..639e827c --- /dev/null +++ b/src/boost/libs/dll/test/link1.cpp @@ -0,0 +1,10 @@ +// Copyright 2018-2019 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) +// +// For more information, see http://www.boost.org + + +#include "link.hpp" diff --git a/src/boost/libs/dll/test/link2.cpp b/src/boost/libs/dll/test/link2.cpp new file mode 100644 index 00000000..670d3906 --- /dev/null +++ b/src/boost/libs/dll/test/link2.cpp @@ -0,0 +1,12 @@ +// Copyright 2018-2019 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) +// +// For more information, see http://www.boost.org + + +#include "link.hpp" + +int main() {} diff --git a/src/boost/libs/dll/test/section_name_too_big.cpp b/src/boost/libs/dll/test/section_name_too_big.cpp new file mode 100644 index 00000000..03db48f5 --- /dev/null +++ b/src/boost/libs/dll/test/section_name_too_big.cpp @@ -0,0 +1,17 @@ +// Copyright 2011-2012 Renato Tegon Forti +// Copyright 2014 Renato Tegon Forti, Antony Polukhin. +// Copyright 2015-2019 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) + +// For more information, see http://www.boost.org + +#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION +#include <boost/dll/config.hpp> +#include <boost/dll/alias.hpp> + +int integer_g = 100; +BOOST_DLL_ALIAS_SECTIONED(integer_g, integer_g_aliased, "long_section_name") + diff --git a/src/boost/libs/dll/test/shared_library_concurrent_load_test.cpp b/src/boost/libs/dll/test/shared_library_concurrent_load_test.cpp new file mode 100644 index 00000000..e97926b7 --- /dev/null +++ b/src/boost/libs/dll/test/shared_library_concurrent_load_test.cpp @@ -0,0 +1,82 @@ +// Copyright 2015-2019 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) + +// For more information, see http://www.boost.org + +#ifdef BOOST_TRAVISCI_BUILD + +int main() { + return 0; +} + +#else // #ifdef BOOST_TRAVISCI_BUILD + +#include "../example/b2_workarounds.hpp" +#include <boost/dll.hpp> +#include <boost/filesystem/path.hpp> +#include <boost/thread/thread.hpp> +#include <boost/thread/barrier.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/bind.hpp> +#include <cctype> +#include <vector> + +typedef std::vector<boost::dll::fs::path> paths_t; +const std::size_t thread_count = 4; +boost::barrier b(thread_count); + + +// Disgusting workarounds for b2 on Windows platform +inline paths_t generate_paths(int argc, char* argv[]) { + paths_t ret; + ret.reserve(argc - 1); + + for (int i = 1; i < argc; ++i) { + boost::dll::fs::path p = argv[i]; + if (b2_workarounds::is_shared_library(p)) { + ret.push_back(p); + } + } + + return ret; +} + +inline void load_unload(const paths_t& paths, std::size_t count) { + for (std::size_t j = 0; j < count; j += 2) { + for (std::size_t i = 0; i < paths.size(); ++i) { + boost::dll::shared_library lib(paths[i]); + BOOST_TEST(lib); + } + for (std::size_t i = 0; i < paths.size(); ++i) { + boost::dll::shared_library lib(paths[i]); + BOOST_TEST(lib.location() != ""); + } + + // Waiting for all threads to unload shared libraries + b.wait(); + } +} + + +int main(int argc, char* argv[]) { + BOOST_TEST(argc >= 3); + paths_t paths = generate_paths(argc, argv); + BOOST_TEST(!paths.empty()); + + std::cout << "Libraries:\n\t"; + std::copy(paths.begin(), paths.end(), std::ostream_iterator<boost::dll::fs::path>(std::cout, ", ")); + std::cout << std::endl; + + boost::thread_group threads; + for (std::size_t i = 0; i < thread_count; ++i) { + threads.create_thread(boost::bind(load_unload, paths, 1000)); + } + threads.join_all(); + + return boost::report_errors(); +} + +#endif // #ifdef BOOST_TRAVISCI_BUILD diff --git a/src/boost/libs/dll/test/shared_library_errors.cpp b/src/boost/libs/dll/test/shared_library_errors.cpp new file mode 100644 index 00000000..2f186fe1 --- /dev/null +++ b/src/boost/libs/dll/test/shared_library_errors.cpp @@ -0,0 +1,100 @@ +// Copyright 2011-2012 Renato Tegon Forti. +// Copyright 2014 Renato Tegon Forti, Antony Polukhin. +// Copyright 2015-2019 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) + +// For more information, see http://www.boost.org + +#include "../example/b2_workarounds.hpp" +#include <boost/dll/shared_library.hpp> +#include <boost/dll/library_info.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/function.hpp> + + +// Unit Tests +int main(int argc, char* argv[]) { + using namespace boost::dll; + + boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv); + BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos); + BOOST_TEST(b2_workarounds::is_shared_library(shared_library_path)); + boost::dll::fs::path bad_path = shared_library_path / "directory_that_does_not_exist"; + + try { + shared_library lib(bad_path); + BOOST_TEST(false); + } catch (const boost::dll::fs::system_error& e) { + std::cout << e.what() << '\n'; + } + + try { + shared_library lib; + lib.get<int>("variable_or_function_that_does_not_exist"); + BOOST_TEST(false); + } catch (const boost::dll::fs::system_error& e) { + std::cout << e.what() << '\n'; + } + + try { + shared_library lib(""); + BOOST_TEST(false); + } catch (const boost::dll::fs::system_error& e) { + std::cout << e.what() << '\n'; + } + + try { + shared_library lib("\0\0"); + BOOST_TEST(false); + } catch (const boost::dll::fs::system_error& e) { + std::cout << e.what() << '\n'; + } + + try { + shared_library lib; + lib.location(); + BOOST_TEST(false); + } catch (const boost::dll::fs::system_error& e) { + std::cout << e.what() << '\n'; + } + + try { + shared_library lib; + lib.load("\0\0", load_mode::rtld_global); + BOOST_TEST(false); + } catch (const boost::dll::fs::system_error& e) { + std::cout << e.what() << '\n'; + } + + shared_library sl(shared_library_path); + try { + sl.get<int>("variable_or_function_that_does_not_exist"); + BOOST_TEST(false); + } catch (const boost::dll::fs::system_error& e) { + std::cout << e.what() << '\n'; + } + + try { + library_info lib("\0"); + BOOST_TEST(false); + } catch (const std::exception& e) { + std::cout << e.what() << '\n'; + } + + try { + std::string not_a_binary(argv[1]); + not_a_binary += "/not_a_binary"; + std::ofstream ofs(not_a_binary.c_str()); + ofs << "This is not a binary file, so library_info must report 'Unsupported binary format'"; + ofs.close(); + library_info lib(not_a_binary); + BOOST_TEST(false); + } catch (const std::exception& e) { + std::cout << e.what() << '\n'; + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/dll/test/shared_library_get_symbol_test.cpp b/src/boost/libs/dll/test/shared_library_get_symbol_test.cpp new file mode 100644 index 00000000..82e524d3 --- /dev/null +++ b/src/boost/libs/dll/test/shared_library_get_symbol_test.cpp @@ -0,0 +1,193 @@ +// Copyright 2011-2012 Renato Tegon Forti. +// Copyright 2014 Renato Tegon Forti, Antony Polukhin. +// Copyright 2015-2019 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) + +// For more information, see http://www.boost.org + +#include "../example/b2_workarounds.hpp" +#include <boost/dll.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/function.hpp> +#include <boost/fusion/container.hpp> +// lib functions + +typedef float (lib_version_func)(); +typedef void (say_hello_func) (); +typedef int (increment) (int); + +typedef boost::fusion::vector<std::vector<int>, std::vector<int>, std::vector<int>, const std::vector<int>*, std::vector<int>* > do_share_res_t; +typedef boost::shared_ptr<do_share_res_t> (do_share_t)( + std::vector<int> v1, + std::vector<int>& v2, + const std::vector<int>& v3, + const std::vector<int>* v4, + std::vector<int>* v5 + ); + +void refcountable_test(boost::dll::fs::path shared_library_path) { + using namespace boost::dll; + using namespace boost::fusion; + + std::vector<int> v(1000); + + { + boost::function<say_hello_func> sz2 + = import<say_hello_func>(shared_library_path, "say_hello"); + + sz2(); + sz2(); + sz2(); + } + + { + boost::function<std::size_t(const std::vector<int>&)> sz + = import_alias<std::size_t(const std::vector<int>&)>(shared_library_path, "foo_bar"); + BOOST_TEST(sz(v) == 1000); + } + + + { + boost::function<do_share_t> f; + + { + boost::function<do_share_t> f2 = import_alias<do_share_t>(shared_library_path, "do_share"); + f = f2; + } + + std::vector<int> v1(1, 1), v2(2, 2), v3(3, 3), v4(4, 4), v5(1000, 5); + boost::shared_ptr<do_share_res_t> res = f(v1, v2, v3, &v4, &v5); + + BOOST_TEST(at_c<0>(*res).size() == 1); BOOST_TEST(at_c<0>(*res).front() == 1); + BOOST_TEST(at_c<1>(*res).size() == 2); BOOST_TEST(at_c<1>(*res).front() == 2); + BOOST_TEST(at_c<2>(*res).size() == 3); BOOST_TEST(at_c<2>(*res).front() == 3); + BOOST_TEST(at_c<3>(*res)->size() == 4); BOOST_TEST(at_c<3>(*res)->front() == 4); + BOOST_TEST(at_c<4>(*res)->size() == 1000); BOOST_TEST(at_c<4>(*res)->front() == 5); + + BOOST_TEST(at_c<3>(*res) == &v4); + BOOST_TEST(at_c<4>(*res) == &v5); + BOOST_TEST(at_c<1>(*res).back() == 777); + BOOST_TEST(v5.back() == 9990); + } + + { + boost::shared_ptr<int> i = import<int>(shared_library_path, "integer_g"); + BOOST_TEST(*i == 100); + + boost::shared_ptr<int> i2; + i.swap(i2); + BOOST_TEST(*i2 == 100); + } + + { + boost::function<int&()> f = import_alias<int&()>(shared_library_path, "ref_returning_function"); + BOOST_TEST(f() == 0); + + f() = 10; + BOOST_TEST(f() == 10); + + boost::function<int&()> f1 = import_alias<int&()>(shared_library_path, "ref_returning_function"); + BOOST_TEST(f1() == 10); + + f1() += 10; + BOOST_TEST(f() == 20); + } + + { + boost::shared_ptr<const int> i = import<const int>(shared_library_path, "const_integer_g"); + BOOST_TEST(*i == 777); + + boost::shared_ptr<const int> i2 = i; + i.reset(); + BOOST_TEST(*i2 == 777); + } + + { + boost::shared_ptr<std::string> s = import_alias<std::string>(shared_library_path, "info"); + BOOST_TEST(*s == "I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world')."); + + boost::shared_ptr<std::string> s2; + s.swap(s2); + BOOST_TEST(*s2 == "I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world')."); + } +} + +// exe function +extern "C" int BOOST_SYMBOL_EXPORT exef() { + return 15; +} + +// Unit Tests +int main(int argc, char* argv[]) { + using namespace boost::dll; + + boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv); + BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos); + BOOST_TEST(b2_workarounds::is_shared_library(shared_library_path)); + + refcountable_test(shared_library_path); + + shared_library sl(shared_library_path); + + BOOST_TEST(sl.get<int>("integer_g") == 100); + + sl.get<int>("integer_g") = 10; + BOOST_TEST(sl.get<int>("integer_g") == 10); + BOOST_TEST(sl.get<int>(std::string("integer_g")) == 10); + + BOOST_TEST(sl.get<say_hello_func>("say_hello")); + sl.get<say_hello_func>("say_hello")(); + + float ver = sl.get<lib_version_func>("lib_version")(); + BOOST_TEST(ver == 1.0); + + int n = sl.get<increment>("increment")(1); + BOOST_TEST(n == 2); + + BOOST_TEST(sl.get<const int>("const_integer_g") == 777); + + boost::function<int(int)> inc = sl.get<int(int)>("increment"); + BOOST_TEST(inc(1) == 2); + BOOST_TEST(inc(2) == 3); + BOOST_TEST(inc(3) == 4); + + // Checking that symbols are still available, after another load+unload of the library + { shared_library sl2(shared_library_path); } + + BOOST_TEST(inc(1) == 2); + BOOST_TEST(sl.get<int>("integer_g") == 10); + + + // Checking aliases + boost::function<std::size_t(const std::vector<int>&)> sz + = sl.get_alias<std::size_t(const std::vector<int>&)>("foo_bar"); + + std::vector<int> v(10); + BOOST_TEST(sz(v) == 10); + BOOST_TEST(sl.get_alias<std::size_t>("foo_variable") == 42); + + + sz = sl.get<std::size_t(*)(const std::vector<int>&)>("foo_bar"); + BOOST_TEST(sz(v) == 10); + BOOST_TEST(*sl.get<std::size_t*>("foo_variable") == 42); + + { // self + shared_library sl(program_location()); + int val = sl.get<int(void)>("exef")(); + BOOST_TEST(val == 15); + } + + int& reference_to_internal_integer = sl.get<int&>("reference_to_internal_integer"); + BOOST_TEST(reference_to_internal_integer == 0xFF0000); + +#ifndef BOOST_NO_RVALUE_REFERENCES + int&& rvalue_reference_to_internal_integer = sl.get<int&&>("rvalue_reference_to_internal_integer"); + BOOST_TEST(rvalue_reference_to_internal_integer == 0xFF0000); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/dll/test/shared_library_load_test.cpp b/src/boost/libs/dll/test/shared_library_load_test.cpp new file mode 100644 index 00000000..de7e619e --- /dev/null +++ b/src/boost/libs/dll/test/shared_library_load_test.cpp @@ -0,0 +1,528 @@ +// Copyright 2011-2012 Renato Tegon Forti +// Copyright 2015-2019 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) + +// For more information, see http://www.boost.org + +#include "../example/b2_workarounds.hpp" +#include <boost/dll.hpp> +#include <boost/core/lightweight_test.hpp> +// Unit Tests + +namespace boost { namespace dll { namespace fs { + +#ifdef BOOST_DLL_USE_STD_FS +using std::filesystem::remove; +using std::filesystem::copy; +#else +using boost::filesystem::remove; +using boost::filesystem::copy; +#endif + +}}} + +inline boost::dll::fs::path drop_version(const boost::dll::fs::path& lhs) { + boost::dll::fs::path ext = lhs.filename().extension(); + if (ext.native().size() > 1 && std::isdigit(ext.string()[1])) { + ext = lhs; + ext.replace_extension().replace_extension().replace_extension(); + return ext; + } + + return lhs; +} + +inline bool lib_path_equal(const boost::dll::fs::path& lhs, const boost::dll::fs::path& rhs) { + const bool res = (drop_version(lhs).filename() == drop_version(rhs).filename()); + if (!res) { + std::cerr << "lhs != rhs: " << lhs << " != " << rhs << '\n'; + } + return res; +} + +struct fs_copy_guard { + const boost::dll::fs::path actual_path_; + const bool same_; + + inline explicit fs_copy_guard(const boost::dll::fs::path& shared_library_path) + : actual_path_( drop_version(shared_library_path) ) + , same_(actual_path_ == shared_library_path) + { + if (!same_) { + boost::dll::fs::error_code ignore; + boost::dll::fs::remove(actual_path_, ignore); + boost::dll::fs::copy(shared_library_path, actual_path_, ignore); + } + } + + inline ~fs_copy_guard() { + if (!same_) { + boost::dll::fs::error_code ignore; + boost::dll::fs::remove(actual_path_, ignore); + } + } +}; + +// Disgusting workarounds for b2 on Windows platform +inline boost::dll::fs::path do_find_correct_libs_path(int argc, char* argv[], const char* lib_name) { + boost::dll::fs::path ret; + + for (int i = 1; i < argc; ++i) { + ret = argv[i]; + if (ret.string().find(lib_name) != std::string::npos && b2_workarounds::is_shared_library(ret)) { + return ret; + } + } + + return lib_name; +} + +int main(int argc, char* argv[]) +{ + using namespace boost::dll; + + BOOST_TEST(argc >= 3); + boost::dll::fs::path shared_library_path = do_find_correct_libs_path(argc, argv, "test_library"); + std::cout << "Library: " << shared_library_path; + + { + shared_library sl(shared_library_path); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + + shared_library sl2; + BOOST_TEST(!sl2.is_loaded()); + BOOST_TEST(!sl2); + + swap(sl, sl2); + BOOST_TEST(!sl.is_loaded()); + BOOST_TEST(!sl); + BOOST_TEST(sl2.is_loaded()); + BOOST_TEST(sl2); + + sl.assign(sl2); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(sl2.is_loaded()); + BOOST_TEST(sl2); + BOOST_TEST(sl2.location() == sl.location()); + + sl.assign(sl2); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(sl2.is_loaded()); + BOOST_TEST(sl2); + BOOST_TEST(sl2.location() == sl.location()); + + sl2.assign(sl); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(sl2.is_loaded()); + BOOST_TEST(sl2); + BOOST_TEST(sl2.location() == sl.location()); + + // Assigning an empty shared library + sl2.assign(shared_library()); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!sl2.is_loaded()); + BOOST_TEST(!sl2); + boost::dll::fs::error_code ec; + BOOST_TEST(sl2.location(ec) != sl.location()); + BOOST_TEST(ec); + } + + { + boost::dll::fs::error_code ec; + shared_library sl(shared_library_path, ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!ec); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path)); + BOOST_TEST(!ec); + + // Checking self assignment #1 + sl.assign(sl); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!ec); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path)); + + // Checking self assignment #2 + sl.assign(sl, ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!ec); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path)); + } + + { + shared_library sl; + BOOST_TEST(!sl.is_loaded()); + + sl.assign(sl); + BOOST_TEST(!sl); + + shared_library sl2(sl); + BOOST_TEST(!sl); + BOOST_TEST(!sl2); + + sl2.assign(sl); + BOOST_TEST(!sl); + BOOST_TEST(!sl2); + } + + { + shared_library sl; + sl.load(shared_library_path); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + } + + { + shared_library sl; + boost::dll::fs::error_code ec; + sl.load(shared_library_path, ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!ec); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + } + + { + shared_library sl(shared_library_path, load_mode::load_with_altered_search_path ); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + } + + { + boost::dll::fs::error_code ec; + shared_library sl(shared_library_path, load_mode::load_with_altered_search_path, ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!ec); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path)); + BOOST_TEST(!ec); + } + + { + boost::dll::fs::error_code ec; + shared_library sl(shared_library_path, load_mode::search_system_folders, ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!ec); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path)); + BOOST_TEST(!ec); + } + + { + try { +#if BOOST_OS_WINDOWS + boost::dll::shared_library("winmm.dll"); +#elif BOOST_OS_LINUX + boost::dll::shared_library("libdl.so"); +#endif + BOOST_TEST(false); + } catch (...) {} + } + + { + try { +#if BOOST_OS_WINDOWS + boost::dll::shared_library("winmm", load_mode::search_system_folders | load_mode::append_decorations); +#elif BOOST_OS_LINUX + boost::dll::shared_library("dl", boost::dll::load_mode::search_system_folders | load_mode::append_decorations); +#endif + } catch (...) { + BOOST_TEST(false); + } + } + + { + shared_library sl; + sl.load(shared_library_path, load_mode::load_with_altered_search_path); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + } + + { + shared_library sl; + boost::dll::fs::error_code ec; + sl.load(shared_library_path, load_mode::load_with_altered_search_path, ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + } + + { + shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + } + + { + shared_library sl(shared_library_path, load_mode::rtld_local); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + } + + { + shared_library sl(shared_library_path, load_mode::rtld_now); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + } + + { + fs_copy_guard guard(shared_library_path); + + boost::dll::fs::path platform_independent_path = guard.actual_path_; + platform_independent_path.replace_extension(); + if (platform_independent_path.filename().wstring().find(L"lib") == 0) { + platform_independent_path + = platform_independent_path.parent_path() / platform_independent_path.filename().wstring().substr(3); + } + std::cerr << "platform_independent_path: " << platform_independent_path << '\n'; + + shared_library sl(platform_independent_path, load_mode::append_decorations); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + + sl.unload(); + BOOST_TEST(!sl.is_loaded()); + BOOST_TEST(!sl); + } + + { + shared_library sl(shared_library_path, load_mode::rtld_now | load_mode::rtld_global | load_mode::load_with_altered_search_path); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + } + + { + boost::dll::fs::error_code ec; + shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!ec); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + } + + { + shared_library sl; + sl.load(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + } + + + { // Non-default flags with assignment + shared_library sl(shared_library_path, + load_mode::rtld_now | load_mode::rtld_global | load_mode::load_with_altered_search_path + +// `load_mode::rtld_deepbind` is incompatible with sanitizers: +// You are trying to dlopen a libtest_library.so shared library with RTLD_DEEPBIND flag which is incompatibe with sanitizer runtime +// (see https://github.com/google/sanitizers/issues/611 for details). +#ifndef BOOST_TRAVISCI_BUILD + | load_mode::rtld_deepbind +#endif + + ); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + + boost::dll::fs::error_code ec; + shared_library sl2(sl, ec); + BOOST_TEST(!ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(sl2.is_loaded()); + BOOST_TEST(sl2); + BOOST_TEST(sl2.location() == sl.location()); + + shared_library sl3(sl); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(sl3.is_loaded()); + BOOST_TEST(sl3); + + shared_library sl4; + sl4.assign(sl, ec); + BOOST_TEST(!ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(sl4.is_loaded()); + BOOST_TEST(sl4); + } + + { // Non-default flags with assignment and error_code + boost::dll::fs::error_code ec; + shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!ec); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + + shared_library sl2(sl, ec); + BOOST_TEST(!ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(sl2.is_loaded()); + BOOST_TEST(sl2); + BOOST_TEST(sl2.location() == sl.location()); + + shared_library sl3(sl); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(sl3.is_loaded()); + BOOST_TEST(sl3); + BOOST_TEST(sl3.location() == sl.location()); + } + + { // self_load + shared_library sl(program_location()); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + std::cout << "\nProgram location: " << program_location(); + std::cout << "\nLibrary location: " << sl.location(); + BOOST_TEST( boost::dll::fs::equivalent(sl.location(), program_location()) ); + + boost::dll::fs::error_code ec; + shared_library sl2(program_location()); + BOOST_TEST(sl2.is_loaded()); + BOOST_TEST( boost::dll::fs::equivalent(sl2.location(), program_location()) ); + BOOST_TEST(sl2); + BOOST_TEST(!ec); + + BOOST_TEST(sl == sl2); + BOOST_TEST(!(sl < sl2 || sl2 <sl)); + BOOST_TEST(!(sl != sl2)); + + sl.load(shared_library_path); + BOOST_TEST(sl != sl2); + BOOST_TEST(sl < sl2 || sl2 <sl); + BOOST_TEST(!(sl == sl2)); + + sl.unload(); + BOOST_TEST(!sl); + BOOST_TEST(sl != sl2); + BOOST_TEST(sl < sl2 || sl2 <sl); + BOOST_TEST(!(sl == sl2)); + + sl2.unload(); + BOOST_TEST(!sl2); + BOOST_TEST(sl == sl2); + BOOST_TEST(!(sl < sl2 || sl2 <sl)); + BOOST_TEST(!(sl != sl2)); + + // assigning self + sl.load(program_location()); + sl2 = sl; + BOOST_TEST(sl == sl2); + BOOST_TEST(sl.location() == sl2.location()); + } + + { + shared_library sl; + boost::dll::fs::error_code ec; + sl.load(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!ec); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + + sl.load(program_location()); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + + sl.load(program_location()); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!ec); + } + + { // self_load + shared_library sl; + boost::dll::fs::error_code ec; + sl.load(program_location()); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(!ec); + } + + { // unload + shared_library sl(shared_library_path); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + BOOST_TEST(lib_path_equal(sl.location(), shared_library_path)); + sl.unload(); + BOOST_TEST(!sl.is_loaded()); + BOOST_TEST(!sl); + } + + + { // error_code load calls test + boost::dll::fs::error_code ec; + shared_library sl(shared_library_path / "dir_that_does_not_exist", ec); + BOOST_TEST(ec); + BOOST_TEST(!sl.is_loaded()); + BOOST_TEST(!sl); + + boost::dll::fs::path bad_path(shared_library_path); + bad_path += ".1.1.1.1.1.1"; + sl.load(bad_path, ec); + BOOST_TEST(ec); + BOOST_TEST(!sl.is_loaded()); + BOOST_TEST(!sl); + + sl.load(shared_library_path, ec); + BOOST_TEST(!ec); + BOOST_TEST(sl.is_loaded()); + BOOST_TEST(sl); + + shared_library sl2(bad_path, ec); + BOOST_TEST(ec); + BOOST_TEST(!sl2.is_loaded()); + BOOST_TEST(!sl2); + + shared_library sl3(shared_library_path, ec); + BOOST_TEST(!ec); + BOOST_TEST(sl3.is_loaded()); + BOOST_TEST(sl3); + + sl.load("", ec); + BOOST_TEST(ec); + BOOST_TEST(!sl.is_loaded()); + BOOST_TEST(!sl); + } + + + shared_library_path = do_find_correct_libs_path(argc, argv, "library1"); + fs_copy_guard guard(shared_library_path); + shared_library starts_with_lib( + boost::dll::fs::path(guard.actual_path_).replace_extension(), + load_mode::append_decorations + ); + + starts_with_lib.load( + boost::dll::fs::path(guard.actual_path_).replace_extension(), + load_mode::append_decorations + ); + + return boost::report_errors(); +} diff --git a/src/boost/libs/dll/test/shared_library_search_symbol_test.cpp b/src/boost/libs/dll/test/shared_library_search_symbol_test.cpp new file mode 100644 index 00000000..cf1dc66f --- /dev/null +++ b/src/boost/libs/dll/test/shared_library_search_symbol_test.cpp @@ -0,0 +1,49 @@ +// Copyright 2011-2012 Renato Tegon Forti +// Copyright 2014 Renato Tegon Forti, Antony Polukhin. +// Copyright 2015-2019 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) + +// For more information, see http://www.boost.org + +#include "../example/b2_workarounds.hpp" +#include <boost/dll.hpp> +#include <boost/core/lightweight_test.hpp> + +// Unit Tests + +extern "C" void BOOST_SYMBOL_EXPORT exef() { +} + +int main(int argc, char* argv[]) +{ + using namespace boost::dll; + + boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv); + BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos); + BOOST_TEST(b2_workarounds::is_shared_library(shared_library_path)); + std::cout << "Library: " << shared_library_path; + + { + shared_library sl(shared_library_path); + BOOST_TEST(sl.has("say_hello")); + BOOST_TEST(sl.has("lib_version")); + BOOST_TEST(sl.has("integer_g")); + BOOST_TEST(sl.has(std::string("integer_g"))); + BOOST_TEST(!sl.has("i_do_not_exist")); + BOOST_TEST(!sl.has(std::string("i_do_not_exist"))); + } + + { + shared_library sl(program_location()); + BOOST_TEST(sl.has("exef")); + BOOST_TEST(!sl.has("i_do_not_exist")); + } + + + exef(); // Make sure that this function still callable in traditional way + return boost::report_errors(); +} + diff --git a/src/boost/libs/dll/test/structures_tests.cpp b/src/boost/libs/dll/test/structures_tests.cpp new file mode 100644 index 00000000..1598dc73 --- /dev/null +++ b/src/boost/libs/dll/test/structures_tests.cpp @@ -0,0 +1,345 @@ +// Copyright 2014 Renato Tegon Forti, Antony Polukhin. +// Copyright 2015-2019 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) + +// For more information, see http://www.boost.org + +#include <boost/dll/detail/elf_info.hpp> +#include <boost/dll/detail/pe_info.hpp> +#include <boost/dll/detail/macho_info.hpp> +#include <boost/static_assert.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/predef/os.h> + +#if BOOST_OS_WINDOWS +# include <windows.h> +#elif BOOST_OS_MACOS || BOOST_OS_IOS +# include <mach-o/loader.h> +# include <mach-o/nlist.h> +#elif BOOST_OS_QNX +// QNX's copy of <elf.h> and <link.h> reside in sys folder +# include <sys/elf.h> +#else + #include <elf.h> +#endif + +namespace dd = boost::dll::detail; + +template <class T1, class T2> +inline std::size_t get_offset(const T1& v1, const T2& v2) { + const unsigned char* p1 = reinterpret_cast<const unsigned char*>(&v1); + const unsigned char* p2 = reinterpret_cast<const unsigned char*>(&v2); + + if (p1 < p2) { + return static_cast<std::size_t>(p2 - p1); + } + + return static_cast<std::size_t>(p1 - p2); +} + +#define CHECK_FIELD(Field) \ + BOOST_STATIC_ASSERT(sizeof(v1.Field) == sizeof(v2.Field)); \ + BOOST_TEST(get_offset(v1, v1.Field) == get_offset(v2, v2.Field)) \ + /**/ + + +// ELF structures +template <class T1, class T2> +void elf_header_checks(const T1& v1, const T2& v2) { + BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2)); + + CHECK_FIELD(e_ident); + CHECK_FIELD(e_type); + CHECK_FIELD(e_machine); + CHECK_FIELD(e_version); + CHECK_FIELD(e_entry); + CHECK_FIELD(e_phoff); + CHECK_FIELD(e_shoff); + CHECK_FIELD(e_flags); + CHECK_FIELD(e_ehsize); + CHECK_FIELD(e_phentsize); + CHECK_FIELD(e_phnum); + CHECK_FIELD(e_shentsize); + CHECK_FIELD(e_shnum); + CHECK_FIELD(e_shstrndx); +} + +template <class T1, class T2> +void elf_sheader_checks(const T1& v1, const T2& v2) { + BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2)); + + CHECK_FIELD(sh_name); + CHECK_FIELD(sh_type); + CHECK_FIELD(sh_flags); + CHECK_FIELD(sh_addr); + CHECK_FIELD(sh_offset); + CHECK_FIELD(sh_size); + CHECK_FIELD(sh_link); + CHECK_FIELD(sh_info); + CHECK_FIELD(sh_addralign); + CHECK_FIELD(sh_entsize); +} + +template <class T1, class T2> +void elf_sym_header_checks(const T1& v1, const T2& v2) { + BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2)); + + CHECK_FIELD(st_name); + CHECK_FIELD(st_value); + CHECK_FIELD(st_size); + CHECK_FIELD(st_info); + CHECK_FIELD(st_other); + CHECK_FIELD(st_shndx); +} + + +// PE structures +template <class T> +void generic_header_check(const T& v1, const dd::IMAGE_DOS_HEADER_& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(e_magic); + CHECK_FIELD(e_cblp); + CHECK_FIELD(e_cp); + CHECK_FIELD(e_crlc); + CHECK_FIELD(e_cparhdr); + CHECK_FIELD(e_minalloc); + CHECK_FIELD(e_maxalloc); + CHECK_FIELD(e_ss); + CHECK_FIELD(e_sp); + CHECK_FIELD(e_csum); + CHECK_FIELD(e_ip); + CHECK_FIELD(e_cs); + CHECK_FIELD(e_lfarlc); + CHECK_FIELD(e_ovno); + CHECK_FIELD(e_res); + CHECK_FIELD(e_oemid); + CHECK_FIELD(e_oeminfo); + CHECK_FIELD(e_res2); + CHECK_FIELD(e_lfanew); +} + +template <class T> +void generic_header_check(const T& v1, const dd::IMAGE_FILE_HEADER_& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(Machine); + CHECK_FIELD(NumberOfSections); + CHECK_FIELD(TimeDateStamp); + CHECK_FIELD(PointerToSymbolTable); + CHECK_FIELD(NumberOfSymbols); + CHECK_FIELD(SizeOfOptionalHeader); + CHECK_FIELD(Characteristics); +} + +template <class T> +void generic_header_check(const T& v1, const dd::IMAGE_DATA_DIRECTORY_& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(VirtualAddress); + CHECK_FIELD(Size); +} + +template <class T> +void generic_header_check(const T& v1, const dd::IMAGE_EXPORT_DIRECTORY_& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(Characteristics); + CHECK_FIELD(TimeDateStamp); + CHECK_FIELD(MajorVersion); + CHECK_FIELD(MinorVersion); + CHECK_FIELD(Name); + CHECK_FIELD(Base); + CHECK_FIELD(NumberOfFunctions); + CHECK_FIELD(NumberOfNames); + CHECK_FIELD(AddressOfFunctions); + CHECK_FIELD(AddressOfNames); + CHECK_FIELD(AddressOfNameOrdinals); +} + + +template <class T> +void generic_header_check(const T& v1, const dd::IMAGE_SECTION_HEADER_& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(Name); + CHECK_FIELD(VirtualAddress); + CHECK_FIELD(SizeOfRawData); + CHECK_FIELD(PointerToRawData); + CHECK_FIELD(PointerToRelocations); + CHECK_FIELD(PointerToLinenumbers); + CHECK_FIELD(NumberOfRelocations); + CHECK_FIELD(NumberOfLinenumbers); + CHECK_FIELD(Characteristics); +} + +template <class T, class AddrT> +void generic_header_check(const T& v1, const dd::IMAGE_OPTIONAL_HEADER_template<AddrT>& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(Magic); + CHECK_FIELD(MajorLinkerVersion); + CHECK_FIELD(MinorLinkerVersion); + CHECK_FIELD(SizeOfCode); + CHECK_FIELD(SizeOfInitializedData); + CHECK_FIELD(SizeOfUninitializedData); + CHECK_FIELD(AddressOfEntryPoint); + CHECK_FIELD(ImageBase); + CHECK_FIELD(SectionAlignment); + CHECK_FIELD(FileAlignment); + CHECK_FIELD(MajorOperatingSystemVersion); + CHECK_FIELD(MinorOperatingSystemVersion); + CHECK_FIELD(MajorImageVersion); + CHECK_FIELD(MinorImageVersion); + CHECK_FIELD(MajorSubsystemVersion); + CHECK_FIELD(MinorSubsystemVersion); + CHECK_FIELD(Win32VersionValue); + CHECK_FIELD(SizeOfImage); + CHECK_FIELD(SizeOfHeaders); + CHECK_FIELD(CheckSum); + CHECK_FIELD(Subsystem); + CHECK_FIELD(DllCharacteristics); + CHECK_FIELD(SizeOfStackReserve); + CHECK_FIELD(SizeOfStackCommit); + CHECK_FIELD(SizeOfHeapReserve); + CHECK_FIELD(SizeOfHeapCommit); + CHECK_FIELD(LoaderFlags); + CHECK_FIELD(NumberOfRvaAndSizes); + CHECK_FIELD(DataDirectory); +} + +template <class T, class AddrT> +void generic_header_check(const T& v1, const dd::IMAGE_NT_HEADERS_template<AddrT>& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(Signature); + CHECK_FIELD(FileHeader); + CHECK_FIELD(OptionalHeader); +} +template <class T, class AddrT> +void generic_header_check(const T& v1, const dd::mach_header_template<AddrT>& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(magic); + CHECK_FIELD(cputype); + CHECK_FIELD(cpusubtype); + CHECK_FIELD(filetype); + CHECK_FIELD(ncmds); + CHECK_FIELD(sizeofcmds); + //CHECK_FIELD(flags); +} + +template <class T, class AddrT> +void generic_header_check(const T& v1, const dd::segment_command_template<AddrT>& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(cmd); + CHECK_FIELD(cmdsize); + CHECK_FIELD(segname); + CHECK_FIELD(vmaddr); + CHECK_FIELD(vmsize); + CHECK_FIELD(fileoff); + CHECK_FIELD(filesize); + CHECK_FIELD(maxprot); + CHECK_FIELD(initprot); + CHECK_FIELD(nsects); + CHECK_FIELD(flags); +} + +template <class T, class AddrT> +void generic_header_check(const T& v1, const dd::section_template<AddrT>& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(sectname); + CHECK_FIELD(segname); + CHECK_FIELD(addr); + CHECK_FIELD(size); + CHECK_FIELD(offset); + CHECK_FIELD(align); + CHECK_FIELD(reloff); + CHECK_FIELD(nreloc); + CHECK_FIELD(flags); + //CHECK_FIELD(reserved vs reserveed1&reserved2); +} + +template <class T> +void generic_header_check(const T& v1, const dd::symtab_command_& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(cmd); + CHECK_FIELD(cmdsize); + CHECK_FIELD(symoff); + CHECK_FIELD(nsyms); + CHECK_FIELD(stroff); + CHECK_FIELD(strsize); +} + +template <class T, class AddrT> +void generic_header_check(const T& v1, const dd::nlist_template<AddrT>& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + //CHECK_FIELD(n_strx); + CHECK_FIELD(n_type); + CHECK_FIELD(n_sect); + CHECK_FIELD(n_desc); + CHECK_FIELD(n_value); +} + +template <class T> +void generic_header_check(const T& v1, const dd::load_command_& v2) { + BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); + + CHECK_FIELD(cmd); + CHECK_FIELD(cmdsize); +} + + + +// Unit Tests +int main(int /*argc*/, char* /*argv*/[]) { + +#if BOOST_OS_WINDOWS + generic_header_check(::IMAGE_DOS_HEADER(), dd::IMAGE_DOS_HEADER_()); + generic_header_check(::IMAGE_FILE_HEADER(), dd::IMAGE_FILE_HEADER_()); + generic_header_check(::IMAGE_DATA_DIRECTORY(), dd::IMAGE_DATA_DIRECTORY_()); + generic_header_check(::IMAGE_EXPORT_DIRECTORY(), dd::IMAGE_EXPORT_DIRECTORY_()); + generic_header_check(::IMAGE_SECTION_HEADER(), dd::IMAGE_SECTION_HEADER_()); + generic_header_check(::IMAGE_OPTIONAL_HEADER32(), dd::IMAGE_OPTIONAL_HEADER32_()); + generic_header_check(::IMAGE_OPTIONAL_HEADER64(), dd::IMAGE_OPTIONAL_HEADER64_()); + generic_header_check(::IMAGE_NT_HEADERS32(), dd::IMAGE_NT_HEADERS32_()); + generic_header_check(::IMAGE_NT_HEADERS64(), dd::IMAGE_NT_HEADERS64_()); +#elif BOOST_OS_MACOS || BOOST_OS_IOS + generic_header_check(::mach_header(), dd::mach_header_32_()); + generic_header_check(::mach_header_64(), dd::mach_header_64_()); + + generic_header_check(::segment_command(), dd::segment_command_32_()); + generic_header_check(::segment_command_64(), dd::segment_command_64_()); + + generic_header_check(::section(), dd::section_32_()); + generic_header_check(::section_64(), dd::section_64_()); + + generic_header_check(::load_command(), dd::load_command_()); + generic_header_check(::symtab_command(), dd::symtab_command_()); + + struct ::nlist nl32_var; + generic_header_check(nl32_var, dd::nlist_32_()); + struct ::nlist_64 nl64_var; + generic_header_check(nl64_var, dd::nlist_64_()); + +#else + elf_header_checks(::Elf32_Ehdr(), dd::Elf32_Ehdr_()); + elf_header_checks(::Elf64_Ehdr(), dd::Elf64_Ehdr_()); + + elf_sheader_checks(::Elf32_Shdr(), dd::Elf32_Shdr_()); + elf_sheader_checks(::Elf64_Shdr(), dd::Elf64_Shdr_()); + + elf_sym_header_checks(::Elf32_Sym(), dd::Elf32_Sym_()); + elf_sym_header_checks(::Elf64_Sym(), dd::Elf64_Sym_()); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/dll/test/symbol_runtime_info_test.cpp b/src/boost/libs/dll/test/symbol_runtime_info_test.cpp new file mode 100644 index 00000000..bfeb69bf --- /dev/null +++ b/src/boost/libs/dll/test/symbol_runtime_info_test.cpp @@ -0,0 +1,231 @@ +// Copyright 2014 Renato Tegon Forti, Antony Polukhin. +// Copyright 2015-2019 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) + +// For more information, see http://www.boost.org + +#include "../example/b2_workarounds.hpp" +#include <boost/dll.hpp> +#include <boost/dll/runtime_symbol_info.hpp> +#include <boost/filesystem/operations.hpp> + +#include <boost/core/lightweight_test.hpp> + +#include <boost/predef/os.h> + + +#include <cmath> +#include <exception> // std::set_terminate +#include <signal.h> // ::signal + +// Makes global error variables dirty. Useful for preventing issues like https://github.com/boostorg/dll/issues/16 +void make_error_code_dirty() { + using namespace std; + (void)log(-1.0); + +#if BOOST_OS_WINDOWS + boost::winapi::WCHAR_ path_hldr[10]; + int some_invalid_value_for_handle = 0xFF004242; + boost::winapi::HMODULE_ some_invalid_handle; + memcpy(&some_invalid_handle, &some_invalid_value_for_handle, sizeof(some_invalid_value_for_handle)); + boost::winapi::GetModuleFileNameW(some_invalid_handle, path_hldr, 10); +#endif +} + + + +// lib functions + +typedef float (lib_version_func)(); +typedef void (say_hello_func) (); +typedef int (increment) (int); + +// exe function +extern "C" int BOOST_SYMBOL_EXPORT exef() { + return 15; +} + + +extern "C" void BOOST_SYMBOL_EXPORT my_terminate_handler() { + std::abort(); +} + +extern "C" void BOOST_SYMBOL_EXPORT my_signal_handler(int) { + std::abort(); +} + +void internal_function() {} +int internal_variable = 1; + +// Unit Tests +int main(int argc, char* argv[]) { + using namespace boost::dll; + + boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv); + BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos); + + make_error_code_dirty(); + + shared_library lib(shared_library_path); + + std::cout << std::endl; + std::cout << "shared_library: " << shared_library_path << std::endl; + std::cout << "symbol_location: " << symbol_location(lib.get<int>("integer_g")) << std::endl; + std::cout << "lib.location(): " << lib.location() << std::endl; + BOOST_TEST( + symbol_location(lib.get<int>("integer_g")) == lib.location() + ); + + make_error_code_dirty(); + + BOOST_TEST( + symbol_location(lib.get<say_hello_func>("say_hello")) == lib.location() + ); + + BOOST_TEST( + symbol_location(lib.get<lib_version_func>("lib_version")) == lib.location() + ); + + make_error_code_dirty(); + + BOOST_TEST( + symbol_location(lib.get<const int>("const_integer_g")) == lib.location() + ); + + // Checking that symbols are still available, after another load+unload of the library + { shared_library sl2(shared_library_path); } + + BOOST_TEST( + symbol_location(lib.get<int>("integer_g")) == lib.location() + ); + + + make_error_code_dirty(); + + // Checking aliases + BOOST_TEST( + symbol_location(lib.get<std::size_t(*)(const std::vector<int>&)>("foo_bar")) == lib.location() + ); + BOOST_TEST( + symbol_location(lib.get_alias<std::size_t(const std::vector<int>&)>("foo_bar")) == lib.location() + ); + + + BOOST_TEST( + symbol_location(lib.get<std::size_t*>("foo_variable")) == lib.location() + ); + BOOST_TEST( + symbol_location(lib.get_alias<std::size_t>("foo_variable")) == lib.location() + ); + + { // self + + make_error_code_dirty(); + + shared_library sl(program_location()); + + make_error_code_dirty(); + + BOOST_TEST( + (boost::dll::fs::equivalent(symbol_location(sl.get<int(void)>("exef")), argv[0])) + ); + } + + { // self with error_code + boost::dll::fs::error_code ec; + shared_library sl(program_location(ec)); + BOOST_TEST(!ec); + + BOOST_TEST( + (boost::dll::fs::equivalent(symbol_location(sl.get<int(void)>("exef"), ec), argv[0])) + ); + BOOST_TEST(!ec); + + symbol_location(&sl.get<int(void)>("exef"), ec); + BOOST_TEST(ec); + } + + std::cout << "\ninternal_function: " << symbol_location(internal_function); + std::cout << "\nargv[0] : " << boost::filesystem::absolute(argv[0]); + BOOST_TEST( + (boost::dll::fs::equivalent(symbol_location(internal_function), argv[0])) + ); + + BOOST_TEST( + (boost::dll::fs::equivalent(symbol_location(internal_variable), argv[0])) + ); + + make_error_code_dirty(); + + BOOST_TEST( + (boost::dll::fs::equivalent(this_line_location(), argv[0])) + ); + + { // this_line_location with error_code + boost::dll::fs::error_code ec; + make_error_code_dirty(); + BOOST_TEST( + (boost::dll::fs::equivalent(this_line_location(ec), argv[0])) + ); + BOOST_TEST(!ec); + } + + BOOST_TEST( + lib.get_alias<boost::dll::fs::path()>("module_location_from_itself")() == lib.location() + ); + + // Checking docs content + std::cout << "\nsymbol_location(std::cerr); // " << symbol_location(std::cerr); + std::cout << "\nsymbol_location(std::puts); // " << symbol_location(std::puts); + + std::set_terminate(&my_terminate_handler); + BOOST_TEST((boost::dll::fs::equivalent( + symbol_location_ptr(std::set_terminate(0)), + argv[0] + ))); + + { + boost::dll::fs::error_code ec; + boost::dll::fs::path p = symbol_location_ptr(std::set_terminate(0), ec); + BOOST_TEST(ec || !p.empty()); + } + + { + boost::dll::fs::error_code ec; + symbol_location(std::set_terminate(0), ec), + BOOST_TEST(ec); + } + + { + std::set_terminate(&my_terminate_handler); + boost::dll::fs::error_code ec; + make_error_code_dirty(); + symbol_location(std::set_terminate(0), ec), + BOOST_TEST(ec); + } + + { + boost::dll::fs::error_code ec; + ::signal(SIGSEGV, &my_signal_handler); + boost::dll::fs::path p = symbol_location_ptr(::signal(SIGSEGV, SIG_DFL), ec); + BOOST_TEST((boost::dll::fs::equivalent( + p, + argv[0] + )) || ec); + } + + { + ::signal(SIGSEGV, &my_signal_handler); + boost::dll::fs::error_code ec; + make_error_code_dirty(); + symbol_location(::signal(SIGSEGV, SIG_DFL), ec); + BOOST_TEST(ec); + } + + + return boost::report_errors(); +} + diff --git a/src/boost/libs/dll/test/test_library.cpp b/src/boost/libs/dll/test/test_library.cpp new file mode 100644 index 00000000..fee07c62 --- /dev/null +++ b/src/boost/libs/dll/test/test_library.cpp @@ -0,0 +1,115 @@ +// Copyright 2011-2012 Renato Tegon Forti +// Copyright 2014 Renato Tegon Forti, Antony Polukhin. +// Copyright 2015-2019 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) + +// For more information, see http://www.boost.org + +// MinGW related workaround +#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION + +#include <boost/dll/config.hpp> +#include <boost/dll/alias.hpp> +#include <iostream> +#include <vector> + +#include <boost/shared_ptr.hpp> +#include <boost/make_shared.hpp> +#include <boost/fusion/container.hpp> + +#define LIBRARY_API BOOST_SYMBOL_EXPORT + +extern "C" void LIBRARY_API say_hello(void); +extern "C" float LIBRARY_API lib_version(void); +extern "C" int LIBRARY_API increment(int); + +extern "C" int LIBRARY_API integer_g; +extern "C" const int LIBRARY_API const_integer_g = 777; + +namespace foo { + std::size_t bar(const std::vector<int>& v) { + return v.size(); + } + + std::size_t variable = 42; +} + + + +// Make sure that aliases have no problems with memory allocations and different types of input parameters +namespace namespace1 { namespace namespace2 { namespace namespace3 { + typedef + boost::fusion::vector<std::vector<int>, std::vector<int>, std::vector<int>, const std::vector<int>*, std::vector<int>* > + do_share_res_t; + + boost::shared_ptr<do_share_res_t> do_share( + std::vector<int> v1, + std::vector<int>& v2, + const std::vector<int>& v3, + const std::vector<int>* v4, + std::vector<int>* v5 + ) + { + v2.back() = 777; + v5->back() = 9990; + return boost::make_shared<do_share_res_t>(v1, v2, v3, v4, v5); + } + + std::string info("I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world')."); + + int& ref_returning_function() { + static int i = 0; + return i; + } +}}} + + + +BOOST_DLL_ALIAS(foo::bar, foo_bar) +BOOST_DLL_ALIAS(foo::variable, foo_variable) +BOOST_DLL_ALIAS(namespace1::namespace2::namespace3::do_share, do_share) +BOOST_DLL_ALIAS(namespace1::namespace2::namespace3::info, info) +BOOST_DLL_ALIAS(const_integer_g, const_integer_g_alias) +BOOST_DLL_ALIAS(namespace1::namespace2::namespace3::ref_returning_function, ref_returning_function) + + + +int integer_g = 100; + +void say_hello(void) +{ + std::cout << "Hello, Boost.Application!" << std::endl; +} + +float lib_version(void) +{ + return 1.0; +} + +int increment(int n) +{ + return ++n; +} + +#include <boost/dll/runtime_symbol_info.hpp> + +boost::dll::fs::path this_module_location_from_itself() { + return boost::dll::this_line_location(); +} + +BOOST_DLL_ALIAS(this_module_location_from_itself, module_location_from_itself) + + + +int internal_integer_i = 0xFF0000; +extern "C" LIBRARY_API int& reference_to_internal_integer; +int& reference_to_internal_integer = internal_integer_i; + +#ifndef BOOST_NO_RVALUE_REFERENCES +extern "C" LIBRARY_API int&& rvalue_reference_to_internal_integer; +int&& rvalue_reference_to_internal_integer = static_cast<int&&>(internal_integer_i); +#endif + |