Cleanup symbol add method in ElfBuilder.

Use deque to avoid reallocating the cached symbols.

We never generate absolute symbols because gdb don't like them.

Add helper method to add symbols as Elf_Sym.

Test: build.oat is unchanged.
Change-Id: Id8289a71a23cf602f3f9e3e2c2a26277faf937a9
diff --git a/compiler/linker/elf_builder.h b/compiler/linker/elf_builder.h
index 81ecc17..44f3296 100644
--- a/compiler/linker/elf_builder.h
+++ b/compiler/linker/elf_builder.h
@@ -18,6 +18,7 @@
 #define ART_COMPILER_LINKER_ELF_BUILDER_H_
 
 #include <vector>
+#include <deque>
 
 #include "arch/instruction_set.h"
 #include "arch/mips/instruction_set_features_mips.h"
@@ -357,57 +358,49 @@
     }
 
     // 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,
              Elf_Word size,
              uint8_t binding,
              uint8_t type) {
-      Elf_Word section_index;
-      if (section != nullptr) {
-        DCHECK_LE(section->GetAddress(), addr);
-        DCHECK_LE(addr, section->GetAddress() + section->header_.sh_size);
-        section_index = section->GetSectionIndex();
-      } else {
-        section_index = static_cast<Elf_Word>(SHN_ABS);
-      }
-      Add(name, section_index, addr, size, binding, type);
-    }
-
-    // Buffer symbol for this section.  It will be written later.
-    void Add(Elf_Word name,
-             Elf_Word section_index,
-             Elf_Addr addr,
-             Elf_Word size,
-             uint8_t binding,
-             uint8_t type) {
       Elf_Sym sym = Elf_Sym();
       sym.st_name = name;
       sym.st_value = addr;
       sym.st_size = size;
       sym.st_other = 0;
-      sym.st_shndx = section_index;
       sym.st_info = (binding << 4) + (type & 0xf);
-      syms_.push_back(sym);
+      Add(sym, section);
+    }
+
+    // Buffer symbol for this section.  It will be written later.
+    void Add(Elf_Sym sym, const Section* section) {
+      DCHECK(section != nullptr);
+      DCHECK_LE(section->GetAddress(), sym.st_value);
+      DCHECK_LE(sym.st_value, section->GetAddress() + section->header_.sh_size);
+      sym.st_shndx = section->GetSectionIndex();
 
       // The sh_info file must be set to index one-past the last local symbol.
-      if (binding == STB_LOCAL) {
-        this->header_.sh_info = syms_.size();
+      if (sym.getBinding() == STB_LOCAL) {
+        DCHECK_EQ(syms_.back().getBinding(), STB_LOCAL);
+        this->header_.sh_info = syms_.size() + 1;
       }
+
+      syms_.push_back(sym);
     }
 
     Elf_Word GetCacheSize() { return syms_.size() * sizeof(Elf_Sym); }
 
     void WriteCachedSection() {
       this->Start();
-      this->WriteFully(syms_.data(), syms_.size() * sizeof(Elf_Sym));
+      for (; !syms_.empty(); syms_.pop_front()) {
+        this->WriteFully(&syms_.front(), sizeof(Elf_Sym));
+      }
       this->End();
     }
 
    private:
-    std::vector<Elf_Sym> syms_;  // Buffered/cached content of the whole section.
+    std::deque<Elf_Sym> syms_;  // Buffered/cached content of the whole section.
   };
 
   class AbiflagsSection final : public Section {