Add flag that makes linker honor min(p_vaddr)

Bug: http://b/21523078
Change-Id: Ice72766fb6ad3bd333c32b496e7870121e17a763
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 @@
   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 @@
     } 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 @@
       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;