From 07e5bc152d8a3ad4c50808bb86f3c0f2c5e2f514 Mon Sep 17 00:00:00 2001 From: Dmitriy Ivanov Date: Fri, 3 Oct 2014 17:52:44 -0700 Subject: [PATCH] Add file_offset parameter to android_extinfo Bug: 17762003 Change-Id: I8fb267a3155acef3dba534038cf5d1ef00d7154b --- libc/include/android/dlext.h | 10 +++- linker/dlfcn.cpp | 2 +- linker/linker.cpp | 68 ++++++++++++++--------- linker/linker.h | 6 +- linker/linker_phdr.cpp | 17 ++++-- linker/linker_phdr.h | 3 +- tests/dlext_test.cpp | 91 +++++++++++++++++++++++++------ tests/libs/Android.build.dlext_testzip.mk | 48 ++++++++++++++++ tests/libs/Android.mk | 17 +++++- 9 files changed, 205 insertions(+), 57 deletions(-) create mode 100644 tests/libs/Android.build.dlext_testzip.mk diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h index 5c3a206a4..f81ec70d5 100644 --- a/libc/include/android/dlext.h +++ b/libc/include/android/dlext.h @@ -54,12 +54,19 @@ enum { */ ANDROID_DLEXT_USE_LIBRARY_FD = 0x10, + /* When opening library using library_fd read it starting with library_offset + * This flag is only valid when ANDROID_DLEXT_USE_LIBRARY_FD is set. + */ + + ANDROID_DLEXT_USE_LIBRARY_OFFSET = 0x20, + /* Mask of valid bits */ ANDROID_DLEXT_VALID_FLAG_BITS = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_HINT | ANDROID_DLEXT_WRITE_RELRO | ANDROID_DLEXT_USE_RELRO | - ANDROID_DLEXT_USE_LIBRARY_FD, + ANDROID_DLEXT_USE_LIBRARY_FD | + ANDROID_DLEXT_USE_LIBRARY_OFFSET, }; typedef struct { @@ -68,6 +75,7 @@ typedef struct { size_t reserved_size; int relro_fd; int library_fd; + off64_t library_offset; } android_dlextinfo; extern void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo); diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp index 98931c703..367179d8d 100644 --- a/linker/dlfcn.cpp +++ b/linker/dlfcn.cpp @@ -232,7 +232,7 @@ static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0 }; static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; #endif -static soinfo __libdl_info("libdl.so", nullptr, RTLD_GLOBAL); +static soinfo __libdl_info("libdl.so", nullptr, 0, RTLD_GLOBAL); // This is used by the dynamic linker. Every process gets these symbols for free. soinfo* get_libdl_info() { diff --git a/linker/linker.cpp b/linker/linker.cpp index a8c2b1e83..be2b45ac5 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -282,13 +282,13 @@ static void protect_data(int protection) { g_soinfo_links_allocator.protect_all(protection); } -static soinfo* soinfo_alloc(const char* name, struct stat* file_stat, int rtld_flags) { +static soinfo* soinfo_alloc(const char* name, struct stat* file_stat, off64_t file_offset, int rtld_flags) { if (strlen(name) >= SOINFO_NAME_LEN) { DL_ERR("library name \"%s\" too long", name); return nullptr; } - soinfo* si = new (g_soinfo_allocator.alloc()) soinfo(name, file_stat, rtld_flags); + soinfo* si = new (g_soinfo_allocator.alloc()) soinfo(name, file_stat, file_offset, rtld_flags); sonext->next = si; sonext = si; @@ -452,7 +452,7 @@ static ElfW(Sym)* soinfo_elf_lookup(soinfo* si, unsigned hash, const char* name) return nullptr; } -soinfo::soinfo(const char* name, const struct stat* file_stat, int rtld_flags) { +soinfo::soinfo(const char* name, const struct stat* file_stat, off64_t file_offset, int rtld_flags) { memset(this, 0, sizeof(*this)); strlcpy(this->name, name, sizeof(this->name)); @@ -460,8 +460,9 @@ soinfo::soinfo(const char* name, const struct stat* file_stat, int rtld_flags) { version = SOINFO_VERSION; if (file_stat != nullptr) { - set_st_dev(file_stat->st_dev); - set_st_ino(file_stat->st_ino); + this->st_dev = file_stat->st_dev; + this->st_ino = file_stat->st_ino; + this->file_offset = file_offset; } this->rtld_flags = rtld_flags; @@ -781,10 +782,14 @@ static void for_each_dt_needed(const soinfo* si, F action) { static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int rtld_flags, const android_dlextinfo* extinfo) { int fd = -1; + off64_t file_offset = 0; ScopedFd file_guard(-1); if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) { fd = extinfo->library_fd; + if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_OFFSET) != 0) { + file_offset = extinfo->library_offset; + } } else { // Open the file. fd = open_library(name); @@ -796,6 +801,11 @@ static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int rtld file_guard.reset(fd); } + if ((file_offset % PAGE_SIZE) != 0) { + DL_ERR("file offset for the library %s is not page-aligned: %" PRId64, name, file_offset); + return nullptr; + } + struct stat file_stat; if (TEMP_FAILURE_RETRY(fstat(fd, &file_stat)) != 0) { DL_ERR("unable to stat file for the library %s: %s", name, strerror(errno)); @@ -808,7 +818,8 @@ static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int rtld if (si->get_st_dev() != 0 && si->get_st_ino() != 0 && si->get_st_dev() == file_stat.st_dev && - si->get_st_ino() == file_stat.st_ino) { + si->get_st_ino() == file_stat.st_ino && + si->get_file_offset() == file_offset) { TRACE("library \"%s\" is already loaded under different name/path \"%s\" - will return existing soinfo", name, si->name); return si; } @@ -820,12 +831,12 @@ static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int rtld } // Read the ELF header and load the segments. - ElfReader elf_reader(name, fd); + ElfReader elf_reader(name, fd, file_offset); if (!elf_reader.Load(extinfo)) { return nullptr; } - soinfo* si = soinfo_alloc(SEARCH_NAME(name), &file_stat, rtld_flags); + soinfo* si = soinfo_alloc(SEARCH_NAME(name), &file_stat, file_offset, rtld_flags); if (si == nullptr) { return nullptr; } @@ -1043,9 +1054,16 @@ soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo) DL_ERR("invalid flags to dlopen: %x", flags); return nullptr; } - if (extinfo != nullptr && ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0)) { - DL_ERR("invalid extended flags to android_dlopen_ext: %" PRIx64, extinfo->flags); - return nullptr; + if (extinfo != nullptr) { + if ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0) { + DL_ERR("invalid extended flags to android_dlopen_ext: 0x%" PRIx64, extinfo->flags); + return nullptr; + } + if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) == 0 && + (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_OFFSET) != 0) { + DL_ERR("invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_OFFSET without ANDROID_DLEXT_USE_LIBRARY_FD): 0x%" PRIx64, extinfo->flags); + return nullptr; + } } protect_data(PROT_READ | PROT_WRITE); soinfo* si = find_library(name, flags, extinfo); @@ -1727,18 +1745,6 @@ void soinfo::remove_all_links() { children.clear(); } -void soinfo::set_st_dev(dev_t dev) { - if (has_min_version(0)) { - st_dev = dev; - } -} - -void soinfo::set_st_ino(ino_t ino) { - if (has_min_version(0)) { - st_ino = ino; - } -} - dev_t soinfo::get_st_dev() { if (has_min_version(0)) { return st_dev; @@ -1755,6 +1761,14 @@ ino_t soinfo::get_st_ino() { return 0; } +off64_t soinfo::get_file_offset() { + if (has_min_version(1)) { + return file_offset; + } + + return 0; +} + int soinfo::get_rtld_flags() { if (has_min_version(1)) { return rtld_flags; @@ -2242,7 +2256,7 @@ static void add_vdso(KernelArgumentBlock& args __unused) { return; } - soinfo* si = soinfo_alloc("[vdso]", nullptr, 0); + soinfo* si = soinfo_alloc("[vdso]", nullptr, 0, 0); si->phdr = reinterpret_cast(reinterpret_cast(ehdr_vdso) + ehdr_vdso->e_phoff); si->phnum = ehdr_vdso->e_phnum; @@ -2263,7 +2277,7 @@ static void add_vdso(KernelArgumentBlock& args __unused) { #else #define LINKER_PATH "/system/bin/linker" #endif -static soinfo linker_soinfo_for_gdb(LINKER_PATH, nullptr, 0); +static soinfo linker_soinfo_for_gdb(LINKER_PATH, nullptr, 0, 0); /* gdb expects the linker to be in the debug shared object list. * Without this, gdb has trouble locating the linker's ".text" @@ -2327,7 +2341,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW( INFO("[ android linker & debugger ]"); - soinfo* si = soinfo_alloc(args.argv[0], nullptr, RTLD_GLOBAL); + soinfo* si = soinfo_alloc(args.argv[0], nullptr, 0, RTLD_GLOBAL); if (si == nullptr) { exit(EXIT_FAILURE); } @@ -2515,7 +2529,7 @@ extern "C" ElfW(Addr) __linker_init(void* raw_args) { ElfW(Ehdr)* elf_hdr = reinterpret_cast(linker_addr); ElfW(Phdr)* phdr = reinterpret_cast(linker_addr + elf_hdr->e_phoff); - soinfo linker_so("[dynamic linker]", nullptr, 0); + soinfo linker_so("[dynamic linker]", nullptr, 0, 0); // If the linker is not acting as PT_INTERP entry_point is equal to // _start. Which means that the linker is running as an executable and diff --git a/linker/linker.h b/linker/linker.h index c8e5c68eb..08dd625bb 100644 --- a/linker/linker.h +++ b/linker/linker.h @@ -201,7 +201,7 @@ struct soinfo { #endif bool has_DT_SYMBOLIC; - soinfo(const char* name, const struct stat* file_stat, int rtld_flags); + soinfo(const char* name, const struct stat* file_stat, off64_t file_offset, int rtld_flags); void CallConstructors(); void CallDestructors(); @@ -212,10 +212,9 @@ struct soinfo { void add_child(soinfo* child); void remove_all_links(); - void set_st_dev(dev_t st_dev); - void set_st_ino(ino_t st_ino); ino_t get_st_ino(); dev_t get_st_dev(); + off64_t get_file_offset(); int get_rtld_flags(); @@ -254,6 +253,7 @@ struct soinfo { soinfo_list_t parents; // version >= 1 + off64_t file_offset; int rtld_flags; size_t strtab_size; diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp index 44c8e9e70..e0d6d0e78 100644 --- a/linker/linker_phdr.cpp +++ b/linker/linker_phdr.cpp @@ -119,8 +119,8 @@ MAYBE_MAP_FLAG((x), PF_R, PROT_READ) | \ MAYBE_MAP_FLAG((x), PF_W, PROT_WRITE)) -ElfReader::ElfReader(const char* name, int fd) - : name_(name), fd_(fd), +ElfReader::ElfReader(const char* name, int fd, off64_t file_offset) + : name_(name), fd_(fd), file_offset_(file_offset), phdr_num_(0), phdr_mmap_(nullptr), phdr_table_(nullptr), phdr_size_(0), load_start_(nullptr), load_size_(0), load_bias_(0), loaded_phdr_(nullptr) { @@ -142,6 +142,13 @@ bool ElfReader::Load(const android_dlextinfo* extinfo) { } bool ElfReader::ReadElfHeader() { + off64_t actual_offset = lseek64(fd_, file_offset_, SEEK_SET); + + if (actual_offset != file_offset_) { + DL_ERR("seek to %" PRId64 " failed: %s", file_offset_, strerror(errno)); + return false; + } + ssize_t rc = TEMP_FAILURE_RETRY(read(fd_, &header_, sizeof(header_))); if (rc < 0) { DL_ERR("can't read file \"%s\": %s", name_, strerror(errno)); @@ -225,7 +232,7 @@ bool ElfReader::ReadProgramHeader() { phdr_size_ = page_max - page_min; - void* mmap_result = mmap(nullptr, phdr_size_, PROT_READ, MAP_PRIVATE, fd_, page_min); + void* mmap_result = mmap64(nullptr, phdr_size_, PROT_READ, MAP_PRIVATE, fd_, file_offset_ + page_min); if (mmap_result == MAP_FAILED) { DL_ERR("\"%s\" phdr mmap failed: %s", name_, strerror(errno)); return false; @@ -356,12 +363,12 @@ bool ElfReader::LoadSegments() { ElfW(Addr) file_length = file_end - file_page_start; if (file_length != 0) { - void* seg_addr = mmap(reinterpret_cast(seg_page_start), + void* seg_addr = mmap64(reinterpret_cast(seg_page_start), file_length, PFLAGS_TO_PROT(phdr->p_flags), MAP_FIXED|MAP_PRIVATE, fd_, - file_page_start); + file_offset_ + file_page_start); if (seg_addr == MAP_FAILED) { DL_ERR("couldn't map \"%s\" segment %zd: %s", name_, i, strerror(errno)); return false; diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h index 593fb5a20..65d302cdb 100644 --- a/linker/linker_phdr.h +++ b/linker/linker_phdr.h @@ -39,7 +39,7 @@ class ElfReader { public: - ElfReader(const char* name, int fd); + ElfReader(const char* name, int fd, off64_t file_offset); ~ElfReader(); bool Load(const android_dlextinfo* extinfo); @@ -61,6 +61,7 @@ class ElfReader { const char* name_; int fd_; + off64_t file_offset_; ElfW(Ehdr) header_; size_t phdr_num_; diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp index 7bd59c84c..7585e9b30 100644 --- a/tests/dlext_test.cpp +++ b/tests/dlext_test.cpp @@ -31,7 +31,7 @@ #define ASSERT_DL_NOTNULL(ptr) \ - ASSERT_TRUE(ptr != NULL) << "dlerror: " << dlerror() + ASSERT_TRUE(ptr != nullptr) << "dlerror: " << dlerror() #define ASSERT_DL_ZERO(i) \ ASSERT_EQ(0, i) << "dlerror: " << dlerror() @@ -46,23 +46,31 @@ typedef int (*fn)(void); #define LIBSIZE 1024*1024 // how much address space to reserve for it #if defined(__LP64__) -#define LIBPATH "%s/nativetest64/libdlext_test_fd/libdlext_test_fd.so" +#define LIBPATH_PREFIX "%s/nativetest64/libdlext_test_fd/" #else -#define LIBPATH "%s/nativetest/libdlext_test_fd/libdlext_test_fd.so" +#define LIBPATH_PREFIX "%s/nativetest/libdlext_test_fd/" #endif +#define LIBPATH LIBPATH_PREFIX "libdlext_test_fd.so" +#define LIBZIPPATH LIBPATH_PREFIX "dlext_test.zip" + +#define LIBZIP_OFFSET 2*PAGE_SIZE + class DlExtTest : public ::testing::Test { protected: virtual void SetUp() { - handle_ = NULL; + handle_ = nullptr; // verify that we don't have the library loaded already - ASSERT_EQ(NULL, dlsym(RTLD_DEFAULT, "getRandomNumber")); + void* h = dlopen(LIBNAME, RTLD_NOW | RTLD_NOLOAD); + ASSERT_TRUE(h == nullptr); + h = dlopen(LIBNAME_NORELRO, RTLD_NOW | RTLD_NOLOAD); + ASSERT_TRUE(h == nullptr); // call dlerror() to swallow the error, and check it was the one we wanted - ASSERT_STREQ("undefined symbol: getRandomNumber", dlerror()); + ASSERT_STREQ("dlopen failed: library \"" LIBNAME_NORELRO "\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror()); } virtual void TearDown() { - if (handle_ != NULL) { + if (handle_ != nullptr) { ASSERT_DL_ZERO(dlclose(handle_)); } } @@ -71,7 +79,7 @@ protected: }; TEST_F(DlExtTest, ExtInfoNull) { - handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, NULL); + handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, nullptr); ASSERT_DL_NOTNULL(handle_); fn f = reinterpret_cast(dlsym(handle_, "getRandomNumber")); ASSERT_DL_NOTNULL(f); @@ -90,7 +98,7 @@ TEST_F(DlExtTest, ExtInfoNoFlags) { TEST_F(DlExtTest, ExtInfoUseFd) { const char* android_data = getenv("ANDROID_DATA"); - ASSERT_TRUE(android_data != NULL); + ASSERT_TRUE(android_data != nullptr); char lib_path[PATH_MAX]; snprintf(lib_path, sizeof(lib_path), LIBPATH, android_data); @@ -105,8 +113,55 @@ TEST_F(DlExtTest, ExtInfoUseFd) { EXPECT_EQ(4, f()); } +TEST_F(DlExtTest, ExtInfoUseFdWithOffset) { + const char* android_data = getenv("ANDROID_DATA"); + ASSERT_TRUE(android_data != nullptr); + + char lib_path[PATH_MAX]; + snprintf(lib_path, sizeof(lib_path), LIBZIPPATH, android_data); + + android_dlextinfo extinfo; + extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_OFFSET; + extinfo.library_fd = TEMP_FAILURE_RETRY(open(lib_path, O_RDONLY | O_CLOEXEC)); + extinfo.library_offset = LIBZIP_OFFSET; + + handle_ = android_dlopen_ext(lib_path, RTLD_NOW, &extinfo); + ASSERT_DL_NOTNULL(handle_); + + fn f = reinterpret_cast(dlsym(handle_, "getRandomNumber")); + ASSERT_DL_NOTNULL(f); + EXPECT_EQ(4, f()); +} + +TEST_F(DlExtTest, ExtInfoUseFdWithInvalidOffset) { + const char* android_data = getenv("ANDROID_DATA"); + ASSERT_TRUE(android_data != nullptr); + + char lib_path[PATH_MAX]; + snprintf(lib_path, sizeof(lib_path), LIBZIPPATH, android_data); + + android_dlextinfo extinfo; + extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_OFFSET; + extinfo.library_fd = TEMP_FAILURE_RETRY(open(lib_path, O_RDONLY | O_CLOEXEC)); + extinfo.library_offset = 17; + + handle_ = android_dlopen_ext("libname_placeholder", RTLD_NOW, &extinfo); + ASSERT_TRUE(handle_ == nullptr); + ASSERT_STREQ("dlopen failed: file offset for the library libname_placeholder is not page-aligned: 17", dlerror()); +} + +TEST_F(DlExtTest, ExtInfoUseOffsetWihtoutFd) { + android_dlextinfo extinfo; + extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_OFFSET; + extinfo.library_offset = LIBZIP_OFFSET; + + handle_ = android_dlopen_ext("/some/lib/that/does_not_exist", RTLD_NOW, &extinfo); + ASSERT_TRUE(handle_ == nullptr); + ASSERT_STREQ("dlopen failed: invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_OFFSET without ANDROID_DLEXT_USE_LIBRARY_FD): 0x20", dlerror()); +} + TEST_F(DlExtTest, Reserved) { - void* start = mmap(NULL, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, + void* start = mmap(nullptr, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ASSERT_TRUE(start != MAP_FAILED); android_dlextinfo extinfo; @@ -124,7 +179,7 @@ TEST_F(DlExtTest, Reserved) { } TEST_F(DlExtTest, ReservedTooSmall) { - void* start = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, + void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ASSERT_TRUE(start != MAP_FAILED); android_dlextinfo extinfo; @@ -132,11 +187,11 @@ TEST_F(DlExtTest, ReservedTooSmall) { extinfo.reserved_addr = start; extinfo.reserved_size = PAGE_SIZE; handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo); - EXPECT_EQ(NULL, handle_); + EXPECT_EQ(nullptr, handle_); } TEST_F(DlExtTest, ReservedHint) { - void* start = mmap(NULL, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, + void* start = mmap(nullptr, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ASSERT_TRUE(start != MAP_FAILED); android_dlextinfo extinfo; @@ -154,7 +209,7 @@ TEST_F(DlExtTest, ReservedHint) { } TEST_F(DlExtTest, ReservedHintTooSmall) { - void* start = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, + void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ASSERT_TRUE(start != MAP_FAILED); android_dlextinfo extinfo; @@ -175,7 +230,7 @@ class DlExtRelroSharingTest : public DlExtTest { protected: virtual void SetUp() { DlExtTest::SetUp(); - void* start = mmap(NULL, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, + void* start = mmap(nullptr, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ASSERT_TRUE(start != MAP_FAILED); extinfo_.flags = ANDROID_DLEXT_RESERVED_ADDRESS; @@ -184,7 +239,7 @@ protected: extinfo_.relro_fd = -1; const char* android_data = getenv("ANDROID_DATA"); - ASSERT_TRUE(android_data != NULL); + ASSERT_TRUE(android_data != nullptr); snprintf(relro_file_, sizeof(relro_file_), "%s/local/tmp/libdlext_test.relro", android_data); } @@ -205,7 +260,7 @@ protected: extinfo_.flags |= ANDROID_DLEXT_WRITE_RELRO; extinfo_.relro_fd = relro_fd; void* handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo_); - if (handle == NULL) { + if (handle == nullptr) { fprintf(stderr, "in child: %s\n", dlerror()); exit(1); } @@ -333,7 +388,7 @@ void DlExtRelroSharingTest::SpawnChildrenAndMeasurePss(const char* lib, bool sha } else { handle = dlopen(lib, RTLD_NOW); } - if (handle == NULL) { + if (handle == nullptr) { fprintf(stderr, "in child: %s\n", dlerror()); exit(1); } diff --git a/tests/libs/Android.build.dlext_testzip.mk b/tests/libs/Android.build.dlext_testzip.mk new file mode 100644 index 000000000..e672091a1 --- /dev/null +++ b/tests/libs/Android.build.dlext_testzip.mk @@ -0,0 +1,48 @@ +# +# Copyright (C) 2014 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# ----------------------------------------------------------------------------- +# Library used by dlext tests - zipped and aligned +# ----------------------------------------------------------------------------- + +# TODO: It there simple way to do this? +$(bionic_2nd_arch_prefix)bionic_dlext_test_zip := \ + $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATES)/libdlext_test_fd/dlext_test_origin.zip +$(bionic_2nd_arch_prefix)bionic_dlext_test_zip_aligned := \ + $($(bionic_2nd_arch_prefix)TARGET_OUT_DATA_NATIVE_TESTS)/libdlext_test_fd/dlext_test.zip +ALL_MODULES += $($(bionic_2nd_arch_prefix)bionic_dlext_test_zip_aligned) + +$(bionic_2nd_arch_prefix)bionic_dlext_built_shared_libraries := \ + $($(bionic_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/libdlext_test_fd.so + +bionic_dlext_test_zip_alignment := 4096 # PAGE_SIZE + +$(bionic_2nd_arch_prefix)bionic_dlext_test_zip_tmpdir := $(dir $($(bionic_2nd_arch_prefix)bionic_dlext_test_zip)) + +$($(bionic_2nd_arch_prefix)bionic_dlext_test_zip)_prepare: $($(bionic_2nd_arch_prefix)bionic_dlext_built_shared_libraries) + $(hide) mkdir -p $(dir $@) + $(hide) cp -p $< $(dir $@) + +$($(bionic_2nd_arch_prefix)bionic_dlext_test_zip): $($(bionic_2nd_arch_prefix)bionic_dlext_test_zip)_prepare + @echo "Zip: $@" + $(hide) (cd $(dir $@) && touch empty_file.txt && zip -rD0 $(notdir $@) empty_file.txt libdlext_test_fd.so) + +$($(bionic_2nd_arch_prefix)bionic_dlext_test_zip_aligned): $($(bionic_2nd_arch_prefix)bionic_dlext_test_zip) | $(ZIPALIGN) + $(hide) rm -rf $@ + $(hide) mkdir -p $(dir $@) + @echo "Zipalign $(bionic_dlext_test_zip_alignment): $@" + $(hide) zipalign $(bionic_dlext_test_zip_alignment) $< $@ + diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk index c98fea8d9..0cff66051 100644 --- a/tests/libs/Android.mk +++ b/tests/libs/Android.mk @@ -95,6 +95,17 @@ build_target := SHARED_LIBRARY include $(TEST_PATH)/Android.build.mk # ----------------------------------------------------------------------------- +# Library used by dlext tests - zipped and aligned +# ----------------------------------------------------------------------------- +include $(CLEAR_VARS) +bionic_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX) +include $(LOCAL_PATH)/Android.build.dlext_testzip.mk +ifneq ($(TARGET_2ND_ARCH),) + bionic_2nd_arch_prefix := + include $(LOCAL_PATH)/Android.build.dlext_testzip.mk +endif + +# ----------------------------------------------------------------------------- # Library used by dlfcn tests # ----------------------------------------------------------------------------- libtest_simple_src_files := \ @@ -338,4 +349,8 @@ libtest_dlsym_weak_func_src_files := \ module := libtest_dlsym_weak_func include $(LOCAL_PATH)/Android.build.testlib.mk -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/Android.build.testlib.mk $(TEST_PATH)/Android.build.mk +LOCAL_ADDITIONAL_DEPENDENCIES := \ + $(LOCAL_PATH)/Android.mk \ + $(LOCAL_PATH)/Android.build.dlext_testzip.mk \ + $(LOCAL_PATH)/Android.build.testlib.mk \ + $(TEST_PATH)/Android.build.mk -- 2.11.0