ART: Allow method references across oat files for multi-image, 2nd attempt.

These were disabled because we didn't have sufficient
information about the multi-image layout when processing
link-time patches in OatWriter. This CL refactors the
ELF file creation so that the information is available.

Also clean up ImageWriter to use oat file indexes instead
of filenames and avoid reopening the oat file to retrieve
the checksum.

Change-Id: Icc7b528deca29da1e473c8f079521a36d6c4892f
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index 1d71e57..19346ec 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -88,14 +88,12 @@
   ~ElfWriterQuick();
 
   void Start() OVERRIDE;
-  void PrepareDebugInfo(size_t rodata_section_size,
-                        size_t text_section_size,
-                        const ArrayRef<const debug::MethodDebugInfo>& method_infos) OVERRIDE;
+  void SetLoadedSectionSizes(size_t rodata_size, size_t text_size, size_t bss_size) OVERRIDE;
+  void PrepareDebugInfo(const ArrayRef<const debug::MethodDebugInfo>& method_infos) OVERRIDE;
   OutputStream* StartRoData() OVERRIDE;
   void EndRoData(OutputStream* rodata) OVERRIDE;
   OutputStream* StartText() OVERRIDE;
   void EndText(OutputStream* text) OVERRIDE;
-  void SetBssSize(size_t bss_size) OVERRIDE;
   void WriteDynamicSection() OVERRIDE;
   void WriteDebugInfo(const ArrayRef<const debug::MethodDebugInfo>& method_infos) OVERRIDE;
   void WritePatchLocations(const ArrayRef<const uintptr_t>& patch_locations) OVERRIDE;
@@ -103,12 +101,17 @@
 
   virtual OutputStream* GetStream() OVERRIDE;
 
+  size_t GetLoadedSize() OVERRIDE;
+
   static void EncodeOatPatches(const std::vector<uintptr_t>& locations,
                                std::vector<uint8_t>* buffer);
 
  private:
   const CompilerOptions* const compiler_options_;
   File* const elf_file_;
+  size_t rodata_size_;
+  size_t text_size_;
+  size_t bss_size_;
   std::unique_ptr<BufferedOutputStream> output_stream_;
   std::unique_ptr<ElfBuilder<ElfTypes>> builder_;
   std::unique_ptr<DebugInfoTask> debug_info_task_;
@@ -134,6 +137,9 @@
     : ElfWriter(),
       compiler_options_(compiler_options),
       elf_file_(elf_file),
+      rodata_size_(0u),
+      text_size_(0u),
+      bss_size_(0u),
       output_stream_(MakeUnique<BufferedOutputStream>(MakeUnique<FileOutputStream>(elf_file))),
       builder_(new ElfBuilder<ElfTypes>(instruction_set, output_stream_.get())) {}
 
@@ -146,6 +152,19 @@
 }
 
 template <typename ElfTypes>
+void ElfWriterQuick<ElfTypes>::SetLoadedSectionSizes(size_t rodata_size,
+                                                     size_t text_size,
+                                                     size_t bss_size) {
+  DCHECK_EQ(rodata_size_, 0u);
+  rodata_size_ = rodata_size;
+  DCHECK_EQ(text_size_, 0u);
+  text_size_ = text_size;
+  DCHECK_EQ(bss_size_, 0u);
+  bss_size_ = bss_size;
+  builder_->PrepareDynamicSection(elf_file_->GetPath(), rodata_size_, text_size_, bss_size_);
+}
+
+template <typename ElfTypes>
 OutputStream* ElfWriterQuick<ElfTypes>::StartRoData() {
   auto* rodata = builder_->GetRoData();
   rodata->Start();
@@ -172,31 +191,21 @@
 }
 
 template <typename ElfTypes>
-void ElfWriterQuick<ElfTypes>::SetBssSize(size_t bss_size) {
-  auto* bss = builder_->GetBss();
-  if (bss_size != 0u) {
-    bss->WriteNoBitsSection(bss_size);
-  }
-}
-
-template <typename ElfTypes>
 void ElfWriterQuick<ElfTypes>::WriteDynamicSection() {
-  builder_->WriteDynamicSection(elf_file_->GetPath());
+  if (bss_size_ != 0u) {
+    builder_->GetBss()->WriteNoBitsSection(bss_size_);
+  }
+  builder_->WriteDynamicSection();
 }
 
 template <typename ElfTypes>
 void ElfWriterQuick<ElfTypes>::PrepareDebugInfo(
-    size_t rodata_section_size,
-    size_t text_section_size,
     const ArrayRef<const debug::MethodDebugInfo>& method_infos) {
   if (!method_infos.empty() && compiler_options_->GetGenerateMiniDebugInfo()) {
     // Prepare the mini-debug-info in background while we do other I/O.
     Thread* self = Thread::Current();
     debug_info_task_ = std::unique_ptr<DebugInfoTask>(
-        new DebugInfoTask(builder_->GetIsa(),
-                          rodata_section_size,
-                          text_section_size,
-                          method_infos));
+        new DebugInfoTask(builder_->GetIsa(), rodata_size_, text_size_, method_infos));
     debug_info_thread_pool_ = std::unique_ptr<ThreadPool>(
         new ThreadPool("Mini-debug-info writer", 1));
     debug_info_thread_pool_->AddTask(self, debug_info_task_.get());
@@ -245,6 +254,11 @@
   return builder_->GetStream();
 }
 
+template <typename ElfTypes>
+size_t ElfWriterQuick<ElfTypes>::GetLoadedSize() {
+  return builder_->GetLoadedSize();
+}
+
 // Explicit instantiations
 template class ElfWriterQuick<ElfTypes32>;
 template class ElfWriterQuick<ElfTypes64>;