Home | History | Annotate | Download | only in runtime
      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_file.h"
     18 
     19 #include <inttypes.h>
     20 #include <sys/types.h>
     21 #include <unistd.h>
     22 
     23 #include "arch/instruction_set.h"
     24 #include "base/logging.h"
     25 #include "base/stringprintf.h"
     26 #include "base/stl_util.h"
     27 #include "base/unix_file/fd_file.h"
     28 #include "elf_file_impl.h"
     29 #include "elf_utils.h"
     30 #include "leb128.h"
     31 #include "utils.h"
     32 
     33 namespace art {
     34 
     35 template <typename ElfTypes>
     36 ElfFileImpl<ElfTypes>::ElfFileImpl(File* file, bool writable,
     37                                    bool program_header_only,
     38                                    uint8_t* requested_base)
     39   : file_(file),
     40     writable_(writable),
     41     program_header_only_(program_header_only),
     42     header_(nullptr),
     43     base_address_(nullptr),
     44     program_headers_start_(nullptr),
     45     section_headers_start_(nullptr),
     46     dynamic_program_header_(nullptr),
     47     dynamic_section_start_(nullptr),
     48     symtab_section_start_(nullptr),
     49     dynsym_section_start_(nullptr),
     50     strtab_section_start_(nullptr),
     51     dynstr_section_start_(nullptr),
     52     hash_section_start_(nullptr),
     53     symtab_symbol_table_(nullptr),
     54     dynsym_symbol_table_(nullptr),
     55     requested_base_(requested_base) {
     56   CHECK(file != nullptr);
     57 }
     58 
     59 template <typename ElfTypes>
     60 ElfFileImpl<ElfTypes>* ElfFileImpl<ElfTypes>::Open(File* file,
     61                                                    bool writable,
     62                                                    bool program_header_only,
     63                                                    bool low_4gb,
     64                                                    std::string* error_msg,
     65                                                    uint8_t* requested_base) {
     66   std::unique_ptr<ElfFileImpl<ElfTypes>> elf_file(new ElfFileImpl<ElfTypes>
     67       (file, writable, program_header_only, requested_base));
     68   int prot;
     69   int flags;
     70   if (writable) {
     71     prot = PROT_READ | PROT_WRITE;
     72     flags = MAP_SHARED;
     73   } else {
     74     prot = PROT_READ;
     75     flags = MAP_PRIVATE;
     76   }
     77   if (!elf_file->Setup(prot, flags, low_4gb, error_msg)) {
     78     return nullptr;
     79   }
     80   return elf_file.release();
     81 }
     82 
     83 template <typename ElfTypes>
     84 ElfFileImpl<ElfTypes>* ElfFileImpl<ElfTypes>::Open(File* file,
     85                                                    int prot,
     86                                                    int flags,
     87                                                    bool low_4gb,
     88                                                    std::string* error_msg) {
     89   std::unique_ptr<ElfFileImpl<ElfTypes>> elf_file(new ElfFileImpl<ElfTypes>
     90       (file, (prot & PROT_WRITE) == PROT_WRITE, /*program_header_only*/false,
     91       /*requested_base*/nullptr));
     92   if (!elf_file->Setup(prot, flags, low_4gb, error_msg)) {
     93     return nullptr;
     94   }
     95   return elf_file.release();
     96 }
     97 
     98 template <typename ElfTypes>
     99 bool ElfFileImpl<ElfTypes>::Setup(int prot, int flags, bool low_4gb, std::string* error_msg) {
    100   int64_t temp_file_length = file_->GetLength();
    101   if (temp_file_length < 0) {
    102     errno = -temp_file_length;
    103     *error_msg = StringPrintf("Failed to get length of file: '%s' fd=%d: %s",
    104                               file_->GetPath().c_str(), file_->Fd(), strerror(errno));
    105     return false;
    106   }
    107   size_t file_length = static_cast<size_t>(temp_file_length);
    108   if (file_length < sizeof(Elf_Ehdr)) {
    109     *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF header of "
    110                               "%zd bytes: '%s'", file_length, sizeof(Elf_Ehdr),
    111                               file_->GetPath().c_str());
    112     return false;
    113   }
    114 
    115   if (program_header_only_) {
    116     // first just map ELF header to get program header size information
    117     size_t elf_header_size = sizeof(Elf_Ehdr);
    118     if (!SetMap(MemMap::MapFile(elf_header_size,
    119                                 prot,
    120                                 flags,
    121                                 file_->Fd(),
    122                                 0,
    123                                 low_4gb,
    124                                 file_->GetPath().c_str(),
    125                                 error_msg),
    126                 error_msg)) {
    127       return false;
    128     }
    129     // then remap to cover program header
    130     size_t program_header_size = header_->e_phoff + (header_->e_phentsize * header_->e_phnum);
    131     if (file_length < program_header_size) {
    132       *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF program "
    133                                 "header of %zd bytes: '%s'", file_length,
    134                                 sizeof(Elf_Ehdr), file_->GetPath().c_str());
    135       return false;
    136     }
    137     if (!SetMap(MemMap::MapFile(program_header_size,
    138                                 prot,
    139                                 flags,
    140                                 file_->Fd(),
    141                                 0,
    142                                 low_4gb,
    143                                 file_->GetPath().c_str(),
    144                                 error_msg),
    145                 error_msg)) {
    146       *error_msg = StringPrintf("Failed to map ELF program headers: %s", error_msg->c_str());
    147       return false;
    148     }
    149   } else {
    150     // otherwise map entire file
    151     if (!SetMap(MemMap::MapFile(file_->GetLength(),
    152                                 prot,
    153                                 flags,
    154                                 file_->Fd(),
    155                                 0,
    156                                 low_4gb,
    157                                 file_->GetPath().c_str(),
    158                                 error_msg),
    159                 error_msg)) {
    160       *error_msg = StringPrintf("Failed to map ELF file: %s", error_msg->c_str());
    161       return false;
    162     }
    163   }
    164 
    165   if (program_header_only_) {
    166     program_headers_start_ = Begin() + GetHeader().e_phoff;
    167   } else {
    168     if (!CheckAndSet(GetHeader().e_phoff, "program headers", &program_headers_start_, error_msg)) {
    169       return false;
    170     }
    171 
    172     // Setup section headers.
    173     if (!CheckAndSet(GetHeader().e_shoff, "section headers", &section_headers_start_, error_msg)) {
    174       return false;
    175     }
    176 
    177     // Find shstrtab.
    178     Elf_Shdr* shstrtab_section_header = GetSectionNameStringSection();
    179     if (shstrtab_section_header == nullptr) {
    180       *error_msg = StringPrintf("Failed to find shstrtab section header in ELF file: '%s'",
    181                                 file_->GetPath().c_str());
    182       return false;
    183     }
    184 
    185     // Find .dynamic section info from program header
    186     dynamic_program_header_ = FindProgamHeaderByType(PT_DYNAMIC);
    187     if (dynamic_program_header_ == nullptr) {
    188       *error_msg = StringPrintf("Failed to find PT_DYNAMIC program header in ELF file: '%s'",
    189                                 file_->GetPath().c_str());
    190       return false;
    191     }
    192 
    193     if (!CheckAndSet(GetDynamicProgramHeader().p_offset, "dynamic section",
    194                      reinterpret_cast<uint8_t**>(&dynamic_section_start_), error_msg)) {
    195       return false;
    196     }
    197 
    198     // Find other sections from section headers
    199     for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
    200       Elf_Shdr* section_header = GetSectionHeader(i);
    201       if (section_header == nullptr) {
    202         *error_msg = StringPrintf("Failed to find section header for section %d in ELF file: '%s'",
    203                                   i, file_->GetPath().c_str());
    204         return false;
    205       }
    206       switch (section_header->sh_type) {
    207         case SHT_SYMTAB: {
    208           if (!CheckAndSet(section_header->sh_offset, "symtab",
    209                            reinterpret_cast<uint8_t**>(&symtab_section_start_), error_msg)) {
    210             return false;
    211           }
    212           break;
    213         }
    214         case SHT_DYNSYM: {
    215           if (!CheckAndSet(section_header->sh_offset, "dynsym",
    216                            reinterpret_cast<uint8_t**>(&dynsym_section_start_), error_msg)) {
    217             return false;
    218           }
    219           break;
    220         }
    221         case SHT_STRTAB: {
    222           // TODO: base these off of sh_link from .symtab and .dynsym above
    223           if ((section_header->sh_flags & SHF_ALLOC) != 0) {
    224             // Check that this is named ".dynstr" and ignore otherwise.
    225             const char* header_name = GetString(*shstrtab_section_header, section_header->sh_name);
    226             if (strncmp(".dynstr", header_name, 8) == 0) {
    227               if (!CheckAndSet(section_header->sh_offset, "dynstr",
    228                                reinterpret_cast<uint8_t**>(&dynstr_section_start_), error_msg)) {
    229                 return false;
    230               }
    231             }
    232           } else {
    233             // Check that this is named ".strtab" and ignore otherwise.
    234             const char* header_name = GetString(*shstrtab_section_header, section_header->sh_name);
    235             if (strncmp(".strtab", header_name, 8) == 0) {
    236               if (!CheckAndSet(section_header->sh_offset, "strtab",
    237                                reinterpret_cast<uint8_t**>(&strtab_section_start_), error_msg)) {
    238                 return false;
    239               }
    240             }
    241           }
    242           break;
    243         }
    244         case SHT_DYNAMIC: {
    245           if (reinterpret_cast<uint8_t*>(dynamic_section_start_) !=
    246               Begin() + section_header->sh_offset) {
    247             LOG(WARNING) << "Failed to find matching SHT_DYNAMIC for PT_DYNAMIC in "
    248                          << file_->GetPath() << ": " << std::hex
    249                          << reinterpret_cast<void*>(dynamic_section_start_)
    250                          << " != " << reinterpret_cast<void*>(Begin() + section_header->sh_offset);
    251             return false;
    252           }
    253           break;
    254         }
    255         case SHT_HASH: {
    256           if (!CheckAndSet(section_header->sh_offset, "hash section",
    257                            reinterpret_cast<uint8_t**>(&hash_section_start_), error_msg)) {
    258             return false;
    259           }
    260           break;
    261         }
    262       }
    263     }
    264 
    265     // Check for the existence of some sections.
    266     if (!CheckSectionsExist(error_msg)) {
    267       return false;
    268     }
    269   }
    270 
    271   return true;
    272 }
    273 
    274 template <typename ElfTypes>
    275 ElfFileImpl<ElfTypes>::~ElfFileImpl() {
    276   STLDeleteElements(&segments_);
    277   delete symtab_symbol_table_;
    278   delete dynsym_symbol_table_;
    279 }
    280 
    281 template <typename ElfTypes>
    282 bool ElfFileImpl<ElfTypes>::CheckAndSet(Elf32_Off offset, const char* label,
    283                                         uint8_t** target, std::string* error_msg) {
    284   if (Begin() + offset >= End()) {
    285     *error_msg = StringPrintf("Offset %d is out of range for %s in ELF file: '%s'", offset, label,
    286                               file_->GetPath().c_str());
    287     return false;
    288   }
    289   *target = Begin() + offset;
    290   return true;
    291 }
    292 
    293 template <typename ElfTypes>
    294 bool ElfFileImpl<ElfTypes>::CheckSectionsLinked(const uint8_t* source,
    295                                                 const uint8_t* target) const {
    296   // Only works in whole-program mode, as we need to iterate over the sections.
    297   // Note that we normally can't search by type, as duplicates are allowed for most section types.
    298   if (program_header_only_) {
    299     return true;
    300   }
    301 
    302   Elf_Shdr* source_section = nullptr;
    303   Elf_Word target_index = 0;
    304   bool target_found = false;
    305   for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
    306     Elf_Shdr* section_header = GetSectionHeader(i);
    307 
    308     if (Begin() + section_header->sh_offset == source) {
    309       // Found the source.
    310       source_section = section_header;
    311       if (target_index) {
    312         break;
    313       }
    314     } else if (Begin() + section_header->sh_offset == target) {
    315       target_index = i;
    316       target_found = true;
    317       if (source_section != nullptr) {
    318         break;
    319       }
    320     }
    321   }
    322 
    323   return target_found && source_section != nullptr && source_section->sh_link == target_index;
    324 }
    325 
    326 template <typename ElfTypes>
    327 bool ElfFileImpl<ElfTypes>::CheckSectionsExist(std::string* error_msg) const {
    328   if (!program_header_only_) {
    329     // If in full mode, need section headers.
    330     if (section_headers_start_ == nullptr) {
    331       *error_msg = StringPrintf("No section headers in ELF file: '%s'", file_->GetPath().c_str());
    332       return false;
    333     }
    334   }
    335 
    336   // This is redundant, but defensive.
    337   if (dynamic_program_header_ == nullptr) {
    338     *error_msg = StringPrintf("Failed to find PT_DYNAMIC program header in ELF file: '%s'",
    339                               file_->GetPath().c_str());
    340     return false;
    341   }
    342 
    343   // Need a dynamic section. This is redundant, but defensive.
    344   if (dynamic_section_start_ == nullptr) {
    345     *error_msg = StringPrintf("Failed to find dynamic section in ELF file: '%s'",
    346                               file_->GetPath().c_str());
    347     return false;
    348   }
    349 
    350   // Symtab validation. These is not really a hard failure, as we are currently not using the
    351   // symtab internally, but it's nice to be defensive.
    352   if (symtab_section_start_ != nullptr) {
    353     // When there's a symtab, there should be a strtab.
    354     if (strtab_section_start_ == nullptr) {
    355       *error_msg = StringPrintf("No strtab for symtab in ELF file: '%s'", file_->GetPath().c_str());
    356       return false;
    357     }
    358 
    359     // The symtab should link to the strtab.
    360     if (!CheckSectionsLinked(reinterpret_cast<const uint8_t*>(symtab_section_start_),
    361                              reinterpret_cast<const uint8_t*>(strtab_section_start_))) {
    362       *error_msg = StringPrintf("Symtab is not linked to the strtab in ELF file: '%s'",
    363                                 file_->GetPath().c_str());
    364       return false;
    365     }
    366   }
    367 
    368   // We always need a dynstr & dynsym.
    369   if (dynstr_section_start_ == nullptr) {
    370     *error_msg = StringPrintf("No dynstr in ELF file: '%s'", file_->GetPath().c_str());
    371     return false;
    372   }
    373   if (dynsym_section_start_ == nullptr) {
    374     *error_msg = StringPrintf("No dynsym in ELF file: '%s'", file_->GetPath().c_str());
    375     return false;
    376   }
    377 
    378   // Need a hash section for dynamic symbol lookup.
    379   if (hash_section_start_ == nullptr) {
    380     *error_msg = StringPrintf("Failed to find hash section in ELF file: '%s'",
    381                               file_->GetPath().c_str());
    382     return false;
    383   }
    384 
    385   // And the hash section should be linking to the dynsym.
    386   if (!CheckSectionsLinked(reinterpret_cast<const uint8_t*>(hash_section_start_),
    387                            reinterpret_cast<const uint8_t*>(dynsym_section_start_))) {
    388     *error_msg = StringPrintf("Hash section is not linked to the dynstr in ELF file: '%s'",
    389                               file_->GetPath().c_str());
    390     return false;
    391   }
    392 
    393   // We'd also like to confirm a shstrtab in program_header_only_ mode (else Open() does this for
    394   // us). This is usually the last in an oat file, and a good indicator of whether writing was
    395   // successful (or the process crashed and left garbage).
    396   if (program_header_only_) {
    397     // It might not be mapped, but we can compare against the file size.
    398     int64_t offset = static_cast<int64_t>(GetHeader().e_shoff +
    399                                           (GetHeader().e_shstrndx * GetHeader().e_shentsize));
    400     if (offset >= file_->GetLength()) {
    401       *error_msg = StringPrintf("Shstrtab is not in the mapped ELF file: '%s'",
    402                                 file_->GetPath().c_str());
    403       return false;
    404     }
    405   }
    406 
    407   return true;
    408 }
    409 
    410 template <typename ElfTypes>
    411 bool ElfFileImpl<ElfTypes>::SetMap(MemMap* map, std::string* error_msg) {
    412   if (map == nullptr) {
    413     // MemMap::Open should have already set an error.
    414     DCHECK(!error_msg->empty());
    415     return false;
    416   }
    417   map_.reset(map);
    418   CHECK(map_.get() != nullptr) << file_->GetPath();
    419   CHECK(map_->Begin() != nullptr) << file_->GetPath();
    420 
    421   header_ = reinterpret_cast<Elf_Ehdr*>(map_->Begin());
    422   if ((ELFMAG0 != header_->e_ident[EI_MAG0])
    423       || (ELFMAG1 != header_->e_ident[EI_MAG1])
    424       || (ELFMAG2 != header_->e_ident[EI_MAG2])
    425       || (ELFMAG3 != header_->e_ident[EI_MAG3])) {
    426     *error_msg = StringPrintf("Failed to find ELF magic value %d %d %d %d in %s, found %d %d %d %d",
    427                               ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
    428                               file_->GetPath().c_str(),
    429                               header_->e_ident[EI_MAG0],
    430                               header_->e_ident[EI_MAG1],
    431                               header_->e_ident[EI_MAG2],
    432                               header_->e_ident[EI_MAG3]);
    433     return false;
    434   }
    435   uint8_t elf_class = (sizeof(Elf_Addr) == sizeof(Elf64_Addr)) ? ELFCLASS64 : ELFCLASS32;
    436   if (elf_class != header_->e_ident[EI_CLASS]) {
    437     *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d in %s, found %d",
    438                               elf_class,
    439                               file_->GetPath().c_str(),
    440                               header_->e_ident[EI_CLASS]);
    441     return false;
    442   }
    443   if (ELFDATA2LSB != header_->e_ident[EI_DATA]) {
    444     *error_msg = StringPrintf("Failed to find expected EI_DATA value %d in %s, found %d",
    445                               ELFDATA2LSB,
    446                               file_->GetPath().c_str(),
    447                               header_->e_ident[EI_CLASS]);
    448     return false;
    449   }
    450   if (EV_CURRENT != header_->e_ident[EI_VERSION]) {
    451     *error_msg = StringPrintf("Failed to find expected EI_VERSION value %d in %s, found %d",
    452                               EV_CURRENT,
    453                               file_->GetPath().c_str(),
    454                               header_->e_ident[EI_CLASS]);
    455     return false;
    456   }
    457   if (ET_DYN != header_->e_type) {
    458     *error_msg = StringPrintf("Failed to find expected e_type value %d in %s, found %d",
    459                               ET_DYN,
    460                               file_->GetPath().c_str(),
    461                               header_->e_type);
    462     return false;
    463   }
    464   if (EV_CURRENT != header_->e_version) {
    465     *error_msg = StringPrintf("Failed to find expected e_version value %d in %s, found %d",
    466                               EV_CURRENT,
    467                               file_->GetPath().c_str(),
    468                               header_->e_version);
    469     return false;
    470   }
    471   if (0 != header_->e_entry) {
    472     *error_msg = StringPrintf("Failed to find expected e_entry value %d in %s, found %d",
    473                               0,
    474                               file_->GetPath().c_str(),
    475                               static_cast<int32_t>(header_->e_entry));
    476     return false;
    477   }
    478   if (0 == header_->e_phoff) {
    479     *error_msg = StringPrintf("Failed to find non-zero e_phoff value in %s",
    480                               file_->GetPath().c_str());
    481     return false;
    482   }
    483   if (0 == header_->e_shoff) {
    484     *error_msg = StringPrintf("Failed to find non-zero e_shoff value in %s",
    485                               file_->GetPath().c_str());
    486     return false;
    487   }
    488   if (0 == header_->e_ehsize) {
    489     *error_msg = StringPrintf("Failed to find non-zero e_ehsize value in %s",
    490                               file_->GetPath().c_str());
    491     return false;
    492   }
    493   if (0 == header_->e_phentsize) {
    494     *error_msg = StringPrintf("Failed to find non-zero e_phentsize value in %s",
    495                               file_->GetPath().c_str());
    496     return false;
    497   }
    498   if (0 == header_->e_phnum) {
    499     *error_msg = StringPrintf("Failed to find non-zero e_phnum value in %s",
    500                               file_->GetPath().c_str());
    501     return false;
    502   }
    503   if (0 == header_->e_shentsize) {
    504     *error_msg = StringPrintf("Failed to find non-zero e_shentsize value in %s",
    505                               file_->GetPath().c_str());
    506     return false;
    507   }
    508   if (0 == header_->e_shnum) {
    509     *error_msg = StringPrintf("Failed to find non-zero e_shnum value in %s",
    510                               file_->GetPath().c_str());
    511     return false;
    512   }
    513   if (0 == header_->e_shstrndx) {
    514     *error_msg = StringPrintf("Failed to find non-zero e_shstrndx value in %s",
    515                               file_->GetPath().c_str());
    516     return false;
    517   }
    518   if (header_->e_shstrndx >= header_->e_shnum) {
    519     *error_msg = StringPrintf("Failed to find e_shnum value %d less than %d in %s",
    520                               header_->e_shstrndx,
    521                               header_->e_shnum,
    522                               file_->GetPath().c_str());
    523     return false;
    524   }
    525 
    526   if (!program_header_only_) {
    527     if (header_->e_phoff >= Size()) {
    528       *error_msg = StringPrintf("Failed to find e_phoff value %" PRIu64 " less than %zd in %s",
    529                                 static_cast<uint64_t>(header_->e_phoff),
    530                                 Size(),
    531                                 file_->GetPath().c_str());
    532       return false;
    533     }
    534     if (header_->e_shoff >= Size()) {
    535       *error_msg = StringPrintf("Failed to find e_shoff value %" PRIu64 " less than %zd in %s",
    536                                 static_cast<uint64_t>(header_->e_shoff),
    537                                 Size(),
    538                                 file_->GetPath().c_str());
    539       return false;
    540     }
    541   }
    542   return true;
    543 }
    544 
    545 template <typename ElfTypes>
    546 typename ElfTypes::Ehdr& ElfFileImpl<ElfTypes>::GetHeader() const {
    547   CHECK(header_ != nullptr);  // Header has been checked in SetMap. This is a sanity check.
    548   return *header_;
    549 }
    550 
    551 template <typename ElfTypes>
    552 uint8_t* ElfFileImpl<ElfTypes>::GetProgramHeadersStart() const {
    553   CHECK(program_headers_start_ != nullptr);  // Header has been set in Setup. This is a sanity
    554                                              // check.
    555   return program_headers_start_;
    556 }
    557 
    558 template <typename ElfTypes>
    559 uint8_t* ElfFileImpl<ElfTypes>::GetSectionHeadersStart() const {
    560   CHECK(!program_header_only_);              // Only used in "full" mode.
    561   CHECK(section_headers_start_ != nullptr);  // Is checked in CheckSectionsExist. Sanity check.
    562   return section_headers_start_;
    563 }
    564 
    565 template <typename ElfTypes>
    566 typename ElfTypes::Phdr& ElfFileImpl<ElfTypes>::GetDynamicProgramHeader() const {
    567   CHECK(dynamic_program_header_ != nullptr);  // Is checked in CheckSectionsExist. Sanity check.
    568   return *dynamic_program_header_;
    569 }
    570 
    571 template <typename ElfTypes>
    572 typename ElfTypes::Dyn* ElfFileImpl<ElfTypes>::GetDynamicSectionStart() const {
    573   CHECK(dynamic_section_start_ != nullptr);  // Is checked in CheckSectionsExist. Sanity check.
    574   return dynamic_section_start_;
    575 }
    576 
    577 template <typename ElfTypes>
    578 typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::GetSymbolSectionStart(
    579     Elf_Word section_type) const {
    580   CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
    581   switch (section_type) {
    582     case SHT_SYMTAB: {
    583       return symtab_section_start_;
    584       break;
    585     }
    586     case SHT_DYNSYM: {
    587       return dynsym_section_start_;
    588       break;
    589     }
    590     default: {
    591       LOG(FATAL) << section_type;
    592       return nullptr;
    593     }
    594   }
    595 }
    596 
    597 template <typename ElfTypes>
    598 const char* ElfFileImpl<ElfTypes>::GetStringSectionStart(
    599     Elf_Word section_type) const {
    600   CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
    601   switch (section_type) {
    602     case SHT_SYMTAB: {
    603       return strtab_section_start_;
    604     }
    605     case SHT_DYNSYM: {
    606       return dynstr_section_start_;
    607     }
    608     default: {
    609       LOG(FATAL) << section_type;
    610       return nullptr;
    611     }
    612   }
    613 }
    614 
    615 template <typename ElfTypes>
    616 const char* ElfFileImpl<ElfTypes>::GetString(Elf_Word section_type,
    617                                              Elf_Word i) const {
    618   CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
    619   if (i == 0) {
    620     return nullptr;
    621   }
    622   const char* string_section_start = GetStringSectionStart(section_type);
    623   if (string_section_start == nullptr) {
    624     return nullptr;
    625   }
    626   return string_section_start + i;
    627 }
    628 
    629 // WARNING: The following methods do not check for an error condition (non-existent hash section).
    630 //          It is the caller's job to do this.
    631 
    632 template <typename ElfTypes>
    633 typename ElfTypes::Word* ElfFileImpl<ElfTypes>::GetHashSectionStart() const {
    634   return hash_section_start_;
    635 }
    636 
    637 template <typename ElfTypes>
    638 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashBucketNum() const {
    639   return GetHashSectionStart()[0];
    640 }
    641 
    642 template <typename ElfTypes>
    643 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashChainNum() const {
    644   return GetHashSectionStart()[1];
    645 }
    646 
    647 template <typename ElfTypes>
    648 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashBucket(size_t i, bool* ok) const {
    649   if (i >= GetHashBucketNum()) {
    650     *ok = false;
    651     return 0;
    652   }
    653   *ok = true;
    654   // 0 is nbucket, 1 is nchain
    655   return GetHashSectionStart()[2 + i];
    656 }
    657 
    658 template <typename ElfTypes>
    659 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashChain(size_t i, bool* ok) const {
    660   if (i >= GetHashChainNum()) {
    661     *ok = false;
    662     return 0;
    663   }
    664   *ok = true;
    665   // 0 is nbucket, 1 is nchain, & chains are after buckets
    666   return GetHashSectionStart()[2 + GetHashBucketNum() + i];
    667 }
    668 
    669 template <typename ElfTypes>
    670 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetProgramHeaderNum() const {
    671   return GetHeader().e_phnum;
    672 }
    673 
    674 template <typename ElfTypes>
    675 typename ElfTypes::Phdr* ElfFileImpl<ElfTypes>::GetProgramHeader(Elf_Word i) const {
    676   CHECK_LT(i, GetProgramHeaderNum()) << file_->GetPath();  // Sanity check for caller.
    677   uint8_t* program_header = GetProgramHeadersStart() + (i * GetHeader().e_phentsize);
    678   if (program_header >= End()) {
    679     return nullptr;  // Failure condition.
    680   }
    681   return reinterpret_cast<Elf_Phdr*>(program_header);
    682 }
    683 
    684 template <typename ElfTypes>
    685 typename ElfTypes::Phdr* ElfFileImpl<ElfTypes>::FindProgamHeaderByType(Elf_Word type) const {
    686   for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) {
    687     Elf_Phdr* program_header = GetProgramHeader(i);
    688     if (program_header->p_type == type) {
    689       return program_header;
    690     }
    691   }
    692   return nullptr;
    693 }
    694 
    695 template <typename ElfTypes>
    696 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetSectionHeaderNum() const {
    697   return GetHeader().e_shnum;
    698 }
    699 
    700 template <typename ElfTypes>
    701 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::GetSectionHeader(Elf_Word i) const {
    702   // Can only access arbitrary sections when we have the whole file, not just program header.
    703   // Even if we Load(), it doesn't bring in all the sections.
    704   CHECK(!program_header_only_) << file_->GetPath();
    705   if (i >= GetSectionHeaderNum()) {
    706     return nullptr;  // Failure condition.
    707   }
    708   uint8_t* section_header = GetSectionHeadersStart() + (i * GetHeader().e_shentsize);
    709   if (section_header >= End()) {
    710     return nullptr;  // Failure condition.
    711   }
    712   return reinterpret_cast<Elf_Shdr*>(section_header);
    713 }
    714 
    715 template <typename ElfTypes>
    716 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::FindSectionByType(Elf_Word type) const {
    717   // Can only access arbitrary sections when we have the whole file, not just program header.
    718   // We could change this to switch on known types if they were detected during loading.
    719   CHECK(!program_header_only_) << file_->GetPath();
    720   for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
    721     Elf_Shdr* section_header = GetSectionHeader(i);
    722     if (section_header->sh_type == type) {
    723       return section_header;
    724     }
    725   }
    726   return nullptr;
    727 }
    728 
    729 // from bionic
    730 static unsigned elfhash(const char *_name) {
    731   const unsigned char *name = (const unsigned char *) _name;
    732   unsigned h = 0, g;
    733 
    734   while (*name) {
    735     h = (h << 4) + *name++;
    736     g = h & 0xf0000000;
    737     h ^= g;
    738     h ^= g >> 24;
    739   }
    740   return h;
    741 }
    742 
    743 template <typename ElfTypes>
    744 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::GetSectionNameStringSection() const {
    745   return GetSectionHeader(GetHeader().e_shstrndx);
    746 }
    747 
    748 template <typename ElfTypes>
    749 const uint8_t* ElfFileImpl<ElfTypes>::FindDynamicSymbolAddress(
    750     const std::string& symbol_name) const {
    751   // Check that we have a hash section.
    752   if (GetHashSectionStart() == nullptr) {
    753     return nullptr;  // Failure condition.
    754   }
    755   const Elf_Sym* sym = FindDynamicSymbol(symbol_name);
    756   if (sym != nullptr) {
    757     // TODO: we need to change this to calculate base_address_ in ::Open,
    758     // otherwise it will be wrongly 0 if ::Load has not yet been called.
    759     return base_address_ + sym->st_value;
    760   } else {
    761     return nullptr;
    762   }
    763 }
    764 
    765 // WARNING: Only called from FindDynamicSymbolAddress. Elides check for hash section.
    766 template <typename ElfTypes>
    767 const typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::FindDynamicSymbol(
    768     const std::string& symbol_name) const {
    769   if (GetHashBucketNum() == 0) {
    770     // No dynamic symbols at all.
    771     return nullptr;
    772   }
    773   Elf_Word hash = elfhash(symbol_name.c_str());
    774   Elf_Word bucket_index = hash % GetHashBucketNum();
    775   bool ok;
    776   Elf_Word symbol_and_chain_index = GetHashBucket(bucket_index, &ok);
    777   if (!ok) {
    778     return nullptr;
    779   }
    780   while (symbol_and_chain_index != 0 /* STN_UNDEF */) {
    781     Elf_Sym* symbol = GetSymbol(SHT_DYNSYM, symbol_and_chain_index);
    782     if (symbol == nullptr) {
    783       return nullptr;  // Failure condition.
    784     }
    785     const char* name = GetString(SHT_DYNSYM, symbol->st_name);
    786     if (symbol_name == name) {
    787       return symbol;
    788     }
    789     symbol_and_chain_index = GetHashChain(symbol_and_chain_index, &ok);
    790     if (!ok) {
    791       return nullptr;
    792     }
    793   }
    794   return nullptr;
    795 }
    796 
    797 template <typename ElfTypes>
    798 bool ElfFileImpl<ElfTypes>::IsSymbolSectionType(Elf_Word section_type) {
    799   return ((section_type == SHT_SYMTAB) || (section_type == SHT_DYNSYM));
    800 }
    801 
    802 template <typename ElfTypes>
    803 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetSymbolNum(Elf_Shdr& section_header) const {
    804   CHECK(IsSymbolSectionType(section_header.sh_type))
    805       << file_->GetPath() << " " << section_header.sh_type;
    806   CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath();
    807   return section_header.sh_size / section_header.sh_entsize;
    808 }
    809 
    810 template <typename ElfTypes>
    811 typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::GetSymbol(Elf_Word section_type, Elf_Word i) const {
    812   Elf_Sym* sym_start = GetSymbolSectionStart(section_type);
    813   if (sym_start == nullptr) {
    814     return nullptr;
    815   }
    816   return sym_start + i;
    817 }
    818 
    819 template <typename ElfTypes>
    820 typename ElfFileImpl<ElfTypes>::SymbolTable**
    821 ElfFileImpl<ElfTypes>::GetSymbolTable(Elf_Word section_type) {
    822   CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
    823   switch (section_type) {
    824     case SHT_SYMTAB: {
    825       return &symtab_symbol_table_;
    826     }
    827     case SHT_DYNSYM: {
    828       return &dynsym_symbol_table_;
    829     }
    830     default: {
    831       LOG(FATAL) << section_type;
    832       return nullptr;
    833     }
    834   }
    835 }
    836 
    837 template <typename ElfTypes>
    838 typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::FindSymbolByName(
    839     Elf_Word section_type, const std::string& symbol_name, bool build_map) {
    840   CHECK(!program_header_only_) << file_->GetPath();
    841   CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
    842 
    843   SymbolTable** symbol_table = GetSymbolTable(section_type);
    844   if (*symbol_table != nullptr || build_map) {
    845     if (*symbol_table == nullptr) {
    846       DCHECK(build_map);
    847       *symbol_table = new SymbolTable;
    848       Elf_Shdr* symbol_section = FindSectionByType(section_type);
    849       if (symbol_section == nullptr) {
    850         return nullptr;  // Failure condition.
    851       }
    852       Elf_Shdr* string_section = GetSectionHeader(symbol_section->sh_link);
    853       if (string_section == nullptr) {
    854         return nullptr;  // Failure condition.
    855       }
    856       for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
    857         Elf_Sym* symbol = GetSymbol(section_type, i);
    858         if (symbol == nullptr) {
    859           return nullptr;  // Failure condition.
    860         }
    861         unsigned char type = (sizeof(Elf_Addr) == sizeof(Elf64_Addr))
    862                              ? ELF64_ST_TYPE(symbol->st_info)
    863                              : ELF32_ST_TYPE(symbol->st_info);
    864         if (type == STT_NOTYPE) {
    865           continue;
    866         }
    867         const char* name = GetString(*string_section, symbol->st_name);
    868         if (name == nullptr) {
    869           continue;
    870         }
    871         std::pair<typename SymbolTable::iterator, bool> result =
    872             (*symbol_table)->insert(std::make_pair(name, symbol));
    873         if (!result.second) {
    874           // If a duplicate, make sure it has the same logical value. Seen on x86.
    875           if ((symbol->st_value != result.first->second->st_value) ||
    876               (symbol->st_size != result.first->second->st_size) ||
    877               (symbol->st_info != result.first->second->st_info) ||
    878               (symbol->st_other != result.first->second->st_other) ||
    879               (symbol->st_shndx != result.first->second->st_shndx)) {
    880             return nullptr;  // Failure condition.
    881           }
    882         }
    883       }
    884     }
    885     CHECK(*symbol_table != nullptr);
    886     typename SymbolTable::const_iterator it = (*symbol_table)->find(symbol_name);
    887     if (it == (*symbol_table)->end()) {
    888       return nullptr;
    889     }
    890     return it->second;
    891   }
    892 
    893   // Fall back to linear search
    894   Elf_Shdr* symbol_section = FindSectionByType(section_type);
    895   if (symbol_section == nullptr) {
    896     return nullptr;
    897   }
    898   Elf_Shdr* string_section = GetSectionHeader(symbol_section->sh_link);
    899   if (string_section == nullptr) {
    900     return nullptr;
    901   }
    902   for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
    903     Elf_Sym* symbol = GetSymbol(section_type, i);
    904     if (symbol == nullptr) {
    905       return nullptr;  // Failure condition.
    906     }
    907     const char* name = GetString(*string_section, symbol->st_name);
    908     if (name == nullptr) {
    909       continue;
    910     }
    911     if (symbol_name == name) {
    912       return symbol;
    913     }
    914   }
    915   return nullptr;
    916 }
    917 
    918 template <typename ElfTypes>
    919 typename ElfTypes::Addr ElfFileImpl<ElfTypes>::FindSymbolAddress(
    920     Elf_Word section_type, const std::string& symbol_name, bool build_map) {
    921   Elf_Sym* symbol = FindSymbolByName(section_type, symbol_name, build_map);
    922   if (symbol == nullptr) {
    923     return 0;
    924   }
    925   return symbol->st_value;
    926 }
    927 
    928 template <typename ElfTypes>
    929 const char* ElfFileImpl<ElfTypes>::GetString(Elf_Shdr& string_section,
    930                                              Elf_Word i) const {
    931   CHECK(!program_header_only_) << file_->GetPath();
    932   // TODO: remove this static_cast from enum when using -std=gnu++0x
    933   if (static_cast<Elf_Word>(SHT_STRTAB) != string_section.sh_type) {
    934     return nullptr;  // Failure condition.
    935   }
    936   if (i >= string_section.sh_size) {
    937     return nullptr;
    938   }
    939   if (i == 0) {
    940     return nullptr;
    941   }
    942   uint8_t* strings = Begin() + string_section.sh_offset;
    943   uint8_t* string = strings + i;
    944   if (string >= End()) {
    945     return nullptr;
    946   }
    947   return reinterpret_cast<const char*>(string);
    948 }
    949 
    950 template <typename ElfTypes>
    951 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetDynamicNum() const {
    952   return GetDynamicProgramHeader().p_filesz / sizeof(Elf_Dyn);
    953 }
    954 
    955 template <typename ElfTypes>
    956 typename ElfTypes::Dyn& ElfFileImpl<ElfTypes>::GetDynamic(Elf_Word i) const {
    957   CHECK_LT(i, GetDynamicNum()) << file_->GetPath();
    958   return *(GetDynamicSectionStart() + i);
    959 }
    960 
    961 template <typename ElfTypes>
    962 typename ElfTypes::Dyn* ElfFileImpl<ElfTypes>::FindDynamicByType(Elf_Sword type) const {
    963   for (Elf_Word i = 0; i < GetDynamicNum(); i++) {
    964     Elf_Dyn* dyn = &GetDynamic(i);
    965     if (dyn->d_tag == type) {
    966       return dyn;
    967     }
    968   }
    969   return nullptr;
    970 }
    971 
    972 template <typename ElfTypes>
    973 typename ElfTypes::Word ElfFileImpl<ElfTypes>::FindDynamicValueByType(Elf_Sword type) const {
    974   Elf_Dyn* dyn = FindDynamicByType(type);
    975   if (dyn == nullptr) {
    976     return 0;
    977   } else {
    978     return dyn->d_un.d_val;
    979   }
    980 }
    981 
    982 template <typename ElfTypes>
    983 typename ElfTypes::Rel* ElfFileImpl<ElfTypes>::GetRelSectionStart(Elf_Shdr& section_header) const {
    984   CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
    985   return reinterpret_cast<Elf_Rel*>(Begin() + section_header.sh_offset);
    986 }
    987 
    988 template <typename ElfTypes>
    989 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetRelNum(Elf_Shdr& section_header) const {
    990   CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
    991   CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath();
    992   return section_header.sh_size / section_header.sh_entsize;
    993 }
    994 
    995 template <typename ElfTypes>
    996 typename ElfTypes::Rel& ElfFileImpl<ElfTypes>::GetRel(Elf_Shdr& section_header, Elf_Word i) const {
    997   CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
    998   CHECK_LT(i, GetRelNum(section_header)) << file_->GetPath();
    999   return *(GetRelSectionStart(section_header) + i);
   1000 }
   1001 
   1002 template <typename ElfTypes>
   1003 typename ElfTypes::Rela* ElfFileImpl<ElfTypes>::GetRelaSectionStart(Elf_Shdr& section_header) const {
   1004   CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
   1005   return reinterpret_cast<Elf_Rela*>(Begin() + section_header.sh_offset);
   1006 }
   1007 
   1008 template <typename ElfTypes>
   1009 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetRelaNum(Elf_Shdr& section_header) const {
   1010   CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
   1011   return section_header.sh_size / section_header.sh_entsize;
   1012 }
   1013 
   1014 template <typename ElfTypes>
   1015 typename ElfTypes::Rela& ElfFileImpl<ElfTypes>::GetRela(Elf_Shdr& section_header, Elf_Word i) const {
   1016   CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
   1017   CHECK_LT(i, GetRelaNum(section_header)) << file_->GetPath();
   1018   return *(GetRelaSectionStart(section_header) + i);
   1019 }
   1020 
   1021 // Base on bionic phdr_table_get_load_size
   1022 template <typename ElfTypes>
   1023 bool ElfFileImpl<ElfTypes>::GetLoadedSize(size_t* size, std::string* error_msg) const {
   1024   Elf_Addr min_vaddr = static_cast<Elf_Addr>(-1);
   1025   Elf_Addr max_vaddr = 0u;
   1026   for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) {
   1027     Elf_Phdr* program_header = GetProgramHeader(i);
   1028     if (program_header->p_type != PT_LOAD) {
   1029       continue;
   1030     }
   1031     Elf_Addr begin_vaddr = program_header->p_vaddr;
   1032     if (begin_vaddr < min_vaddr) {
   1033        min_vaddr = begin_vaddr;
   1034     }
   1035     Elf_Addr end_vaddr = program_header->p_vaddr + program_header->p_memsz;
   1036     if (UNLIKELY(begin_vaddr > end_vaddr)) {
   1037       std::ostringstream oss;
   1038       oss << "Program header #" << i << " has overflow in p_vaddr+p_memsz: 0x" << std::hex
   1039           << program_header->p_vaddr << "+0x" << program_header->p_memsz << "=0x" << end_vaddr
   1040           << " in ELF file \"" << file_->GetPath() << "\"";
   1041       *error_msg = oss.str();
   1042       *size = static_cast<size_t>(-1);
   1043       return false;
   1044     }
   1045     if (end_vaddr > max_vaddr) {
   1046       max_vaddr = end_vaddr;
   1047     }
   1048   }
   1049   min_vaddr = RoundDown(min_vaddr, kPageSize);
   1050   max_vaddr = RoundUp(max_vaddr, kPageSize);
   1051   CHECK_LT(min_vaddr, max_vaddr) << file_->GetPath();
   1052   Elf_Addr loaded_size = max_vaddr - min_vaddr;
   1053   // Check that the loaded_size fits in size_t.
   1054   if (UNLIKELY(loaded_size > std::numeric_limits<size_t>::max())) {
   1055     std::ostringstream oss;
   1056     oss << "Loaded size is 0x" << std::hex << loaded_size << " but maximum size_t is 0x"
   1057         << std::numeric_limits<size_t>::max() << " for ELF file \"" << file_->GetPath() << "\"";
   1058     *error_msg = oss.str();
   1059     *size = static_cast<size_t>(-1);
   1060     return false;
   1061   }
   1062   *size = loaded_size;
   1063   return true;
   1064 }
   1065 
   1066 template <typename ElfTypes>
   1067 bool ElfFileImpl<ElfTypes>::Load(bool executable, bool low_4gb, std::string* error_msg) {
   1068   CHECK(program_header_only_) << file_->GetPath();
   1069 
   1070   if (executable) {
   1071     InstructionSet elf_ISA = GetInstructionSetFromELF(GetHeader().e_machine, GetHeader().e_flags);
   1072     if (elf_ISA != kRuntimeISA) {
   1073       std::ostringstream oss;
   1074       oss << "Expected ISA " << kRuntimeISA << " but found " << elf_ISA;
   1075       *error_msg = oss.str();
   1076       return false;
   1077     }
   1078   }
   1079 
   1080   bool reserved = false;
   1081   for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) {
   1082     Elf_Phdr* program_header = GetProgramHeader(i);
   1083     if (program_header == nullptr) {
   1084       *error_msg = StringPrintf("No program header for entry %d in ELF file %s.",
   1085                                 i, file_->GetPath().c_str());
   1086       return false;
   1087     }
   1088 
   1089     // Record .dynamic header information for later use
   1090     if (program_header->p_type == PT_DYNAMIC) {
   1091       dynamic_program_header_ = program_header;
   1092       continue;
   1093     }
   1094 
   1095     // Not something to load, move on.
   1096     if (program_header->p_type != PT_LOAD) {
   1097       continue;
   1098     }
   1099 
   1100     // Found something to load.
   1101 
   1102     // Before load the actual segments, reserve a contiguous chunk
   1103     // of required size and address for all segments, but with no
   1104     // permissions. We'll then carve that up with the proper
   1105     // permissions as we load the actual segments. If p_vaddr is
   1106     // non-zero, the segments require the specific address specified,
   1107     // which either was specified in the file because we already set
   1108     // base_address_ after the first zero segment).
   1109     int64_t temp_file_length = file_->GetLength();
   1110     if (temp_file_length < 0) {
   1111       errno = -temp_file_length;
   1112       *error_msg = StringPrintf("Failed to get length of file: '%s' fd=%d: %s",
   1113                                 file_->GetPath().c_str(), file_->Fd(), strerror(errno));
   1114       return false;
   1115     }
   1116     size_t file_length = static_cast<size_t>(temp_file_length);
   1117     if (!reserved) {
   1118       uint8_t* reserve_base = reinterpret_cast<uint8_t*>(program_header->p_vaddr);
   1119       uint8_t* reserve_base_override = reserve_base;
   1120       // Override the base (e.g. when compiling with --compile-pic)
   1121       if (requested_base_ != nullptr) {
   1122         reserve_base_override = requested_base_;
   1123       }
   1124       std::string reservation_name("ElfFile reservation for ");
   1125       reservation_name += file_->GetPath();
   1126       size_t loaded_size;
   1127       if (!GetLoadedSize(&loaded_size, error_msg)) {
   1128         DCHECK(!error_msg->empty());
   1129         return false;
   1130       }
   1131       std::unique_ptr<MemMap> reserve(MemMap::MapAnonymous(reservation_name.c_str(),
   1132                                                            reserve_base_override,
   1133                                                            loaded_size,
   1134                                                            PROT_NONE,
   1135                                                            low_4gb,
   1136                                                            false,
   1137                                                            error_msg));
   1138       if (reserve.get() == nullptr) {
   1139         *error_msg = StringPrintf("Failed to allocate %s: %s",
   1140                                   reservation_name.c_str(), error_msg->c_str());
   1141         return false;
   1142       }
   1143       reserved = true;
   1144 
   1145       // Base address is the difference of actual mapped location and the p_vaddr
   1146       base_address_ = reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(reserve->Begin())
   1147                        - reinterpret_cast<uintptr_t>(reserve_base));
   1148       // By adding the p_vaddr of a section/symbol to base_address_ we will always get the
   1149       // dynamic memory address of where that object is actually mapped
   1150       //
   1151       // TODO: base_address_ needs to be calculated in ::Open, otherwise
   1152       // FindDynamicSymbolAddress returns the wrong values until Load is called.
   1153       segments_.push_back(reserve.release());
   1154     }
   1155     // empty segment, nothing to map
   1156     if (program_header->p_memsz == 0) {
   1157       continue;
   1158     }
   1159     uint8_t* p_vaddr = base_address_ + program_header->p_vaddr;
   1160     int prot = 0;
   1161     if (executable && ((program_header->p_flags & PF_X) != 0)) {
   1162       prot |= PROT_EXEC;
   1163     }
   1164     if ((program_header->p_flags & PF_W) != 0) {
   1165       prot |= PROT_WRITE;
   1166     }
   1167     if ((program_header->p_flags & PF_R) != 0) {
   1168       prot |= PROT_READ;
   1169     }
   1170     int flags = 0;
   1171     if (writable_) {
   1172       prot |= PROT_WRITE;
   1173       flags |= MAP_SHARED;
   1174     } else {
   1175       flags |= MAP_PRIVATE;
   1176     }
   1177     if (program_header->p_filesz > program_header->p_memsz) {
   1178       *error_msg = StringPrintf("Invalid p_filesz > p_memsz (%" PRIu64 " > %" PRIu64 "): %s",
   1179                                 static_cast<uint64_t>(program_header->p_filesz),
   1180                                 static_cast<uint64_t>(program_header->p_memsz),
   1181                                 file_->GetPath().c_str());
   1182       return false;
   1183     }
   1184     if (program_header->p_filesz < program_header->p_memsz &&
   1185         !IsAligned<kPageSize>(program_header->p_filesz)) {
   1186       *error_msg = StringPrintf("Unsupported unaligned p_filesz < p_memsz (%" PRIu64
   1187                                 " < %" PRIu64 "): %s",
   1188                                 static_cast<uint64_t>(program_header->p_filesz),
   1189                                 static_cast<uint64_t>(program_header->p_memsz),
   1190                                 file_->GetPath().c_str());
   1191       return false;
   1192     }
   1193     if (file_length < (program_header->p_offset + program_header->p_filesz)) {
   1194       *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF segment "
   1195                                 "%d of %" PRIu64 " bytes: '%s'", file_length, i,
   1196                                 static_cast<uint64_t>(program_header->p_offset + program_header->p_filesz),
   1197                                 file_->GetPath().c_str());
   1198       return false;
   1199     }
   1200     if (program_header->p_filesz != 0u) {
   1201       std::unique_ptr<MemMap> segment(
   1202           MemMap::MapFileAtAddress(p_vaddr,
   1203                                    program_header->p_filesz,
   1204                                    prot,
   1205                                    flags,
   1206                                    file_->Fd(),
   1207                                    program_header->p_offset,
   1208                                    /*low4_gb*/false,
   1209                                    /*reuse*/true,  // implies MAP_FIXED
   1210                                    file_->GetPath().c_str(),
   1211                                    error_msg));
   1212       if (segment.get() == nullptr) {
   1213         *error_msg = StringPrintf("Failed to map ELF file segment %d from %s: %s",
   1214                                   i, file_->GetPath().c_str(), error_msg->c_str());
   1215         return false;
   1216       }
   1217       if (segment->Begin() != p_vaddr) {
   1218         *error_msg = StringPrintf("Failed to map ELF file segment %d from %s at expected address %p, "
   1219                                   "instead mapped to %p",
   1220                                   i, file_->GetPath().c_str(), p_vaddr, segment->Begin());
   1221         return false;
   1222       }
   1223       segments_.push_back(segment.release());
   1224     }
   1225     if (program_header->p_filesz < program_header->p_memsz) {
   1226       std::string name = StringPrintf("Zero-initialized segment %" PRIu64 " of ELF file %s",
   1227                                       static_cast<uint64_t>(i), file_->GetPath().c_str());
   1228       std::unique_ptr<MemMap> segment(
   1229           MemMap::MapAnonymous(name.c_str(),
   1230                                p_vaddr + program_header->p_filesz,
   1231                                program_header->p_memsz - program_header->p_filesz,
   1232                                prot, false, true /* reuse */, error_msg));
   1233       if (segment == nullptr) {
   1234         *error_msg = StringPrintf("Failed to map zero-initialized ELF file segment %d from %s: %s",
   1235                                   i, file_->GetPath().c_str(), error_msg->c_str());
   1236         return false;
   1237       }
   1238       if (segment->Begin() != p_vaddr) {
   1239         *error_msg = StringPrintf("Failed to map zero-initialized ELF file segment %d from %s "
   1240                                   "at expected address %p, instead mapped to %p",
   1241                                   i, file_->GetPath().c_str(), p_vaddr, segment->Begin());
   1242         return false;
   1243       }
   1244       segments_.push_back(segment.release());
   1245     }
   1246   }
   1247 
   1248   // Now that we are done loading, .dynamic should be in memory to find .dynstr, .dynsym, .hash
   1249   uint8_t* dsptr = base_address_ + GetDynamicProgramHeader().p_vaddr;
   1250   if ((dsptr < Begin() || dsptr >= End()) && !ValidPointer(dsptr)) {
   1251     *error_msg = StringPrintf("dynamic section address invalid in ELF file %s",
   1252                               file_->GetPath().c_str());
   1253     return false;
   1254   }
   1255   dynamic_section_start_ = reinterpret_cast<Elf_Dyn*>(dsptr);
   1256 
   1257   for (Elf_Word i = 0; i < GetDynamicNum(); i++) {
   1258     Elf_Dyn& elf_dyn = GetDynamic(i);
   1259     uint8_t* d_ptr = base_address_ + elf_dyn.d_un.d_ptr;
   1260     switch (elf_dyn.d_tag) {
   1261       case DT_HASH: {
   1262         if (!ValidPointer(d_ptr)) {
   1263           *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
   1264                                     d_ptr, file_->GetPath().c_str());
   1265           return false;
   1266         }
   1267         hash_section_start_ = reinterpret_cast<Elf_Word*>(d_ptr);
   1268         break;
   1269       }
   1270       case DT_STRTAB: {
   1271         if (!ValidPointer(d_ptr)) {
   1272           *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
   1273                                     d_ptr, file_->GetPath().c_str());
   1274           return false;
   1275         }
   1276         dynstr_section_start_ = reinterpret_cast<char*>(d_ptr);
   1277         break;
   1278       }
   1279       case DT_SYMTAB: {
   1280         if (!ValidPointer(d_ptr)) {
   1281           *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
   1282                                     d_ptr, file_->GetPath().c_str());
   1283           return false;
   1284         }
   1285         dynsym_section_start_ = reinterpret_cast<Elf_Sym*>(d_ptr);
   1286         break;
   1287       }
   1288       case DT_NULL: {
   1289         if (GetDynamicNum() != i+1) {
   1290           *error_msg = StringPrintf("DT_NULL found after %d .dynamic entries, "
   1291                                     "expected %d as implied by size of PT_DYNAMIC segment in %s",
   1292                                     i + 1, GetDynamicNum(), file_->GetPath().c_str());
   1293           return false;
   1294         }
   1295         break;
   1296       }
   1297     }
   1298   }
   1299 
   1300   // Check for the existence of some sections.
   1301   if (!CheckSectionsExist(error_msg)) {
   1302     return false;
   1303   }
   1304 
   1305   return true;
   1306 }
   1307 
   1308 template <typename ElfTypes>
   1309 bool ElfFileImpl<ElfTypes>::ValidPointer(const uint8_t* start) const {
   1310   for (size_t i = 0; i < segments_.size(); ++i) {
   1311     const MemMap* segment = segments_[i];
   1312     if (segment->Begin() <= start && start < segment->End()) {
   1313       return true;
   1314     }
   1315   }
   1316   return false;
   1317 }
   1318 
   1319 
   1320 template <typename ElfTypes>
   1321 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::FindSectionByName(
   1322     const std::string& name) const {
   1323   CHECK(!program_header_only_);
   1324   Elf_Shdr* shstrtab_sec = GetSectionNameStringSection();
   1325   if (shstrtab_sec == nullptr) {
   1326     return nullptr;
   1327   }
   1328   for (uint32_t i = 0; i < GetSectionHeaderNum(); i++) {
   1329     Elf_Shdr* shdr = GetSectionHeader(i);
   1330     if (shdr == nullptr) {
   1331       return nullptr;
   1332     }
   1333     const char* sec_name = GetString(*shstrtab_sec, shdr->sh_name);
   1334     if (sec_name == nullptr) {
   1335       continue;
   1336     }
   1337     if (name == sec_name) {
   1338       return shdr;
   1339     }
   1340   }
   1341   return nullptr;
   1342 }
   1343 
   1344 template <typename ElfTypes>
   1345 bool ElfFileImpl<ElfTypes>::FixupDebugSections(Elf_Addr base_address_delta) {
   1346   if (base_address_delta == 0) {
   1347     return true;
   1348   }
   1349   return ApplyOatPatchesTo(".debug_frame", base_address_delta) &&
   1350          ApplyOatPatchesTo(".debug_info", base_address_delta) &&
   1351          ApplyOatPatchesTo(".debug_line", base_address_delta);
   1352 }
   1353 
   1354 template <typename ElfTypes>
   1355 bool ElfFileImpl<ElfTypes>::ApplyOatPatchesTo(
   1356     const char* target_section_name, Elf_Addr delta) {
   1357   auto target_section = FindSectionByName(target_section_name);
   1358   if (target_section == nullptr) {
   1359     return true;
   1360   }
   1361   std::string patches_name = target_section_name + std::string(".oat_patches");
   1362   auto patches_section = FindSectionByName(patches_name.c_str());
   1363   if (patches_section == nullptr) {
   1364     LOG(ERROR) << patches_name << " section not found.";
   1365     return false;
   1366   }
   1367   if (patches_section->sh_type != SHT_OAT_PATCH) {
   1368     LOG(ERROR) << "Unexpected type of " << patches_name;
   1369     return false;
   1370   }
   1371   ApplyOatPatches(
   1372       Begin() + patches_section->sh_offset,
   1373       Begin() + patches_section->sh_offset + patches_section->sh_size,
   1374       delta,
   1375       Begin() + target_section->sh_offset,
   1376       Begin() + target_section->sh_offset + target_section->sh_size);
   1377   return true;
   1378 }
   1379 
   1380 // Apply LEB128 encoded patches to given section.
   1381 template <typename ElfTypes>
   1382 void ElfFileImpl<ElfTypes>::ApplyOatPatches(
   1383     const uint8_t* patches, const uint8_t* patches_end, Elf_Addr delta,
   1384     uint8_t* to_patch, const uint8_t* to_patch_end) {
   1385   typedef __attribute__((__aligned__(1))) Elf_Addr UnalignedAddress;
   1386   while (patches < patches_end) {
   1387     to_patch += DecodeUnsignedLeb128(&patches);
   1388     DCHECK_LE(patches, patches_end) << "Unexpected end of patch list.";
   1389     DCHECK_LT(to_patch, to_patch_end) << "Patch past the end of section.";
   1390     *reinterpret_cast<UnalignedAddress*>(to_patch) += delta;
   1391   }
   1392 }
   1393 
   1394 template <typename ElfTypes>
   1395 bool ElfFileImpl<ElfTypes>::Strip(std::string* error_msg) {
   1396   // ELF files produced by MCLinker look roughly like this
   1397   //
   1398   // +------------+
   1399   // | Elf_Ehdr   | contains number of Elf_Shdr and offset to first
   1400   // +------------+
   1401   // | Elf_Phdr   | program headers
   1402   // | Elf_Phdr   |
   1403   // | ...        |
   1404   // | Elf_Phdr   |
   1405   // +------------+
   1406   // | section    | mixture of needed and unneeded sections
   1407   // +------------+
   1408   // | section    |
   1409   // +------------+
   1410   // | ...        |
   1411   // +------------+
   1412   // | section    |
   1413   // +------------+
   1414   // | Elf_Shdr   | section headers
   1415   // | Elf_Shdr   |
   1416   // | ...        | contains offset to section start
   1417   // | Elf_Shdr   |
   1418   // +------------+
   1419   //
   1420   // To strip:
   1421   // - leave the Elf_Ehdr and Elf_Phdr values in place.
   1422   // - walk the sections making a new set of Elf_Shdr section headers for what we want to keep
   1423   // - move the sections are keeping up to fill in gaps of sections we want to strip
   1424   // - write new Elf_Shdr section headers to end of file, updating Elf_Ehdr
   1425   // - truncate rest of file
   1426   //
   1427 
   1428   std::vector<Elf_Shdr> section_headers;
   1429   std::vector<Elf_Word> section_headers_original_indexes;
   1430   section_headers.reserve(GetSectionHeaderNum());
   1431 
   1432 
   1433   Elf_Shdr* string_section = GetSectionNameStringSection();
   1434   CHECK(string_section != nullptr);
   1435   for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
   1436     Elf_Shdr* sh = GetSectionHeader(i);
   1437     CHECK(sh != nullptr);
   1438     const char* name = GetString(*string_section, sh->sh_name);
   1439     if (name == nullptr) {
   1440       CHECK_EQ(0U, i);
   1441       section_headers.push_back(*sh);
   1442       section_headers_original_indexes.push_back(0);
   1443       continue;
   1444     }
   1445     if (StartsWith(name, ".debug")
   1446         || (strcmp(name, ".strtab") == 0)
   1447         || (strcmp(name, ".symtab") == 0)) {
   1448       continue;
   1449     }
   1450     section_headers.push_back(*sh);
   1451     section_headers_original_indexes.push_back(i);
   1452   }
   1453   CHECK_NE(0U, section_headers.size());
   1454   CHECK_EQ(section_headers.size(), section_headers_original_indexes.size());
   1455 
   1456   // section 0 is the null section, sections start at offset of first section
   1457   CHECK(GetSectionHeader(1) != nullptr);
   1458   Elf_Off offset = GetSectionHeader(1)->sh_offset;
   1459   for (size_t i = 1; i < section_headers.size(); i++) {
   1460     Elf_Shdr& new_sh = section_headers[i];
   1461     Elf_Shdr* old_sh = GetSectionHeader(section_headers_original_indexes[i]);
   1462     CHECK(old_sh != nullptr);
   1463     CHECK_EQ(new_sh.sh_name, old_sh->sh_name);
   1464     if (old_sh->sh_addralign > 1) {
   1465       offset = RoundUp(offset, old_sh->sh_addralign);
   1466     }
   1467     if (old_sh->sh_offset == offset) {
   1468       // already in place
   1469       offset += old_sh->sh_size;
   1470       continue;
   1471     }
   1472     // shift section earlier
   1473     memmove(Begin() + offset,
   1474             Begin() + old_sh->sh_offset,
   1475             old_sh->sh_size);
   1476     new_sh.sh_offset = offset;
   1477     offset += old_sh->sh_size;
   1478   }
   1479 
   1480   Elf_Off shoff = offset;
   1481   size_t section_headers_size_in_bytes = section_headers.size() * sizeof(Elf_Shdr);
   1482   memcpy(Begin() + offset, &section_headers[0], section_headers_size_in_bytes);
   1483   offset += section_headers_size_in_bytes;
   1484 
   1485   GetHeader().e_shnum = section_headers.size();
   1486   GetHeader().e_shoff = shoff;
   1487   int result = ftruncate(file_->Fd(), offset);
   1488   if (result != 0) {
   1489     *error_msg = StringPrintf("Failed to truncate while stripping ELF file: '%s': %s",
   1490                               file_->GetPath().c_str(), strerror(errno));
   1491     return false;
   1492   }
   1493   return true;
   1494 }
   1495 
   1496 static const bool DEBUG_FIXUP = false;
   1497 
   1498 template <typename ElfTypes>
   1499 bool ElfFileImpl<ElfTypes>::Fixup(Elf_Addr base_address) {
   1500   if (!FixupDynamic(base_address)) {
   1501     LOG(WARNING) << "Failed to fixup .dynamic in " << file_->GetPath();
   1502     return false;
   1503   }
   1504   if (!FixupSectionHeaders(base_address)) {
   1505     LOG(WARNING) << "Failed to fixup section headers in " << file_->GetPath();
   1506     return false;
   1507   }
   1508   if (!FixupProgramHeaders(base_address)) {
   1509     LOG(WARNING) << "Failed to fixup program headers in " << file_->GetPath();
   1510     return false;
   1511   }
   1512   if (!FixupSymbols(base_address, true)) {
   1513     LOG(WARNING) << "Failed to fixup .dynsym in " << file_->GetPath();
   1514     return false;
   1515   }
   1516   if (!FixupSymbols(base_address, false)) {
   1517     LOG(WARNING) << "Failed to fixup .symtab in " << file_->GetPath();
   1518     return false;
   1519   }
   1520   if (!FixupRelocations(base_address)) {
   1521     LOG(WARNING) << "Failed to fixup .rel.dyn in " << file_->GetPath();
   1522     return false;
   1523   }
   1524   static_assert(sizeof(Elf_Off) >= sizeof(base_address), "Potentially losing precision.");
   1525   if (!FixupDebugSections(static_cast<Elf_Off>(base_address))) {
   1526     LOG(WARNING) << "Failed to fixup debug sections in " << file_->GetPath();
   1527     return false;
   1528   }
   1529   return true;
   1530 }
   1531 
   1532 template <typename ElfTypes>
   1533 bool ElfFileImpl<ElfTypes>::FixupDynamic(Elf_Addr base_address) {
   1534   for (Elf_Word i = 0; i < GetDynamicNum(); i++) {
   1535     Elf_Dyn& elf_dyn = GetDynamic(i);
   1536     Elf_Word d_tag = elf_dyn.d_tag;
   1537     if (IsDynamicSectionPointer(d_tag, GetHeader().e_machine)) {
   1538       Elf_Addr d_ptr = elf_dyn.d_un.d_ptr;
   1539       if (DEBUG_FIXUP) {
   1540         LOG(INFO) << StringPrintf("In %s moving Elf_Dyn[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
   1541                                   GetFile().GetPath().c_str(), i,
   1542                                   static_cast<uint64_t>(d_ptr),
   1543                                   static_cast<uint64_t>(d_ptr + base_address));
   1544       }
   1545       d_ptr += base_address;
   1546       elf_dyn.d_un.d_ptr = d_ptr;
   1547     }
   1548   }
   1549   return true;
   1550 }
   1551 
   1552 template <typename ElfTypes>
   1553 bool ElfFileImpl<ElfTypes>::FixupSectionHeaders(Elf_Addr base_address) {
   1554   for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
   1555     Elf_Shdr* sh = GetSectionHeader(i);
   1556     CHECK(sh != nullptr);
   1557     // 0 implies that the section will not exist in the memory of the process
   1558     if (sh->sh_addr == 0) {
   1559       continue;
   1560     }
   1561     if (DEBUG_FIXUP) {
   1562       LOG(INFO) << StringPrintf("In %s moving Elf_Shdr[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
   1563                                 GetFile().GetPath().c_str(), i,
   1564                                 static_cast<uint64_t>(sh->sh_addr),
   1565                                 static_cast<uint64_t>(sh->sh_addr + base_address));
   1566     }
   1567     sh->sh_addr += base_address;
   1568   }
   1569   return true;
   1570 }
   1571 
   1572 template <typename ElfTypes>
   1573 bool ElfFileImpl<ElfTypes>::FixupProgramHeaders(Elf_Addr base_address) {
   1574   // TODO: ELFObjectFile doesn't have give to Elf_Phdr, so we do that ourselves for now.
   1575   for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) {
   1576     Elf_Phdr* ph = GetProgramHeader(i);
   1577     CHECK(ph != nullptr);
   1578     CHECK_EQ(ph->p_vaddr, ph->p_paddr) << GetFile().GetPath() << " i=" << i;
   1579     CHECK((ph->p_align == 0) || (0 == ((ph->p_vaddr - ph->p_offset) & (ph->p_align - 1))))
   1580             << GetFile().GetPath() << " i=" << i;
   1581     if (DEBUG_FIXUP) {
   1582       LOG(INFO) << StringPrintf("In %s moving Elf_Phdr[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
   1583                                 GetFile().GetPath().c_str(), i,
   1584                                 static_cast<uint64_t>(ph->p_vaddr),
   1585                                 static_cast<uint64_t>(ph->p_vaddr + base_address));
   1586     }
   1587     ph->p_vaddr += base_address;
   1588     ph->p_paddr += base_address;
   1589     CHECK((ph->p_align == 0) || (0 == ((ph->p_vaddr - ph->p_offset) & (ph->p_align - 1))))
   1590             << GetFile().GetPath() << " i=" << i;
   1591   }
   1592   return true;
   1593 }
   1594 
   1595 template <typename ElfTypes>
   1596 bool ElfFileImpl<ElfTypes>::FixupSymbols(Elf_Addr base_address, bool dynamic) {
   1597   Elf_Word section_type = dynamic ? SHT_DYNSYM : SHT_SYMTAB;
   1598   // TODO: Unfortunate ELFObjectFile has protected symbol access, so use ElfFile
   1599   Elf_Shdr* symbol_section = FindSectionByType(section_type);
   1600   if (symbol_section == nullptr) {
   1601     // file is missing optional .symtab
   1602     CHECK(!dynamic) << GetFile().GetPath();
   1603     return true;
   1604   }
   1605   for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
   1606     Elf_Sym* symbol = GetSymbol(section_type, i);
   1607     CHECK(symbol != nullptr);
   1608     if (symbol->st_value != 0) {
   1609       if (DEBUG_FIXUP) {
   1610         LOG(INFO) << StringPrintf("In %s moving Elf_Sym[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
   1611                                   GetFile().GetPath().c_str(), i,
   1612                                   static_cast<uint64_t>(symbol->st_value),
   1613                                   static_cast<uint64_t>(symbol->st_value + base_address));
   1614       }
   1615       symbol->st_value += base_address;
   1616     }
   1617   }
   1618   return true;
   1619 }
   1620 
   1621 template <typename ElfTypes>
   1622 bool ElfFileImpl<ElfTypes>::FixupRelocations(Elf_Addr base_address) {
   1623   for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
   1624     Elf_Shdr* sh = GetSectionHeader(i);
   1625     CHECK(sh != nullptr);
   1626     if (sh->sh_type == SHT_REL) {
   1627       for (uint32_t j = 0; j < GetRelNum(*sh); j++) {
   1628         Elf_Rel& rel = GetRel(*sh, j);
   1629         if (DEBUG_FIXUP) {
   1630           LOG(INFO) << StringPrintf("In %s moving Elf_Rel[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
   1631                                     GetFile().GetPath().c_str(), j,
   1632                                     static_cast<uint64_t>(rel.r_offset),
   1633                                     static_cast<uint64_t>(rel.r_offset + base_address));
   1634         }
   1635         rel.r_offset += base_address;
   1636       }
   1637     } else if (sh->sh_type == SHT_RELA) {
   1638       for (uint32_t j = 0; j < GetRelaNum(*sh); j++) {
   1639         Elf_Rela& rela = GetRela(*sh, j);
   1640         if (DEBUG_FIXUP) {
   1641           LOG(INFO) << StringPrintf("In %s moving Elf_Rela[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
   1642                                     GetFile().GetPath().c_str(), j,
   1643                                     static_cast<uint64_t>(rela.r_offset),
   1644                                     static_cast<uint64_t>(rela.r_offset + base_address));
   1645         }
   1646         rela.r_offset += base_address;
   1647       }
   1648     }
   1649   }
   1650   return true;
   1651 }
   1652 
   1653 // Explicit instantiations
   1654 template class ElfFileImpl<ElfTypes32>;
   1655 template class ElfFileImpl<ElfTypes64>;
   1656 
   1657 ElfFile::ElfFile(ElfFileImpl32* elf32) : elf32_(elf32), elf64_(nullptr) {
   1658 }
   1659 
   1660 ElfFile::ElfFile(ElfFileImpl64* elf64) : elf32_(nullptr), elf64_(elf64) {
   1661 }
   1662 
   1663 ElfFile::~ElfFile() {
   1664   // Should never have 32 and 64-bit impls.
   1665   CHECK_NE(elf32_.get() == nullptr, elf64_.get() == nullptr);
   1666 }
   1667 
   1668 ElfFile* ElfFile::Open(File* file,
   1669                        bool writable,
   1670                        bool program_header_only,
   1671                        bool low_4gb,
   1672                        std::string* error_msg,
   1673                        uint8_t* requested_base) {
   1674   if (file->GetLength() < EI_NIDENT) {
   1675     *error_msg = StringPrintf("File %s is too short to be a valid ELF file",
   1676                               file->GetPath().c_str());
   1677     return nullptr;
   1678   }
   1679   std::unique_ptr<MemMap> map(MemMap::MapFile(EI_NIDENT,
   1680                                               PROT_READ,
   1681                                               MAP_PRIVATE,
   1682                                               file->Fd(),
   1683                                               0,
   1684                                               low_4gb,
   1685                                               file->GetPath().c_str(),
   1686                                               error_msg));
   1687   if (map == nullptr && map->Size() != EI_NIDENT) {
   1688     return nullptr;
   1689   }
   1690   uint8_t* header = map->Begin();
   1691   if (header[EI_CLASS] == ELFCLASS64) {
   1692     ElfFileImpl64* elf_file_impl = ElfFileImpl64::Open(file,
   1693                                                        writable,
   1694                                                        program_header_only,
   1695                                                        low_4gb,
   1696                                                        error_msg,
   1697                                                        requested_base);
   1698     if (elf_file_impl == nullptr)
   1699       return nullptr;
   1700     return new ElfFile(elf_file_impl);
   1701   } else if (header[EI_CLASS] == ELFCLASS32) {
   1702     ElfFileImpl32* elf_file_impl = ElfFileImpl32::Open(file,
   1703                                                        writable,
   1704                                                        program_header_only,
   1705                                                        low_4gb,
   1706                                                        error_msg,
   1707                                                        requested_base);
   1708     if (elf_file_impl == nullptr) {
   1709       return nullptr;
   1710     }
   1711     return new ElfFile(elf_file_impl);
   1712   } else {
   1713     *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d or %d in %s, found %d",
   1714                               ELFCLASS32, ELFCLASS64,
   1715                               file->GetPath().c_str(),
   1716                               header[EI_CLASS]);
   1717     return nullptr;
   1718   }
   1719 }
   1720 
   1721 ElfFile* ElfFile::Open(File* file, int mmap_prot, int mmap_flags, std::string* error_msg) {
   1722   // low_4gb support not required for this path.
   1723   constexpr bool low_4gb = false;
   1724   if (file->GetLength() < EI_NIDENT) {
   1725     *error_msg = StringPrintf("File %s is too short to be a valid ELF file",
   1726                               file->GetPath().c_str());
   1727     return nullptr;
   1728   }
   1729   std::unique_ptr<MemMap> map(MemMap::MapFile(EI_NIDENT,
   1730                                               PROT_READ,
   1731                                               MAP_PRIVATE,
   1732                                               file->Fd(),
   1733                                               0,
   1734                                               low_4gb,
   1735                                               file->GetPath().c_str(),
   1736                                               error_msg));
   1737   if (map == nullptr && map->Size() != EI_NIDENT) {
   1738     return nullptr;
   1739   }
   1740   uint8_t* header = map->Begin();
   1741   if (header[EI_CLASS] == ELFCLASS64) {
   1742     ElfFileImpl64* elf_file_impl = ElfFileImpl64::Open(file,
   1743                                                        mmap_prot,
   1744                                                        mmap_flags,
   1745                                                        low_4gb,
   1746                                                        error_msg);
   1747     if (elf_file_impl == nullptr) {
   1748       return nullptr;
   1749     }
   1750     return new ElfFile(elf_file_impl);
   1751   } else if (header[EI_CLASS] == ELFCLASS32) {
   1752     ElfFileImpl32* elf_file_impl = ElfFileImpl32::Open(file,
   1753                                                        mmap_prot,
   1754                                                        mmap_flags,
   1755                                                        low_4gb,
   1756                                                        error_msg);
   1757     if (elf_file_impl == nullptr) {
   1758       return nullptr;
   1759     }
   1760     return new ElfFile(elf_file_impl);
   1761   } else {
   1762     *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d or %d in %s, found %d",
   1763                               ELFCLASS32, ELFCLASS64,
   1764                               file->GetPath().c_str(),
   1765                               header[EI_CLASS]);
   1766     return nullptr;
   1767   }
   1768 }
   1769 
   1770 #define DELEGATE_TO_IMPL(func, ...) \
   1771   if (elf64_.get() != nullptr) { \
   1772     return elf64_->func(__VA_ARGS__); \
   1773   } else { \
   1774     DCHECK(elf32_.get() != nullptr); \
   1775     return elf32_->func(__VA_ARGS__); \
   1776   }
   1777 
   1778 bool ElfFile::Load(bool executable, bool low_4gb, std::string* error_msg) {
   1779   DELEGATE_TO_IMPL(Load, executable, low_4gb, error_msg);
   1780 }
   1781 
   1782 const uint8_t* ElfFile::FindDynamicSymbolAddress(const std::string& symbol_name) const {
   1783   DELEGATE_TO_IMPL(FindDynamicSymbolAddress, symbol_name);
   1784 }
   1785 
   1786 size_t ElfFile::Size() const {
   1787   DELEGATE_TO_IMPL(Size);
   1788 }
   1789 
   1790 uint8_t* ElfFile::Begin() const {
   1791   DELEGATE_TO_IMPL(Begin);
   1792 }
   1793 
   1794 uint8_t* ElfFile::End() const {
   1795   DELEGATE_TO_IMPL(End);
   1796 }
   1797 
   1798 const File& ElfFile::GetFile() const {
   1799   DELEGATE_TO_IMPL(GetFile);
   1800 }
   1801 
   1802 bool ElfFile::GetSectionOffsetAndSize(const char* section_name, uint64_t* offset,
   1803                                       uint64_t* size) const {
   1804   if (elf32_.get() == nullptr) {
   1805     CHECK(elf64_.get() != nullptr);
   1806 
   1807     Elf64_Shdr *shdr = elf64_->FindSectionByName(section_name);
   1808     if (shdr == nullptr) {
   1809       return false;
   1810     }
   1811     if (offset != nullptr) {
   1812       *offset = shdr->sh_offset;
   1813     }
   1814     if (size != nullptr) {
   1815       *size = shdr->sh_size;
   1816     }
   1817     return true;
   1818   } else {
   1819     Elf32_Shdr *shdr = elf32_->FindSectionByName(section_name);
   1820     if (shdr == nullptr) {
   1821       return false;
   1822     }
   1823     if (offset != nullptr) {
   1824       *offset = shdr->sh_offset;
   1825     }
   1826     if (size != nullptr) {
   1827       *size = shdr->sh_size;
   1828     }
   1829     return true;
   1830   }
   1831 }
   1832 
   1833 bool ElfFile::HasSection(const std::string& name) const {
   1834   if (elf64_.get() != nullptr) {
   1835     return elf64_->FindSectionByName(name) != nullptr;
   1836   } else {
   1837     return elf32_->FindSectionByName(name) != nullptr;
   1838   }
   1839 }
   1840 
   1841 uint64_t ElfFile::FindSymbolAddress(unsigned section_type,
   1842                                     const std::string& symbol_name,
   1843                                     bool build_map) {
   1844   DELEGATE_TO_IMPL(FindSymbolAddress, section_type, symbol_name, build_map);
   1845 }
   1846 
   1847 bool ElfFile::GetLoadedSize(size_t* size, std::string* error_msg) const {
   1848   DELEGATE_TO_IMPL(GetLoadedSize, size, error_msg);
   1849 }
   1850 
   1851 bool ElfFile::Strip(File* file, std::string* error_msg) {
   1852   std::unique_ptr<ElfFile> elf_file(ElfFile::Open(file, true, false, /*low_4gb*/false, error_msg));
   1853   if (elf_file.get() == nullptr) {
   1854     return false;
   1855   }
   1856 
   1857   if (elf_file->elf64_.get() != nullptr)
   1858     return elf_file->elf64_->Strip(error_msg);
   1859   else
   1860     return elf_file->elf32_->Strip(error_msg);
   1861 }
   1862 
   1863 bool ElfFile::Fixup(uint64_t base_address) {
   1864   if (elf64_.get() != nullptr) {
   1865     return elf64_->Fixup(static_cast<Elf64_Addr>(base_address));
   1866   } else {
   1867     DCHECK(elf32_.get() != nullptr);
   1868     CHECK(IsUint<32>(base_address)) << std::hex << base_address;
   1869     return elf32_->Fixup(static_cast<Elf32_Addr>(base_address));
   1870   }
   1871   DELEGATE_TO_IMPL(Fixup, base_address);
   1872 }
   1873 
   1874 }  // namespace art
   1875