Add file_offset parameter to android_extinfo

Bug: 17762003

(cherry picked from commit 07e5bc152d)

Change-Id: I72d527831384ff5dde013a4c8dfe639fbec165f5
This commit is contained in:
Dmitriy Ivanov 2014-10-03 17:52:44 -07:00
parent c712ceeec4
commit de01780f46
9 changed files with 206 additions and 58 deletions

View File

@ -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);

View File

@ -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);
static soinfo __libdl_info("libdl.so", nullptr, 0);
// This is used by the dynamic linker. Every process gets these symbols for free.
soinfo* get_libdl_info() {

View File

@ -285,13 +285,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) {
static soinfo* soinfo_alloc(const char* name, struct stat* file_stat, off64_t file_offset) {
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);
soinfo* si = new (g_soinfo_allocator.alloc()) soinfo(name, file_stat, file_offset);
sonext->next = si;
sonext = si;
@ -457,7 +457,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) {
soinfo::soinfo(const char* name, const struct stat* file_stat, off64_t file_offset) {
memset(this, 0, sizeof(*this));
strlcpy(this->name, name, sizeof(this->name));
@ -465,8 +465,9 @@ soinfo::soinfo(const char* name, const struct stat* file_stat) {
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;
}
}
@ -811,10 +812,14 @@ static void for_each_dt_needed(const soinfo* si, F action) {
static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int dlflags, 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);
@ -826,6 +831,11 @@ static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int dlfl
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));
@ -838,7 +848,8 @@ static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int dlfl
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;
}
@ -850,12 +861,12 @@ static soinfo* load_library(LoadTaskList& load_tasks, const char* name, int dlfl
}
// 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);
soinfo* si = soinfo_alloc(SEARCH_NAME(name), &file_stat, file_offset);
if (si == nullptr) {
return nullptr;
}
@ -1068,10 +1079,17 @@ 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);
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);
if (si != nullptr) {
@ -1752,18 +1770,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;
@ -1780,6 +1786,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;
}
// This is a return on get_children()/get_parents() if
// 'this->flags' does not have FLAG_NEW_SOINFO set.
static soinfo::soinfo_list_t g_empty_list;
@ -2200,7 +2214,7 @@ static void add_vdso(KernelArgumentBlock& args __unused) {
return;
}
soinfo* si = soinfo_alloc("[vdso]", nullptr);
soinfo* si = soinfo_alloc("[vdso]", nullptr, 0);
si->phdr = reinterpret_cast<ElfW(Phdr)*>(reinterpret_cast<char*>(ehdr_vdso) + ehdr_vdso->e_phoff);
si->phnum = ehdr_vdso->e_phnum;
@ -2221,7 +2235,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);
static soinfo linker_soinfo_for_gdb(LINKER_PATH, nullptr, 0);
/* gdb expects the linker to be in the debug shared object list.
* Without this, gdb has trouble locating the linker's ".text"
@ -2285,7 +2299,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
INFO("[ android linker & debugger ]");
soinfo* si = soinfo_alloc(args.argv[0], nullptr);
soinfo* si = soinfo_alloc(args.argv[0], nullptr, 0);
if (si == nullptr) {
exit(EXIT_FAILURE);
}
@ -2473,7 +2487,7 @@ extern "C" ElfW(Addr) __linker_init(void* raw_args) {
ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_addr);
ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_addr + elf_hdr->e_phoff);
soinfo linker_so("[dynamic linker]", nullptr);
soinfo linker_so("[dynamic linker]", nullptr, 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

View File

@ -197,11 +197,9 @@ struct soinfo {
#if !defined(__LP64__)
bool has_text_relocations;
#endif
// TODO: remove this flag, dynamic linker
// should not use it in any way.
bool has_DT_SYMBOLIC;
soinfo(const char* name, const struct stat* file_stat);
soinfo(const char* name, const struct stat* file_stat, off64_t file_offset);
void CallConstructors();
void CallDestructors();
@ -212,10 +210,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();
soinfo_list_t& get_children();
soinfo_list_t& get_parents();
@ -248,6 +245,7 @@ struct soinfo {
soinfo_list_t parents;
// version >= 1
off64_t file_offset;
};
extern soinfo* get_libdl_info();

View File

@ -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<void*>(seg_page_start),
void* seg_addr = mmap64(reinterpret_cast<void*>(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;

View File

@ -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_;

View File

@ -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<fn>(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<fn>(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;
@ -174,7 +229,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;
@ -183,7 +238,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);
}
@ -204,7 +259,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);
}
@ -327,7 +382,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);
}

View File

@ -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) $< $@

View File

@ -90,6 +90,17 @@ build_type := target
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 :=
include $(LOCAL_PATH)/Android.build.dlext_testzip.mk
ifneq ($(TARGET_2ND_ARCH),)
bionic_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
include $(LOCAL_PATH)/Android.build.dlext_testzip.mk
endif
# -----------------------------------------------------------------------------
# Library used by dlfcn tests
# -----------------------------------------------------------------------------
@ -332,3 +343,9 @@ build_type := target
include $(TEST_PATH)/Android.build.mk
build_type := host
include $(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