Home | History | Annotate | Download | only in compiler
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "elf_writer_quick.h"
     18 
     19 #include "base/logging.h"
     20 #include "base/stl_util.h"
     21 #include "base/unix_file/fd_file.h"
     22 #include "buffered_output_stream.h"
     23 #include "driver/compiler_driver.h"
     24 #include "dwarf.h"
     25 #include "elf_utils.h"
     26 #include "file_output_stream.h"
     27 #include "globals.h"
     28 #include "oat.h"
     29 #include "oat_writer.h"
     30 #include "utils.h"
     31 
     32 namespace art {
     33 
     34 static constexpr Elf32_Word NextOffset(const Elf32_Shdr& cur, const Elf32_Shdr& prev) {
     35   return RoundUp(prev.sh_size + prev.sh_offset, cur.sh_addralign);
     36 }
     37 
     38 static uint8_t MakeStInfo(uint8_t binding, uint8_t type) {
     39   return ((binding) << 4) + ((type) & 0xf);
     40 }
     41 
     42 class ElfFilePiece {
     43  public:
     44   virtual ~ElfFilePiece() {}
     45 
     46   virtual bool Write(File* elf_file) {
     47     if (static_cast<off_t>(offset_) != lseek(elf_file->Fd(), offset_, SEEK_SET)) {
     48       PLOG(ERROR) << "Failed to seek to " << GetDescription() << " offset " << offset_ << " for "
     49           << elf_file->GetPath();
     50       return false;
     51     }
     52 
     53     return DoActualWrite(elf_file);
     54   }
     55 
     56   static bool Compare(ElfFilePiece* a, ElfFilePiece* b) {
     57     return a->offset_ < b->offset_;
     58   }
     59 
     60  protected:
     61   explicit ElfFilePiece(Elf32_Word offset) : offset_(offset) {}
     62 
     63   virtual std::string GetDescription() = 0;
     64   virtual bool DoActualWrite(File* elf_file) = 0;
     65 
     66   Elf32_Word offset_;
     67 };
     68 
     69 class ElfFileMemoryPiece : public ElfFilePiece {
     70  public:
     71   ElfFileMemoryPiece(const std::string& name, Elf32_Word offset, const void* data, Elf32_Word size)
     72       : ElfFilePiece(offset), dbg_name_(name), data_(data), size_(size) {}
     73 
     74   bool DoActualWrite(File* elf_file) OVERRIDE {
     75     DCHECK(data_ != nullptr || size_ == 0U) << dbg_name_ << " " << size_;
     76 
     77     if (!elf_file->WriteFully(data_, size_)) {
     78       PLOG(ERROR) << "Failed to write " << dbg_name_ << " for " << elf_file->GetPath();
     79       return false;
     80     }
     81 
     82     return true;
     83   }
     84 
     85   std::string GetDescription() OVERRIDE {
     86     return dbg_name_;
     87   }
     88 
     89  private:
     90   const std::string& dbg_name_;
     91   const void *data_;
     92   Elf32_Word size_;
     93 };
     94 
     95 class ElfFileRodataPiece : public ElfFilePiece {
     96  public:
     97   ElfFileRodataPiece(Elf32_Word offset, OatWriter* oat_writer) : ElfFilePiece(offset),
     98       oat_writer_(oat_writer) {}
     99 
    100   bool DoActualWrite(File* elf_file) OVERRIDE {
    101     std::unique_ptr<BufferedOutputStream> output_stream(
    102         new BufferedOutputStream(new FileOutputStream(elf_file)));
    103     if (!oat_writer_->Write(output_stream.get())) {
    104       PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file->GetPath();
    105       return false;
    106     }
    107 
    108     return true;
    109   }
    110 
    111   std::string GetDescription() OVERRIDE {
    112     return ".rodata";
    113   }
    114 
    115  private:
    116   OatWriter* oat_writer_;
    117 };
    118 
    119 class ElfFileOatTextPiece : public ElfFilePiece {
    120  public:
    121   ElfFileOatTextPiece(Elf32_Word offset, OatWriter* oat_writer) : ElfFilePiece(offset),
    122       oat_writer_(oat_writer) {}
    123 
    124   bool DoActualWrite(File* elf_file) OVERRIDE {
    125     // All data is written by the ElfFileRodataPiece right now, as the oat writer writes in one
    126     // piece. This is for future flexibility.
    127     UNUSED(oat_writer_);
    128     return true;
    129   }
    130 
    131   std::string GetDescription() OVERRIDE {
    132     return ".text";
    133   }
    134 
    135  private:
    136   OatWriter* oat_writer_;
    137 };
    138 
    139 static bool WriteOutFile(const std::vector<ElfFilePiece*>& pieces, File* elf_file) {
    140   // TODO It would be nice if this checked for overlap.
    141   for (auto it = pieces.begin(); it != pieces.end(); ++it) {
    142     if (!(*it)->Write(elf_file)) {
    143       return false;
    144     }
    145   }
    146   return true;
    147 }
    148 
    149 bool ElfWriterQuick::ElfBuilder::Write() {
    150   // The basic layout of the elf file. Order may be different in final output.
    151   // +-------------------------+
    152   // | Elf32_Ehdr              |
    153   // +-------------------------+
    154   // | Elf32_Phdr PHDR         |
    155   // | Elf32_Phdr LOAD R       | .dynsym .dynstr .hash .rodata
    156   // | Elf32_Phdr LOAD R X     | .text
    157   // | Elf32_Phdr LOAD RW      | .dynamic
    158   // | Elf32_Phdr DYNAMIC      | .dynamic
    159   // +-------------------------+
    160   // | .dynsym                 |
    161   // | Elf32_Sym  STN_UNDEF    |
    162   // | Elf32_Sym  oatdata      |
    163   // | Elf32_Sym  oatexec      |
    164   // | Elf32_Sym  oatlastword  |
    165   // +-------------------------+
    166   // | .dynstr                 |
    167   // | \0                      |
    168   // | oatdata\0               |
    169   // | oatexec\0               |
    170   // | oatlastword\0           |
    171   // | boot.oat\0              |
    172   // +-------------------------+
    173   // | .hash                   |
    174   // | Elf32_Word nbucket = b  |
    175   // | Elf32_Word nchain  = c  |
    176   // | Elf32_Word bucket[0]    |
    177   // |         ...             |
    178   // | Elf32_Word bucket[b - 1]|
    179   // | Elf32_Word chain[0]     |
    180   // |         ...             |
    181   // | Elf32_Word chain[c - 1] |
    182   // +-------------------------+
    183   // | .rodata                 |
    184   // | oatdata..oatexec-4      |
    185   // +-------------------------+
    186   // | .text                   |
    187   // | oatexec..oatlastword    |
    188   // +-------------------------+
    189   // | .dynamic                |
    190   // | Elf32_Dyn DT_SONAME     |
    191   // | Elf32_Dyn DT_HASH       |
    192   // | Elf32_Dyn DT_SYMTAB     |
    193   // | Elf32_Dyn DT_SYMENT     |
    194   // | Elf32_Dyn DT_STRTAB     |
    195   // | Elf32_Dyn DT_STRSZ      |
    196   // | Elf32_Dyn DT_NULL       |
    197   // +-------------------------+  (Optional)
    198   // | .strtab                 |  (Optional)
    199   // | program symbol names    |  (Optional)
    200   // +-------------------------+  (Optional)
    201   // | .symtab                 |  (Optional)
    202   // | program symbols         |  (Optional)
    203   // +-------------------------+
    204   // | .shstrtab               |
    205   // | \0                      |
    206   // | .dynamic\0              |
    207   // | .dynsym\0               |
    208   // | .dynstr\0               |
    209   // | .hash\0                 |
    210   // | .rodata\0               |
    211   // | .text\0                 |
    212   // | .shstrtab\0             |
    213   // | .symtab\0               |  (Optional)
    214   // | .strtab\0               |  (Optional)
    215   // | .debug_str\0            |  (Optional)
    216   // | .debug_info\0           |  (Optional)
    217   // | .eh_frame\0             |  (Optional)
    218   // | .debug_abbrev\0         |  (Optional)
    219   // +-------------------------+  (Optional)
    220   // | .debug_str              |  (Optional)
    221   // +-------------------------+  (Optional)
    222   // | .debug_info             |  (Optional)
    223   // +-------------------------+  (Optional)
    224   // | .eh_frame               |  (Optional)
    225   // +-------------------------+  (Optional)
    226   // | .debug_abbrev           |  (Optional)
    227   // +-------------------------+
    228   // | Elf32_Shdr NULL         |
    229   // | Elf32_Shdr .dynsym      |
    230   // | Elf32_Shdr .dynstr      |
    231   // | Elf32_Shdr .hash        |
    232   // | Elf32_Shdr .text        |
    233   // | Elf32_Shdr .rodata      |
    234   // | Elf32_Shdr .dynamic     |
    235   // | Elf32_Shdr .shstrtab    |
    236   // | Elf32_Shdr .debug_str   |  (Optional)
    237   // | Elf32_Shdr .debug_info  |  (Optional)
    238   // | Elf32_Shdr .eh_frame    |  (Optional)
    239   // | Elf32_Shdr .debug_abbrev|  (Optional)
    240   // +-------------------------+
    241 
    242 
    243   if (fatal_error_) {
    244     return false;
    245   }
    246   // Step 1. Figure out all the offsets.
    247 
    248   // What phdr is.
    249   uint32_t phdr_offset = sizeof(Elf32_Ehdr);
    250   const uint8_t PH_PHDR     = 0;
    251   const uint8_t PH_LOAD_R__ = 1;
    252   const uint8_t PH_LOAD_R_X = 2;
    253   const uint8_t PH_LOAD_RW_ = 3;
    254   const uint8_t PH_DYNAMIC  = 4;
    255   const uint8_t PH_NUM      = 5;
    256   uint32_t phdr_size = sizeof(Elf32_Phdr) * PH_NUM;
    257   if (debug_logging_) {
    258     LOG(INFO) << "phdr_offset=" << phdr_offset << std::hex << " " << phdr_offset;
    259     LOG(INFO) << "phdr_size=" << phdr_size << std::hex << " " << phdr_size;
    260   }
    261   Elf32_Phdr program_headers[PH_NUM];
    262   memset(&program_headers, 0, sizeof(program_headers));
    263   program_headers[PH_PHDR].p_type    = PT_PHDR;
    264   program_headers[PH_PHDR].p_offset  = phdr_offset;
    265   program_headers[PH_PHDR].p_vaddr   = phdr_offset;
    266   program_headers[PH_PHDR].p_paddr   = phdr_offset;
    267   program_headers[PH_PHDR].p_filesz  = sizeof(program_headers);
    268   program_headers[PH_PHDR].p_memsz   = sizeof(program_headers);
    269   program_headers[PH_PHDR].p_flags   = PF_R;
    270   program_headers[PH_PHDR].p_align   = sizeof(Elf32_Word);
    271 
    272   program_headers[PH_LOAD_R__].p_type    = PT_LOAD;
    273   program_headers[PH_LOAD_R__].p_offset  = 0;
    274   program_headers[PH_LOAD_R__].p_vaddr   = 0;
    275   program_headers[PH_LOAD_R__].p_paddr   = 0;
    276   program_headers[PH_LOAD_R__].p_flags   = PF_R;
    277 
    278   program_headers[PH_LOAD_R_X].p_type    = PT_LOAD;
    279   program_headers[PH_LOAD_R_X].p_flags   = PF_R | PF_X;
    280 
    281   program_headers[PH_LOAD_RW_].p_type    = PT_LOAD;
    282   program_headers[PH_LOAD_RW_].p_flags   = PF_R | PF_W;
    283 
    284   program_headers[PH_DYNAMIC].p_type    = PT_DYNAMIC;
    285   program_headers[PH_DYNAMIC].p_flags   = PF_R | PF_W;
    286 
    287   // Get the dynstr string.
    288   std::string dynstr(dynsym_builder_.GenerateStrtab());
    289 
    290   // Add the SONAME to the dynstr.
    291   uint32_t dynstr_soname_offset = dynstr.size();
    292   std::string file_name(elf_file_->GetPath());
    293   size_t directory_separator_pos = file_name.rfind('/');
    294   if (directory_separator_pos != std::string::npos) {
    295     file_name = file_name.substr(directory_separator_pos + 1);
    296   }
    297   dynstr += file_name;
    298   dynstr += '\0';
    299   if (debug_logging_) {
    300     LOG(INFO) << "dynstr size (bytes)   =" << dynstr.size()
    301               << std::hex << " " << dynstr.size();
    302     LOG(INFO) << "dynsym size (elements)=" << dynsym_builder_.GetSize()
    303               << std::hex << " " << dynsym_builder_.GetSize();
    304   }
    305 
    306   // get the strtab
    307   std::string strtab;
    308   if (IncludingDebugSymbols()) {
    309     strtab = symtab_builder_.GenerateStrtab();
    310     if (debug_logging_) {
    311       LOG(INFO) << "strtab size (bytes)    =" << strtab.size()
    312                 << std::hex << " " << strtab.size();
    313       LOG(INFO) << "symtab size (elements) =" << symtab_builder_.GetSize()
    314                 << std::hex << " " << symtab_builder_.GetSize();
    315     }
    316   }
    317 
    318   // Get the section header string table.
    319   std::vector<Elf32_Shdr*> section_ptrs;
    320   std::string shstrtab;
    321   shstrtab += '\0';
    322 
    323   // Setup sym_undef
    324   Elf32_Shdr null_hdr;
    325   memset(&null_hdr, 0, sizeof(null_hdr));
    326   null_hdr.sh_type = SHT_NULL;
    327   null_hdr.sh_link = SHN_UNDEF;
    328   section_ptrs.push_back(&null_hdr);
    329 
    330   uint32_t section_index = 1;
    331 
    332   // setup .dynsym
    333   section_ptrs.push_back(&dynsym_builder_.section_);
    334   AssignSectionStr(&dynsym_builder_, &shstrtab);
    335   dynsym_builder_.section_index_ = section_index++;
    336 
    337   // Setup .dynstr
    338   section_ptrs.push_back(&dynsym_builder_.strtab_.section_);
    339   AssignSectionStr(&dynsym_builder_.strtab_, &shstrtab);
    340   dynsym_builder_.strtab_.section_index_ = section_index++;
    341 
    342   // Setup .hash
    343   section_ptrs.push_back(&hash_builder_.section_);
    344   AssignSectionStr(&hash_builder_, &shstrtab);
    345   hash_builder_.section_index_ = section_index++;
    346 
    347   // Setup .rodata
    348   section_ptrs.push_back(&rodata_builder_.section_);
    349   AssignSectionStr(&rodata_builder_, &shstrtab);
    350   rodata_builder_.section_index_ = section_index++;
    351 
    352   // Setup .text
    353   section_ptrs.push_back(&text_builder_.section_);
    354   AssignSectionStr(&text_builder_, &shstrtab);
    355   text_builder_.section_index_ = section_index++;
    356 
    357   // Setup .dynamic
    358   section_ptrs.push_back(&dynamic_builder_.section_);
    359   AssignSectionStr(&dynamic_builder_, &shstrtab);
    360   dynamic_builder_.section_index_ = section_index++;
    361 
    362   if (IncludingDebugSymbols()) {
    363     // Setup .symtab
    364     section_ptrs.push_back(&symtab_builder_.section_);
    365     AssignSectionStr(&symtab_builder_, &shstrtab);
    366     symtab_builder_.section_index_ = section_index++;
    367 
    368     // Setup .strtab
    369     section_ptrs.push_back(&symtab_builder_.strtab_.section_);
    370     AssignSectionStr(&symtab_builder_.strtab_, &shstrtab);
    371     symtab_builder_.strtab_.section_index_ = section_index++;
    372   }
    373   ElfRawSectionBuilder* it = other_builders_.data();
    374   for (uint32_t cnt = 0; cnt < other_builders_.size(); ++it, ++cnt) {
    375     // Setup all the other sections.
    376     section_ptrs.push_back(&it->section_);
    377     AssignSectionStr(it, &shstrtab);
    378     it->section_index_ = section_index++;
    379   }
    380 
    381   // Setup shstrtab
    382   section_ptrs.push_back(&shstrtab_builder_.section_);
    383   AssignSectionStr(&shstrtab_builder_, &shstrtab);
    384   shstrtab_builder_.section_index_ = section_index++;
    385 
    386   if (debug_logging_) {
    387     LOG(INFO) << ".shstrtab size    (bytes)   =" << shstrtab.size()
    388               << std::hex << " " << shstrtab.size();
    389     LOG(INFO) << "section list size (elements)=" << section_ptrs.size()
    390               << std::hex << " " << section_ptrs.size();
    391   }
    392 
    393   // Fill in the hash section.
    394   std::vector<Elf32_Word> hash = dynsym_builder_.GenerateHashContents();
    395 
    396   if (debug_logging_) {
    397     LOG(INFO) << ".hash size (bytes)=" << hash.size() * sizeof(Elf32_Word)
    398               << std::hex << " " << hash.size() * sizeof(Elf32_Word);
    399   }
    400 
    401   Elf32_Word base_offset = sizeof(Elf32_Ehdr) + sizeof(program_headers);
    402   std::vector<ElfFilePiece*> pieces;
    403 
    404   // Get the layout in the sections.
    405   //
    406   // Get the layout of the dynsym section.
    407   dynsym_builder_.section_.sh_offset = RoundUp(base_offset, dynsym_builder_.section_.sh_addralign);
    408   dynsym_builder_.section_.sh_addr = dynsym_builder_.section_.sh_offset;
    409   dynsym_builder_.section_.sh_size = dynsym_builder_.GetSize() * sizeof(Elf32_Sym);
    410   dynsym_builder_.section_.sh_link = dynsym_builder_.GetLink();
    411 
    412   // Get the layout of the dynstr section.
    413   dynsym_builder_.strtab_.section_.sh_offset = NextOffset(dynsym_builder_.strtab_.section_,
    414                                                           dynsym_builder_.section_);
    415   dynsym_builder_.strtab_.section_.sh_addr = dynsym_builder_.strtab_.section_.sh_offset;
    416   dynsym_builder_.strtab_.section_.sh_size = dynstr.size();
    417   dynsym_builder_.strtab_.section_.sh_link = dynsym_builder_.strtab_.GetLink();
    418 
    419   // Get the layout of the hash section
    420   hash_builder_.section_.sh_offset = NextOffset(hash_builder_.section_,
    421                                                 dynsym_builder_.strtab_.section_);
    422   hash_builder_.section_.sh_addr = hash_builder_.section_.sh_offset;
    423   hash_builder_.section_.sh_size = hash.size() * sizeof(Elf32_Word);
    424   hash_builder_.section_.sh_link = hash_builder_.GetLink();
    425 
    426   // Get the layout of the rodata section.
    427   rodata_builder_.section_.sh_offset = NextOffset(rodata_builder_.section_,
    428                                                   hash_builder_.section_);
    429   rodata_builder_.section_.sh_addr = rodata_builder_.section_.sh_offset;
    430   rodata_builder_.section_.sh_size = rodata_builder_.size_;
    431   rodata_builder_.section_.sh_link = rodata_builder_.GetLink();
    432 
    433   // Get the layout of the text section.
    434   text_builder_.section_.sh_offset = NextOffset(text_builder_.section_, rodata_builder_.section_);
    435   text_builder_.section_.sh_addr = text_builder_.section_.sh_offset;
    436   text_builder_.section_.sh_size = text_builder_.size_;
    437   text_builder_.section_.sh_link = text_builder_.GetLink();
    438   CHECK_ALIGNED(rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size, kPageSize);
    439 
    440   // Get the layout of the dynamic section.
    441   dynamic_builder_.section_.sh_offset = NextOffset(dynamic_builder_.section_,
    442                                                    text_builder_.section_);
    443   dynamic_builder_.section_.sh_addr = dynamic_builder_.section_.sh_offset;
    444   dynamic_builder_.section_.sh_size = dynamic_builder_.GetSize() * sizeof(Elf32_Dyn);
    445   dynamic_builder_.section_.sh_link = dynamic_builder_.GetLink();
    446 
    447   Elf32_Shdr prev = dynamic_builder_.section_;
    448   if (IncludingDebugSymbols()) {
    449     // Get the layout of the symtab section.
    450     symtab_builder_.section_.sh_offset = NextOffset(symtab_builder_.section_,
    451                                                     dynamic_builder_.section_);
    452     symtab_builder_.section_.sh_addr = 0;
    453     // Add to leave space for the null symbol.
    454     symtab_builder_.section_.sh_size = symtab_builder_.GetSize() * sizeof(Elf32_Sym);
    455     symtab_builder_.section_.sh_link = symtab_builder_.GetLink();
    456 
    457     // Get the layout of the dynstr section.
    458     symtab_builder_.strtab_.section_.sh_offset = NextOffset(symtab_builder_.strtab_.section_,
    459                                                             symtab_builder_.section_);
    460     symtab_builder_.strtab_.section_.sh_addr = 0;
    461     symtab_builder_.strtab_.section_.sh_size = strtab.size();
    462     symtab_builder_.strtab_.section_.sh_link = symtab_builder_.strtab_.GetLink();
    463 
    464     prev = symtab_builder_.strtab_.section_;
    465   }
    466   if (debug_logging_) {
    467     LOG(INFO) << "dynsym off=" << dynsym_builder_.section_.sh_offset
    468               << " dynsym size=" << dynsym_builder_.section_.sh_size;
    469     LOG(INFO) << "dynstr off=" << dynsym_builder_.strtab_.section_.sh_offset
    470               << " dynstr size=" << dynsym_builder_.strtab_.section_.sh_size;
    471     LOG(INFO) << "hash off=" << hash_builder_.section_.sh_offset
    472               << " hash size=" << hash_builder_.section_.sh_size;
    473     LOG(INFO) << "rodata off=" << rodata_builder_.section_.sh_offset
    474               << " rodata size=" << rodata_builder_.section_.sh_size;
    475     LOG(INFO) << "text off=" << text_builder_.section_.sh_offset
    476               << " text size=" << text_builder_.section_.sh_size;
    477     LOG(INFO) << "dynamic off=" << dynamic_builder_.section_.sh_offset
    478               << " dynamic size=" << dynamic_builder_.section_.sh_size;
    479     if (IncludingDebugSymbols()) {
    480       LOG(INFO) << "symtab off=" << symtab_builder_.section_.sh_offset
    481                 << " symtab size=" << symtab_builder_.section_.sh_size;
    482       LOG(INFO) << "strtab off=" << symtab_builder_.strtab_.section_.sh_offset
    483                 << " strtab size=" << symtab_builder_.strtab_.section_.sh_size;
    484     }
    485   }
    486   // Get the layout of the extra sections. (This will deal with the debug
    487   // sections if they are there)
    488   for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) {
    489     it->section_.sh_offset = NextOffset(it->section_, prev);
    490     it->section_.sh_addr = 0;
    491     it->section_.sh_size = it->GetBuffer()->size();
    492     it->section_.sh_link = it->GetLink();
    493 
    494     // We postpone adding an ElfFilePiece to keep the order in "pieces."
    495 
    496     prev = it->section_;
    497     if (debug_logging_) {
    498       LOG(INFO) << it->name_ << " off=" << it->section_.sh_offset
    499                 << " " << it->name_ << " size=" << it->section_.sh_size;
    500     }
    501   }
    502   // Get the layout of the shstrtab section
    503   shstrtab_builder_.section_.sh_offset = NextOffset(shstrtab_builder_.section_, prev);
    504   shstrtab_builder_.section_.sh_addr = 0;
    505   shstrtab_builder_.section_.sh_size = shstrtab.size();
    506   shstrtab_builder_.section_.sh_link = shstrtab_builder_.GetLink();
    507   if (debug_logging_) {
    508       LOG(INFO) << "shstrtab off=" << shstrtab_builder_.section_.sh_offset
    509                 << " shstrtab size=" << shstrtab_builder_.section_.sh_size;
    510   }
    511 
    512   // The section list comes after come after.
    513   Elf32_Word sections_offset = RoundUp(
    514       shstrtab_builder_.section_.sh_offset + shstrtab_builder_.section_.sh_size,
    515       sizeof(Elf32_Word));
    516 
    517   // Setup the actual symbol arrays.
    518   std::vector<Elf32_Sym> dynsym = dynsym_builder_.GenerateSymtab();
    519   CHECK_EQ(dynsym.size() * sizeof(Elf32_Sym), dynsym_builder_.section_.sh_size);
    520   std::vector<Elf32_Sym> symtab;
    521   if (IncludingDebugSymbols()) {
    522     symtab = symtab_builder_.GenerateSymtab();
    523     CHECK_EQ(symtab.size() * sizeof(Elf32_Sym), symtab_builder_.section_.sh_size);
    524   }
    525 
    526   // Setup the dynamic section.
    527   // This will add the 2 values we cannot know until now time, namely the size
    528   // and the soname_offset.
    529   std::vector<Elf32_Dyn> dynamic = dynamic_builder_.GetDynamics(dynstr.size(),
    530                                                                 dynstr_soname_offset);
    531   CHECK_EQ(dynamic.size() * sizeof(Elf32_Dyn), dynamic_builder_.section_.sh_size);
    532 
    533   // Finish setup of the program headers now that we know the layout of the
    534   // whole file.
    535   Elf32_Word load_r_size = rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size;
    536   program_headers[PH_LOAD_R__].p_filesz = load_r_size;
    537   program_headers[PH_LOAD_R__].p_memsz =  load_r_size;
    538   program_headers[PH_LOAD_R__].p_align =  rodata_builder_.section_.sh_addralign;
    539 
    540   Elf32_Word load_rx_size = text_builder_.section_.sh_size;
    541   program_headers[PH_LOAD_R_X].p_offset = text_builder_.section_.sh_offset;
    542   program_headers[PH_LOAD_R_X].p_vaddr  = text_builder_.section_.sh_offset;
    543   program_headers[PH_LOAD_R_X].p_paddr  = text_builder_.section_.sh_offset;
    544   program_headers[PH_LOAD_R_X].p_filesz = load_rx_size;
    545   program_headers[PH_LOAD_R_X].p_memsz  = load_rx_size;
    546   program_headers[PH_LOAD_R_X].p_align  = text_builder_.section_.sh_addralign;
    547 
    548   program_headers[PH_LOAD_RW_].p_offset = dynamic_builder_.section_.sh_offset;
    549   program_headers[PH_LOAD_RW_].p_vaddr  = dynamic_builder_.section_.sh_offset;
    550   program_headers[PH_LOAD_RW_].p_paddr  = dynamic_builder_.section_.sh_offset;
    551   program_headers[PH_LOAD_RW_].p_filesz = dynamic_builder_.section_.sh_size;
    552   program_headers[PH_LOAD_RW_].p_memsz  = dynamic_builder_.section_.sh_size;
    553   program_headers[PH_LOAD_RW_].p_align  = dynamic_builder_.section_.sh_addralign;
    554 
    555   program_headers[PH_DYNAMIC].p_offset = dynamic_builder_.section_.sh_offset;
    556   program_headers[PH_DYNAMIC].p_vaddr  = dynamic_builder_.section_.sh_offset;
    557   program_headers[PH_DYNAMIC].p_paddr  = dynamic_builder_.section_.sh_offset;
    558   program_headers[PH_DYNAMIC].p_filesz = dynamic_builder_.section_.sh_size;
    559   program_headers[PH_DYNAMIC].p_memsz  = dynamic_builder_.section_.sh_size;
    560   program_headers[PH_DYNAMIC].p_align  = dynamic_builder_.section_.sh_addralign;
    561 
    562   // Finish setup of the Ehdr values.
    563   elf_header_.e_phoff = phdr_offset;
    564   elf_header_.e_shoff = sections_offset;
    565   elf_header_.e_phnum = PH_NUM;
    566   elf_header_.e_shnum = section_ptrs.size();
    567   elf_header_.e_shstrndx = shstrtab_builder_.section_index_;
    568 
    569   // Add the rest of the pieces to the list.
    570   pieces.push_back(new ElfFileMemoryPiece("Elf Header", 0, &elf_header_, sizeof(elf_header_)));
    571   pieces.push_back(new ElfFileMemoryPiece("Program headers", phdr_offset,
    572                                           &program_headers, sizeof(program_headers)));
    573   pieces.push_back(new ElfFileMemoryPiece(".dynamic", dynamic_builder_.section_.sh_offset,
    574                                           dynamic.data(), dynamic_builder_.section_.sh_size));
    575   pieces.push_back(new ElfFileMemoryPiece(".dynsym", dynsym_builder_.section_.sh_offset,
    576                                           dynsym.data(), dynsym.size() * sizeof(Elf32_Sym)));
    577   pieces.push_back(new ElfFileMemoryPiece(".dynstr", dynsym_builder_.strtab_.section_.sh_offset,
    578                                           dynstr.c_str(), dynstr.size()));
    579   pieces.push_back(new ElfFileMemoryPiece(".hash", hash_builder_.section_.sh_offset,
    580                                           hash.data(), hash.size() * sizeof(Elf32_Word)));
    581   pieces.push_back(new ElfFileRodataPiece(rodata_builder_.section_.sh_offset, oat_writer_));
    582   pieces.push_back(new ElfFileOatTextPiece(text_builder_.section_.sh_offset, oat_writer_));
    583   if (IncludingDebugSymbols()) {
    584     pieces.push_back(new ElfFileMemoryPiece(".symtab", symtab_builder_.section_.sh_offset,
    585                                             symtab.data(), symtab.size() * sizeof(Elf32_Sym)));
    586     pieces.push_back(new ElfFileMemoryPiece(".strtab", symtab_builder_.strtab_.section_.sh_offset,
    587                                             strtab.c_str(), strtab.size()));
    588   }
    589   pieces.push_back(new ElfFileMemoryPiece(".shstrtab", shstrtab_builder_.section_.sh_offset,
    590                                           &shstrtab[0], shstrtab.size()));
    591   for (uint32_t i = 0; i < section_ptrs.size(); ++i) {
    592     // Just add all the sections in individually since they are all over the
    593     // place on the heap/stack.
    594     Elf32_Word cur_off = sections_offset + i * sizeof(Elf32_Shdr);
    595     pieces.push_back(new ElfFileMemoryPiece("section table piece", cur_off,
    596                                             section_ptrs[i], sizeof(Elf32_Shdr)));
    597   }
    598 
    599   // Postponed debug info.
    600   for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) {
    601     pieces.push_back(new ElfFileMemoryPiece(it->name_, it->section_.sh_offset,
    602                                             it->GetBuffer()->data(), it->GetBuffer()->size()));
    603   }
    604 
    605   if (!WriteOutFile(pieces, elf_file_)) {
    606     LOG(ERROR) << "Unable to write to file " << elf_file_->GetPath();
    607 
    608     STLDeleteElements(&pieces);  // Have to manually clean pieces.
    609     return false;
    610   }
    611 
    612   STLDeleteElements(&pieces);  // Have to manually clean pieces.
    613   return true;
    614 }
    615 
    616 void ElfWriterQuick::ElfBuilder::SetupDynamic() {
    617   dynamic_builder_.AddDynamicTag(DT_HASH, 0, &hash_builder_);
    618   dynamic_builder_.AddDynamicTag(DT_STRTAB, 0, &dynsym_builder_.strtab_);
    619   dynamic_builder_.AddDynamicTag(DT_SYMTAB, 0, &dynsym_builder_);
    620   dynamic_builder_.AddDynamicTag(DT_SYMENT, sizeof(Elf32_Sym));
    621 }
    622 
    623 void ElfWriterQuick::ElfBuilder::SetupRequiredSymbols() {
    624   dynsym_builder_.AddSymbol("oatdata", &rodata_builder_, 0, true,
    625                             rodata_builder_.size_, STB_GLOBAL, STT_OBJECT);
    626   dynsym_builder_.AddSymbol("oatexec", &text_builder_, 0, true,
    627                             text_builder_.size_, STB_GLOBAL, STT_OBJECT);
    628   dynsym_builder_.AddSymbol("oatlastword", &text_builder_, text_builder_.size_ - 4,
    629                             true, 4, STB_GLOBAL, STT_OBJECT);
    630 }
    631 
    632 void ElfWriterQuick::ElfDynamicBuilder::AddDynamicTag(Elf32_Sword tag, Elf32_Word d_un) {
    633   if (tag == DT_NULL) {
    634     return;
    635   }
    636   dynamics_.push_back({nullptr, tag, d_un});
    637 }
    638 
    639 void ElfWriterQuick::ElfDynamicBuilder::AddDynamicTag(Elf32_Sword tag, Elf32_Word d_un,
    640                                                       ElfSectionBuilder* section) {
    641   if (tag == DT_NULL) {
    642     return;
    643   }
    644   dynamics_.push_back({section, tag, d_un});
    645 }
    646 
    647 std::vector<Elf32_Dyn> ElfWriterQuick::ElfDynamicBuilder::GetDynamics(Elf32_Word strsz,
    648                                                                       Elf32_Word soname) {
    649   std::vector<Elf32_Dyn> ret;
    650   for (auto it = dynamics_.cbegin(); it != dynamics_.cend(); ++it) {
    651     if (it->section_) {
    652       // We are adding an address relative to a section.
    653       ret.push_back(
    654           {it->tag_, {it->off_ + it->section_->section_.sh_addr}});
    655     } else {
    656       ret.push_back({it->tag_, {it->off_}});
    657     }
    658   }
    659   ret.push_back({DT_STRSZ, {strsz}});
    660   ret.push_back({DT_SONAME, {soname}});
    661   ret.push_back({DT_NULL, {0}});
    662   return ret;
    663 }
    664 
    665 std::vector<Elf32_Sym> ElfWriterQuick::ElfSymtabBuilder::GenerateSymtab() {
    666   std::vector<Elf32_Sym> ret;
    667   Elf32_Sym undef_sym;
    668   memset(&undef_sym, 0, sizeof(undef_sym));
    669   undef_sym.st_shndx = SHN_UNDEF;
    670   ret.push_back(undef_sym);
    671 
    672   for (auto it = symbols_.cbegin(); it != symbols_.cend(); ++it) {
    673     Elf32_Sym sym;
    674     memset(&sym, 0, sizeof(sym));
    675     sym.st_name = it->name_idx_;
    676     if (it->is_relative_) {
    677       sym.st_value = it->addr_ + it->section_->section_.sh_offset;
    678     } else {
    679       sym.st_value = it->addr_;
    680     }
    681     sym.st_size = it->size_;
    682     sym.st_other = it->other_;
    683     sym.st_shndx = it->section_->section_index_;
    684     sym.st_info = it->info_;
    685 
    686     ret.push_back(sym);
    687   }
    688   return ret;
    689 }
    690 
    691 std::string ElfWriterQuick::ElfSymtabBuilder::GenerateStrtab() {
    692   std::string tab;
    693   tab += '\0';
    694   for (auto it = symbols_.begin(); it != symbols_.end(); ++it) {
    695     it->name_idx_ = tab.size();
    696     tab += it->name_;
    697     tab += '\0';
    698   }
    699   strtab_.section_.sh_size = tab.size();
    700   return tab;
    701 }
    702 
    703 void ElfWriterQuick::ElfBuilder::AssignSectionStr(
    704     ElfSectionBuilder* builder, std::string* strtab) {
    705   builder->section_.sh_name = strtab->size();
    706   *strtab += builder->name_;
    707   *strtab += '\0';
    708   if (debug_logging_) {
    709     LOG(INFO) << "adding section name \"" << builder->name_ << "\" "
    710               << "to shstrtab at offset " << builder->section_.sh_name;
    711   }
    712 }
    713 
    714 // from bionic
    715 static unsigned elfhash(const char *_name) {
    716   const unsigned char *name = (const unsigned char *) _name;
    717   unsigned h = 0, g;
    718 
    719   while (*name) {
    720     h = (h << 4) + *name++;
    721     g = h & 0xf0000000;
    722     h ^= g;
    723     h ^= g >> 24;
    724   }
    725   return h;
    726 }
    727 
    728 
    729 std::vector<Elf32_Word> ElfWriterQuick::ElfSymtabBuilder::GenerateHashContents() {
    730   // Here is how The ELF hash table works.
    731   // There are 3 arrays to worry about.
    732   // * The symbol table where the symbol information is.
    733   // * The bucket array which is an array of indexes into the symtab and chain.
    734   // * The chain array which is also an array of indexes into the symtab and chain.
    735   //
    736   // Lets say the state is something like this.
    737   // +--------+       +--------+      +-----------+
    738   // | symtab |       | bucket |      |   chain   |
    739   // |  nullptr  |       | 1      |      | STN_UNDEF |
    740   // | <sym1> |       | 4      |      | 2         |
    741   // | <sym2> |       |        |      | 5         |
    742   // | <sym3> |       |        |      | STN_UNDEF |
    743   // | <sym4> |       |        |      | 3         |
    744   // | <sym5> |       |        |      | STN_UNDEF |
    745   // +--------+       +--------+      +-----------+
    746   //
    747   // The lookup process (in python psudocode) is
    748   //
    749   // def GetSym(name):
    750   //     # NB STN_UNDEF == 0
    751   //     indx = bucket[elfhash(name) % num_buckets]
    752   //     while indx != STN_UNDEF:
    753   //         if GetSymbolName(symtab[indx]) == name:
    754   //             return symtab[indx]
    755   //         indx = chain[indx]
    756   //     return SYMBOL_NOT_FOUND
    757   //
    758   // Between bucket and chain arrays every symtab index must be present exactly
    759   // once (except for STN_UNDEF, which must be present 1 + num_bucket times).
    760 
    761   // Select number of buckets.
    762   // This is essentially arbitrary.
    763   Elf32_Word nbuckets;
    764   Elf32_Word chain_size = GetSize();
    765   if (symbols_.size() < 8) {
    766     nbuckets = 2;
    767   } else if (symbols_.size() < 32) {
    768     nbuckets = 4;
    769   } else if (symbols_.size() < 256) {
    770     nbuckets = 16;
    771   } else {
    772     // Have about 32 ids per bucket.
    773     nbuckets = RoundUp(symbols_.size()/32, 2);
    774   }
    775   std::vector<Elf32_Word> hash;
    776   hash.push_back(nbuckets);
    777   hash.push_back(chain_size);
    778   uint32_t bucket_offset = hash.size();
    779   uint32_t chain_offset = bucket_offset + nbuckets;
    780   hash.resize(hash.size() + nbuckets + chain_size, 0);
    781 
    782   Elf32_Word* buckets = hash.data() + bucket_offset;
    783   Elf32_Word* chain   = hash.data() + chain_offset;
    784 
    785   // Set up the actual hash table.
    786   for (Elf32_Word i = 0; i < symbols_.size(); i++) {
    787     // Add 1 since we need to have the null symbol that is not in the symbols
    788     // list.
    789     Elf32_Word index = i + 1;
    790     Elf32_Word hash_val = static_cast<Elf32_Word>(elfhash(symbols_[i].name_.c_str())) % nbuckets;
    791     if (buckets[hash_val] == 0) {
    792       buckets[hash_val] = index;
    793     } else {
    794       hash_val = buckets[hash_val];
    795       CHECK_LT(hash_val, chain_size);
    796       while (chain[hash_val] != 0) {
    797         hash_val = chain[hash_val];
    798         CHECK_LT(hash_val, chain_size);
    799       }
    800       chain[hash_val] = index;
    801       // Check for loops. Works because if this is non-empty then there must be
    802       // another cell which already contains the same symbol index as this one,
    803       // which means some symbol has more then one name, which isn't allowed.
    804       CHECK_EQ(chain[index], static_cast<Elf32_Word>(0));
    805     }
    806   }
    807 
    808   return hash;
    809 }
    810 
    811 void ElfWriterQuick::ElfBuilder::SetupEhdr() {
    812   memset(&elf_header_, 0, sizeof(elf_header_));
    813   elf_header_.e_ident[EI_MAG0]       = ELFMAG0;
    814   elf_header_.e_ident[EI_MAG1]       = ELFMAG1;
    815   elf_header_.e_ident[EI_MAG2]       = ELFMAG2;
    816   elf_header_.e_ident[EI_MAG3]       = ELFMAG3;
    817   elf_header_.e_ident[EI_CLASS]      = ELFCLASS32;
    818   elf_header_.e_ident[EI_DATA]       = ELFDATA2LSB;
    819   elf_header_.e_ident[EI_VERSION]    = EV_CURRENT;
    820   elf_header_.e_ident[EI_OSABI]      = ELFOSABI_LINUX;
    821   elf_header_.e_ident[EI_ABIVERSION] = 0;
    822   elf_header_.e_type = ET_DYN;
    823   elf_header_.e_version = 1;
    824   elf_header_.e_entry = 0;
    825   elf_header_.e_ehsize = sizeof(Elf32_Ehdr);
    826   elf_header_.e_phentsize = sizeof(Elf32_Phdr);
    827   elf_header_.e_shentsize = sizeof(Elf32_Shdr);
    828   elf_header_.e_phoff = sizeof(Elf32_Ehdr);
    829 }
    830 
    831 void ElfWriterQuick::ElfBuilder::SetISA(InstructionSet isa) {
    832   switch (isa) {
    833     case kArm:
    834       // Fall through.
    835     case kThumb2: {
    836       elf_header_.e_machine = EM_ARM;
    837       elf_header_.e_flags = EF_ARM_EABI_VER5;
    838       break;
    839     }
    840     case kArm64: {
    841       elf_header_.e_machine = EM_AARCH64;
    842       elf_header_.e_flags = 0;
    843       break;
    844     }
    845     case kX86: {
    846       elf_header_.e_machine = EM_386;
    847       elf_header_.e_flags = 0;
    848       break;
    849     }
    850     case kX86_64: {
    851       elf_header_.e_machine = EM_X86_64;
    852       elf_header_.e_flags = 0;
    853       break;
    854     }
    855     case kMips: {
    856       elf_header_.e_machine = EM_MIPS;
    857       elf_header_.e_flags = (EF_MIPS_NOREORDER |
    858                              EF_MIPS_PIC       |
    859                              EF_MIPS_CPIC      |
    860                              EF_MIPS_ABI_O32   |
    861                              EF_MIPS_ARCH_32R2);
    862       break;
    863     }
    864     default: {
    865       fatal_error_ = true;
    866       LOG(FATAL) << "Unknown instruction set: " << isa;
    867       break;
    868     }
    869   }
    870 }
    871 
    872 void ElfWriterQuick::ElfSymtabBuilder::AddSymbol(
    873     const std::string& name, const ElfSectionBuilder* section, Elf32_Addr addr,
    874     bool is_relative, Elf32_Word size, uint8_t binding, uint8_t type, uint8_t other) {
    875   CHECK(section);
    876   ElfSymtabBuilder::ElfSymbolState state {name, section, addr, size, is_relative,
    877                                           MakeStInfo(binding, type), other, 0};
    878   symbols_.push_back(state);
    879 }
    880 
    881 bool ElfWriterQuick::Create(File* elf_file,
    882                             OatWriter* oat_writer,
    883                             const std::vector<const DexFile*>& dex_files,
    884                             const std::string& android_root,
    885                             bool is_host,
    886                             const CompilerDriver& driver) {
    887   ElfWriterQuick elf_writer(driver, elf_file);
    888   return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
    889 }
    890 
    891 // Add patch information to this section. Each patch is a Elf32_Word that
    892 // identifies an offset from the start of the text section
    893 void ElfWriterQuick::ReservePatchSpace(std::vector<uint8_t>* buffer, bool debug) {
    894   const size_t size =
    895       compiler_driver_->GetCodeToPatch().size() +
    896       compiler_driver_->GetMethodsToPatch().size() +
    897       compiler_driver_->GetClassesToPatch().size() +
    898       compiler_driver_->GetStringsToPatch().size();
    899   if (size == 0) {
    900     if (debug) {
    901       LOG(INFO) << "No patches to record";
    902     }
    903     return;
    904   }
    905   buffer->resize(size * sizeof(uintptr_t));
    906   if (debug) {
    907     LOG(INFO) << "Patches reserved for " << size;
    908   }
    909 }
    910 
    911 bool ElfWriterQuick::Write(OatWriter* oat_writer,
    912                            const std::vector<const DexFile*>& dex_files_unused,
    913                            const std::string& android_root_unused,
    914                            bool is_host_unused) {
    915   const bool debug = false;
    916   const bool add_symbols = oat_writer->DidAddSymbols();
    917   const OatHeader& oat_header = oat_writer->GetOatHeader();
    918   Elf32_Word oat_data_size = oat_header.GetExecutableOffset();
    919   uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;
    920 
    921   ElfBuilder builder(oat_writer, elf_file_, compiler_driver_->GetInstructionSet(), 0,
    922                      oat_data_size, oat_data_size, oat_exec_size, add_symbols, debug);
    923 
    924   if (add_symbols) {
    925     AddDebugSymbols(builder, oat_writer, debug);
    926   }
    927 
    928   bool generateDebugInformation = compiler_driver_->GetCallFrameInformation() != nullptr;
    929   if (generateDebugInformation) {
    930     ElfRawSectionBuilder debug_info(".debug_info",   SHT_PROGBITS, 0, nullptr, 0, 1, 0);
    931     ElfRawSectionBuilder debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
    932     ElfRawSectionBuilder debug_str(".debug_str",    SHT_PROGBITS, 0, nullptr, 0, 1, 0);
    933     ElfRawSectionBuilder eh_frame(".eh_frame",  SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0);
    934     eh_frame.SetBuffer(*compiler_driver_->GetCallFrameInformation());
    935 
    936     FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
    937                          debug_abbrev.GetBuffer(), debug_str.GetBuffer());
    938     builder.RegisterRawSection(debug_info);
    939     builder.RegisterRawSection(debug_abbrev);
    940     builder.RegisterRawSection(eh_frame);
    941     builder.RegisterRawSection(debug_str);
    942   }
    943 
    944   if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) {
    945     ElfRawSectionBuilder oat_patches(".oat_patches", SHT_OAT_PATCH, 0, NULL, 0,
    946                                      sizeof(size_t), sizeof(size_t));
    947     ReservePatchSpace(oat_patches.GetBuffer(), debug);
    948     builder.RegisterRawSection(oat_patches);
    949   }
    950 
    951   return builder.Write();
    952 }
    953 
    954 void ElfWriterQuick::AddDebugSymbols(ElfBuilder& builder, OatWriter* oat_writer, bool debug) {
    955   const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
    956   ElfSymtabBuilder* symtab = &builder.symtab_builder_;
    957   for (auto it = method_info.begin(); it != method_info.end(); ++it) {
    958     symtab->AddSymbol(it->method_name_, &builder.text_builder_, it->low_pc_, true,
    959                       it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
    960   }
    961 }
    962 
    963 static void UpdateWord(std::vector<uint8_t>*buf, int offset, int data) {
    964   (*buf)[offset+0] = data;
    965   (*buf)[offset+1] = data >> 8;
    966   (*buf)[offset+2] = data >> 16;
    967   (*buf)[offset+3] = data >> 24;
    968 }
    969 
    970 static void PushWord(std::vector<uint8_t>*buf, int data) {
    971   buf->push_back(data & 0xff);
    972   buf->push_back((data >> 8) & 0xff);
    973   buf->push_back((data >> 16) & 0xff);
    974   buf->push_back((data >> 24) & 0xff);
    975 }
    976 
    977 static void PushHalf(std::vector<uint8_t>*buf, int data) {
    978   buf->push_back(data & 0xff);
    979   buf->push_back((data >> 8) & 0xff);
    980 }
    981 
    982 void ElfWriterQuick::FillInCFIInformation(OatWriter* oat_writer,
    983                                           std::vector<uint8_t>* dbg_info,
    984                                           std::vector<uint8_t>* dbg_abbrev,
    985                                           std::vector<uint8_t>* dbg_str) {
    986   // Create the debug_abbrev section with boilerplate information.
    987   // We only care about low_pc and high_pc right now for the compilation
    988   // unit and methods.
    989 
    990   // Tag 1: Compilation unit: DW_TAG_compile_unit.
    991   dbg_abbrev->push_back(1);
    992   dbg_abbrev->push_back(DW_TAG_compile_unit);
    993 
    994   // There are children (the methods).
    995   dbg_abbrev->push_back(DW_CHILDREN_yes);
    996 
    997   // DW_LANG_Java DW_FORM_data1.
    998   dbg_abbrev->push_back(DW_AT_language);
    999   dbg_abbrev->push_back(DW_FORM_data1);
   1000 
   1001   // DW_AT_low_pc DW_FORM_addr.
   1002   dbg_abbrev->push_back(DW_AT_low_pc);
   1003   dbg_abbrev->push_back(DW_FORM_addr);
   1004 
   1005   // DW_AT_high_pc DW_FORM_addr.
   1006   dbg_abbrev->push_back(DW_AT_high_pc);
   1007   dbg_abbrev->push_back(DW_FORM_addr);
   1008 
   1009   // End of DW_TAG_compile_unit.
   1010   PushHalf(dbg_abbrev, 0);
   1011 
   1012   // Tag 2: Compilation unit: DW_TAG_subprogram.
   1013   dbg_abbrev->push_back(2);
   1014   dbg_abbrev->push_back(DW_TAG_subprogram);
   1015 
   1016   // There are no children.
   1017   dbg_abbrev->push_back(DW_CHILDREN_no);
   1018 
   1019   // Name of the method.
   1020   dbg_abbrev->push_back(DW_AT_name);
   1021   dbg_abbrev->push_back(DW_FORM_strp);
   1022 
   1023   // DW_AT_low_pc DW_FORM_addr.
   1024   dbg_abbrev->push_back(DW_AT_low_pc);
   1025   dbg_abbrev->push_back(DW_FORM_addr);
   1026 
   1027   // DW_AT_high_pc DW_FORM_addr.
   1028   dbg_abbrev->push_back(DW_AT_high_pc);
   1029   dbg_abbrev->push_back(DW_FORM_addr);
   1030 
   1031   // End of DW_TAG_subprogram.
   1032   PushHalf(dbg_abbrev, 0);
   1033 
   1034   // Start the debug_info section with the header information
   1035   // 'unit_length' will be filled in later.
   1036   PushWord(dbg_info, 0);
   1037 
   1038   // 'version' - 3.
   1039   PushHalf(dbg_info, 3);
   1040 
   1041   // Offset into .debug_abbrev section (always 0).
   1042   PushWord(dbg_info, 0);
   1043 
   1044   // Address size: 4.
   1045   dbg_info->push_back(4);
   1046 
   1047   // Start the description for the compilation unit.
   1048   // This uses tag 1.
   1049   dbg_info->push_back(1);
   1050 
   1051   // The language is Java.
   1052   dbg_info->push_back(DW_LANG_Java);
   1053 
   1054   // Leave space for low_pc and high_pc.
   1055   int low_pc_offset = dbg_info->size();
   1056   PushWord(dbg_info, 0);
   1057   PushWord(dbg_info, 0);
   1058 
   1059   // Walk through the information in the method table, and enter into dbg_info.
   1060   const std::vector<OatWriter::DebugInfo>& dbg = oat_writer->GetCFIMethodInfo();
   1061   uint32_t low_pc = 0xFFFFFFFFU;
   1062   uint32_t high_pc = 0;
   1063 
   1064   for (uint32_t i = 0; i < dbg.size(); i++) {
   1065     const OatWriter::DebugInfo& info = dbg[i];
   1066     if (info.low_pc_ < low_pc) {
   1067       low_pc = info.low_pc_;
   1068     }
   1069     if (info.high_pc_ > high_pc) {
   1070       high_pc = info.high_pc_;
   1071     }
   1072 
   1073     // Start a new TAG: subroutine (2).
   1074     dbg_info->push_back(2);
   1075 
   1076     // Enter the name into the string table (and NUL terminate).
   1077     uint32_t str_offset = dbg_str->size();
   1078     dbg_str->insert(dbg_str->end(), info.method_name_.begin(), info.method_name_.end());
   1079     dbg_str->push_back('\0');
   1080 
   1081     // Enter name, low_pc, high_pc.
   1082     PushWord(dbg_info, str_offset);
   1083     PushWord(dbg_info, info.low_pc_);
   1084     PushWord(dbg_info, info.high_pc_);
   1085   }
   1086 
   1087   // One byte terminator
   1088   dbg_info->push_back(0);
   1089 
   1090   // We have now walked all the methods.  Fill in lengths and low/high PCs.
   1091   UpdateWord(dbg_info, 0, dbg_info->size() - 4);
   1092   UpdateWord(dbg_info, low_pc_offset, low_pc);
   1093   UpdateWord(dbg_info, low_pc_offset + 4, high_pc);
   1094 }
   1095 
   1096 }  // namespace art
   1097