OSDN Git Service

Tidy ELF builder.
authorIan Rogers <irogers@google.com>
Thu, 9 Oct 2014 00:27:48 +0000 (17:27 -0700)
committerIan Rogers <irogers@google.com>
Thu, 9 Oct 2014 15:25:34 +0000 (08:25 -0700)
Don't do "if (ptr)". Use const. Use DISALLOW_COPY_AND_ASSIGN. Avoid public
member variables.
Move ValueObject to base and use in ELF builder.
Tidy VectorOutputStream to not use non-const reference arguments.

Change-Id: I2c727c3fc61769c3726de7cfb68b2d6eb4477e53

17 files changed:
compiler/buffered_output_stream.h
compiler/elf_builder.h
compiler/elf_writer_mclinker.cc
compiler/elf_writer_quick.cc
compiler/file_output_stream.h
compiler/optimizing/builder.h
compiler/optimizing/graph_visualizer.h
compiler/optimizing/locations.h
compiler/optimizing/nodes.h
compiler/optimizing/parallel_move_resolver.h
compiler/optimizing/stack_map_stream.h
compiler/output_stream_test.cc
compiler/utils/arena_object.h [moved from compiler/utils/allocation.h with 75% similarity]
compiler/vector_output_stream.cc
compiler/vector_output_stream.h
oatdump/oatdump.cc
runtime/base/value_object.h [new file with mode: 0644]

