Revert "Allow method references across oat files for multi-image."

Breaks Quick tests.

This reverts commit 6065402316da2b51eed5fc34cffbd991766bd408.

Change-Id: I8a5469ba7cea5f46b85cb489b3e0ef06ed548f03
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
index f7da609..b673eeb 100644
--- a/compiler/elf_builder.h
+++ b/compiler/elf_builder.h
@@ -86,24 +86,12 @@
   // Base class of all sections.
   class Section : public OutputStream {
    public:
-    Section(ElfBuilder<ElfTypes>* owner,
-            const std::string& name,
-            Elf_Word type,
-            Elf_Word flags,
-            const Section* link,
-            Elf_Word info,
-            Elf_Word align,
-            Elf_Word entsize)
-        : OutputStream(name),
-          owner_(owner),
-          header_(),
-          section_index_(0),
-          name_(name),
-          link_(link),
-          started_(false),
-          finished_(false),
-          phdr_flags_(PF_R),
-          phdr_type_(0) {
+    Section(ElfBuilder<ElfTypes>* owner, const std::string& name,
+            Elf_Word type, Elf_Word flags, const Section* link,
+            Elf_Word info, Elf_Word align, Elf_Word entsize)
+        : OutputStream(name), owner_(owner), header_(),
+          section_index_(0), name_(name), link_(link),
+          started_(false), finished_(false), phdr_flags_(PF_R), phdr_type_(0) {
       DCHECK_GE(align, 1u);
       header_.sh_type = type;
       header_.sh_flags = flags;
@@ -240,84 +228,12 @@
     DISALLOW_COPY_AND_ASSIGN(Section);
   };
 
-  class CachedSection : public Section {
-   public:
-    CachedSection(ElfBuilder<ElfTypes>* owner,
-                  const std::string& name,
-                  Elf_Word type,
-                  Elf_Word flags,
-                  const Section* link,
-                  Elf_Word info,
-                  Elf_Word align,
-                  Elf_Word entsize)
-        : Section(owner, name, type, flags, link, info, align, entsize), cache_() { }
-
-    Elf_Word Add(const void* data, size_t length) {
-      Elf_Word offset = cache_.size();
-      const uint8_t* d = reinterpret_cast<const uint8_t*>(data);
-      cache_.insert(cache_.end(), d, d + length);
-      return offset;
-    }
-
-    Elf_Word GetCacheSize() {
-      return cache_.size();
-    }
-
-    void Write() {
-      this->WriteFully(cache_.data(), cache_.size());
-      cache_.clear();
-      cache_.shrink_to_fit();
-    }
-
-    void WriteCachedSection() {
-      this->Start();
-      Write();
-      this->End();
-    }
-
-   private:
-    std::vector<uint8_t> cache_;
-  };
-
-  // Writer of .dynstr section.
-  class CachedStringSection FINAL : public CachedSection {
-   public:
-    CachedStringSection(ElfBuilder<ElfTypes>* owner,
-                        const std::string& name,
-                        Elf_Word flags,
-                        Elf_Word align)
-        : CachedSection(owner,
-                        name,
-                        SHT_STRTAB,
-                        flags,
-                        /* link */ nullptr,
-                        /* info */ 0,
-                        align,
-                        /* entsize */ 0) { }
-
-    Elf_Word Add(const std::string& name) {
-      if (CachedSection::GetCacheSize() == 0u) {
-        DCHECK(name.empty());
-      }
-      return CachedSection::Add(name.c_str(), name.length() + 1);
-    }
-  };
-
-  // Writer of .strtab and .shstrtab sections.
+  // Writer of .dynstr .strtab and .shstrtab sections.
   class StringSection FINAL : public Section {
    public:
-    StringSection(ElfBuilder<ElfTypes>* owner,
-                  const std::string& name,
-                  Elf_Word flags,
-                  Elf_Word align)
-        : Section(owner,
-                  name,
-                  SHT_STRTAB,
-                  flags,
-                  /* link */ nullptr,
-                  /* info */ 0,
-                  align,
-                  /* entsize */ 0),
+    StringSection(ElfBuilder<ElfTypes>* owner, const std::string& name,
+                  Elf_Word flags, Elf_Word align)
+        : Section(owner, name, SHT_STRTAB, flags, nullptr, 0, align, 0),
           current_offset_(0) {
     }
 
@@ -336,60 +252,42 @@
   };
 
   // Writer of .dynsym and .symtab sections.
-  class SymbolSection FINAL : public CachedSection {
+  class SymbolSection FINAL : public Section {
    public:
-    SymbolSection(ElfBuilder<ElfTypes>* owner,
-                  const std::string& name,
-                  Elf_Word type,
-                  Elf_Word flags,
-                  Section* strtab)
-        : CachedSection(owner,
-                        name,
-                        type,
-                        flags,
-                        strtab,
-                        /* info */ 0,
-                        sizeof(Elf_Off),
-                        sizeof(Elf_Sym)) {
-      // The symbol table always has to start with NULL symbol.
-      Elf_Sym null_symbol = Elf_Sym();
-      CachedSection::Add(&null_symbol, sizeof(null_symbol));
+    SymbolSection(ElfBuilder<ElfTypes>* owner, const std::string& name,
+                  Elf_Word type, Elf_Word flags, StringSection* strtab)
+        : Section(owner, name, type, flags, strtab, 0,
+                  sizeof(Elf_Off), sizeof(Elf_Sym)) {
     }
 
     // Buffer symbol for this section.  It will be written later.
     // If the symbol's section is null, it will be considered absolute (SHN_ABS).
     // (we use this in JIT to reference code which is stored outside the debug ELF file)
-    void Add(Elf_Word name,
-             const Section* section,
-             Elf_Addr addr,
-             bool is_relative,
-             Elf_Word size,
-             uint8_t binding,
-             uint8_t type,
-             uint8_t other = 0) {
-      DCHECK(section != nullptr || !is_relative);
-      Elf_Addr abs_addr = addr + (is_relative ? section->GetAddress() : 0);
-      Elf_Word section_index =
-          (section != nullptr) ? section->GetSectionIndex() : static_cast<Elf_Word>(SHN_ABS);
-      Add(name, section_index, abs_addr, size, binding, type, other);
-    }
-
-    void Add(Elf_Word name,
-             Elf_Word section_index,
-             Elf_Addr addr,
-             Elf_Word size,
-             uint8_t binding,
-             uint8_t type,
-             uint8_t other = 0) {
+    void Add(Elf_Word name, const Section* section,
+             Elf_Addr addr, bool is_relative, Elf_Word size,
+             uint8_t binding, uint8_t type, uint8_t other = 0) {
       Elf_Sym sym = Elf_Sym();
       sym.st_name = name;
-      sym.st_value = addr;
+      sym.st_value = addr + (is_relative ? section->GetAddress() : 0);
       sym.st_size = size;
       sym.st_other = other;
-      sym.st_shndx = section_index;
+      sym.st_shndx = (section != nullptr ? section->GetSectionIndex()
+                                         : static_cast<Elf_Word>(SHN_ABS));
       sym.st_info = (binding << 4) + (type & 0xf);
-      CachedSection::Add(&sym, sizeof(sym));
+      symbols_.push_back(sym);
     }
+
+    void Write() {
+      // The symbol table always has to start with NULL symbol.
+      Elf_Sym null_symbol = Elf_Sym();
+      this->WriteFully(&null_symbol, sizeof(null_symbol));
+      this->WriteFully(symbols_.data(), symbols_.size() * sizeof(symbols_[0]));
+      symbols_.clear();
+      symbols_.shrink_to_fit();
+    }
+
+   private:
+    std::vector<Elf_Sym> symbols_;
   };
 
   ElfBuilder(InstructionSet isa, OutputStream* output)
@@ -411,8 +309,6 @@
         debug_line_(this, ".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0),
         shstrtab_(this, ".shstrtab", 0, 1),
         started_(false),
-        write_program_headers_(false),
-        loaded_size_(0u),
         virtual_address_(0) {
     text_.phdr_flags_ = PF_R | PF_X;
     bss_.phdr_flags_ = PF_R | PF_W;
@@ -484,14 +380,6 @@
   void End() {
     DCHECK(started_);
 
-    // Note: loaded_size_ == 0 for tests that don't write .rodata, .text, .bss,
-    // .dynstr, dynsym, .hash and .dynamic. These tests should not read loaded_size_.
-    // TODO: Either refactor the .eh_frame creation so that it counts towards loaded_size_,
-    // or remove all support for .eh_frame. (The currently unused .eh_frame counts towards
-    // the virtual_address_ but we don't consider it for loaded_size_.)
-    CHECK(loaded_size_ == 0 || loaded_size_ == RoundUp(virtual_address_, kPageSize))
-        << loaded_size_ << " " << virtual_address_;
-
     // Write section names and finish the section headers.
     shstrtab_.Start();
     shstrtab_.Write("");
@@ -546,58 +434,45 @@
   // information like the address and size of .rodata and .text.
   // It also contains other metadata like the SONAME.
   // The .dynamic section is found using the PT_DYNAMIC program header.
-  void PrepareDynamicSection(const std::string& elf_file_path,
-                             Elf_Word rodata_size,
-                             Elf_Word text_size,
-                             Elf_Word bss_size) {
+  void WriteDynamicSection(const std::string& elf_file_path) {
     std::string soname(elf_file_path);
     size_t directory_separator_pos = soname.rfind('/');
     if (directory_separator_pos != std::string::npos) {
       soname = soname.substr(directory_separator_pos + 1);
     }
 
-    // Calculate addresses of .text, .bss and .dynstr.
-    DCHECK_EQ(rodata_.header_.sh_addralign, static_cast<Elf_Word>(kPageSize));
-    DCHECK_EQ(text_.header_.sh_addralign, static_cast<Elf_Word>(kPageSize));
-    DCHECK_EQ(bss_.header_.sh_addralign, static_cast<Elf_Word>(kPageSize));
-    DCHECK_EQ(dynstr_.header_.sh_addralign, static_cast<Elf_Word>(kPageSize));
-    Elf_Word rodata_address = rodata_.GetAddress();
-    Elf_Word text_address = RoundUp(rodata_address + rodata_size, kPageSize);
-    Elf_Word bss_address = RoundUp(text_address + text_size, kPageSize);
-    Elf_Word dynstr_address = RoundUp(bss_address + bss_size, kPageSize);
-
-    // Cache .dynstr, .dynsym and .hash data.
-    dynstr_.Add("");  // dynstr should start with empty string.
-    Elf_Word rodata_index = rodata_.GetSectionIndex();
-    Elf_Word oatdata = dynstr_.Add("oatdata");
-    dynsym_.Add(oatdata, rodata_index, rodata_address, rodata_size, STB_GLOBAL, STT_OBJECT);
-    if (text_size != 0u) {
-      Elf_Word text_index = rodata_index + 1u;
-      Elf_Word oatexec = dynstr_.Add("oatexec");
-      dynsym_.Add(oatexec, text_index, text_address, text_size, STB_GLOBAL, STT_OBJECT);
-      Elf_Word oatlastword = dynstr_.Add("oatlastword");
-      Elf_Word oatlastword_address = text_address + text_size - 4;
-      dynsym_.Add(oatlastword, text_index, oatlastword_address, 4, STB_GLOBAL, STT_OBJECT);
-    } else if (rodata_size != 0) {
+    dynstr_.Start();
+    dynstr_.Write("");  // dynstr should start with empty string.
+    dynsym_.Add(dynstr_.Write("oatdata"), &rodata_, 0, true,
+                rodata_.GetSize(), STB_GLOBAL, STT_OBJECT);
+    if (text_.GetSize() != 0u) {
+      dynsym_.Add(dynstr_.Write("oatexec"), &text_, 0, true,
+                  text_.GetSize(), STB_GLOBAL, STT_OBJECT);
+      dynsym_.Add(dynstr_.Write("oatlastword"), &text_, text_.GetSize() - 4,
+                  true, 4, STB_GLOBAL, STT_OBJECT);
+    } else if (rodata_.GetSize() != 0) {
       // rodata_ can be size 0 for dwarf_test.
-      Elf_Word oatlastword = dynstr_.Add("oatlastword");
-      Elf_Word oatlastword_address = rodata_address + rodata_size - 4;
-      dynsym_.Add(oatlastword, rodata_index, oatlastword_address, 4, STB_GLOBAL, STT_OBJECT);
+      dynsym_.Add(dynstr_.Write("oatlastword"), &rodata_, rodata_.GetSize() - 4,
+                  true, 4, STB_GLOBAL, STT_OBJECT);
     }
-    if (bss_size != 0u) {
-      Elf_Word bss_index = rodata_index + 1u + (text_size != 0 ? 1u : 0u);
-      Elf_Word oatbss = dynstr_.Add("oatbss");
-      dynsym_.Add(oatbss, bss_index, bss_address, bss_size, STB_GLOBAL, STT_OBJECT);
-      Elf_Word oatbsslastword = dynstr_.Add("oatbsslastword");
-      Elf_Word bsslastword_address = bss_address + bss_size - 4;
-      dynsym_.Add(oatbsslastword, bss_index, bsslastword_address, 4, STB_GLOBAL, STT_OBJECT);
+    if (bss_.finished_) {
+      dynsym_.Add(dynstr_.Write("oatbss"), &bss_,
+                  0, true, bss_.GetSize(), STB_GLOBAL, STT_OBJECT);
+      dynsym_.Add(dynstr_.Write("oatbsslastword"), &bss_,
+                  bss_.GetSize() - 4, true, 4, STB_GLOBAL, STT_OBJECT);
     }
-    Elf_Word soname_offset = dynstr_.Add(soname);
+    Elf_Word soname_offset = dynstr_.Write(soname);
+    dynstr_.End();
+
+    dynsym_.Start();
+    dynsym_.Write();
+    dynsym_.End();
 
     // We do not really need a hash-table since there is so few entries.
     // However, the hash-table is the only way the linker can actually
     // determine the number of symbols in .dynsym so it is required.
-    int count = dynsym_.GetCacheSize() / sizeof(Elf_Sym);  // Includes NULL.
+    hash_.Start();
+    int count = dynsym_.GetSize() / sizeof(Elf_Sym);  // Includes NULL.
     std::vector<Elf_Word> hash;
     hash.push_back(1);  // Number of buckets.
     hash.push_back(count);  // Number of chains.
@@ -609,44 +484,21 @@
       hash.push_back(i + 1);  // Each symbol points to the next one.
     }
     hash.push_back(0);  // Last symbol terminates the chain.
-    hash_.Add(hash.data(), hash.size() * sizeof(hash[0]));
+    hash_.WriteFully(hash.data(), hash.size() * sizeof(hash[0]));
+    hash_.End();
 
-    // Calculate addresses of .dynsym, .hash and .dynamic.
-    DCHECK_EQ(dynstr_.header_.sh_flags, dynsym_.header_.sh_flags);
-    DCHECK_EQ(dynsym_.header_.sh_flags, hash_.header_.sh_flags);
-    Elf_Word dynsym_address =
-        RoundUp(dynstr_address + dynstr_.GetCacheSize(), dynsym_.header_.sh_addralign);
-    Elf_Word hash_address =
-        RoundUp(dynsym_address + dynsym_.GetCacheSize(), hash_.header_.sh_addralign);
-    DCHECK_EQ(dynamic_.header_.sh_addralign, static_cast<Elf_Word>(kPageSize));
-    Elf_Word dynamic_address = RoundUp(hash_address + dynsym_.GetCacheSize(), kPageSize);
-
+    dynamic_.Start();
     Elf_Dyn dyns[] = {
-      { DT_HASH, { hash_address } },
-      { DT_STRTAB, { dynstr_address } },
-      { DT_SYMTAB, { dynsym_address } },
+      { DT_HASH, { hash_.GetAddress() } },
+      { DT_STRTAB, { dynstr_.GetAddress() } },
+      { DT_SYMTAB, { dynsym_.GetAddress() } },
       { DT_SYMENT, { sizeof(Elf_Sym) } },
-      { DT_STRSZ, { dynstr_.GetCacheSize() } },
+      { DT_STRSZ, { dynstr_.GetSize() } },
       { DT_SONAME, { soname_offset } },
       { DT_NULL, { 0 } },
     };
-    dynamic_.Add(&dyns, sizeof(dyns));
-
-    loaded_size_ = RoundUp(dynamic_address + dynamic_.GetCacheSize(), kPageSize);
-  }
-
-  void WriteDynamicSection() {
-    dynstr_.WriteCachedSection();
-    dynsym_.WriteCachedSection();
-    hash_.WriteCachedSection();
-    dynamic_.WriteCachedSection();
-
-    CHECK_EQ(loaded_size_, RoundUp(dynamic_.GetAddress() + dynamic_.GetSize(), kPageSize));
-  }
-
-  Elf_Word GetLoadedSize() {
-    CHECK_NE(loaded_size_, 0u);
-    return loaded_size_;
+    dynamic_.WriteFully(&dyns, sizeof(dyns));
+    dynamic_.End();
   }
 
   // Returns true if all writes and seeks on the output stream succeeded.
@@ -824,10 +676,10 @@
   Section rodata_;
   Section text_;
   Section bss_;
-  CachedStringSection dynstr_;
+  StringSection dynstr_;
   SymbolSection dynsym_;
-  CachedSection hash_;
-  CachedSection dynamic_;
+  Section hash_;
+  Section dynamic_;
   Section eh_frame_;
   Section eh_frame_hdr_;
   StringSection strtab_;
@@ -842,14 +694,12 @@
   std::vector<Section*> sections_;
 
   bool started_;
-  bool write_program_headers_;
-
-  // The size of the memory taken by the ELF file when loaded.
-  size_t loaded_size_;
 
   // Used for allocation of virtual address space.
   Elf_Addr virtual_address_;
 
+  size_t write_program_headers_;
+
   DISALLOW_COPY_AND_ASSIGN(ElfBuilder);
 };