Move .oat files to ELF format

Generates .oat in ELF file format using MCLinker
- Uses MCLinker IRBuilder to create a synthetic .o from OatWriter output.
- Uses new ElfFile for prelinking to support art image optimizations.

Adapted OatFile to load using dlopen, ElfFile, or memory, removing raw MemMap mechanism.

Changed image code to not assume oat data will be immediately after
image to allow space for ELF headers.

Passes test-art and works with installd.

Change-Id: Idc026eddb5de93f4b97490c405f3ed7b39589749
diff --git a/src/image_test.cc b/src/image_test.cc
index 502e1a0..89e3a05 100644
--- a/src/image_test.cc
+++ b/src/image_test.cc
@@ -20,12 +20,12 @@
 #include "common_test.h"
 #include "image.h"
 #include "image_writer.h"
-#include "file_output_stream.h"
 #include "oat_writer.h"
 #include "signal_catcher.h"
 #include "gc/space.h"
 #include "UniquePtr.h"
 #include "utils.h"
+#include "vector_output_stream.h"
 
 namespace art {
 
@@ -33,43 +33,48 @@
 
  protected:
   virtual void SetUp() {
-    // Reserve where the image will be loaded up front so that other parts of test set up don't
-    // accidentally end up colliding with the fixed memory address when we need to load the image.
-    image_reservation_.reset(MemMap::MapAnonymous("Image reservation", (byte*)ART_BASE_ADDRESS,
-                                                  (size_t)100 * 1024 *1024,  // 100MB
-                                                  PROT_NONE));
+    ReserveImageSpace();
     CommonTest::SetUp();
   }
-  UniquePtr<MemMap> image_reservation_;
 };
 
 TEST_F(ImageTest, WriteRead) {
-  ScratchFile tmp_oat;
+  ScratchFile tmp_elf;
   {
-    ScopedObjectAccess soa(Thread::Current());
-    std::vector<const DexFile*> dex_files;
-    dex_files.push_back(java_lang_dex_file_);
-    FileOutputStream file_output_stream(tmp_oat.GetFile());
-    bool success_oat = OatWriter::Create(file_output_stream, dex_files, 0, 0, "", *compiler_.get());
-    ASSERT_TRUE(success_oat);
+    std::vector<uint8_t> oat_contents;
+    {
+      ScopedObjectAccess soa(Thread::Current());
+      std::vector<const DexFile*> dex_files;
+      dex_files.push_back(java_lang_dex_file_);
+      VectorOutputStream output_stream(tmp_elf.GetFilename(), oat_contents);
+      bool success_oat = OatWriter::Create(output_stream, dex_files, 0, 0, "", *compiler_.get());
+      ASSERT_TRUE(success_oat);
 
-    // Force all system classes into memory
-    for (size_t i = 0; i < java_lang_dex_file_->NumClassDefs(); ++i) {
-      const DexFile::ClassDef& class_def = java_lang_dex_file_->GetClassDef(i);
-      const char* descriptor = java_lang_dex_file_->GetClassDescriptor(class_def);
-      Class* klass = class_linker_->FindSystemClass(descriptor);
-      EXPECT_TRUE(klass != NULL) << descriptor;
+      // Force all system classes into memory
+      for (size_t i = 0; i < java_lang_dex_file_->NumClassDefs(); ++i) {
+        const DexFile::ClassDef& class_def = java_lang_dex_file_->GetClassDef(i);
+        const char* descriptor = java_lang_dex_file_->GetClassDescriptor(class_def);
+        Class* klass = class_linker_->FindSystemClass(descriptor);
+        EXPECT_TRUE(klass != NULL) << descriptor;
+      }
     }
+    bool success_elf = compiler_->WriteElf(oat_contents, tmp_elf.GetFile());
+    ASSERT_TRUE(success_elf);
   }
+  // Workound bug that mcld::Linker::emit closes tmp_elf by reopening as tmp_oat.
+  UniquePtr<File> tmp_oat(OS::OpenFile(tmp_elf.GetFilename().c_str(), true, false));
+  ASSERT_TRUE(tmp_oat.get() != NULL);
 
   ScratchFile tmp_image;
   const uintptr_t requested_image_base = ART_BASE_ADDRESS;
   {
     ImageWriter writer(NULL);
     bool success_image = writer.Write(tmp_image.GetFilename(), requested_image_base,
-                                      tmp_oat.GetFilename(), tmp_oat.GetFilename(),
+                                      tmp_oat->GetPath(), tmp_oat->GetPath(),
                                       *compiler_.get());
     ASSERT_TRUE(success_image);
+    bool success_fixup = compiler_->FixupElf(tmp_oat.get(), writer.GetOatDataBegin());
+    ASSERT_TRUE(success_fixup);
   }
 
   {
@@ -99,7 +104,7 @@
   ASSERT_TRUE(dex.get() != NULL);
 
   // Remove the reservation of the memory for use to load the image.
-  image_reservation_.reset();
+  UnreserveImageSpace();
 
   Runtime::Options options;
   std::string image("-Ximage:");