Chromium Code Reviews| 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/native_library.h" | 6 #include "base/native_library.h" |
| 7 #include "base/path_service.h" | |
| 8 #include "build/build_config.h" | |
| 7 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 8 | 10 |
| 11 #if defined(OS_WIN) | |
| 12 #define EXPORT __declspec(dllexport) | |
| 13 #else | |
| 14 #define EXPORT __attribute__((visibility("default"))) | |
| 15 #endif | |
| 16 | |
| 17 // This variable name must match the exported variable in | |
| 18 // native_library_test_library.cc. | |
| 19 int EXPORT g_native_library_exported_value = 0; | |
| 20 | |
| 21 // This function name must match the exported function with the same signature | |
| 22 // in native_library_test_library.cc. This function must return a different | |
| 23 // value from the one defined there. | |
| 24 int EXPORT GetNativeLibraryTestMagicValue() { return 41; } | |
| 25 | |
| 9 namespace base { | 26 namespace base { |
| 10 | 27 |
| 11 const FilePath::CharType kDummyLibraryPath[] = | 28 const FilePath::CharType kDummyLibraryPath[] = |
| 12 FILE_PATH_LITERAL("dummy_library"); | 29 FILE_PATH_LITERAL("dummy_library"); |
| 13 | 30 |
| 14 TEST(NativeLibraryTest, LoadFailure) { | 31 TEST(NativeLibraryTest, LoadFailure) { |
| 15 NativeLibraryLoadError error; | 32 NativeLibraryLoadError error; |
| 16 EXPECT_FALSE(LoadNativeLibrary(FilePath(kDummyLibraryPath), &error)); | 33 EXPECT_FALSE(LoadNativeLibrary(FilePath(kDummyLibraryPath), &error)); |
| 17 EXPECT_FALSE(error.ToString().empty()); | 34 EXPECT_FALSE(error.ToString().empty()); |
| 18 } | 35 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 29 #elif defined(OS_MACOSX) | 46 #elif defined(OS_MACOSX) |
| 30 "libmylib.dylib"; | 47 "libmylib.dylib"; |
| 31 #elif defined(OS_POSIX) | 48 #elif defined(OS_POSIX) |
| 32 "libmylib.so"; | 49 "libmylib.so"; |
| 33 #elif defined(OS_WIN) | 50 #elif defined(OS_WIN) |
| 34 "mylib.dll"; | 51 "mylib.dll"; |
| 35 #endif | 52 #endif |
| 36 EXPECT_EQ(kExpectedName, GetNativeLibraryName("mylib")); | 53 EXPECT_EQ(kExpectedName, GetNativeLibraryName("mylib")); |
| 37 } | 54 } |
| 38 | 55 |
| 56 // We don't support dynamic loading on iOS, and ASAN will complain about our | |
| 57 // intentional ODR violation here. | |
| 58 #if !defined(OS_IOS) && !defined(ADDRESS_SANITIZER) | |
| 59 | |
| 60 const char kTestLibraryName[] = | |
| 61 #if defined(OS_MACOSX) | |
| 62 "libnative_library_test_library.dylib"; | |
| 63 #elif defined(OS_ANDROID) && defined(COMPONENT_BUILD) | |
| 64 "libnative_library_test_library.cr.so"; | |
| 65 #elif defined(OS_POSIX) | |
| 66 "libnative_library_test_library.so"; | |
| 67 #elif defined(OS_WIN) | |
| 68 "native_library_test_library.dll"; | |
| 69 #endif | |
| 70 | |
| 71 class TestLibrary { | |
| 72 public: | |
| 73 explicit TestLibrary( | |
| 74 const NativeLibraryOptions& options = NativeLibraryOptions()) | |
| 75 : library_(nullptr) { | |
| 76 base::FilePath exe_path; | |
| 77 CHECK(base::PathService::Get(base::DIR_EXE, &exe_path)); | |
| 78 | |
| 79 library_ = LoadNativeLibraryWithOptions( | |
| 80 exe_path.AppendASCII(kTestLibraryName), options, nullptr); | |
| 81 CHECK(library_); | |
| 82 } | |
| 83 | |
| 84 ~TestLibrary() { | |
| 85 UnloadNativeLibrary(library_); | |
| 86 } | |
| 87 | |
| 88 template <typename ReturnType, typename... Args> | |
| 89 ReturnType Call(const char* function_name, Args... args) { | |
| 90 return reinterpret_cast<ReturnType(*)(Args...)>( | |
| 91 GetFunctionPointerFromNativeLibrary(library_, function_name))(args...); | |
| 92 } | |
| 93 | |
| 94 private: | |
| 95 NativeLibrary library_; | |
| 96 }; | |
| 97 | |
| 98 // Verifies that we can load a native library and resolve its exported symbols. | |
| 99 TEST(NativeLibraryTest, LoadLibrary) { | |
| 100 TestLibrary library; | |
| 101 EXPECT_EQ(5, library.Call<int>("GetSimpleTestValue")); | |
| 102 } | |
| 103 | |
| 104 // Android dlopen() behavior is not well specified and may vary across versions. | |
| 105 #if !defined(OS_ANDROID) | |
| 106 | |
| 107 // Verifies that the |prefer_own_symbols| option satisfies its guarantee that | |
| 108 // a loaded library will always prefer local symbol resolution before | |
| 109 // considering global symbols. | |
| 110 TEST(NativeLibraryTest, LoadLibraryPreferOwnSymbols) { | |
| 111 NativeLibraryOptions options; | |
| 112 options.prefer_own_symbols = true; | |
| 113 TestLibrary library(options); | |
| 114 | |
| 115 // Verify that this binary and the DSO use different storage for | |
| 116 // |g_native_library_exported_value|. | |
| 117 g_native_library_exported_value = 1; | |
| 118 library.Call<void>("SetExportedValue", 2); | |
| 119 EXPECT_EQ(1, g_native_library_exported_value); | |
| 120 g_native_library_exported_value = 3; | |
| 121 EXPECT_EQ(2, library.Call<int>("GetExportedValue")); | |
| 122 | |
| 123 // Both this binary and the library export GetNativeLibraryTestMagicValue(), | |
| 124 // which is called internally by the DSO's GetMagicValue(). We verify here | |
| 125 // that the DSO always calls its own local definition rather than ours. | |
| 126 EXPECT_EQ(42, library.Call<int>("GetMagicValue")); | |
|
Ken Rockot(use gerrit already)
2016/08/25 17:43:21
Only problem now: If prefer_own_symbols is false,
| |
| 127 | |
| 128 // Likewise, we should always call our own local definition. | |
| 129 EXPECT_EQ(41, GetNativeLibraryTestMagicValue()); | |
| 130 } | |
| 131 | |
| 132 #endif // !defined(OS_ANDROID) | |
| 133 | |
| 134 #endif // !defined(OS_IOS) && !defined(ADDRESS_SANITIZER) | |
| 135 | |
| 39 } // namespace base | 136 } // namespace base |
| OLD | NEW |