OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/files/file_path.h" | 5 #include "base/files/file_path.h" |
| 6 #include "base/macros.h" |
6 #include "base/native_library.h" | 7 #include "base/native_library.h" |
| 8 #include "base/path_service.h" |
| 9 #include "base/test/native_library_test_utils.h" |
| 10 #include "build/build_config.h" |
7 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
8 | 12 |
9 namespace base { | 13 namespace base { |
10 | 14 |
11 const FilePath::CharType kDummyLibraryPath[] = | 15 const FilePath::CharType kDummyLibraryPath[] = |
12 FILE_PATH_LITERAL("dummy_library"); | 16 FILE_PATH_LITERAL("dummy_library"); |
13 | 17 |
14 TEST(NativeLibraryTest, LoadFailure) { | 18 TEST(NativeLibraryTest, LoadFailure) { |
15 NativeLibraryLoadError error; | 19 NativeLibraryLoadError error; |
16 EXPECT_FALSE(LoadNativeLibrary(FilePath(kDummyLibraryPath), &error)); | 20 EXPECT_FALSE(LoadNativeLibrary(FilePath(kDummyLibraryPath), &error)); |
(...skipping 12 matching lines...) Expand all Loading... |
29 #elif defined(OS_MACOSX) | 33 #elif defined(OS_MACOSX) |
30 "libmylib.dylib"; | 34 "libmylib.dylib"; |
31 #elif defined(OS_POSIX) | 35 #elif defined(OS_POSIX) |
32 "libmylib.so"; | 36 "libmylib.so"; |
33 #elif defined(OS_WIN) | 37 #elif defined(OS_WIN) |
34 "mylib.dll"; | 38 "mylib.dll"; |
35 #endif | 39 #endif |
36 EXPECT_EQ(kExpectedName, GetNativeLibraryName("mylib")); | 40 EXPECT_EQ(kExpectedName, GetNativeLibraryName("mylib")); |
37 } | 41 } |
38 | 42 |
| 43 // We don't support dynamic loading on iOS, and ASAN will complain about our |
| 44 // intentional ODR violation because of |g_native_library_exported_value| being |
| 45 // defined globally both here and in the shared library. |
| 46 #if !defined(OS_IOS) && !defined(ADDRESS_SANITIZER) |
| 47 |
| 48 const char kTestLibraryName[] = |
| 49 #if defined(OS_MACOSX) |
| 50 "libtest_shared_library.dylib"; |
| 51 #elif defined(OS_ANDROID) && defined(COMPONENT_BUILD) |
| 52 "libtest_shared_library.cr.so"; |
| 53 #elif defined(OS_POSIX) |
| 54 "libtest_shared_library.so"; |
| 55 #elif defined(OS_WIN) |
| 56 "test_shared_library.dll"; |
| 57 #endif |
| 58 |
| 59 class TestLibrary { |
| 60 public: |
| 61 TestLibrary() : TestLibrary(NativeLibraryOptions()) {} |
| 62 |
| 63 explicit TestLibrary(const NativeLibraryOptions& options) |
| 64 : library_(nullptr) { |
| 65 base::FilePath exe_path; |
| 66 CHECK(base::PathService::Get(base::DIR_EXE, &exe_path)); |
| 67 |
| 68 library_ = LoadNativeLibraryWithOptions( |
| 69 exe_path.AppendASCII(kTestLibraryName), options, nullptr); |
| 70 CHECK(library_); |
| 71 } |
| 72 |
| 73 ~TestLibrary() { |
| 74 UnloadNativeLibrary(library_); |
| 75 } |
| 76 |
| 77 template <typename ReturnType, typename... Args> |
| 78 ReturnType Call(const char* function_name, Args... args) { |
| 79 return reinterpret_cast<ReturnType(*)(Args...)>( |
| 80 GetFunctionPointerFromNativeLibrary(library_, function_name))(args...); |
| 81 } |
| 82 |
| 83 private: |
| 84 NativeLibrary library_; |
| 85 |
| 86 DISALLOW_COPY_AND_ASSIGN(TestLibrary); |
| 87 }; |
| 88 |
| 89 // Verifies that we can load a native library and resolve its exported symbols. |
| 90 TEST(NativeLibraryTest, LoadLibrary) { |
| 91 TestLibrary library; |
| 92 EXPECT_EQ(5, library.Call<int>("GetSimpleTestValue")); |
| 93 } |
| 94 |
| 95 // Android dlopen() requires further investigation, as it might vary across |
| 96 // versions with respect to symbol resolution scope. |
| 97 #if !defined(OS_ANDROID) |
| 98 |
| 99 // Verifies that the |prefer_own_symbols| option satisfies its guarantee that |
| 100 // a loaded library will always prefer local symbol resolution before |
| 101 // considering global symbols. |
| 102 TEST(NativeLibraryTest, LoadLibraryPreferOwnSymbols) { |
| 103 NativeLibraryOptions options; |
| 104 options.prefer_own_symbols = true; |
| 105 TestLibrary library(options); |
| 106 |
| 107 // Verify that this binary and the DSO use different storage for |
| 108 // |g_native_library_exported_value|. |
| 109 g_native_library_exported_value = 1; |
| 110 library.Call<void>("SetExportedValue", 2); |
| 111 EXPECT_EQ(1, g_native_library_exported_value); |
| 112 g_native_library_exported_value = 3; |
| 113 EXPECT_EQ(2, library.Call<int>("GetExportedValue")); |
| 114 |
| 115 // Both this binary and the library link against the |
| 116 // native_library_test_utils source library, which in turn exports the |
| 117 // NativeLibraryTestIncrement() function whose return value depends on some |
| 118 // static internal state. |
| 119 // |
| 120 // The DSO's GetIncrementValue() forwards to that function inside the DSO. |
| 121 // |
| 122 // Here we verify that direct calls to NativeLibraryTestIncrement() in this |
| 123 // binary return a sequence of values independent from the sequence returned |
| 124 // by GetIncrementValue(), ensuring that the DSO is calling its own local |
| 125 // definition of NativeLibraryTestIncrement(). |
| 126 EXPECT_EQ(1, library.Call<int>("GetIncrementValue")); |
| 127 EXPECT_EQ(1, NativeLibraryTestIncrement()); |
| 128 EXPECT_EQ(2, library.Call<int>("GetIncrementValue")); |
| 129 EXPECT_EQ(3, library.Call<int>("GetIncrementValue")); |
| 130 EXPECT_EQ(4, library.Call<int>("NativeLibraryTestIncrement")); |
| 131 EXPECT_EQ(2, NativeLibraryTestIncrement()); |
| 132 EXPECT_EQ(3, NativeLibraryTestIncrement()); |
| 133 } |
| 134 |
| 135 #endif // !defined(OS_ANDROID) |
| 136 |
| 137 #endif // !defined(OS_IOS) && !defined(ADDRESS_SANITIZER) |
| 138 |
39 } // namespace base | 139 } // namespace base |
OLD | NEW |