blob: 299b408088e20d22655250536be29374e5eda680 [file] [log] [blame]
Torne (Richard Coles)12bbb912014-02-06 14:34:21 +00001/*
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 <dlfcn.h>
20#include <android/dlext.h>
21#include <sys/mman.h>
22
23
24#define ASSERT_DL_NOTNULL(ptr) \
25 ASSERT_TRUE(ptr != NULL) << "dlerror: " << dlerror()
26
27#define ASSERT_DL_ZERO(i) \
28 ASSERT_EQ(0, i) << "dlerror: " << dlerror()
29
30
31typedef int (*fn)(void);
32#define LIBNAME "libdlext_test.so"
33#define LIBSIZE 1024*1024 // how much address space to reserve for it
34
35
36class DlExtTest : public ::testing::Test {
37protected:
38 virtual void SetUp() {
39 handle_ = NULL;
40 // verify that we don't have the library loaded already
41 ASSERT_EQ(NULL, dlsym(RTLD_DEFAULT, "getRandomNumber"));
42 // call dlerror() to swallow the error, and check it was the one we wanted
43 ASSERT_STREQ("undefined symbol: getRandomNumber", dlerror());
44 }
45
46 virtual void TearDown() {
47 if (handle_ != NULL) {
48 ASSERT_DL_ZERO(dlclose(handle_));
49 }
50 }
51
52 void* handle_;
53};
54
55TEST_F(DlExtTest, ExtInfoNull) {
56 handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, NULL);
57 ASSERT_DL_NOTNULL(handle_);
58 fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
59 ASSERT_DL_NOTNULL(f);
60 EXPECT_EQ(4, f());
61}
62
63TEST_F(DlExtTest, ExtInfoNoFlags) {
64 android_dlextinfo extinfo;
65 extinfo.flags = 0;
66 handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo);
67 ASSERT_DL_NOTNULL(handle_);
68 fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
69 ASSERT_DL_NOTNULL(f);
70 EXPECT_EQ(4, f());
71}
72
73TEST_F(DlExtTest, Reserved) {
74 void* start = mmap(NULL, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
75 -1, 0);
76 ASSERT_TRUE(start != MAP_FAILED);
77 android_dlextinfo extinfo;
78 extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
79 extinfo.reserved_addr = start;
80 extinfo.reserved_size = LIBSIZE;
81 handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo);
82 ASSERT_DL_NOTNULL(handle_);
83 fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
84 ASSERT_DL_NOTNULL(f);
85 EXPECT_GE(f, start);
86 EXPECT_LT(reinterpret_cast<void*>(f),
87 reinterpret_cast<char*>(start) + LIBSIZE);
88 EXPECT_EQ(4, f());
89}
90
91TEST_F(DlExtTest, ReservedTooSmall) {
92 void* start = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
93 -1, 0);
94 ASSERT_TRUE(start != MAP_FAILED);
95 android_dlextinfo extinfo;
96 extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
97 extinfo.reserved_addr = start;
98 extinfo.reserved_size = PAGE_SIZE;
99 handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo);
100 EXPECT_EQ(NULL, handle_);
101}
102
103TEST_F(DlExtTest, ReservedHint) {
104 void* start = mmap(NULL, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
105 -1, 0);
106 ASSERT_TRUE(start != MAP_FAILED);
107 android_dlextinfo extinfo;
108 extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS_HINT;
109 extinfo.reserved_addr = start;
110 extinfo.reserved_size = LIBSIZE;
111 handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo);
112 ASSERT_DL_NOTNULL(handle_);
113 fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
114 ASSERT_DL_NOTNULL(f);
115 EXPECT_GE(f, start);
116 EXPECT_LT(reinterpret_cast<void*>(f),
117 reinterpret_cast<char*>(start) + LIBSIZE);
118 EXPECT_EQ(4, f());
119}
120
121TEST_F(DlExtTest, ReservedHintTooSmall) {
122 void* start = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
123 -1, 0);
124 ASSERT_TRUE(start != MAP_FAILED);
125 android_dlextinfo extinfo;
126 extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS_HINT;
127 extinfo.reserved_addr = start;
128 extinfo.reserved_size = PAGE_SIZE;
129 handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo);
130 ASSERT_DL_NOTNULL(handle_);
131 fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
132 ASSERT_DL_NOTNULL(f);
133 EXPECT_TRUE(f < start || (reinterpret_cast<void*>(f) >=
134 reinterpret_cast<char*>(start) + PAGE_SIZE));
135 EXPECT_EQ(4, f());
136}