1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "gtest/gtest.h"
18 
19 #include <android/api-level.h>
20 #include <dlfcn.h>
21 #include <link.h>
22 
23 extern "C" {
24 int SharedFunction();
25 }
26 
27 namespace {
28 
TestDlopenAndDlsym(const char * library_name,const char * symbol_name)29 void TestDlopenAndDlsym(const char* library_name, const char* symbol_name) {
30   void* handle = dlopen(library_name, RTLD_NOW);
31   ASSERT_TRUE(handle != nullptr) << dlerror();
32   ASSERT_TRUE(dlsym(handle, symbol_name) != nullptr) << dlerror();
33   ASSERT_EQ(dlclose(handle), 0);
34 }
35 
TestDlopenAndDlsymUnstable(const char * library_name,std::initializer_list<const char * > symbol_names)36 void TestDlopenAndDlsymUnstable(const char* library_name,
37                                 std::initializer_list<const char*> symbol_names) {
38   void* handle = dlopen(library_name, RTLD_NOW);
39   ASSERT_TRUE(handle != nullptr) << dlerror();
40   bool symbol_found = false;
41   for (const auto& symbol_name : symbol_names) {
42     if (dlsym(handle, symbol_name) != nullptr) {
43       symbol_found = true;
44       break;
45     }
46   }
47   ASSERT_TRUE(symbol_found);
48   ASSERT_EQ(dlclose(handle), 0);
49 }
50 
51 struct DlIteratePhdrData {
52   int n;
53 };
54 
DlIteratePhdrCallback(struct dl_phdr_info *,size_t,void * data)55 int DlIteratePhdrCallback(struct dl_phdr_info* /* info */, size_t /* size */, void* data) {
56   DlIteratePhdrData* phdr_data = static_cast<DlIteratePhdrData*>(data);
57   ++phdr_data->n;
58   return 0;
59 }
60 
61 }  // namespace
62 
TEST(Shared,CallFunction)63 TEST(Shared, CallFunction) {
64   EXPECT_TRUE(SharedFunction());
65 }
66 
TEST(Shared,DlOpen)67 TEST(Shared, DlOpen) {
68   TestDlopenAndDlsym("libberberis_ndk_tests_shared_lib.so", "SharedFunction");
69 }
70 
TEST(Shared,DlOpenGreylistedLibrariesAndroidM)71 TEST(Shared, DlOpenGreylistedLibrariesAndroidM) {
72   TestDlopenAndDlsym(
73       "libandroid_runtime.so",
74       "_ZN7android14AndroidRuntime21registerNativeMethodsEP7_JNIEnvPKcPK15JNINativeMethodi");
75   TestDlopenAndDlsym("libstagefright.so", "_ZN7android25MEDIA_MIMETYPE_AUDIO_MPEGE");
76 }
77 
TEST(Shared,DlOpenSystemLibraries)78 TEST(Shared, DlOpenSystemLibraries) {
79   TestDlopenAndDlsym("libEGL.so", "eglGetError");
80   TestDlopenAndDlsym("libGLESv1_CM.so", "glScalef");
81   TestDlopenAndDlsym("libGLESv2.so", "glClear");
82   TestDlopenAndDlsym("libOpenSLES.so", "SL_IID_OBJECT");
83   TestDlopenAndDlsym("libandroid.so", "AConfiguration_new");
84   TestDlopenAndDlsymUnstable("libicuuc.so",
85                              {"ucnv_convert",
86                               "ucnv_convert_3_2",
87                               "ucnv_convert_3_8",
88                               "ucnv_convert_4_2",
89                               "ucnv_convert_44",
90                               "ucnv_convert_46",
91                               "ucnv_convert_48",
92                               "ucnv_convert_50",
93                               "ucnv_convert_51",
94                               "ucnv_convert_52",
95                               "ucnv_convert_53",
96                               "ucnv_convert_54",
97                               "ucnv_convert_55",
98                               "ucnv_convert_56",
99                               "ucnv_convert_57",
100                               "ucnv_convert_58",
101                               "ucnv_convert_59",
102                               "ucnv_convert_60"});
103   TestDlopenAndDlsym("libdl.so", "dlopen");
104   TestDlopenAndDlsym("libjnigraphics.so", "AndroidBitmap_getInfo");
105   TestDlopenAndDlsym("liblog.so", "__android_log_print");
106   TestDlopenAndDlsym("libm.so", "sinh");
107   TestDlopenAndDlsym("libnativehelper.so", "jniRegisterNativeMethods");
108   TestDlopenAndDlsym("libz.so", "gzopen");
109 }
110 
TEST(Shared,DlSym)111 TEST(Shared, DlSym) {
112   void* handle = dlopen("libberberis_ndk_tests_shared_lib.so", RTLD_NOW);
113   void* func = reinterpret_cast<void*>(SharedFunction);
114   EXPECT_EQ(func, dlsym(handle, "SharedFunction"));
115   EXPECT_EQ(func, dlsym(RTLD_DEFAULT, "SharedFunction"));
116 }
117 
TEST(Shared,DlIteratePhdr)118 TEST(Shared, DlIteratePhdr) {
119   DlIteratePhdrData data{};
120   dl_iterate_phdr(DlIteratePhdrCallback, &data);
121   EXPECT_LT(0, data.n);
122 }
123