Simplify template parameters of Elf classes.

The ELF specification defines several types which differ between
32-bit ELF and 64-bit ELF.  We used to template all ELF-related
methods on all of those types which was very verbose.

This CL wraps all the types as typedefs in ElfTypes32 and ElfTypes64.
One of those wrappers is then used as the template parameter.

Change-Id: I65247c2c79d92a7c4799e988cf3e4a1b10eb4788
diff --git a/compiler/dwarf/dwarf_test.h b/compiler/dwarf/dwarf_test.h
index d31cfa5..99b8e79 100644
--- a/compiler/dwarf/dwarf_test.h
+++ b/compiler/dwarf/dwarf_test.h
@@ -56,8 +56,7 @@
   }
 
   // Pretty-print the generated DWARF data using objdump.
-  template<typename Elf_Word, typename Elf_Sword, typename Elf_Addr, typename Elf_Dyn,
-           typename Elf_Sym, typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr>
+  template<typename ElfTypes>
   std::vector<std::string> Objdump(bool is64bit, const char* args) {
     // Write simple elf file with just the DWARF sections.
     class NoCode : public CodeOutput {
@@ -66,10 +65,9 @@
     } code;
     ScratchFile file;
     InstructionSet isa = is64bit ? kX86_64 : kX86;
-    ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-               Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr> builder(
+    ElfBuilder<ElfTypes> builder(
         &code, file.GetFile(), isa, 0, 0, 0, 0, 0, 0, false, false);
-    typedef ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> Section;
+    typedef ElfRawSectionBuilder<ElfTypes> Section;
     Section debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
     Section debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
     Section debug_str(".debug_str", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
@@ -125,11 +123,9 @@
 
   std::vector<std::string> Objdump(bool is64bit, const char* args) {
     if (is64bit) {
-      return Objdump<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn,
-          Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(is64bit, args);
+      return Objdump<ElfTypes64>(is64bit, args);
     } else {
-      return Objdump<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
-          Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(is64bit, args);
+      return Objdump<ElfTypes32>(is64bit, args);
     }
   }
 
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
index 323c933..b67dd26 100644
--- a/compiler/elf_builder.h
+++ b/compiler/elf_builder.h
@@ -26,11 +26,14 @@
 
 namespace art {
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
+template <typename ElfTypes>
 class ElfSectionBuilder : public ValueObject {
  public:
+  using Elf_Word = typename ElfTypes::Word;
+  using Elf_Shdr = typename ElfTypes::Shdr;
+
   ElfSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags,
-                    const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *link, Elf_Word info,
+                    const ElfSectionBuilder<ElfTypes> *link, Elf_Word info,
                     Elf_Word align, Elf_Word entsize)
       : section_index_(0), name_(sec_name), link_(link) {
     memset(&section_, 0, sizeof(section_));
@@ -75,9 +78,14 @@
   const ElfSectionBuilder* const link_;
 };
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Dyn, typename Elf_Shdr>
-class ElfDynamicBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+template <typename ElfTypes>
+class ElfDynamicBuilder FINAL : public ElfSectionBuilder<ElfTypes> {
  public:
+  using Elf_Word = typename ElfTypes::Word;
+  using Elf_Sword = typename ElfTypes::Sword;
+  using Elf_Shdr = typename ElfTypes::Shdr;
+  using Elf_Dyn = typename ElfTypes::Dyn;
+
   void AddDynamicTag(Elf_Sword tag, Elf_Word d_un) {
     if (tag == DT_NULL) {
       return;
@@ -86,7 +94,7 @@
   }
 
   void AddDynamicTag(Elf_Sword tag, Elf_Word d_un,
-                     const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section) {
+                     const ElfSectionBuilder<ElfTypes>* section) {
     if (tag == DT_NULL) {
       return;
     }
@@ -94,9 +102,9 @@
   }
 
   ElfDynamicBuilder(const std::string& sec_name,
-                    ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *link)
-  : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, SHT_DYNAMIC, SHF_ALLOC | SHF_ALLOC,
-                                                     link, 0, kPageSize, sizeof(Elf_Dyn)) {}
+                    ElfSectionBuilder<ElfTypes> *link)
+  : ElfSectionBuilder<ElfTypes>(sec_name, SHT_DYNAMIC, SHF_ALLOC | SHF_ALLOC,
+                                link, 0, kPageSize, sizeof(Elf_Dyn)) {}
   ~ElfDynamicBuilder() {}
 
   Elf_Word GetSize() const {
@@ -129,21 +137,22 @@
 
  private:
   struct ElfDynamicState {
-    const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_;
+    const ElfSectionBuilder<ElfTypes>* section_;
     Elf_Sword tag_;
     Elf_Word off_;
   };
   std::vector<ElfDynamicState> dynamics_;
 };
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
-class ElfRawSectionBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+template <typename ElfTypes>
+class ElfRawSectionBuilder FINAL : public ElfSectionBuilder<ElfTypes> {
  public:
+  using Elf_Word = typename ElfTypes::Word;
+
   ElfRawSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags,
-                       const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* link, Elf_Word info,
+                       const ElfSectionBuilder<ElfTypes>* link, Elf_Word info,
                        Elf_Word align, Elf_Word entsize)
-    : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, type, flags, link, info, align,
-                                                       entsize) {
+    : ElfSectionBuilder<ElfTypes>(sec_name, type, flags, link, info, align, entsize) {
   }
   ElfRawSectionBuilder(const ElfRawSectionBuilder&) = default;
 
@@ -161,13 +170,14 @@
   std::vector<uint8_t> buf_;
 };
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
-class ElfOatSectionBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+template <typename ElfTypes>
+class ElfOatSectionBuilder FINAL : public ElfSectionBuilder<ElfTypes> {
  public:
+  using Elf_Word = typename ElfTypes::Word;
+
   ElfOatSectionBuilder(const std::string& sec_name, Elf_Word size, Elf_Word offset,
                        Elf_Word type, Elf_Word flags)
-    : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, type, flags, nullptr, 0, kPageSize,
-                                                       0),
+    : ElfSectionBuilder<ElfTypes>(sec_name, type, flags, nullptr, 0, kPageSize, 0),
       offset_(offset), size_(size) {
   }
 
@@ -206,14 +216,17 @@
   return h;
 }
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, typename Elf_Sym,
-          typename Elf_Shdr>
-class ElfSymtabBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+template <typename ElfTypes>
+class ElfSymtabBuilder FINAL : public ElfSectionBuilder<ElfTypes> {
  public:
+  using Elf_Addr = typename ElfTypes::Addr;
+  using Elf_Word = typename ElfTypes::Word;
+  using Elf_Sym = typename ElfTypes::Sym;
+
   // Add a symbol with given name to this symtab. The symbol refers to
   // 'relative_addr' within the given section and has the given attributes.
   void AddSymbol(const std::string& name,
-                 const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section,
+                 const ElfSectionBuilder<ElfTypes>* section,
                  Elf_Addr addr,
                  bool is_relative,
                  Elf_Word size,
@@ -228,14 +241,14 @@
 
   ElfSymtabBuilder(const std::string& sec_name, Elf_Word type,
                    const std::string& str_name, Elf_Word str_type, bool alloc)
-  : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, type, ((alloc) ? SHF_ALLOC : 0U),
-                                                     &strtab_, 0, sizeof(Elf_Word),
-                                                     sizeof(Elf_Sym)), str_name_(str_name),
-                                                     str_type_(str_type),
-                                                     strtab_(str_name,
-                                                             str_type,
-                                                             ((alloc) ? SHF_ALLOC : 0U),
-                                                             nullptr, 0, 1, 1) {
+  : ElfSectionBuilder<ElfTypes>(sec_name, type, ((alloc) ? SHF_ALLOC : 0U),
+                                &strtab_, 0, sizeof(Elf_Word),
+                                sizeof(Elf_Sym)), str_name_(str_name),
+                                str_type_(str_type),
+                                strtab_(str_name,
+                                        str_type,
+                                        ((alloc) ? SHF_ALLOC : 0U),
+                                        nullptr, 0, 1, 1) {
   }
 
   ~ElfSymtabBuilder() {}
@@ -365,14 +378,14 @@
     return symbols_.size() + 1;
   }
 
-  ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* GetStrTab() {
+  ElfSectionBuilder<ElfTypes>* GetStrTab() {
     return &strtab_;
   }
 
  private:
   struct ElfSymbolState {
     const std::string name_;
-    const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_;
+    const ElfSectionBuilder<ElfTypes>* section_;
     Elf_Addr addr_;
     Elf_Word size_;
     bool is_relative_;
@@ -387,7 +400,7 @@
   Elf_Word str_type_;
   // The symbols in the same order they will be in the symbol table.
   std::vector<ElfSymbolState> symbols_;
-  ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> strtab_;
+  ElfSectionBuilder<ElfTypes> strtab_;
 };
 
 template <typename Elf_Word>
@@ -529,10 +542,18 @@
   return RoundUp(prev.sh_size + prev.sh_offset, cur.sh_addralign);
 }
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, typename Elf_Dyn,
-          typename Elf_Sym, typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr>
+template <typename ElfTypes>
 class ElfBuilder FINAL {
  public:
+  using Elf_Addr = typename ElfTypes::Addr;
+  using Elf_Word = typename ElfTypes::Word;
+  using Elf_Sword = typename ElfTypes::Sword;
+  using Elf_Ehdr = typename ElfTypes::Ehdr;
+  using Elf_Shdr = typename ElfTypes::Shdr;
+  using Elf_Sym = typename ElfTypes::Sym;
+  using Elf_Phdr = typename ElfTypes::Phdr;
+  using Elf_Dyn = typename ElfTypes::Dyn;
+
   ElfBuilder(CodeOutput* oat_writer,
              File* elf_file,
              InstructionSet isa,
@@ -565,11 +586,11 @@
   }
   ~ElfBuilder() {}
 
-  const ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>& GetTextBuilder() const {
+  const ElfOatSectionBuilder<ElfTypes>& GetTextBuilder() const {
     return text_builder_;
   }
 
-  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* GetSymtabBuilder() {
+  ElfSymtabBuilder<ElfTypes>* GetSymtabBuilder() {
     return &symtab_builder_;
   }
 
@@ -1181,12 +1202,11 @@
   }
 
   // Adds the given raw section to the builder.  It does not take ownership.
-  void RegisterRawSection(ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* bld) {
+  void RegisterRawSection(ElfRawSectionBuilder<ElfTypes>* bld) {
     other_builders_.push_back(bld);
   }
 
-  const ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>*
-  FindRawSection(const char* name) {
+  const ElfRawSectionBuilder<ElfTypes>* FindRawSection(const char* name) {
     for (const auto* other_builder : other_builders_) {
       if (other_builder->GetName() == name) {
         return other_builder;
@@ -1304,8 +1324,7 @@
     }
   }
 
-  void AssignSectionStr(ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* builder,
-                        std::string* strtab) {
+  void AssignSectionStr(ElfSectionBuilder<ElfTypes>* builder, std::string* strtab) {
     builder->GetSection()->sh_name = strtab->size();
     *strtab += builder->GetName();
     *strtab += '\0';
@@ -1363,15 +1382,15 @@
   std::vector<const Elf_Shdr*> section_ptrs_;
   std::vector<Elf_Word> hash_;
 
-  ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> text_builder_;
-  ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> rodata_builder_;
-  ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> bss_builder_;
-  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr> dynsym_builder_;
-  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr> symtab_builder_;
-  ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> hash_builder_;
-  ElfDynamicBuilder<Elf_Word, Elf_Sword, Elf_Dyn, Elf_Shdr> dynamic_builder_;
-  ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> shstrtab_builder_;
-  std::vector<ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>*> other_builders_;
+  ElfOatSectionBuilder<ElfTypes> text_builder_;
+  ElfOatSectionBuilder<ElfTypes> rodata_builder_;
+  ElfOatSectionBuilder<ElfTypes> bss_builder_;
+  ElfSymtabBuilder<ElfTypes> dynsym_builder_;
+  ElfSymtabBuilder<ElfTypes> symtab_builder_;
+  ElfSectionBuilder<ElfTypes> hash_builder_;
+  ElfDynamicBuilder<ElfTypes> dynamic_builder_;
+  ElfSectionBuilder<ElfTypes> shstrtab_builder_;
+  std::vector<ElfRawSectionBuilder<ElfTypes>*> other_builders_;
 
   DISALLOW_COPY_AND_ASSIGN(ElfBuilder);
 };
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index 44c14a0..949fcab 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -39,16 +39,13 @@
 
 namespace art {
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Create(File* elf_file,
-                            OatWriter* oat_writer,
-                            const std::vector<const DexFile*>& dex_files,
-                            const std::string& android_root,
-                            bool is_host,
-                            const CompilerDriver& driver) {
+template <typename ElfTypes>
+bool ElfWriterQuick<ElfTypes>::Create(File* elf_file,
+                                      OatWriter* oat_writer,
+                                      const std::vector<const DexFile*>& dex_files,
+                                      const std::string& android_root,
+                                      bool is_host,
+                                      const CompilerDriver& driver) {
   ElfWriterQuick elf_writer(driver, elf_file);
   return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
 }
@@ -67,20 +64,14 @@
   OatWriter* const oat_writer_;
 };
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-static void WriteDebugSymbols(ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-                                         Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
-                              OatWriter* oat_writer);
+template <typename ElfTypes>
+static void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder, OatWriter* oat_writer);
 
 // Encode patch locations in .oat_patches format.
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, Elf_Sym, Elf_Ehdr,
-  Elf_Phdr, Elf_Shdr>::EncodeOatPatches(const OatWriter::PatchLocationsMap& sections,
-                                        std::vector<uint8_t>* buffer) {
+template <typename ElfTypes>
+void ElfWriterQuick<ElfTypes>::EncodeOatPatches(
+    const OatWriter::PatchLocationsMap& sections,
+    std::vector<uint8_t>* buffer) {
   for (const auto& section : sections) {
     const std::string& name = section.first;
     std::vector<uintptr_t>* locations = section.second.get();
@@ -121,41 +112,36 @@
   }
 }
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Write(OatWriter* oat_writer,
-                           const std::vector<const DexFile*>& dex_files_unused ATTRIBUTE_UNUSED,
-                           const std::string& android_root_unused ATTRIBUTE_UNUSED,
-                           bool is_host_unused ATTRIBUTE_UNUSED) {
+template <typename ElfTypes>
+bool ElfWriterQuick<ElfTypes>::Write(
+    OatWriter* oat_writer,
+    const std::vector<const DexFile*>& dex_files_unused ATTRIBUTE_UNUSED,
+    const std::string& android_root_unused ATTRIBUTE_UNUSED,
+    bool is_host_unused ATTRIBUTE_UNUSED) {
   constexpr bool debug = false;
   const OatHeader& oat_header = oat_writer->GetOatHeader();
-  Elf_Word oat_data_size = oat_header.GetExecutableOffset();
+  typename ElfTypes::Word oat_data_size = oat_header.GetExecutableOffset();
   uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;
   uint32_t oat_bss_size = oat_writer->GetBssSize();
 
   OatWriterWrapper wrapper(oat_writer);
 
-  std::unique_ptr<ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-                             Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr> > builder(
-      new ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-                     Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>(
-          &wrapper,
-          elf_file_,
-          compiler_driver_->GetInstructionSet(),
-          0,
-          oat_data_size,
-          oat_data_size,
-          oat_exec_size,
-          RoundUp(oat_data_size + oat_exec_size, kPageSize),
-          oat_bss_size,
-          compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(),
-          debug));
+  std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(
+      &wrapper,
+      elf_file_,
+      compiler_driver_->GetInstructionSet(),
+      0,
+      oat_data_size,
+      oat_data_size,
+      oat_exec_size,
+      RoundUp(oat_data_size + oat_exec_size, kPageSize),
+      oat_bss_size,
+      compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(),
+      debug));
 
   InstructionSet isa = compiler_driver_->GetInstructionSet();
   int alignment = GetInstructionSetPointerSize(isa);
-  typedef ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> RawSection;
+  typedef ElfRawSectionBuilder<ElfTypes> RawSection;
   RawSection eh_frame(".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, alignment, 0);
   RawSection eh_frame_hdr(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0);
   RawSection debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
@@ -210,8 +196,8 @@
   }
 
   // We know where .text and .eh_frame will be located, so patch the addresses.
-  Elf_Addr text_addr = builder->GetTextBuilder().GetSection()->sh_addr;
-  // TODO: Simplify once we use Elf64 - we can use Elf_Addr instead of branching.
+  typename ElfTypes::Addr text_addr = builder->GetTextBuilder().GetSection()->sh_addr;
+  // TODO: Simplify once we use Elf64 - we can use ElfTypes::Addr instead of branching.
   if (Is64BitInstructionSet(compiler_driver_->GetInstructionSet())) {
     // relative_address = (text_addr + address) - (eh_frame_addr + patch_location);
     PatchAddresses<uint64_t, true>(&eh_frame_patches,
@@ -229,14 +215,10 @@
   return builder->Write();
 }
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
+template <typename ElfTypes>
 // Do not inline to avoid Clang stack frame problems. b/18738594
 NO_INLINE
-static void WriteDebugSymbols(ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-                                         Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
-                              OatWriter* oat_writer) {
+static void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder, OatWriter* oat_writer) {
   const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetMethodDebugInfo();
 
   // Find all addresses (low_pc) which contain deduped methods.
@@ -248,8 +230,7 @@
     }
   }
 
-  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab =
-      builder->GetSymtabBuilder();
+  ElfSymtabBuilder<ElfTypes>* symtab = builder->GetSymtabBuilder();
   for (auto it = method_info.begin(); it != method_info.end(); ++it) {
     std::string name = PrettyMethod(it->dex_method_index_, *it->dex_file_, true);
     if (deduped_addresses.find(it->low_pc_) != deduped_addresses.end()) {
@@ -272,9 +253,7 @@
 }
 
 // Explicit instantiations
-template class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
-                              Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>;
-template class ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn,
-                              Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>;
+template class ElfWriterQuick<ElfTypes32>;
+template class ElfWriterQuick<ElfTypes64>;
 
 }  // namespace art
diff --git a/compiler/elf_writer_quick.h b/compiler/elf_writer_quick.h
index 811beb4..955b568 100644
--- a/compiler/elf_writer_quick.h
+++ b/compiler/elf_writer_quick.h
@@ -23,9 +23,7 @@
 
 namespace art {
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
+template <typename ElfTypes>
 class ElfWriterQuick FINAL : public ElfWriter {
  public:
   // Write an ELF file. Returns true on success, false on failure.
@@ -57,10 +55,8 @@
 };
 
 // Explicitly instantiated in elf_writer_quick.cc
-typedef ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
-                       Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr> ElfWriterQuick32;
-typedef ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn,
-                       Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr> ElfWriterQuick64;
+typedef ElfWriterQuick<ElfTypes32> ElfWriterQuick32;
+typedef ElfWriterQuick<ElfTypes64> ElfWriterQuick64;
 
 }  // namespace art