Refactor oat file writing to give Dex2Oat more control.

This is the first step towards writing dex files to oat file
and mapping them from there for the actual AOT compilation.

Change-Id: Icb0d27487eaf6ba3a66c157e695f9bdc5bb9cf9a
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
index 6e8dfd6..c19bc3d 100644
--- a/compiler/elf_builder.h
+++ b/compiler/elf_builder.h
@@ -27,6 +27,7 @@
 #include "elf_utils.h"
 #include "file_output_stream.h"
 #include "leb128.h"
+#include "utils/array_ref.h"
 
 namespace art {
 
@@ -100,7 +101,7 @@
       header_.sh_entsize = entsize;
     }
 
-    virtual ~Section() {
+    ~Section() OVERRIDE {
       if (started_) {
         CHECK(finished_);
       }
@@ -187,6 +188,12 @@
       return owner_->Seek(offset, whence);
     }
 
+    // This function flushes the output and returns whether it succeeded.
+    // If there was a previous failure, this does nothing and returns false, i.e. failed.
+    bool Flush() OVERRIDE {
+      return owner_->Flush();
+    }
+
     Elf_Word GetSectionIndex() const {
       DCHECK(started_);
       DCHECK_NE(section_index_, 0u);
@@ -312,7 +319,7 @@
 
   // Encode patch locations as LEB128 list of deltas between consecutive addresses.
   // (exposed publicly for tests)
-  static void EncodeOatPatches(const std::vector<uintptr_t>& locations,
+  static void EncodeOatPatches(const ArrayRef<const uintptr_t>& locations,
                                std::vector<uint8_t>* buffer) {
     buffer->reserve(buffer->size() + locations.size() * 2);  // guess 2 bytes per ULEB128.
     uintptr_t address = 0;  // relative to start of section.
@@ -323,9 +330,9 @@
     }
   }
 
-  void WritePatches(const char* name, const std::vector<uintptr_t>* patch_locations) {
+  void WritePatches(const char* name, const ArrayRef<const uintptr_t>& patch_locations) {
     std::vector<uint8_t> buffer;
-    EncodeOatPatches(*patch_locations, &buffer);
+    EncodeOatPatches(patch_locations, &buffer);
     std::unique_ptr<Section> s(new Section(this, name, SHT_OAT_PATCH, 0, nullptr, 0, 1, 0));
     s->Start();
     s->WriteFully(buffer.data(), buffer.size());
@@ -385,6 +392,7 @@
     Seek(0, kSeekSet);
     WriteFully(&elf_header, sizeof(elf_header));
     WriteFully(phdrs.data(), phdrs.size() * sizeof(phdrs[0]));
+    Flush();
   }
 
   // The running program does not have access to section headers
@@ -509,6 +517,13 @@
     return new_offset;
   }
 
+  bool Flush() {
+    if (output_good_) {
+      output_good_ = output_->Flush();
+    }
+    return output_good_;
+  }
+
   static Elf_Ehdr MakeElfHeader(InstructionSet isa) {
     Elf_Ehdr elf_header = Elf_Ehdr();
     switch (isa) {