ART isn't using the ART-specific linker features any more.
Bug: N/A Test: ran tests Change-Id: Ide3c295035687019608a2c4716a4a21cb889d121
This commit is contained in:
parent
0c39bd468d
commit
8178c417f6
4 changed files with 9 additions and 103 deletions
|
@ -100,34 +100,11 @@ enum {
|
|||
*/
|
||||
ANDROID_DLEXT_FORCE_LOAD = 0x40,
|
||||
|
||||
/**
|
||||
* When set, if the minimum `p_vaddr` of the ELF file's `PT_LOAD` segments is non-zero,
|
||||
* the dynamic linker will load it at that address.
|
||||
*
|
||||
* This flag is for ART internal use only.
|
||||
*/
|
||||
ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80,
|
||||
|
||||
/**
|
||||
* Instructs dlopen to load the library at the address specified by reserved_addr.
|
||||
*
|
||||
* The difference between `ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS` and
|
||||
* `ANDROID_DLEXT_RESERVED_ADDRESS` is that for `ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS` the linker
|
||||
* reserves memory at `reserved_addr` whereas for `ANDROID_DLEXT_RESERVED_ADDRESS` the linker
|
||||
* relies on the caller to reserve the memory.
|
||||
*
|
||||
* This flag can be used with `ANDROID_DLEXT_FORCE_FIXED_VADDR`. When
|
||||
* `ANDROID_DLEXT_FORCE_FIXED_VADDR` is set and `load_bias` is not 0 (`load_bias` is the
|
||||
* minimum `p_vaddr` of all `PT_LOAD` segments) this flag is ignored because the linker has to
|
||||
* pick one address over the other and this way is more convenient for ART.
|
||||
* Note that `ANDROID_DLEXT_FORCE_FIXED_VADDR` does not generate an error when the minimum
|
||||
* `p_vaddr` is 0.
|
||||
*
|
||||
* Cannot be used with `ANDROID_DLEXT_RESERVED_ADDRESS` or `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`.
|
||||
*
|
||||
* This flag is for ART internal use only.
|
||||
*/
|
||||
ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS = 0x100,
|
||||
// Historically we had two other options for ART.
|
||||
// They were last available in Android P.
|
||||
// Reuse these bits last!
|
||||
// ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80
|
||||
// ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS = 0x100
|
||||
|
||||
/**
|
||||
* This flag used to load library in a different namespace. The namespace is
|
||||
|
@ -145,8 +122,6 @@ enum {
|
|||
ANDROID_DLEXT_USE_LIBRARY_FD |
|
||||
ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET |
|
||||
ANDROID_DLEXT_FORCE_LOAD |
|
||||
ANDROID_DLEXT_FORCE_FIXED_VADDR |
|
||||
ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS |
|
||||
ANDROID_DLEXT_USE_NAMESPACE,
|
||||
};
|
||||
|
||||
|
|
|
@ -2074,13 +2074,6 @@ void* do_dlopen(const char* name, int flags,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0 &&
|
||||
(extinfo->flags & (ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_HINT)) != 0) {
|
||||
DL_ERR("invalid extended flag combination: ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS is not "
|
||||
"compatible with ANDROID_DLEXT_RESERVED_ADDRESS/ANDROID_DLEXT_RESERVED_ADDRESS_HINT");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ((extinfo->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0) {
|
||||
if (extinfo->library_namespace == nullptr) {
|
||||
DL_ERR("ANDROID_DLEXT_USE_NAMESPACE is set but extinfo->library_namespace is null");
|
||||
|
|
|
@ -525,14 +525,10 @@ size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count,
|
|||
|
||||
// Reserve a virtual address range such that if it's limits were extended to the next 2**align
|
||||
// boundary, it would not overlap with any existing mappings.
|
||||
static void* ReserveAligned(void* hint, size_t size, size_t align) {
|
||||
static void* ReserveAligned(size_t size, size_t align) {
|
||||
int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
||||
// Address hint is only used in Art for the image mapping, and it is pretty important. Don't mess
|
||||
// with it.
|
||||
// FIXME: try an aligned allocation and fall back to plain mmap() if the former does not provide a
|
||||
// mapping at the requested address?
|
||||
if (align == PAGE_SIZE || hint != nullptr) {
|
||||
void* mmap_ptr = mmap(hint, size, PROT_NONE, mmap_flags, -1, 0);
|
||||
if (align == PAGE_SIZE) {
|
||||
void* mmap_ptr = mmap(nullptr, size, PROT_NONE, mmap_flags, -1, 0);
|
||||
if (mmap_ptr == MAP_FAILED) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -575,9 +571,6 @@ bool ElfReader::ReserveAddressSpace(const android_dlextinfo* extinfo) {
|
|||
void* start;
|
||||
size_t reserved_size = 0;
|
||||
bool reserved_hint = true;
|
||||
bool strict_hint = false;
|
||||
// Assume position independent executable by default.
|
||||
void* mmap_hint = nullptr;
|
||||
|
||||
if (extinfo != nullptr) {
|
||||
if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS) {
|
||||
|
@ -586,13 +579,6 @@ bool ElfReader::ReserveAddressSpace(const android_dlextinfo* extinfo) {
|
|||
} else if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS_HINT) {
|
||||
reserved_size = extinfo->reserved_size;
|
||||
}
|
||||
|
||||
if (addr != nullptr && (extinfo->flags & ANDROID_DLEXT_FORCE_FIXED_VADDR) != 0) {
|
||||
mmap_hint = addr;
|
||||
} else if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0) {
|
||||
mmap_hint = extinfo->reserved_addr;
|
||||
strict_hint = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (load_size_ > reserved_size) {
|
||||
|
@ -601,17 +587,11 @@ bool ElfReader::ReserveAddressSpace(const android_dlextinfo* extinfo) {
|
|||
reserved_size - load_size_, load_size_, name_.c_str());
|
||||
return false;
|
||||
}
|
||||
start = ReserveAligned(mmap_hint, load_size_, kLibraryAlignment);
|
||||
start = ReserveAligned(load_size_, kLibraryAlignment);
|
||||
if (start == nullptr) {
|
||||
DL_ERR("couldn't reserve %zd bytes of address space for \"%s\"", load_size_, name_.c_str());
|
||||
return false;
|
||||
}
|
||||
if (strict_hint && (start != mmap_hint)) {
|
||||
munmap(start, load_size_);
|
||||
DL_ERR("couldn't reserve %zd bytes of address space at %p for \"%s\"",
|
||||
load_size_, mmap_hint, name_.c_str());
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
start = extinfo->reserved_addr;
|
||||
mapped_by_caller_ = true;
|
||||
|
|
|
@ -367,48 +367,6 @@ TEST_F(DlExtTest, ReservedHintTooSmall) {
|
|||
EXPECT_EQ(4, f());
|
||||
}
|
||||
|
||||
TEST_F(DlExtTest, LoadAtFixedAddress) {
|
||||
void* start = mmap(nullptr, kLibSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
ASSERT_TRUE(start != MAP_FAILED);
|
||||
munmap(start, kLibSize);
|
||||
|
||||
android_dlextinfo extinfo;
|
||||
extinfo.flags = ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS;
|
||||
extinfo.reserved_addr = start;
|
||||
|
||||
handle_ = android_dlopen_ext(kLibName, RTLD_NOW, &extinfo);
|
||||
ASSERT_DL_NOTNULL(handle_);
|
||||
fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
|
||||
ASSERT_DL_NOTNULL(f);
|
||||
EXPECT_GE(reinterpret_cast<void*>(f), start);
|
||||
EXPECT_LT(reinterpret_cast<void*>(f), reinterpret_cast<char*>(start) + kLibSize);
|
||||
|
||||
EXPECT_EQ(4, f());
|
||||
dlclose(handle_);
|
||||
handle_ = nullptr;
|
||||
|
||||
// Check that dlclose unmapped the file
|
||||
void* addr = mmap(start, kLibSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
ASSERT_EQ(start, addr) << "dlclose did not unmap the memory";
|
||||
}
|
||||
|
||||
TEST_F(DlExtTest, LoadAtFixedAddressTooSmall) {
|
||||
void* start = mmap(nullptr, kLibSize + PAGE_SIZE, PROT_NONE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
ASSERT_TRUE(start != MAP_FAILED);
|
||||
munmap(start, kLibSize + PAGE_SIZE);
|
||||
void* new_addr = mmap(reinterpret_cast<uint8_t*>(start) + PAGE_SIZE, kLibSize, PROT_NONE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
ASSERT_TRUE(new_addr != MAP_FAILED);
|
||||
|
||||
android_dlextinfo extinfo;
|
||||
extinfo.flags = ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS;
|
||||
extinfo.reserved_addr = start;
|
||||
|
||||
handle_ = android_dlopen_ext(kLibName, RTLD_NOW, &extinfo);
|
||||
ASSERT_TRUE(handle_ == nullptr);
|
||||
}
|
||||
|
||||
class DlExtRelroSharingTest : public DlExtTest {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
|
|
Loading…
Reference in a new issue