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