• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "base/files/file_path.h"
6 #include "base/macros.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"
11 #include "testing/gtest/include/gtest/gtest.h"
12 
13 namespace base {
14 
15 const FilePath::CharType kDummyLibraryPath[] =
16     FILE_PATH_LITERAL("dummy_library");
17 
TEST(NativeLibraryTest,LoadFailure)18 TEST(NativeLibraryTest, LoadFailure) {
19   NativeLibraryLoadError error;
20   EXPECT_FALSE(LoadNativeLibrary(FilePath(kDummyLibraryPath), &error));
21   EXPECT_FALSE(error.ToString().empty());
22 }
23 
24 // |error| is optional and can be null.
TEST(NativeLibraryTest,LoadFailureWithNullError)25 TEST(NativeLibraryTest, LoadFailureWithNullError) {
26   EXPECT_FALSE(LoadNativeLibrary(FilePath(kDummyLibraryPath), nullptr));
27 }
28 
TEST(NativeLibraryTest,GetNativeLibraryName)29 TEST(NativeLibraryTest, GetNativeLibraryName) {
30   const char kExpectedName[] =
31 #if defined(OS_WIN)
32       "mylib.dll";
33 #elif defined(OS_IOS)
34       "mylib";
35 #elif defined(OS_MACOSX)
36       "libmylib.dylib";
37 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
38       "libmylib.so";
39 #endif
40   EXPECT_EQ(kExpectedName, GetNativeLibraryName("mylib"));
41 }
42 
TEST(NativeLibraryTest,GetLoadableModuleName)43 TEST(NativeLibraryTest, GetLoadableModuleName) {
44   const char kExpectedName[] =
45 #if defined(OS_WIN)
46       "mylib.dll";
47 #elif defined(OS_IOS)
48       "mylib";
49 #elif defined(OS_MACOSX)
50       "mylib.so";
51 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
52       "libmylib.so";
53 #endif
54   EXPECT_EQ(kExpectedName, GetLoadableModuleName("mylib"));
55 }
56 
57 // We don't support dynamic loading on iOS, and ASAN will complain about our
58 // intentional ODR violation because of |g_native_library_exported_value| being
59 // defined globally both here and in the shared library.
60 #if !defined(OS_IOS) && !defined(ADDRESS_SANITIZER)
61 
62 const char kTestLibraryName[] =
63 #if defined(OS_WIN)
64     "test_shared_library.dll";
65 #elif defined(OS_MACOSX)
66     "libtest_shared_library.dylib";
67 #elif defined(OS_ANDROID) && defined(COMPONENT_BUILD)
68     "libtest_shared_library.cr.so";
69 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
70     "libtest_shared_library.so";
71 #endif
72 
73 class TestLibrary {
74  public:
TestLibrary()75   TestLibrary() : TestLibrary(NativeLibraryOptions()) {}
76 
TestLibrary(const NativeLibraryOptions & options)77   explicit TestLibrary(const NativeLibraryOptions& options)
78     : library_(nullptr) {
79     base::FilePath exe_path;
80 
81 #if !defined(OS_FUCHSIA)
82     // Libraries do not sit alongside the executable in Fuchsia. NativeLibrary
83     // is aware of this and is able to resolve library paths correctly.
84     CHECK(base::PathService::Get(base::DIR_EXE, &exe_path));
85 #endif
86 
87     library_ = LoadNativeLibraryWithOptions(
88         exe_path.AppendASCII(kTestLibraryName), options, nullptr);
89     CHECK(library_);
90   }
91 
~TestLibrary()92   ~TestLibrary() {
93     UnloadNativeLibrary(library_);
94   }
95 
96   template <typename ReturnType, typename... Args>
Call(const char * function_name,Args...args)97   ReturnType Call(const char* function_name, Args... args) {
98     return reinterpret_cast<ReturnType(*)(Args...)>(
99         GetFunctionPointerFromNativeLibrary(library_, function_name))(args...);
100   }
101 
102  private:
103   NativeLibrary library_;
104 
105   DISALLOW_COPY_AND_ASSIGN(TestLibrary);
106 };
107 
108 // NativeLibraaryTest.LoadLibrary is failing on M tablets only.
109 // crbug/641309
110 #if !defined(OS_ANDROID)
111 
112 // Verifies that we can load a native library and resolve its exported symbols.
TEST(NativeLibraryTest,LoadLibrary)113 TEST(NativeLibraryTest, LoadLibrary) {
114   TestLibrary library;
115   EXPECT_EQ(5, library.Call<int>("GetSimpleTestValue"));
116 }
117 
118 #endif  // !defined(OS_ANDROID)
119 
120 // Android dlopen() requires further investigation, as it might vary across
121 // versions with respect to symbol resolution scope.
122 // TSan and MSan error out on RTLD_DEEPBIND, https://crbug.com/705255
123 #if !defined(OS_ANDROID) && !defined(THREAD_SANITIZER) && \
124     !defined(MEMORY_SANITIZER)
125 
126 // Verifies that the |prefer_own_symbols| option satisfies its guarantee that
127 // a loaded library will always prefer local symbol resolution before
128 // considering global symbols.
TEST(NativeLibraryTest,LoadLibraryPreferOwnSymbols)129 TEST(NativeLibraryTest, LoadLibraryPreferOwnSymbols) {
130   NativeLibraryOptions options;
131   options.prefer_own_symbols = true;
132   TestLibrary library(options);
133 
134   // Verify that this binary and the DSO use different storage for
135   // |g_native_library_exported_value|.
136   g_native_library_exported_value = 1;
137   library.Call<void>("SetExportedValue", 2);
138   EXPECT_EQ(1, g_native_library_exported_value);
139   g_native_library_exported_value = 3;
140   EXPECT_EQ(2, library.Call<int>("GetExportedValue"));
141 
142   // Both this binary and the library link against the
143   // native_library_test_utils source library, which in turn exports the
144   // NativeLibraryTestIncrement() function whose return value depends on some
145   // static internal state.
146   //
147   // The DSO's GetIncrementValue() forwards to that function inside the DSO.
148   //
149   // Here we verify that direct calls to NativeLibraryTestIncrement() in this
150   // binary return a sequence of values independent from the sequence returned
151   // by GetIncrementValue(), ensuring that the DSO is calling its own local
152   // definition of NativeLibraryTestIncrement().
153   EXPECT_EQ(1, library.Call<int>("GetIncrementValue"));
154   EXPECT_EQ(1, NativeLibraryTestIncrement());
155   EXPECT_EQ(2, library.Call<int>("GetIncrementValue"));
156   EXPECT_EQ(3, library.Call<int>("GetIncrementValue"));
157   EXPECT_EQ(4, library.Call<int>("NativeLibraryTestIncrement"));
158   EXPECT_EQ(2, NativeLibraryTestIncrement());
159   EXPECT_EQ(3, NativeLibraryTestIncrement());
160 }
161 
162 #endif  // !defined(OS_ANDROID)
163 
164 #endif  // !defined(OS_IOS) && !defined(ADDRESS_SANITIZER)
165 
166 }  // namespace base
167