index 75a3f24..bbc49df 100644 (file)
@@ -23,7 +23,7 @@
 
 namespace art {
 
-class BufferedOutputStream : public OutputStream {
+class BufferedOutputStream FINAL : public OutputStream {
  public:
   explicit BufferedOutputStream(OutputStream* out);
 
index 74ee038..c32bdb4 100644 (file)
@@ -18,6 +18,7 @@
 #define ART_COMPILER_ELF_BUILDER_H_
 
 #include "base/stl_util.h"
+#include "base/value_object.h"
 #include "buffered_output_stream.h"
 #include "elf_utils.h"
 #include "file_output_stream.h"
 namespace art {
 
 template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
-class ElfSectionBuilder {
+class ElfSectionBuilder : public ValueObject {
  public:
   ElfSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags,
                     const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *link, Elf_Word info,
-                    Elf_Word align, Elf_Word entsize) : name_(sec_name), link_(link) {
+                    Elf_Word align, Elf_Word entsize)
+      : section_index_(0), name_(sec_name), link_(link) {
     memset(&section_, 0, sizeof(section_));
     section_.sh_type = type;
     section_.sh_flags = flags;
@@ -39,23 +41,41 @@ class ElfSectionBuilder {
     section_.sh_entsize = entsize;
   }
 
-  virtual ~ElfSectionBuilder() {}
+  ~ElfSectionBuilder() {}
 
-  Elf_Shdr section_;
-  Elf_Word section_index_ = 0;
+  Elf_Word GetLink() const {
+    return (link_ != nullptr) ? link_->section_index_ : 0;
+  }
 
-  Elf_Word GetLink() {
-    return (link_) ? link_->section_index_ : 0;
+  const Elf_Shdr* GetSection() const {
+    return &section_;
   }
 
-  const std::string name_;
+  Elf_Shdr* GetSection() {
+    return &section_;
+  }
 
- protected:
-  const ElfSectionBuilder* link_;
+  Elf_Word GetSectionIndex() const {
+    return section_index_;
+  }
+
+  void SetSectionIndex(Elf_Word section_index) {
+    section_index_ = section_index;
+  }
+
+  const std::string& GetName() const {
+    return name_;
+  }
+
+ private:
+  Elf_Shdr section_;
+  Elf_Word section_index_;
+  const std::string name_;
+  const ElfSectionBuilder* const link_;
 };
 
 template <typename Elf_Word, typename Elf_Sword, typename Elf_Dyn, typename Elf_Shdr>
-class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+class ElfDynamicBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
  public:
   void AddDynamicTag(Elf_Sword tag, Elf_Word d_un) {
     if (tag == DT_NULL) {
@@ -65,7 +85,7 @@ class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr
   }
 
   void AddDynamicTag(Elf_Sword tag, Elf_Word d_un,
-                     ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section) {
+                     const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section) {
     if (tag == DT_NULL) {
       return;
     }
@@ -78,7 +98,7 @@ class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr
                                                      link, 0, kPageSize, sizeof(Elf_Dyn)) {}
   ~ElfDynamicBuilder() {}
 
-  Elf_Word GetSize() {
+  Elf_Word GetSize() const {
     // Add 1 for the DT_NULL, 1 for DT_STRSZ, and 1 for DT_SONAME. All of
     // these must be added when we actually put the file together because
     // their values are very dependent on state.
@@ -89,13 +109,13 @@ class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr
   // table and soname_off should be the offset of the soname in .dynstr.
   // Since niether can be found prior to final layout we will wait until here
   // to add them.
-  std::vector<Elf_Dyn> GetDynamics(Elf_Word strsz, Elf_Word soname) {
+  std::vector<Elf_Dyn> GetDynamics(Elf_Word strsz, Elf_Word soname) const {
     std::vector<Elf_Dyn> ret;
     for (auto it = dynamics_.cbegin(); it != dynamics_.cend(); ++it) {
-      if (it->section_) {
+      if (it->section_ != nullptr) {
         // We are adding an address relative to a section.
         ret.push_back(
-            {it->tag_, {it->off_ + it->section_->section_.sh_addr}});
+            {it->tag_, {it->off_ + it->section_->GetSection()->sh_addr}});
       } else {
         ret.push_back({it->tag_, {it->off_}});
       }
@@ -106,9 +126,9 @@ class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr
     return ret;
   }
 
- protected:
+ private:
   struct ElfDynamicState {
-    ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_;
+    const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_;
     Elf_Sword tag_;
     Elf_Word off_;
   };
@@ -116,39 +136,50 @@ class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr
 };
 
 template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
-class ElfRawSectionBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+class ElfRawSectionBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
  public:
   ElfRawSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags,
                        const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* 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) {}
+                                                       entsize) {
+  }
+
   ~ElfRawSectionBuilder() {}
-  std::vector<uint8_t>* GetBuffer() { return &buf_; }
-  void SetBuffer(std::vector<uint8_t>&& buf) { buf_ = buf; }
 
- protected:
+  std::vector<uint8_t>* GetBuffer() {
+    return &buf_;
+  }
+
+  void SetBuffer(const std::vector<uint8_t>& buf) {
+    buf_ = buf;
+  }
+
+ private:
   std::vector<uint8_t> buf_;
 };
 
 template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
-class ElfOatSectionBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+class ElfOatSectionBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
  public:
   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), offset_(offset), size_(size) {}
+                                                       0),
+      offset_(offset), size_(size) {
+  }
+
   ~ElfOatSectionBuilder() {}
 
-  Elf_Word GetOffset() {
+  Elf_Word GetOffset() const {
     return offset_;
   }
 
-  Elf_Word GetSize() {
+  Elf_Word GetSize() const {
     return size_;
   }
 
- protected:
+ private:
   // Offset of the content within the file.
   Elf_Word offset_;
   // Size of the content within the file.
@@ -175,7 +206,7 @@ static inline unsigned elfhash(const char *_name) {
 
 template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, typename Elf_Sym,
           typename Elf_Shdr>
-class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+class ElfSymtabBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
  public:
   // Add a symbol with given name to this symtab. The symbol refers to
   // 'relative_addr' within the given section and has the given attributes.
@@ -202,10 +233,12 @@ class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>
                                                      strtab_(str_name,
                                                              str_type,
                                                              ((alloc) ? SHF_ALLOC : 0U),
-                                                             nullptr, 0, 1, 1) {}
+                                                             nullptr, 0, 1, 1) {
+  }
+
   ~ElfSymtabBuilder() {}
 
-  std::vector<Elf_Word> GenerateHashContents() {
+  std::vector<Elf_Word> GenerateHashContents() const {
     // Here is how The ELF hash table works.
     // There are 3 arrays to worry about.
     // * The symbol table where the symbol information is.
@@ -295,7 +328,7 @@ class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>
       tab += it->name_;
       tab += '\0';
     }
-    strtab_.section_.sh_size = tab.size();
+    strtab_.GetSection()->sh_size = tab.size();
     return tab;
   }
 
@@ -311,13 +344,13 @@ class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>
       memset(&sym, 0, sizeof(sym));
       sym.st_name = it->name_idx_;
       if (it->is_relative_) {
-        sym.st_value = it->addr_ + it->section_->section_.sh_offset;
+        sym.st_value = it->addr_ + it->section_->GetSection()->sh_offset;
       } else {
         sym.st_value = it->addr_;
       }
       sym.st_size = it->size_;
       sym.st_other = it->other_;
-      sym.st_shndx = it->section_->section_index_;
+      sym.st_shndx = it->section_->GetSectionIndex();
       sym.st_info = it->info_;
 
       ret.push_back(sym);
@@ -325,7 +358,7 @@ class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>
     return ret;
   }
 
-  Elf_Word GetSize() {
+  Elf_Word GetSize() const {
     // 1 is for the implicit NULL symbol.
     return symbols_.size() + 1;
   }
@@ -334,7 +367,7 @@ class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>
     return &strtab_;
   }
 
- protected:
+ private:
   struct ElfSymbolState {
     const std::string name_;
     const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_;
@@ -377,18 +410,26 @@ class ElfFilePiece {
  protected:
   explicit ElfFilePiece(Elf_Word offset) : offset_(offset) {}
 
-  virtual std::string GetDescription() = 0;
+  Elf_Word GetOffset() const {
+    return offset_;
+  }
+
+  virtual const char* GetDescription() const = 0;
   virtual bool DoActualWrite(File* elf_file) = 0;
 
-  Elf_Word offset_;
+ private:
+  const Elf_Word offset_;
+
+  DISALLOW_COPY_AND_ASSIGN(ElfFilePiece);
 };
 
 template <typename Elf_Word>
-class ElfFileMemoryPiece : public ElfFilePiece<Elf_Word> {
+class ElfFileMemoryPiece FINAL : public ElfFilePiece<Elf_Word> {
  public:
   ElfFileMemoryPiece(const std::string& name, Elf_Word offset, const void* data, Elf_Word size)
       : ElfFilePiece<Elf_Word>(offset), dbg_name_(name), data_(data), size_(size) {}
 
+ protected:
   bool DoActualWrite(File* elf_file) OVERRIDE {
     DCHECK(data_ != nullptr || size_ == 0U) << dbg_name_ << " " << size_;
 
@@ -400,8 +441,8 @@ class ElfFileMemoryPiece : public ElfFilePiece<Elf_Word> {
     return true;
   }
 
-  std::string GetDescription() OVERRIDE {
-    return dbg_name_;
+  const char* GetDescription() const OVERRIDE {
+    return dbg_name_.c_str();
   }
 
  private:
@@ -418,13 +459,14 @@ class CodeOutput {
 };
 
 template <typename Elf_Word>
-class ElfFileRodataPiece : public ElfFilePiece<Elf_Word> {
+class ElfFileRodataPiece FINAL : public ElfFilePiece<Elf_Word> {
  public:
   ElfFileRodataPiece(Elf_Word offset, CodeOutput* output) : ElfFilePiece<Elf_Word>(offset),
       output_(output) {}
 
+ protected:
   bool DoActualWrite(File* elf_file) OVERRIDE {
-    output_->SetCodeOffset(this->offset_);
+    output_->SetCodeOffset(this->GetOffset());
     std::unique_ptr<BufferedOutputStream> output_stream(
         new BufferedOutputStream(new FileOutputStream(elf_file)));
     if (!output_->Write(output_stream.get())) {
@@ -435,20 +477,23 @@ class ElfFileRodataPiece : public ElfFilePiece<Elf_Word> {
     return true;
   }
 
-  std::string GetDescription() OVERRIDE {
+  const char* GetDescription() const OVERRIDE {
     return ".rodata";
   }
 
  private:
-  CodeOutput* output_;
+  CodeOutput* const output_;
+
+  DISALLOW_COPY_AND_ASSIGN(ElfFileRodataPiece);
 };
 
 template <typename Elf_Word>
-class ElfFileOatTextPiece : public ElfFilePiece<Elf_Word> {
+class ElfFileOatTextPiece FINAL : public ElfFilePiece<Elf_Word> {
  public:
   ElfFileOatTextPiece(Elf_Word offset, CodeOutput* output) : ElfFilePiece<Elf_Word>(offset),
       output_(output) {}
 
+ protected:
   bool DoActualWrite(File* elf_file) OVERRIDE {
     // All data is written by the ElfFileRodataPiece right now, as the oat writer writes in one
     // piece. This is for future flexibility.
@@ -456,12 +501,14 @@ class ElfFileOatTextPiece : public ElfFilePiece<Elf_Word> {
     return true;
   }
 
-  std::string GetDescription() OVERRIDE {
+  const char* GetDescription() const OVERRIDE {
     return ".text";
   }
 
  private:
-  CodeOutput* output_;
+  CodeOutput* const output_;
+
+  DISALLOW_COPY_AND_ASSIGN(ElfFileOatTextPiece);
 };
 
 template <typename Elf_Word>
@@ -513,6 +560,14 @@ class ElfBuilder FINAL {
   }
   ~ElfBuilder() {}
 
+  const ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>& GetTextBuilder() const {
+    return text_builder_;
+  }
+
+  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* GetSymtabBuilder() {
+    return &symtab_builder_;
+  }
+
   bool Init() {
     // The basic layout of the elf file. Order may be different in final output.
     // +-------------------------+
@@ -676,34 +731,40 @@ class ElfBuilder FINAL {
     section_index_ = 1;
 
     // setup .dynsym
-    section_ptrs_.push_back(&dynsym_builder_.section_);
+    section_ptrs_.push_back(dynsym_builder_.GetSection());
     AssignSectionStr(&dynsym_builder_, &shstrtab_);
-    dynsym_builder_.section_index_ = section_index_++;
+    dynsym_builder_.SetSectionIndex(section_index_);
+    section_index_++;
 
     // Setup .dynstr
-    section_ptrs_.push_back(&dynsym_builder_.GetStrTab()->section_);
+    section_ptrs_.push_back(dynsym_builder_.GetStrTab()->GetSection());
     AssignSectionStr(dynsym_builder_.GetStrTab(), &shstrtab_);
-    dynsym_builder_.GetStrTab()->section_index_ = section_index_++;
+    dynsym_builder_.GetStrTab()->SetSectionIndex(section_index_);
+    section_index_++;
 
     // Setup .hash
-    section_ptrs_.push_back(&hash_builder_.section_);
+    section_ptrs_.push_back(hash_builder_.GetSection());
     AssignSectionStr(&hash_builder_, &shstrtab_);
-    hash_builder_.section_index_ = section_index_++;
+    hash_builder_.SetSectionIndex(section_index_);
+    section_index_++;
 
     // Setup .rodata
-    section_ptrs_.push_back(&rodata_builder_.section_);
+    section_ptrs_.push_back(rodata_builder_.GetSection());
     AssignSectionStr(&rodata_builder_, &shstrtab_);
-    rodata_builder_.section_index_ = section_index_++;
+    rodata_builder_.SetSectionIndex(section_index_);
+    section_index_++;
 
     // Setup .text
-    section_ptrs_.push_back(&text_builder_.section_);
+    section_ptrs_.push_back(text_builder_.GetSection());
     AssignSectionStr(&text_builder_, &shstrtab_);
-    text_builder_.section_index_ = section_index_++;
+    text_builder_.SetSectionIndex(section_index_);
+    section_index_++;
 
     // Setup .dynamic
-    section_ptrs_.push_back(&dynamic_builder_.section_);
+    section_ptrs_.push_back(dynamic_builder_.GetSection());
     AssignSectionStr(&dynamic_builder_, &shstrtab_);
-    dynamic_builder_.section_index_ = section_index_++;
+    dynamic_builder_.SetSectionIndex(section_index_);
+    section_index_++;
 
     // Fill in the hash section.
     hash_ = dynsym_builder_.GenerateHashContents();
@@ -718,64 +779,67 @@ class ElfBuilder FINAL {
     // Get the layout in the sections.
     //
     // Get the layout of the dynsym section.
-    dynsym_builder_.section_.sh_offset = RoundUp(base_offset, dynsym_builder_.section_.sh_addralign);
-    dynsym_builder_.section_.sh_addr = dynsym_builder_.section_.sh_offset;
-    dynsym_builder_.section_.sh_size = dynsym_builder_.GetSize() * sizeof(Elf_Sym);
-    dynsym_builder_.section_.sh_link = dynsym_builder_.GetLink();
+    dynsym_builder_.GetSection()->sh_offset =
+        RoundUp(base_offset, dynsym_builder_.GetSection()->sh_addralign);
+    dynsym_builder_.GetSection()->sh_addr = dynsym_builder_.GetSection()->sh_offset;
+    dynsym_builder_.GetSection()->sh_size = dynsym_builder_.GetSize() * sizeof(Elf_Sym);
+    dynsym_builder_.GetSection()->sh_link = dynsym_builder_.GetLink();
 
     // Get the layout of the dynstr section.
-    dynsym_builder_.GetStrTab()->section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                                 (dynsym_builder_.GetStrTab()->section_,
-                                                  dynsym_builder_.section_);
-    dynsym_builder_.GetStrTab()->section_.sh_addr = dynsym_builder_.GetStrTab()->section_.sh_offset;
-    dynsym_builder_.GetStrTab()->section_.sh_size = dynstr_.size();
-    dynsym_builder_.GetStrTab()->section_.sh_link = dynsym_builder_.GetStrTab()->GetLink();
+    dynsym_builder_.GetStrTab()->GetSection()->sh_offset =
+        NextOffset<Elf_Word, Elf_Shdr>(*dynsym_builder_.GetStrTab()->GetSection(),
+                                       *dynsym_builder_.GetSection());
+    dynsym_builder_.GetStrTab()->GetSection()->sh_addr =
+        dynsym_builder_.GetStrTab()->GetSection()->sh_offset;
+    dynsym_builder_.GetStrTab()->GetSection()->sh_size = dynstr_.size();
+    dynsym_builder_.GetStrTab()->GetSection()->sh_link = dynsym_builder_.GetStrTab()->GetLink();
 
     // Get the layout of the hash section
-    hash_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                       (hash_builder_.section_,
-                                        dynsym_builder_.GetStrTab()->section_);
-    hash_builder_.section_.sh_addr = hash_builder_.section_.sh_offset;
-    hash_builder_.section_.sh_size = hash_.size() * sizeof(Elf_Word);
-    hash_builder_.section_.sh_link = hash_builder_.GetLink();
+    hash_builder_.GetSection()->sh_offset =
+        NextOffset<Elf_Word, Elf_Shdr>(*hash_builder_.GetSection(),
+                                       *dynsym_builder_.GetStrTab()->GetSection());
+    hash_builder_.GetSection()->sh_addr = hash_builder_.GetSection()->sh_offset;
+    hash_builder_.GetSection()->sh_size = hash_.size() * sizeof(Elf_Word);
+    hash_builder_.GetSection()->sh_link = hash_builder_.GetLink();
 
     // Get the layout of the rodata section.
-    rodata_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                         (rodata_builder_.section_,
-                                          hash_builder_.section_);
-    rodata_builder_.section_.sh_addr = rodata_builder_.section_.sh_offset;
-    rodata_builder_.section_.sh_size = rodata_builder_.GetSize();
-    rodata_builder_.section_.sh_link = rodata_builder_.GetLink();
+    rodata_builder_.GetSection()->sh_offset =
+        NextOffset<Elf_Word, Elf_Shdr>(*rodata_builder_.GetSection(),
+                                       *hash_builder_.GetSection());
+    rodata_builder_.GetSection()->sh_addr = rodata_builder_.GetSection()->sh_offset;
+    rodata_builder_.GetSection()->sh_size = rodata_builder_.GetSize();
+    rodata_builder_.GetSection()->sh_link = rodata_builder_.GetLink();
 
     // Get the layout of the text section.
-    text_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                       (text_builder_.section_, rodata_builder_.section_);
-    text_builder_.section_.sh_addr = text_builder_.section_.sh_offset;
-    text_builder_.section_.sh_size = text_builder_.GetSize();
-    text_builder_.section_.sh_link = text_builder_.GetLink();
-    CHECK_ALIGNED(rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size, kPageSize);
+    text_builder_.GetSection()->sh_offset =
+        NextOffset<Elf_Word, Elf_Shdr>(*text_builder_.GetSection(),
+                                       *rodata_builder_.GetSection());
+    text_builder_.GetSection()->sh_addr = text_builder_.GetSection()->sh_offset;
+    text_builder_.GetSection()->sh_size = text_builder_.GetSize();
+    text_builder_.GetSection()->sh_link = text_builder_.GetLink();
+    CHECK_ALIGNED(rodata_builder_.GetSection()->sh_offset +
+                  rodata_builder_.GetSection()->sh_size, kPageSize);
 
     // Get the layout of the dynamic section.
-    dynamic_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                          (dynamic_builder_.section_,
-                                           text_builder_.section_);
-    dynamic_builder_.section_.sh_addr = dynamic_builder_.section_.sh_offset;
-    dynamic_builder_.section_.sh_size = dynamic_builder_.GetSize() * sizeof(Elf_Dyn);
-    dynamic_builder_.section_.sh_link = dynamic_builder_.GetLink();
+    dynamic_builder_.GetSection()->sh_offset =
+        NextOffset<Elf_Word, Elf_Shdr>(*dynamic_builder_.GetSection(), *text_builder_.GetSection());
+    dynamic_builder_.GetSection()->sh_addr = dynamic_builder_.GetSection()->sh_offset;
+    dynamic_builder_.GetSection()->sh_size = dynamic_builder_.GetSize() * sizeof(Elf_Dyn);
+    dynamic_builder_.GetSection()->sh_link = dynamic_builder_.GetLink();
 
     if (debug_logging_) {
-      LOG(INFO) << "dynsym off=" << dynsym_builder_.section_.sh_offset
-                << " dynsym size=" << dynsym_builder_.section_.sh_size;
-      LOG(INFO) << "dynstr off=" << dynsym_builder_.GetStrTab()->section_.sh_offset
-                << " dynstr size=" << dynsym_builder_.GetStrTab()->section_.sh_size;
-      LOG(INFO) << "hash off=" << hash_builder_.section_.sh_offset
-                << " hash size=" << hash_builder_.section_.sh_size;
-      LOG(INFO) << "rodata off=" << rodata_builder_.section_.sh_offset
-                << " rodata size=" << rodata_builder_.section_.sh_size;
-      LOG(INFO) << "text off=" << text_builder_.section_.sh_offset
-                << " text size=" << text_builder_.section_.sh_size;
-      LOG(INFO) << "dynamic off=" << dynamic_builder_.section_.sh_offset
-                << " dynamic size=" << dynamic_builder_.section_.sh_size;
+      LOG(INFO) << "dynsym off=" << dynsym_builder_.GetSection()->sh_offset
+                << " dynsym size=" << dynsym_builder_.GetSection()->sh_size;
+      LOG(INFO) << "dynstr off=" << dynsym_builder_.GetStrTab()->GetSection()->sh_offset
+                << " dynstr size=" << dynsym_builder_.GetStrTab()->GetSection()->sh_size;
+      LOG(INFO) << "hash off=" << hash_builder_.GetSection()->sh_offset
+                << " hash size=" << hash_builder_.GetSection()->sh_size;
+      LOG(INFO) << "rodata off=" << rodata_builder_.GetSection()->sh_offset
+                << " rodata size=" << rodata_builder_.GetSection()->sh_size;
+      LOG(INFO) << "text off=" << text_builder_.GetSection()->sh_offset
+                << " text size=" << text_builder_.GetSection()->sh_size;
+      LOG(INFO) << "dynamic off=" << dynamic_builder_.GetSection()->sh_offset
+                << " dynamic size=" << dynamic_builder_.GetSection()->sh_size;
     }
 
     return true;
@@ -783,19 +847,21 @@ class ElfBuilder FINAL {
 
   bool Write() {
     std::vector<ElfFilePiece<Elf_Word>*> pieces;
-    Elf_Shdr prev = dynamic_builder_.section_;
+    Elf_Shdr* prev = dynamic_builder_.GetSection();
     std::string strtab;
 
     if (IncludingDebugSymbols()) {
       // Setup .symtab
-      section_ptrs_.push_back(&symtab_builder_.section_);
+      section_ptrs_.push_back(symtab_builder_.GetSection());
       AssignSectionStr(&symtab_builder_, &shstrtab_);
-      symtab_builder_.section_index_ = section_index_++;
+      symtab_builder_.SetSectionIndex(section_index_);
+      section_index_++;
 
       // Setup .strtab
-      section_ptrs_.push_back(&symtab_builder_.GetStrTab()->section_);
+      section_ptrs_.push_back(symtab_builder_.GetStrTab()->GetSection());
       AssignSectionStr(symtab_builder_.GetStrTab(), &shstrtab_);
-      symtab_builder_.GetStrTab()->section_index_ = section_index_++;
+      symtab_builder_.GetStrTab()->SetSectionIndex(section_index_);
+      section_index_++;
 
       strtab = symtab_builder_.GenerateStrtab();
       if (debug_logging_) {
@@ -810,15 +876,17 @@ class ElfBuilder FINAL {
     for (ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *builder = other_builders_.data(),
          *end = builder + other_builders_.size();
          builder != end; ++builder) {
-      section_ptrs_.push_back(&builder->section_);
+      section_ptrs_.push_back(builder->GetSection());
       AssignSectionStr(builder, &shstrtab_);
-      builder->section_index_ = section_index_++;
+      builder->SetSectionIndex(section_index_);
+      section_index_++;
     }
 
     // Setup shstrtab
-    section_ptrs_.push_back(&shstrtab_builder_.section_);
+    section_ptrs_.push_back(shstrtab_builder_.GetSection());
     AssignSectionStr(&shstrtab_builder_, &shstrtab_);
-    shstrtab_builder_.section_index_ = section_index_++;
+    shstrtab_builder_.SetSectionIndex(section_index_);
+    section_index_++;
 
     if (debug_logging_) {
       LOG(INFO) << ".shstrtab size    (bytes)   =" << shstrtab_.size()
@@ -829,71 +897,71 @@ class ElfBuilder FINAL {
 
     if (IncludingDebugSymbols()) {
       // Get the layout of the symtab section.
-      symtab_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                           (symtab_builder_.section_,
-                                            dynamic_builder_.section_);
-      symtab_builder_.section_.sh_addr = 0;
+      symtab_builder_.GetSection()->sh_offset =
+          NextOffset<Elf_Word, Elf_Shdr>(*symtab_builder_.GetSection(),
+                                         *dynamic_builder_.GetSection());
+      symtab_builder_.GetSection()->sh_addr = 0;
       // Add to leave space for the null symbol.
-      symtab_builder_.section_.sh_size = symtab_builder_.GetSize() * sizeof(Elf_Sym);
-      symtab_builder_.section_.sh_link = symtab_builder_.GetLink();
+      symtab_builder_.GetSection()->sh_size = symtab_builder_.GetSize() * sizeof(Elf_Sym);
+      symtab_builder_.GetSection()->sh_link = symtab_builder_.GetLink();
 
       // Get the layout of the dynstr section.
-      symtab_builder_.GetStrTab()->section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                                   (symtab_builder_.GetStrTab()->section_,
-                                                    symtab_builder_.section_);
-      symtab_builder_.GetStrTab()->section_.sh_addr = 0;
-      symtab_builder_.GetStrTab()->section_.sh_size = strtab.size();
-      symtab_builder_.GetStrTab()->section_.sh_link = symtab_builder_.GetStrTab()->GetLink();
-
-      prev = symtab_builder_.GetStrTab()->section_;
+      symtab_builder_.GetStrTab()->GetSection()->sh_offset =
+          NextOffset<Elf_Word, Elf_Shdr>(*symtab_builder_.GetStrTab()->GetSection(),
+                                         *symtab_builder_.GetSection());
+      symtab_builder_.GetStrTab()->GetSection()->sh_addr = 0;
+      symtab_builder_.GetStrTab()->GetSection()->sh_size = strtab.size();
+      symtab_builder_.GetStrTab()->GetSection()->sh_link = symtab_builder_.GetStrTab()->GetLink();
+
+      prev = symtab_builder_.GetStrTab()->GetSection();
       if (debug_logging_) {
-        LOG(INFO) << "symtab off=" << symtab_builder_.section_.sh_offset
-                  << " symtab size=" << symtab_builder_.section_.sh_size;
-        LOG(INFO) << "strtab off=" << symtab_builder_.GetStrTab()->section_.sh_offset
-                  << " strtab size=" << symtab_builder_.GetStrTab()->section_.sh_size;
+        LOG(INFO) << "symtab off=" << symtab_builder_.GetSection()->sh_offset
+                  << " symtab size=" << symtab_builder_.GetSection()->sh_size;
+        LOG(INFO) << "strtab off=" << symtab_builder_.GetStrTab()->GetSection()->sh_offset
+                  << " strtab size=" << symtab_builder_.GetStrTab()->GetSection()->sh_size;
       }
     }
 
     // Get the layout of the extra sections. (This will deal with the debug
     // sections if they are there)
     for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) {
-      it->section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>(it->section_, prev);
-      it->section_.sh_addr = 0;
-      it->section_.sh_size = it->GetBuffer()->size();
-      it->section_.sh_link = it->GetLink();
+      it->GetSection()->sh_offset = NextOffset<Elf_Word, Elf_Shdr>(*it->GetSection(), *prev);
+      it->GetSection()->sh_addr = 0;
+      it->GetSection()->sh_size = it->GetBuffer()->size();
+      it->GetSection()->sh_link = it->GetLink();
 
       // We postpone adding an ElfFilePiece to keep the order in "pieces."
 
-      prev = it->section_;
+      prev = it->GetSection();
       if (debug_logging_) {
-        LOG(INFO) << it->name_ << " off=" << it->section_.sh_offset
-                  << " size=" << it->section_.sh_size;
+        LOG(INFO) << it->GetName() << " off=" << it->GetSection()->sh_offset
+                  << " size=" << it->GetSection()->sh_size;
       }
     }
 
     // Get the layout of the shstrtab section
-    shstrtab_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                           (shstrtab_builder_.section_, prev);
-    shstrtab_builder_.section_.sh_addr = 0;
-    shstrtab_builder_.section_.sh_size = shstrtab_.size();
-    shstrtab_builder_.section_.sh_link = shstrtab_builder_.GetLink();
+    shstrtab_builder_.GetSection()->sh_offset =
+        NextOffset<Elf_Word, Elf_Shdr>(*shstrtab_builder_.GetSection(), *prev);
+    shstrtab_builder_.GetSection()->sh_addr = 0;
+    shstrtab_builder_.GetSection()->sh_size = shstrtab_.size();
+    shstrtab_builder_.GetSection()->sh_link = shstrtab_builder_.GetLink();
     if (debug_logging_) {
-        LOG(INFO) << "shstrtab off=" << shstrtab_builder_.section_.sh_offset
-                  << " shstrtab size=" << shstrtab_builder_.section_.sh_size;
+        LOG(INFO) << "shstrtab off=" << shstrtab_builder_.GetSection()->sh_offset
+                  << " shstrtab size=" << shstrtab_builder_.GetSection()->sh_size;
     }
 
     // The section list comes after come after.
     Elf_Word sections_offset = RoundUp(
-        shstrtab_builder_.section_.sh_offset + shstrtab_builder_.section_.sh_size,
+        shstrtab_builder_.GetSection()->sh_offset + shstrtab_builder_.GetSection()->sh_size,
         sizeof(Elf_Word));
 
     // Setup the actual symbol arrays.
     std::vector<Elf_Sym> dynsym = dynsym_builder_.GenerateSymtab();
-    CHECK_EQ(dynsym.size() * sizeof(Elf_Sym), dynsym_builder_.section_.sh_size);
+    CHECK_EQ(dynsym.size() * sizeof(Elf_Sym), dynsym_builder_.GetSection()->sh_size);
     std::vector<Elf_Sym> symtab;
     if (IncludingDebugSymbols()) {
       symtab = symtab_builder_.GenerateSymtab();
-      CHECK_EQ(symtab.size() * sizeof(Elf_Sym), symtab_builder_.section_.sh_size);
+      CHECK_EQ(symtab.size() * sizeof(Elf_Sym), symtab_builder_.GetSection()->sh_size);
     }
 
     // Setup the dynamic section.
@@ -901,43 +969,44 @@ class ElfBuilder FINAL {
     // and the soname_offset.
     std::vector<Elf_Dyn> dynamic = dynamic_builder_.GetDynamics(dynstr_.size(),
                                                                   dynstr_soname_offset_);
-    CHECK_EQ(dynamic.size() * sizeof(Elf_Dyn), dynamic_builder_.section_.sh_size);
+    CHECK_EQ(dynamic.size() * sizeof(Elf_Dyn), dynamic_builder_.GetSection()->sh_size);
 
     // Finish setup of the program headers now that we know the layout of the
     // whole file.
-    Elf_Word load_r_size = rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size;
+    Elf_Word load_r_size =
+        rodata_builder_.GetSection()->sh_offset + rodata_builder_.GetSection()->sh_size;
     program_headers_[PH_LOAD_R__].p_filesz = load_r_size;
     program_headers_[PH_LOAD_R__].p_memsz =  load_r_size;
-    program_headers_[PH_LOAD_R__].p_align =  rodata_builder_.section_.sh_addralign;
+    program_headers_[PH_LOAD_R__].p_align =  rodata_builder_.GetSection()->sh_addralign;
 
-    Elf_Word load_rx_size = text_builder_.section_.sh_size;
-    program_headers_[PH_LOAD_R_X].p_offset = text_builder_.section_.sh_offset;
-    program_headers_[PH_LOAD_R_X].p_vaddr  = text_builder_.section_.sh_offset;
-    program_headers_[PH_LOAD_R_X].p_paddr  = text_builder_.section_.sh_offset;
+    Elf_Word load_rx_size = text_builder_.GetSection()->sh_size;
+    program_headers_[PH_LOAD_R_X].p_offset = text_builder_.GetSection()->sh_offset;
+    program_headers_[PH_LOAD_R_X].p_vaddr  = text_builder_.GetSection()->sh_offset;
+    program_headers_[PH_LOAD_R_X].p_paddr  = text_builder_.GetSection()->sh_offset;
     program_headers_[PH_LOAD_R_X].p_filesz = load_rx_size;
     program_headers_[PH_LOAD_R_X].p_memsz  = load_rx_size;
-    program_headers_[PH_LOAD_R_X].p_align  = text_builder_.section_.sh_addralign;
-
-    program_headers_[PH_LOAD_RW_].p_offset = dynamic_builder_.section_.sh_offset;
-    program_headers_[PH_LOAD_RW_].p_vaddr  = dynamic_builder_.section_.sh_offset;
-    program_headers_[PH_LOAD_RW_].p_paddr  = dynamic_builder_.section_.sh_offset;
-    program_headers_[PH_LOAD_RW_].p_filesz = dynamic_builder_.section_.sh_size;
-    program_headers_[PH_LOAD_RW_].p_memsz  = dynamic_builder_.section_.sh_size;
-    program_headers_[PH_LOAD_RW_].p_align  = dynamic_builder_.section_.sh_addralign;
-
-    program_headers_[PH_DYNAMIC].p_offset = dynamic_builder_.section_.sh_offset;
-    program_headers_[PH_DYNAMIC].p_vaddr  = dynamic_builder_.section_.sh_offset;
-    program_headers_[PH_DYNAMIC].p_paddr  = dynamic_builder_.section_.sh_offset;
-    program_headers_[PH_DYNAMIC].p_filesz = dynamic_builder_.section_.sh_size;
-    program_headers_[PH_DYNAMIC].p_memsz  = dynamic_builder_.section_.sh_size;
-    program_headers_[PH_DYNAMIC].p_align  = dynamic_builder_.section_.sh_addralign;
+    program_headers_[PH_LOAD_R_X].p_align  = text_builder_.GetSection()->sh_addralign;
+
+    program_headers_[PH_LOAD_RW_].p_offset = dynamic_builder_.GetSection()->sh_offset;
+    program_headers_[PH_LOAD_RW_].p_vaddr  = dynamic_builder_.GetSection()->sh_offset;
+    program_headers_[PH_LOAD_RW_].p_paddr  = dynamic_builder_.GetSection()->sh_offset;
+    program_headers_[PH_LOAD_RW_].p_filesz = dynamic_builder_.GetSection()->sh_size;
+    program_headers_[PH_LOAD_RW_].p_memsz  = dynamic_builder_.GetSection()->sh_size;
+    program_headers_[PH_LOAD_RW_].p_align  = dynamic_builder_.GetSection()->sh_addralign;
+
+    program_headers_[PH_DYNAMIC].p_offset = dynamic_builder_.GetSection()->sh_offset;
+    program_headers_[PH_DYNAMIC].p_vaddr  = dynamic_builder_.GetSection()->sh_offset;
+    program_headers_[PH_DYNAMIC].p_paddr  = dynamic_builder_.GetSection()->sh_offset;
+    program_headers_[PH_DYNAMIC].p_filesz = dynamic_builder_.GetSection()->sh_size;
+    program_headers_[PH_DYNAMIC].p_memsz  = dynamic_builder_.GetSection()->sh_size;
+    program_headers_[PH_DYNAMIC].p_align  = dynamic_builder_.GetSection()->sh_addralign;
 
     // Finish setup of the Ehdr values.
     elf_header_.e_phoff = PHDR_OFFSET;
     elf_header_.e_shoff = sections_offset;
     elf_header_.e_phnum = PH_NUM;
     elf_header_.e_shnum = section_ptrs_.size();
-    elf_header_.e_shstrndx = shstrtab_builder_.section_index_;
+    elf_header_.e_shstrndx = shstrtab_builder_.GetSectionIndex();
 
     // Add the rest of the pieces to the list.
     pieces.push_back(new ElfFileMemoryPiece<Elf_Word>("Elf Header", 0, &elf_header_,
@@ -945,33 +1014,33 @@ class ElfBuilder FINAL {
     pieces.push_back(new ElfFileMemoryPiece<Elf_Word>("Program headers", PHDR_OFFSET,
                                                       &program_headers_, sizeof(program_headers_)));
     pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynamic",
-                                                      dynamic_builder_.section_.sh_offset,
+                                                      dynamic_builder_.GetSection()->sh_offset,
                                                       dynamic.data(),
-                                                      dynamic_builder_.section_.sh_size));
-    pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynsym", dynsym_builder_.section_.sh_offset,
+                                                      dynamic_builder_.GetSection()->sh_size));
+    pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynsym", dynsym_builder_.GetSection()->sh_offset,
                                                       dynsym.data(),
                                                       dynsym.size() * sizeof(Elf_Sym)));
     pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynstr",
-                                                    dynsym_builder_.GetStrTab()->section_.sh_offset,
+                                                    dynsym_builder_.GetStrTab()->GetSection()->sh_offset,
                                                     dynstr_.c_str(), dynstr_.size()));
-    pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".hash", hash_builder_.section_.sh_offset,
+    pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".hash", hash_builder_.GetSection()->sh_offset,
                                                       hash_.data(),
                                                       hash_.size() * sizeof(Elf_Word)));
-    pieces.push_back(new ElfFileRodataPiece<Elf_Word>(rodata_builder_.section_.sh_offset,
+    pieces.push_back(new ElfFileRodataPiece<Elf_Word>(rodata_builder_.GetSection()->sh_offset,
                                                       oat_writer_));
-    pieces.push_back(new ElfFileOatTextPiece<Elf_Word>(text_builder_.section_.sh_offset,
+    pieces.push_back(new ElfFileOatTextPiece<Elf_Word>(text_builder_.GetSection()->sh_offset,
                                                        oat_writer_));
     if (IncludingDebugSymbols()) {
       pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".symtab",
-                                                        symtab_builder_.section_.sh_offset,
+                                                        symtab_builder_.GetSection()->sh_offset,
                                                         symtab.data(),
                                                         symtab.size() * sizeof(Elf_Sym)));
       pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".strtab",
-                                                    symtab_builder_.GetStrTab()->section_.sh_offset,
+                                                    symtab_builder_.GetStrTab()->GetSection()->sh_offset,
                                                     strtab.c_str(), strtab.size()));
     }
     pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".shstrtab",
-                                                      shstrtab_builder_.section_.sh_offset,
+                                                      shstrtab_builder_.GetSection()->sh_offset,
                                                       &shstrtab_[0], shstrtab_.size()));
     for (uint32_t i = 0; i < section_ptrs_.size(); ++i) {
       // Just add all the sections in induvidually since they are all over the
@@ -983,7 +1052,7 @@ class ElfBuilder FINAL {
 
     // Postponed debug info.
     for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) {
-      pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(it->name_, it->section_.sh_offset,
+      pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(it->GetName(), it->GetSection()->sh_offset,
                                                         it->GetBuffer()->data(),
                                                         it->GetBuffer()->size()));
     }
@@ -1006,47 +1075,6 @@ class ElfBuilder FINAL {
   }
 
  private:
-  CodeOutput* oat_writer_;
-  File* elf_file_;
-  const bool add_symbols_;
-  const bool debug_logging_;
-
-  bool fatal_error_ = false;
-
-  // What phdr is.
-  static const uint32_t PHDR_OFFSET = sizeof(Elf_Ehdr);
-  enum : uint8_t {
-    PH_PHDR     = 0,
-        PH_LOAD_R__ = 1,
-        PH_LOAD_R_X = 2,
-        PH_LOAD_RW_ = 3,
-        PH_DYNAMIC  = 4,
-        PH_NUM      = 5,
-  };
-  static const uint32_t PHDR_SIZE = sizeof(Elf_Phdr) * PH_NUM;
-  Elf_Phdr program_headers_[PH_NUM];
-
-  Elf_Ehdr elf_header_;
-
-  Elf_Shdr null_hdr_;
-  std::string shstrtab_;
-  uint32_t section_index_;
-  std::string dynstr_;
-  uint32_t dynstr_soname_offset_;
-  std::vector<Elf_Shdr*> section_ptrs_;
-  std::vector<Elf_Word> hash_;
-
- public:
-  ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> text_builder_;
-  ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> rodata_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_;
-
- private:
   void SetISA(InstructionSet isa) {
     switch (isa) {
       case kArm:
@@ -1141,14 +1169,14 @@ class ElfBuilder FINAL {
                               true, 4, STB_GLOBAL, STT_OBJECT);
   }
 
-  void AssignSectionStr(ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *builder,
+  void AssignSectionStr(ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>builder,
                         std::string* strtab) {
-    builder->section_.sh_name = strtab->size();
-    *strtab += builder->name_;
+    builder->GetSection()->sh_name = strtab->size();
+    *strtab += builder->GetName();
     *strtab += '\0';
     if (debug_logging_) {
-      LOG(INFO) << "adding section name \"" << builder->name_ << "\" "
-                << "to shstrtab at offset " << builder->section_.sh_name;
+      LOG(INFO) << "adding section name \"" << builder->GetName() << "\" "
+                << "to shstrtab at offset " << builder->GetSection()->sh_name;
     }
   }
 
@@ -1163,7 +1191,51 @@ class ElfBuilder FINAL {
     return true;
   }
 
-  bool IncludingDebugSymbols() { return add_symbols_ && symtab_builder_.GetSize() > 1; }
+  bool IncludingDebugSymbols() const {
+    return add_symbols_ && symtab_builder_.GetSize() > 1;
+  }
+
+  CodeOutput* const oat_writer_;
+  File* const elf_file_;
+  const bool add_symbols_;
+  const bool debug_logging_;
+
+  bool fatal_error_ = false;
+
+  // What phdr is.
+  static const uint32_t PHDR_OFFSET = sizeof(Elf_Ehdr);
+  enum : uint8_t {
+    PH_PHDR     = 0,
+        PH_LOAD_R__ = 1,
+        PH_LOAD_R_X = 2,
+        PH_LOAD_RW_ = 3,
+        PH_DYNAMIC  = 4,
+        PH_NUM      = 5,
+  };
+  static const uint32_t PHDR_SIZE = sizeof(Elf_Phdr) * PH_NUM;
+  Elf_Phdr program_headers_[PH_NUM];
+
+  Elf_Ehdr elf_header_;
+
+  Elf_Shdr null_hdr_;
+  std::string shstrtab_;
+  // The index of the current section being built. The first being 1.
+  uint32_t section_index_;
+  std::string dynstr_;
+  uint32_t dynstr_soname_offset_;
+  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_;
+  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_;
+
+  DISALLOW_COPY_AND_ASSIGN(ElfBuilder);
 };
 
 }  // namespace art
index f017641..7705b9c 100644 (file)
@@ -82,7 +82,7 @@ bool ElfWriterMclinker::Write(OatWriter* oat_writer,
   }
 
   // Fill oat_contents.
-  VectorOutputStream output_stream("oat contents", oat_contents);
+  VectorOutputStream output_stream("oat contents", &oat_contents);
   oat_writer->SetOatDataOffset(oat_section->offset());
   CHECK(oat_writer->Write(&output_stream));
   CHECK_EQ(oat_writer->GetSize(), oat_contents.size());
index e661324..c75d8f8 100644 (file)
@@ -195,7 +195,7 @@ std::vector<uint8_t>* ConstructCIEFrame(InstructionSet isa) {
   }
 }
 
-class OatWriterWrapper : public CodeOutput {
+class OatWriterWrapper FINAL : public CodeOutput {
  public:
   explicit OatWriterWrapper(OatWriter* oat_writer) : oat_writer_(oat_writer) {}
 
@@ -206,7 +206,7 @@ class OatWriterWrapper : public CodeOutput {
     return oat_writer_->Write(out);
   }
  private:
-  OatWriter* oat_writer_;
+  OatWriter* const oat_writer_;
 };
 
 template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
@@ -676,14 +676,14 @@ static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
   std::unique_ptr<std::vector<uint8_t>> cfi_info(
       ConstructCIEFrame(compiler_driver->GetInstructionSet()));
 
-  Elf_Addr text_section_address = builder->text_builder_.section_.sh_addr;
+  Elf_Addr text_section_address = builder->GetTextBuilder().GetSection()->sh_addr;
 
   // Iterate over the compiled methods.
   const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
-  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr,
-                   Elf_Sym, Elf_Shdr>* symtab = &builder->symtab_builder_;
+  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab =
+      builder->GetSymtabBuilder();
   for (auto it = method_info.begin(); it != method_info.end(); ++it) {
-    symtab->AddSymbol(it->method_name_, &builder->text_builder_, it->low_pc_, true,
+    symtab->AddSymbol(it->method_name_, &builder->GetTextBuilder(), it->low_pc_, true,
                       it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
 
     // Include CFI for compiled method, if possible.
index 76b00fe..9dfbd7f 100644 (file)
@@ -23,7 +23,7 @@
 
 namespace art {
 
-class FileOutputStream : public OutputStream {
+class FileOutputStream FINAL : public OutputStream {
  public:
   explicit FileOutputStream(File* file);
 
index 7d7b188..e68cdb0 100644 (file)
@@ -22,7 +22,7 @@
 #include "driver/compiler_driver.h"
 #include "driver/dex_compilation_unit.h"
 #include "primitive.h"
-#include "utils/allocation.h"
+#include "utils/arena_object.h"
 #include "utils/growable_array.h"
 #include "nodes.h"
 
index 6e2c6fd..f17ba3b 100644 (file)
@@ -17,7 +17,7 @@
 #ifndef ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_
 #define ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_
 
-#include "utils/allocation.h"
+#include "base/value_object.h"
 
 namespace art {
 
index 5f85b6a..e6b55c7 100644 (file)
@@ -19,7 +19,8 @@
 
 #include "base/bit_field.h"
 #include "base/bit_vector.h"
-#include "utils/allocation.h"
+#include "base/value_object.h"
+#include "utils/arena_object.h"
 #include "utils/growable_array.h"
 #include "utils/managed_register.h"
 
index fc5b06d..2010e7e 100644 (file)
@@ -20,7 +20,7 @@
 #include "locations.h"
 #include "offsets.h"
 #include "primitive.h"
-#include "utils/allocation.h"
+#include "utils/arena_object.h"
 #include "utils/arena_bit_vector.h"
 #include "utils/growable_array.h"
 
index fcc1de6..309425e 100644 (file)
@@ -17,7 +17,7 @@
 #ifndef ART_COMPILER_OPTIMIZING_PARALLEL_MOVE_RESOLVER_H_
 #define ART_COMPILER_OPTIMIZING_PARALLEL_MOVE_RESOLVER_H_
 
-#include "utils/allocation.h"
+#include "base/value_object.h"
 #include "utils/growable_array.h"
 
 namespace art {
index 0ea11ad..5f74c33 100644 (file)
@@ -18,9 +18,9 @@
 #define ART_COMPILER_OPTIMIZING_STACK_MAP_STREAM_H_
 
 #include "base/bit_vector.h"
+#include "base/value_object.h"
 #include "memory_region.h"
 #include "stack_map.h"
-#include "utils/allocation.h"
 #include "utils/growable_array.h"
 
 namespace art {
index 315ca09..bba9892 100644 (file)
@@ -90,7 +90,7 @@ TEST_F(OutputStreamTest, Buffered) {
 
 TEST_F(OutputStreamTest, Vector) {
   std::vector<uint8_t> output;
-  VectorOutputStream output_stream("test vector output", output);
+  VectorOutputStream output_stream("test vector output", &output);
   SetOutputStream(output_stream);
   GenerateTestOutput();
   CheckTestOutput(output);
similarity index 75%
rename from compiler/utils/allocation.h
rename to compiler/utils/arena_object.h
index b0947ca..50909f7 100644 (file)
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ART_COMPILER_UTILS_ALLOCATION_H_
-#define ART_COMPILER_UTILS_ALLOCATION_H_
+#ifndef ART_COMPILER_UTILS_ARENA_OBJECT_H_
+#define ART_COMPILER_UTILS_ARENA_OBJECT_H_
 
 #include "arena_allocator.h"
 #include "base/logging.h"
@@ -34,17 +34,6 @@ class ArenaObject {
   }
 };
 
-class ValueObject {
- public:
-  void* operator new(size_t size) {
-    LOG(FATAL) << "UNREACHABLE";
-    abort();
-  }
-  void operator delete(void*, size_t) {
-    LOG(FATAL) << "UNREACHABLE";
-  }
-};
-
 }  // namespace art
 
-#endif  // ART_COMPILER_UTILS_ALLOCATION_H_
+#endif  // ART_COMPILER_UTILS_ARENA_OBJECT_H_
index e5ff729..3d33673 100644 (file)
@@ -20,8 +20,8 @@
 
 namespace art {
 
-VectorOutputStream::VectorOutputStream(const std::string& location, std::vector<uint8_t>& vector)
-  : OutputStream(location), offset_(vector.size()), vector_(vector) {}
+VectorOutputStream::VectorOutputStream(const std::string& location, std::vector<uint8_t>* vector)
+  : OutputStream(location), offset_(vector->size()), vector_(vector) {}
 
 off_t VectorOutputStream::Seek(off_t offset, Whence whence) {
   CHECK(whence == kSeekSet || whence == kSeekCurrent || whence == kSeekEnd) << whence;
@@ -36,7 +36,7 @@ off_t VectorOutputStream::Seek(off_t offset, Whence whence) {
       break;
     }
     case kSeekEnd: {
-      new_offset = vector_.size() + offset;
+      new_offset = vector_->size() + offset;
       break;
     }
   }
index 09daa12..3c5877c 100644 (file)
 
 namespace art {
 
-class VectorOutputStream : public OutputStream {
+class VectorOutputStream FINAL : public OutputStream {
  public:
-  VectorOutputStream(const std::string& location, std::vector<uint8_t>& vector);
+  VectorOutputStream(const std::string& location, std::vector<uint8_t>* vector);
 
   virtual ~VectorOutputStream() {}
 
   bool WriteFully(const void* buffer, size_t byte_count) {
-    if (static_cast<size_t>(offset_) == vector_.size()) {
+    if (static_cast<size_t>(offset_) == vector_->size()) {
       const uint8_t* start = reinterpret_cast<const uint8_t*>(buffer);
-      vector_.insert(vector_.end(), &start[0], &start[byte_count]);
+      vector_->insert(vector_->end(), &start[0], &start[byte_count]);
       offset_ += byte_count;
     } else {
       off_t new_offset = offset_ + byte_count;
       EnsureCapacity(new_offset);
-      memcpy(&vector_[offset_], buffer, byte_count);
+      memcpy(&(*vector_)[offset_], buffer, byte_count);
       offset_ = new_offset;
     }
     return true;
@@ -49,13 +49,13 @@ class VectorOutputStream : public OutputStream {
 
  private:
   void EnsureCapacity(off_t new_offset) {
-    if (new_offset > static_cast<off_t>(vector_.size())) {
-      vector_.resize(new_offset);
+    if (new_offset > static_cast<off_t>(vector_->size())) {
+      vector_->resize(new_offset);
     }
   }
 
   off_t offset_;
-  std::vector<uint8_t>& vector_;
+  std::vector<uint8_t>* const vector_;
 
   DISALLOW_COPY_AND_ASSIGN(VectorOutputStream);
 };
index d5e766f..51b7a98 100644 (file)
@@ -120,10 +120,12 @@ const char* image_roots_descriptions_[] = {
   "kClassRoots",
 };
 
-class OatSymbolizer : public CodeOutput {
+class OatSymbolizer FINAL : public CodeOutput {
  public:
-  explicit OatSymbolizer(const OatFile* oat_file, std::string& output_name) :
-      oat_file_(oat_file), builder_(nullptr), elf_output_(nullptr), output_name_(output_name) {}
+  explicit OatSymbolizer(const OatFile* oat_file, const std::string& output_name) :
+      oat_file_(oat_file), builder_(nullptr), elf_output_(nullptr),
+      output_name_(output_name.empty() ? "symbolized.oat" : output_name) {
+  }
 
   bool Init() {
     Elf32_Word oat_data_size = oat_file_->GetOatHeader().GetExecutableOffset();
@@ -131,9 +133,6 @@ class OatSymbolizer : public CodeOutput {
     uint32_t diff = static_cast<uint32_t>(oat_file_->End() - oat_file_->Begin());
     uint32_t oat_exec_size = diff - oat_data_size;
 
-    if (output_name_.empty()) {
-      output_name_ = "symbolized.oat";
-    }
     elf_output_ = OS::CreateEmptyFile(output_name_.c_str());
 
     builder_.reset(new ElfBuilder<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
@@ -307,11 +306,11 @@ class OatSymbolizer : public CodeOutput {
       }
 
       ElfSymtabBuilder<Elf32_Word, Elf32_Sword, Elf32_Addr,
-      Elf32_Sym, Elf32_Shdr>* symtab = &builder_->symtab_builder_;
+      Elf32_Sym, Elf32_Shdr>* symtab = builder_->GetSymtabBuilder();
 
-      symtab->AddSymbol(pretty_name, &builder_->text_builder_, oat_method.GetCodeOffset() -
-                        oat_file_->GetOatHeader().GetExecutableOffset(), true,
-                        oat_method.GetQuickCodeSize(), STB_GLOBAL, STT_FUNC);
+      symtab->AddSymbol(pretty_name, &builder_->GetTextBuilder(),
+          oat_method.GetCodeOffset() - oat_file_->GetOatHeader().GetExecutableOffset(),
+          true, oat_method.GetQuickCodeSize(), STB_GLOBAL, STT_FUNC);
     }
   }
 
@@ -340,7 +339,7 @@ class OatSymbolizer : public CodeOutput {
                               Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr> > builder_;
   File* elf_output_;
   std::unordered_map<uint32_t, uint32_t> state_;
-  std::string output_name_;
+  const std::string output_name_;
 };
 
 class OatDumperOptions {
diff --git a/runtime/base/value_object.h b/runtime/base/value_object.h
new file mode 100644 (file)
index 0000000..ee0e2a0
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_BASE_VALUE_OBJECT_H_
+#define ART_RUNTIME_BASE_VALUE_OBJECT_H_
+
+#include "base/logging.h"
+
+namespace art {
+
+class ValueObject {
+ public:
+  void* operator new(size_t size) {
+    LOG(FATAL) << "UNREACHABLE";
+    abort();
+  }
+  void operator delete(void*, size_t) {
+    LOG(FATAL) << "UNREACHABLE";
+  }
+};
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_BASE_VALUE_OBJECT_H_