Pagetable-friendly shared library address randomization.

Add inaccessible gaps between shared libraries to make it harder for the
attackers to defeat ASLR by random probing.

To avoid excessive page table bloat, only do this when a library is
about to cross a huge page boundary, effectively allowing several
smaller libraries to be lumped together.

Bug: 158113540
Test: look at /proc/$$/maps
Change-Id: I39c0100b81f72447e8b3c6faafa561111492bf8c
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index e1a3c30..7372a51 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -66,7 +66,7 @@
 #define FLAG_PRELINKED        0x00000400 // prelink_image has successfully processed this soinfo
 #define FLAG_NEW_SOINFO       0x40000000 // new soinfo format
 
-#define SOINFO_VERSION 5
+#define SOINFO_VERSION 6
 
 ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr);
 
@@ -345,6 +345,12 @@
 
   SymbolLookupLib get_lookup_lib();
 
+  void set_gap_start(ElfW(Addr) gap_start);
+  ElfW(Addr) get_gap_start() const;
+
+  void set_gap_size(size_t gap_size);
+  size_t get_gap_size() const;
+
  private:
   bool is_image_linked() const;
   void set_image_linked();
@@ -423,6 +429,10 @@
   // version >= 5
   std::unique_ptr<soinfo_tls> tls_;
   std::vector<TlsDynamicResolverArg> tlsdesc_args_;
+
+  // version >= 6
+  ElfW(Addr) gap_start_;
+  size_t gap_size_;
 };
 
 // This function is used by dlvsym() to calculate hash of sym_ver