151c0b2f7Stbbdev /*
2b15aabb3Stbbdev Copyright (c) 2005-2021 Intel Corporation
351c0b2f7Stbbdev
451c0b2f7Stbbdev Licensed under the Apache License, Version 2.0 (the "License");
551c0b2f7Stbbdev you may not use this file except in compliance with the License.
651c0b2f7Stbbdev You may obtain a copy of the License at
751c0b2f7Stbbdev
851c0b2f7Stbbdev http://www.apache.org/licenses/LICENSE-2.0
951c0b2f7Stbbdev
1051c0b2f7Stbbdev Unless required by applicable law or agreed to in writing, software
1151c0b2f7Stbbdev distributed under the License is distributed on an "AS IS" BASIS,
1251c0b2f7Stbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c0b2f7Stbbdev See the License for the specific language governing permissions and
1451c0b2f7Stbbdev limitations under the License.
1551c0b2f7Stbbdev */
1651c0b2f7Stbbdev
1751c0b2f7Stbbdev //! \file test_dynamic_link.cpp
1851c0b2f7Stbbdev //! \brief Test for [internal] functionality
1951c0b2f7Stbbdev
20478de5b1Stbbdev #if _WIN32 || _WIN64
21478de5b1Stbbdev #define _CRT_SECURE_NO_WARNINGS
22478de5b1Stbbdev #endif
23478de5b1Stbbdev
24478de5b1Stbbdev #include "common/test.h"
25478de5b1Stbbdev
2651c0b2f7Stbbdev enum FOO_TYPE {
2751c0b2f7Stbbdev FOO_DUMMY,
2851c0b2f7Stbbdev FOO_IMPLEMENTATION
2951c0b2f7Stbbdev };
3051c0b2f7Stbbdev
3151c0b2f7Stbbdev #if _WIN32 || _WIN64
3251c0b2f7Stbbdev #define TEST_EXPORT
3351c0b2f7Stbbdev #else
3451c0b2f7Stbbdev #define TEST_EXPORT extern "C"
3551c0b2f7Stbbdev #endif /* _WIN32 || _WIN64 */
3651c0b2f7Stbbdev
3751c0b2f7Stbbdev // foo "implementations".
foo1()3851c0b2f7Stbbdev TEST_EXPORT FOO_TYPE foo1() { return FOO_IMPLEMENTATION; }
foo2()3951c0b2f7Stbbdev TEST_EXPORT FOO_TYPE foo2() { return FOO_IMPLEMENTATION; }
4051c0b2f7Stbbdev // foo "dummies".
dummy_foo1()4151c0b2f7Stbbdev FOO_TYPE dummy_foo1() { return FOO_DUMMY; }
dummy_foo2()4251c0b2f7Stbbdev FOO_TYPE dummy_foo2() { return FOO_DUMMY; }
4351c0b2f7Stbbdev
4449e08aacStbbdev #include "oneapi/tbb/detail/_config.h"
4551c0b2f7Stbbdev // Suppress the weak symbol mechanism to avoid surplus compiler warnings.
4651c0b2f7Stbbdev #ifdef __TBB_WEAK_SYMBOLS_PRESENT
4751c0b2f7Stbbdev #undef __TBB_WEAK_SYMBOLS_PRESENT
4851c0b2f7Stbbdev #endif
4951c0b2f7Stbbdev #include "src/tbb/dynamic_link.h"
50*7941f880SIlya Isaev
51*7941f880SIlya Isaev #if __TBB_DYNAMIC_LOAD_ENABLED
52*7941f880SIlya Isaev // Handlers.
53*7941f880SIlya Isaev static FOO_TYPE (*foo1_handler)() = &dummy_foo1;
54*7941f880SIlya Isaev static FOO_TYPE (*foo2_handler)() = &dummy_foo2;
55*7941f880SIlya Isaev
5651c0b2f7Stbbdev // Table describing how to link the handlers.
5751c0b2f7Stbbdev static const tbb::detail::r1::dynamic_link_descriptor LinkTable[] = {
5851c0b2f7Stbbdev { "foo1", (tbb::detail::r1::pointer_to_handler*)(void*)(&foo1_handler) },
5951c0b2f7Stbbdev { "foo2", (tbb::detail::r1::pointer_to_handler*)(void*)(&foo2_handler) }
6051c0b2f7Stbbdev };
61*7941f880SIlya Isaev #endif
6251c0b2f7Stbbdev
6351c0b2f7Stbbdev // The direct include since we want to test internal functionality.
6451c0b2f7Stbbdev #include "src/tbb/dynamic_link.cpp"
65*7941f880SIlya Isaev #include "common/utils.h"
6651c0b2f7Stbbdev #include "common/utils_dynamic_libs.h"
6751c0b2f7Stbbdev
test_dynamic_link(const char * lib_name)6851c0b2f7Stbbdev void test_dynamic_link(const char* lib_name) {
6951c0b2f7Stbbdev #if __TBB_DYNAMIC_LOAD_ENABLED
7051c0b2f7Stbbdev #if !_WIN32
7151c0b2f7Stbbdev // Check if the executable exports its symbols.
7251c0b2f7Stbbdev REQUIRE_MESSAGE((utils::GetAddress(utils::OpenLibrary(nullptr), "foo1") && utils::GetAddress(utils::OpenLibrary(nullptr), "foo2")),
7351c0b2f7Stbbdev "The executable doesn't export its symbols. Is the -rdynamic switch set during linking?");
7451c0b2f7Stbbdev #endif /* !_WIN32 */
7551c0b2f7Stbbdev // We want to link (or fail to link) to the symbols available from the
7651c0b2f7Stbbdev // executable so it doesn't matter what the library name is specified in
7751c0b2f7Stbbdev // the dynamic_link call - let it be an empty string.
7851c0b2f7Stbbdev // Generally speaking the test has sense only on Linux but on Windows it
7951c0b2f7Stbbdev // checks the dynamic_link graceful behavior with incorrect library name.
8051c0b2f7Stbbdev if (tbb::detail::r1::dynamic_link(lib_name, LinkTable, sizeof(LinkTable) / sizeof(LinkTable[0]))) {
8151c0b2f7Stbbdev REQUIRE_MESSAGE((foo1_handler && foo2_handler), "The symbols are corrupted by dynamic_link");
8251c0b2f7Stbbdev REQUIRE_MESSAGE((foo1_handler() == FOO_IMPLEMENTATION && foo2_handler() == FOO_IMPLEMENTATION),
8351c0b2f7Stbbdev "dynamic_link returned the successful code but symbol(s) are wrong");
8451c0b2f7Stbbdev } else {
8551c0b2f7Stbbdev REQUIRE_MESSAGE((foo1_handler == dummy_foo1 && foo2_handler == dummy_foo2), "The symbols are corrupted by dynamic_link");
8651c0b2f7Stbbdev }
87*7941f880SIlya Isaev #else
88*7941f880SIlya Isaev utils::suppress_unused_warning(lib_name);
8951c0b2f7Stbbdev #endif
9051c0b2f7Stbbdev }
9151c0b2f7Stbbdev
9251c0b2f7Stbbdev //! Testing dynamic_link with non-existing library
9351c0b2f7Stbbdev //! \brief \ref error_guessing
9451c0b2f7Stbbdev TEST_CASE("Test dynamic_link with non-existing library") {
9551c0b2f7Stbbdev test_dynamic_link("tbb_unrealNAME.so");
9651c0b2f7Stbbdev }
9751c0b2f7Stbbdev
9851c0b2f7Stbbdev //! Testing dynamic_link
9951c0b2f7Stbbdev //! \brief \ref error_guessing
10051c0b2f7Stbbdev TEST_CASE("Test dynamic_link") {
10151c0b2f7Stbbdev test_dynamic_link("");
10251c0b2f7Stbbdev }
103