ART: Use the right ElfBuilder for oatdump symbolizer

We should not unconditionally output 32-bit ELF files.

Bug: 27293423
Change-Id: Ibbb74a7807b24c46cb23d7b5867936569424e8fe
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index b52f30e..6c6c807 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -98,6 +98,7 @@
   return ret;
 }
 
+template <typename ElfTypes>
 class OatSymbolizer FINAL {
  public:
   OatSymbolizer(const OatFile* oat_file, const std::string& output_name) :
@@ -121,7 +122,7 @@
     File* elf_file = OS::CreateEmptyFile(output_name_.c_str());
     std::unique_ptr<BufferedOutputStream> output_stream(
         MakeUnique<BufferedOutputStream>(MakeUnique<FileOutputStream>(elf_file)));
-    builder_.reset(new ElfBuilder<ElfTypes32>(isa, features, output_stream.get()));
+    builder_.reset(new ElfBuilder<ElfTypes>(isa, features, output_stream.get()));
 
     builder_->Start();
 
@@ -151,14 +152,14 @@
         elf_file->GetPath(), rodata_size, text_size, oat_file_->BssSize());
     builder_->WriteDynamicSection();
 
-    Walk(&art::OatSymbolizer::RegisterForDedup);
+    Walk(&art::OatSymbolizer<ElfTypes>::RegisterForDedup);
 
     NormalizeState();
 
     strtab->Start();
     strtab->Write("");  // strtab should start with empty string.
     AddTrampolineSymbols();
-    Walk(&art::OatSymbolizer::AddSymbol);
+    Walk(&art::OatSymbolizer<ElfTypes>::AddSymbol);
     strtab->End();
 
     symtab->Start();
@@ -346,7 +347,7 @@
   }
 
   const OatFile* oat_file_;
-  std::unique_ptr<ElfBuilder<ElfTypes32> > builder_;
+  std::unique_ptr<ElfBuilder<ElfTypes> > builder_;
   std::unordered_map<uint32_t, uint32_t> state_;
   const std::string output_name_;
 };
@@ -2544,8 +2545,17 @@
     return EXIT_FAILURE;
   }
 
-  OatSymbolizer oat_symbolizer(oat_file, output_name);
-  if (!oat_symbolizer.Symbolize()) {
+  bool result;
+  // Try to produce an ELF file of the same type. This is finicky, as we have used 32-bit ELF
+  // files for 64-bit code in the past.
+  if (Is64BitInstructionSet(oat_file->GetOatHeader().GetInstructionSet())) {
+    OatSymbolizer<ElfTypes64> oat_symbolizer(oat_file, output_name);
+    result = oat_symbolizer.Symbolize();
+  } else {
+    OatSymbolizer<ElfTypes32> oat_symbolizer(oat_file, output_name);
+    result = oat_symbolizer.Symbolize();
+  }
+  if (!result) {
     fprintf(stderr, "Failed to symbolize\n");
     return EXIT_FAILURE;
   }