native_library_unittest.cc 5.5 KB

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