dlext_test.cpp revision 12bbb9164578b6512b8b07a3fb093858244b7c7b
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 <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} 137