diff options
author | Dmitriy Ivanov <dimitry@google.com> | 2015-06-05 22:16:23 -0700 |
---|---|---|
committer | David Srbecky <dsrbecky@google.com> | 2015-06-18 23:58:34 +0100 |
commit | 34e8e47d321b129920c5142a81c2db88128c1595 (patch) | |
tree | 618970aa7d64ff3f2d24dd0d6f73c265c7786f68 /linker | |
parent | 848276051a24266e1eacf2e508692c62d5a6176d (diff) | |
download | bionic-34e8e47d321b129920c5142a81c2db88128c1595.zip bionic-34e8e47d321b129920c5142a81c2db88128c1595.tar.gz bionic-34e8e47d321b129920c5142a81c2db88128c1595.tar.bz2 |
Add flag that makes linker honor min(p_vaddr)
(cherry picked from commit 8a1162835597be38705b381ac34c07da17932568)
Bug: 21924613
Bug: http://b/21523078
Change-Id: I3f944a08dd2ed1df4d8a807da4fee423fdd35eb7
Diffstat (limited to 'linker')
-rw-r--r-- | linker/linker_phdr.cpp | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp index 638c9d6..f586b08 100644 --- a/linker/linker_phdr.cpp +++ b/linker/linker_phdr.cpp @@ -316,6 +316,8 @@ bool ElfReader::ReserveAddressSpace(const android_dlextinfo* extinfo) { void* start; size_t reserved_size = 0; bool reserved_hint = true; + // Assume position independent executable by default. + uint8_t* mmap_hint = nullptr; if (extinfo != nullptr) { if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS) { @@ -324,6 +326,10 @@ bool ElfReader::ReserveAddressSpace(const android_dlextinfo* extinfo) { } else if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS_HINT) { reserved_size = extinfo->reserved_size; } + + if ((extinfo->flags & ANDROID_DLEXT_FORCE_FIXED_VADDR) != 0) { + mmap_hint = addr; + } } if (load_size_ > reserved_size) { @@ -333,7 +339,7 @@ bool ElfReader::ReserveAddressSpace(const android_dlextinfo* extinfo) { return false; } int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS; - start = mmap(nullptr, load_size_, PROT_NONE, mmap_flags, -1, 0); + start = mmap(mmap_hint, load_size_, PROT_NONE, mmap_flags, -1, 0); if (start == MAP_FAILED) { DL_ERR("couldn't reserve %zd bytes of address space for \"%s\"", load_size_, name_); return false; |