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