Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 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 "oat_file.h"
     18 
     19 #include <dlfcn.h>
     20 #ifndef __APPLE__
     21 #include <link.h>  // for dl_iterate_phdr.
     22 #endif
     23 #include <unistd.h>
     24 
     25 #include <cstdlib>
     26 #include <cstring>
     27 #include <sstream>
     28 #include <type_traits>
     29 #include <sys/stat.h>
     30 
     31 // dlopen_ext support from bionic.
     32 #ifdef ART_TARGET_ANDROID
     33 #include "android/dlext.h"
     34 #endif
     35 
     36 #include "android-base/stringprintf.h"
     37 
     38 #include "art_method.h"
     39 #include "base/bit_vector.h"
     40 #include "base/enums.h"
     41 #include "base/file_utils.h"
     42 #include "base/logging.h"  // For VLOG_IS_ON.
     43 #include "base/os.h"
     44 #include "base/stl_util.h"
     45 #include "base/systrace.h"
     46 #include "base/unix_file/fd_file.h"
     47 #include "base/utils.h"
     48 #include "dex/art_dex_file_loader.h"
     49 #include "dex/dex_file_loader.h"
     50 #include "dex/dex_file_types.h"
     51 #include "dex/standard_dex_file.h"
     52 #include "dex/utf-inl.h"
     53 #include "elf_file.h"
     54 #include "elf_utils.h"
     55 #include "gc_root.h"
     56 #include "gc/space/image_space.h"
     57 #include "mem_map.h"
     58 #include "mirror/class.h"
     59 #include "mirror/object-inl.h"
     60 #include "oat.h"
     61 #include "oat_file-inl.h"
     62 #include "oat_file_manager.h"
     63 #include "runtime.h"
     64 #include "type_lookup_table.h"
     65 #include "vdex_file.h"
     66 
     67 namespace art {
     68 
     69 using android::base::StringPrintf;
     70 
     71 // Whether OatFile::Open will try dlopen. Fallback is our own ELF loader.
     72 static constexpr bool kUseDlopen = true;
     73 
     74 // Whether OatFile::Open will try dlopen on the host. On the host we're not linking against
     75 // bionic, so cannot take advantage of the support for changed semantics (loading the same soname
     76 // multiple times). However, if/when we switch the above, we likely want to switch this, too,
     77 // to get test coverage of the code paths.
     78 static constexpr bool kUseDlopenOnHost = true;
     79 
     80 // For debugging, Open will print DlOpen error message if set to true.
     81 static constexpr bool kPrintDlOpenErrorMessage = false;
     82 
     83 // Note for OatFileBase and descendents:
     84 //
     85 // These are used in OatFile::Open to try all our loaders.
     86 //
     87 // The process is simple:
     88 //
     89 // 1) Allocate an instance through the standard constructor (location, executable)
     90 // 2) Load() to try to open the file.
     91 // 3) ComputeFields() to populate the OatFile fields like begin_, using FindDynamicSymbolAddress.
     92 // 4) PreSetup() for any steps that should be done before the final setup.
     93 // 5) Setup() to complete the procedure.
     94 
     95 class OatFileBase : public OatFile {
     96  public:
     97   virtual ~OatFileBase() {}
     98 
     99   template <typename kOatFileBaseSubType>
    100   static OatFileBase* OpenOatFile(int zip_fd,
    101                                   const std::string& vdex_filename,
    102                                   const std::string& elf_filename,
    103                                   const std::string& location,
    104                                   uint8_t* requested_base,
    105                                   uint8_t* oat_file_begin,
    106                                   bool writable,
    107                                   bool executable,
    108                                   bool low_4gb,
    109                                   const char* abs_dex_location,
    110                                   std::string* error_msg);
    111 
    112   template <typename kOatFileBaseSubType>
    113   static OatFileBase* OpenOatFile(int zip_fd,
    114                                   int vdex_fd,
    115                                   int oat_fd,
    116                                   const std::string& vdex_filename,
    117                                   const std::string& oat_filename,
    118                                   uint8_t* requested_base,
    119                                   uint8_t* oat_file_begin,
    120                                   bool writable,
    121                                   bool executable,
    122                                   bool low_4gb,
    123                                   const char* abs_dex_location,
    124                                   std::string* error_msg);
    125 
    126  protected:
    127   OatFileBase(const std::string& filename, bool executable) : OatFile(filename, executable) {}
    128 
    129   virtual const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name,
    130                                                   std::string* error_msg) const = 0;
    131 
    132   virtual void PreLoad() = 0;
    133 
    134   bool LoadVdex(const std::string& vdex_filename,
    135                 bool writable,
    136                 bool low_4gb,
    137                 std::string* error_msg);
    138 
    139   bool LoadVdex(int vdex_fd,
    140                 const std::string& vdex_filename,
    141                 bool writable,
    142                 bool low_4gb,
    143                 std::string* error_msg);
    144 
    145   virtual bool Load(const std::string& elf_filename,
    146                     uint8_t* oat_file_begin,
    147                     bool writable,
    148                     bool executable,
    149                     bool low_4gb,
    150                     std::string* error_msg) = 0;
    151 
    152   virtual bool Load(int oat_fd,
    153                     uint8_t* oat_file_begin,
    154                     bool writable,
    155                     bool executable,
    156                     bool low_4gb,
    157                     std::string* error_msg) = 0;
    158 
    159   bool ComputeFields(uint8_t* requested_base,
    160                      const std::string& file_path,
    161                      std::string* error_msg);
    162 
    163   virtual void PreSetup(const std::string& elf_filename) = 0;
    164 
    165   bool Setup(int zip_fd, const char* abs_dex_location, std::string* error_msg);
    166 
    167   // Setters exposed for ElfOatFile.
    168 
    169   void SetBegin(const uint8_t* begin) {
    170     begin_ = begin;
    171   }
    172 
    173   void SetEnd(const uint8_t* end) {
    174     end_ = end;
    175   }
    176 
    177   void SetVdex(VdexFile* vdex) {
    178     vdex_.reset(vdex);
    179   }
    180 
    181  private:
    182   DISALLOW_COPY_AND_ASSIGN(OatFileBase);
    183 };
    184 
    185 template <typename kOatFileBaseSubType>
    186 OatFileBase* OatFileBase::OpenOatFile(int zip_fd,
    187                                       const std::string& vdex_filename,
    188                                       const std::string& elf_filename,
    189                                       const std::string& location,
    190                                       uint8_t* requested_base,
    191                                       uint8_t* oat_file_begin,
    192                                       bool writable,
    193                                       bool executable,
    194                                       bool low_4gb,
    195                                       const char* abs_dex_location,
    196                                       std::string* error_msg) {
    197   std::unique_ptr<OatFileBase> ret(new kOatFileBaseSubType(location, executable));
    198 
    199   ret->PreLoad();
    200 
    201   if (!ret->Load(elf_filename,
    202                  oat_file_begin,
    203                  writable,
    204                  executable,
    205                  low_4gb,
    206                  error_msg)) {
    207     return nullptr;
    208   }
    209 
    210   if (!ret->ComputeFields(requested_base, elf_filename, error_msg)) {
    211     return nullptr;
    212   }
    213 
    214   if (!ret->LoadVdex(vdex_filename, writable, low_4gb, error_msg)) {
    215     return nullptr;
    216   }
    217 
    218   ret->PreSetup(elf_filename);
    219 
    220   if (!ret->Setup(zip_fd, abs_dex_location, error_msg)) {
    221     return nullptr;
    222   }
    223 
    224   return ret.release();
    225 }
    226 
    227 template <typename kOatFileBaseSubType>
    228 OatFileBase* OatFileBase::OpenOatFile(int zip_fd,
    229                                       int vdex_fd,
    230                                       int oat_fd,
    231                                       const std::string& vdex_location,
    232                                       const std::string& oat_location,
    233                                       uint8_t* requested_base,
    234                                       uint8_t* oat_file_begin,
    235                                       bool writable,
    236                                       bool executable,
    237                                       bool low_4gb,
    238                                       const char* abs_dex_location,
    239                                       std::string* error_msg) {
    240   std::unique_ptr<OatFileBase> ret(new kOatFileBaseSubType(oat_location, executable));
    241 
    242   if (!ret->Load(oat_fd,
    243                  oat_file_begin,
    244                  writable,
    245                  executable,
    246                  low_4gb,
    247                  error_msg)) {
    248     return nullptr;
    249   }
    250 
    251   if (!ret->ComputeFields(requested_base, oat_location, error_msg)) {
    252     return nullptr;
    253   }
    254 
    255   if (!ret->LoadVdex(vdex_fd, vdex_location, writable, low_4gb, error_msg)) {
    256     return nullptr;
    257   }
    258 
    259   ret->PreSetup(oat_location);
    260 
    261   if (!ret->Setup(zip_fd, abs_dex_location, error_msg)) {
    262     return nullptr;
    263   }
    264 
    265   return ret.release();
    266 }
    267 
    268 bool OatFileBase::LoadVdex(const std::string& vdex_filename,
    269                            bool writable,
    270                            bool low_4gb,
    271                            std::string* error_msg) {
    272   vdex_ = VdexFile::OpenAtAddress(vdex_begin_,
    273                                   vdex_end_ - vdex_begin_,
    274                                   vdex_begin_ != nullptr /* mmap_reuse */,
    275                                   vdex_filename,
    276                                   writable,
    277                                   low_4gb,
    278                                   /* unquicken*/ false,
    279                                   error_msg);
    280   if (vdex_.get() == nullptr) {
    281     *error_msg = StringPrintf("Failed to load vdex file '%s' %s",
    282                               vdex_filename.c_str(),
    283                               error_msg->c_str());
    284     return false;
    285   }
    286   return true;
    287 }
    288 
    289 bool OatFileBase::LoadVdex(int vdex_fd,
    290                            const std::string& vdex_filename,
    291                            bool writable,
    292                            bool low_4gb,
    293                            std::string* error_msg) {
    294   if (vdex_fd != -1) {
    295     struct stat s;
    296     int rc = TEMP_FAILURE_RETRY(fstat(vdex_fd, &s));
    297     if (rc == -1) {
    298       PLOG(WARNING) << "Failed getting length of vdex file";
    299     } else {
    300       vdex_ = VdexFile::OpenAtAddress(vdex_begin_,
    301                                       vdex_end_ - vdex_begin_,
    302                                       vdex_begin_ != nullptr /* mmap_reuse */,
    303                                       vdex_fd,
    304                                       s.st_size,
    305                                       vdex_filename,
    306                                       writable,
    307                                       low_4gb,
    308                                       false /* unquicken */,
    309                                       error_msg);
    310       if (vdex_.get() == nullptr) {
    311         *error_msg = "Failed opening vdex file.";
    312         return false;
    313       }
    314     }
    315   }
    316   return true;
    317 }
    318 
    319 bool OatFileBase::ComputeFields(uint8_t* requested_base,
    320                                 const std::string& file_path,
    321                                 std::string* error_msg) {
    322   std::string symbol_error_msg;
    323   begin_ = FindDynamicSymbolAddress("oatdata", &symbol_error_msg);
    324   if (begin_ == nullptr) {
    325     *error_msg = StringPrintf("Failed to find oatdata symbol in '%s' %s",
    326                               file_path.c_str(),
    327                               symbol_error_msg.c_str());
    328     return false;
    329   }
    330   if (requested_base != nullptr && begin_ != requested_base) {
    331     // Host can fail this check. Do not dump there to avoid polluting the output.
    332     if (kIsTargetBuild && (kIsDebugBuild || VLOG_IS_ON(oat))) {
    333       PrintFileToLog("/proc/self/maps", android::base::LogSeverity::WARNING);
    334     }
    335     *error_msg = StringPrintf("Failed to find oatdata symbol at expected address: "
    336         "oatdata=%p != expected=%p. See process maps in the log.",
    337         begin_, requested_base);
    338     return false;
    339   }
    340   end_ = FindDynamicSymbolAddress("oatlastword", &symbol_error_msg);
    341   if (end_ == nullptr) {
    342     *error_msg = StringPrintf("Failed to find oatlastword symbol in '%s' %s",
    343                               file_path.c_str(),
    344                               symbol_error_msg.c_str());
    345     return false;
    346   }
    347   // Readjust to be non-inclusive upper bound.
    348   end_ += sizeof(uint32_t);
    349 
    350   bss_begin_ = const_cast<uint8_t*>(FindDynamicSymbolAddress("oatbss", &symbol_error_msg));
    351   if (bss_begin_ == nullptr) {
    352     // No .bss section.
    353     bss_end_ = nullptr;
    354   } else {
    355     bss_end_ = const_cast<uint8_t*>(FindDynamicSymbolAddress("oatbsslastword", &symbol_error_msg));
    356     if (bss_end_ == nullptr) {
    357       *error_msg = StringPrintf("Failed to find oatbsslastword symbol in '%s'", file_path.c_str());
    358       return false;
    359     }
    360     // Readjust to be non-inclusive upper bound.
    361     bss_end_ += sizeof(uint32_t);
    362     // Find bss methods if present.
    363     bss_methods_ =
    364         const_cast<uint8_t*>(FindDynamicSymbolAddress("oatbssmethods", &symbol_error_msg));
    365     // Find bss roots if present.
    366     bss_roots_ = const_cast<uint8_t*>(FindDynamicSymbolAddress("oatbssroots", &symbol_error_msg));
    367   }
    368 
    369   vdex_begin_ = const_cast<uint8_t*>(FindDynamicSymbolAddress("oatdex", &symbol_error_msg));
    370   if (vdex_begin_ == nullptr) {
    371     // No .vdex section.
    372     vdex_end_ = nullptr;
    373   } else {
    374     vdex_end_ = const_cast<uint8_t*>(FindDynamicSymbolAddress("oatdexlastword", &symbol_error_msg));
    375     if (vdex_end_ == nullptr) {
    376       *error_msg = StringPrintf("Failed to find oatdexlastword symbol in '%s'", file_path.c_str());
    377       return false;
    378     }
    379     // Readjust to be non-inclusive upper bound.
    380     vdex_end_ += sizeof(uint32_t);
    381   }
    382 
    383   return true;
    384 }
    385 
    386 // Read an unaligned entry from the OatDexFile data in OatFile and advance the read
    387 // position by the number of bytes read, i.e. sizeof(T).
    388 // Return true on success, false if the read would go beyond the end of the OatFile.
    389 template <typename T>
    390 inline static bool ReadOatDexFileData(const OatFile& oat_file,
    391                                       /*inout*/const uint8_t** oat,
    392                                       /*out*/T* value) {
    393   DCHECK(oat != nullptr);
    394   DCHECK(value != nullptr);
    395   DCHECK_LE(*oat, oat_file.End());
    396   if (UNLIKELY(static_cast<size_t>(oat_file.End() - *oat) < sizeof(T))) {
    397     return false;
    398   }
    399   static_assert(std::is_trivial<T>::value, "T must be a trivial type");
    400   typedef __attribute__((__aligned__(1))) T unaligned_type;
    401   *value = *reinterpret_cast<const unaligned_type*>(*oat);
    402   *oat += sizeof(T);
    403   return true;
    404 }
    405 
    406 static inline bool MapConstantTables(const gc::space::ImageSpace* space,
    407                                      uint8_t* address) {
    408   // If MREMAP_DUP is ever merged to Linux kernel, use it to avoid the unnecessary open()/close().
    409   // Note: The current approach relies on the filename still referencing the same inode.
    410 
    411   File file(space->GetImageFilename(), O_RDONLY, /* checkUsage */ false);
    412   if (!file.IsOpened()) {
    413     LOG(ERROR) << "Failed to open boot image file " << space->GetImageFilename();
    414     return false;
    415   }
    416 
    417   uint32_t offset = space->GetImageHeader().GetBootImageConstantTablesOffset();
    418   uint32_t size = space->GetImageHeader().GetBootImageConstantTablesSize();
    419   std::string error_msg;
    420   std::unique_ptr<MemMap> mem_map(MemMap::MapFileAtAddress(address,
    421                                                            size,
    422                                                            PROT_READ,
    423                                                            MAP_PRIVATE,
    424                                                            file.Fd(),
    425                                                            offset,
    426                                                            /* low_4gb */ false,
    427                                                            /* reuse */ true,
    428                                                            file.GetPath().c_str(),
    429                                                            &error_msg));
    430   if (mem_map == nullptr) {
    431     LOG(ERROR) << "Failed to mmap boot image tables from file " << space->GetImageFilename();
    432     return false;
    433   }
    434   return true;
    435 }
    436 
    437 static bool ReadIndexBssMapping(OatFile* oat_file,
    438                                 /*inout*/const uint8_t** oat,
    439                                 size_t dex_file_index,
    440                                 const std::string& dex_file_location,
    441                                 const char* tag,
    442                                 /*out*/const IndexBssMapping** mapping,
    443                                 std::string* error_msg) {
    444   uint32_t index_bss_mapping_offset;
    445   if (UNLIKELY(!ReadOatDexFileData(*oat_file, oat, &index_bss_mapping_offset))) {
    446     *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zd for '%s' truncated "
    447                                   "after %s bss mapping offset",
    448                               oat_file->GetLocation().c_str(),
    449                               dex_file_index,
    450                               dex_file_location.c_str(),
    451                               tag);
    452     return false;
    453   }
    454   const bool readable_index_bss_mapping_size =
    455       index_bss_mapping_offset != 0u &&
    456       index_bss_mapping_offset <= oat_file->Size() &&
    457       IsAligned<alignof(IndexBssMapping)>(index_bss_mapping_offset) &&
    458       oat_file->Size() - index_bss_mapping_offset >= IndexBssMapping::ComputeSize(0);
    459   const IndexBssMapping* index_bss_mapping = readable_index_bss_mapping_size
    460       ? reinterpret_cast<const IndexBssMapping*>(oat_file->Begin() + index_bss_mapping_offset)
    461       : nullptr;
    462   if (index_bss_mapping_offset != 0u &&
    463       (UNLIKELY(index_bss_mapping == nullptr) ||
    464           UNLIKELY(index_bss_mapping->size() == 0u) ||
    465           UNLIKELY(oat_file->Size() - index_bss_mapping_offset <
    466                    IndexBssMapping::ComputeSize(index_bss_mapping->size())))) {
    467     *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with unaligned or "
    468                                   " truncated %s bss mapping, offset %u of %zu, length %zu",
    469                               oat_file->GetLocation().c_str(),
    470                               dex_file_index,
    471                               dex_file_location.c_str(),
    472                               tag,
    473                               index_bss_mapping_offset,
    474                               oat_file->Size(),
    475                               index_bss_mapping != nullptr ? index_bss_mapping->size() : 0u);
    476     return false;
    477   }
    478 
    479   *mapping = index_bss_mapping;
    480   return true;
    481 }
    482 
    483 static void DCheckIndexToBssMapping(OatFile* oat_file,
    484                                     uint32_t number_of_indexes,
    485                                     size_t slot_size,
    486                                     const IndexBssMapping* index_bss_mapping) {
    487   if (kIsDebugBuild && index_bss_mapping != nullptr) {
    488     size_t index_bits = IndexBssMappingEntry::IndexBits(number_of_indexes);
    489     const IndexBssMappingEntry* prev_entry = nullptr;
    490     for (const IndexBssMappingEntry& entry : *index_bss_mapping) {
    491       CHECK_ALIGNED_PARAM(entry.bss_offset, slot_size);
    492       // When loading a non-executable ElfOatFile, .bss symbols are not even
    493       // looked up, so we cannot verify the offset against BssSize().
    494       if (oat_file->IsExecutable()) {
    495         CHECK_LT(entry.bss_offset, oat_file->BssSize());
    496       }
    497       uint32_t mask = entry.GetMask(index_bits);
    498       CHECK_LE(POPCOUNT(mask) * slot_size, entry.bss_offset);
    499       size_t index_mask_span = (mask != 0u) ? 32u - index_bits - CTZ(mask) : 0u;
    500       CHECK_LE(index_mask_span, entry.GetIndex(index_bits));
    501       if (prev_entry != nullptr) {
    502         CHECK_LT(prev_entry->GetIndex(index_bits), entry.GetIndex(index_bits) - index_mask_span);
    503       }
    504       prev_entry = &entry;
    505     }
    506     CHECK_LT(prev_entry->GetIndex(index_bits), number_of_indexes);
    507   }
    508 }
    509 
    510 bool OatFileBase::Setup(int zip_fd, const char* abs_dex_location, std::string* error_msg) {
    511   if (!GetOatHeader().IsValid()) {
    512     std::string cause = GetOatHeader().GetValidationErrorMessage();
    513     *error_msg = StringPrintf("Invalid oat header for '%s': %s",
    514                               GetLocation().c_str(),
    515                               cause.c_str());
    516     return false;
    517   }
    518   PointerSize pointer_size = GetInstructionSetPointerSize(GetOatHeader().GetInstructionSet());
    519   size_t key_value_store_size =
    520       (Size() >= sizeof(OatHeader)) ? GetOatHeader().GetKeyValueStoreSize() : 0u;
    521   if (Size() < sizeof(OatHeader) + key_value_store_size) {
    522     *error_msg = StringPrintf("In oat file '%s' found truncated OatHeader, "
    523                                   "size = %zu < %zu + %zu",
    524                               GetLocation().c_str(),
    525                               Size(),
    526                               sizeof(OatHeader),
    527                               key_value_store_size);
    528     return false;
    529   }
    530 
    531   size_t oat_dex_files_offset = GetOatHeader().GetOatDexFilesOffset();
    532   if (oat_dex_files_offset < GetOatHeader().GetHeaderSize() || oat_dex_files_offset > Size()) {
    533     *error_msg = StringPrintf("In oat file '%s' found invalid oat dex files offset: "
    534                                   "%zu is not in [%zu, %zu]",
    535                               GetLocation().c_str(),
    536                               oat_dex_files_offset,
    537                               GetOatHeader().GetHeaderSize(),
    538                               Size());
    539     return false;
    540   }
    541   const uint8_t* oat = Begin() + oat_dex_files_offset;  // Jump to the OatDexFile records.
    542 
    543   DCHECK_GE(static_cast<size_t>(pointer_size), alignof(GcRoot<mirror::Object>));
    544   if (!IsAligned<kPageSize>(bss_begin_) ||
    545       !IsAlignedParam(bss_methods_, static_cast<size_t>(pointer_size)) ||
    546       !IsAlignedParam(bss_roots_, static_cast<size_t>(pointer_size)) ||
    547       !IsAligned<alignof(GcRoot<mirror::Object>)>(bss_end_)) {
    548     *error_msg = StringPrintf("In oat file '%s' found unaligned bss symbol(s): "
    549                                   "begin = %p, methods_ = %p, roots = %p, end = %p",
    550                               GetLocation().c_str(),
    551                               bss_begin_,
    552                               bss_methods_,
    553                               bss_roots_,
    554                               bss_end_);
    555     return false;
    556   }
    557 
    558   if ((bss_methods_ != nullptr && (bss_methods_ < bss_begin_ || bss_methods_ > bss_end_)) ||
    559       (bss_roots_ != nullptr && (bss_roots_ < bss_begin_ || bss_roots_ > bss_end_)) ||
    560       (bss_methods_ != nullptr && bss_roots_ != nullptr && bss_methods_ > bss_roots_)) {
    561     *error_msg = StringPrintf("In oat file '%s' found bss symbol(s) outside .bss or unordered: "
    562                                   "begin = %p, methods = %p, roots = %p, end = %p",
    563                               GetLocation().c_str(),
    564                               bss_begin_,
    565                               bss_methods_,
    566                               bss_roots_,
    567                               bss_end_);
    568     return false;
    569   }
    570 
    571   uint8_t* after_tables =
    572       (bss_methods_ != nullptr) ? bss_methods_ : bss_roots_;  // May be null.
    573   uint8_t* boot_image_tables = (bss_begin_ == after_tables) ? nullptr : bss_begin_;
    574   uint8_t* boot_image_tables_end =
    575       (bss_begin_ == after_tables) ? nullptr : (after_tables != nullptr) ? after_tables : bss_end_;
    576   DCHECK_EQ(boot_image_tables != nullptr, boot_image_tables_end != nullptr);
    577   uint32_t dex_file_count = GetOatHeader().GetDexFileCount();
    578   oat_dex_files_storage_.reserve(dex_file_count);
    579   for (size_t i = 0; i < dex_file_count; i++) {
    580     uint32_t dex_file_location_size;
    581     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_file_location_size))) {
    582       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu truncated after dex file "
    583                                     "location size",
    584                                 GetLocation().c_str(),
    585                                 i);
    586       return false;
    587     }
    588     if (UNLIKELY(dex_file_location_size == 0U)) {
    589       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu with empty location name",
    590                                 GetLocation().c_str(),
    591                                 i);
    592       return false;
    593     }
    594     if (UNLIKELY(static_cast<size_t>(End() - oat) < dex_file_location_size)) {
    595       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu with truncated dex file "
    596                                     "location",
    597                                 GetLocation().c_str(),
    598                                 i);
    599       return false;
    600     }
    601     const char* dex_file_location_data = reinterpret_cast<const char*>(oat);
    602     oat += dex_file_location_size;
    603 
    604     std::string dex_file_location = ResolveRelativeEncodedDexLocation(
    605         abs_dex_location,
    606         std::string(dex_file_location_data, dex_file_location_size));
    607 
    608     uint32_t dex_file_checksum;
    609     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_file_checksum))) {
    610       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' truncated after "
    611                                     "dex file checksum",
    612                                 GetLocation().c_str(),
    613                                 i,
    614                                 dex_file_location.c_str());
    615       return false;
    616     }
    617 
    618     uint32_t dex_file_offset;
    619     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_file_offset))) {
    620       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' truncated "
    621                                     "after dex file offsets",
    622                                 GetLocation().c_str(),
    623                                 i,
    624                                 dex_file_location.c_str());
    625       return false;
    626     }
    627     if (UNLIKELY(dex_file_offset > DexSize())) {
    628       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "
    629                                     "offset %u > %zu",
    630                                 GetLocation().c_str(),
    631                                 i,
    632                                 dex_file_location.c_str(),
    633                                 dex_file_offset,
    634                                 DexSize());
    635       return false;
    636     }
    637     const uint8_t* dex_file_pointer = nullptr;
    638     if (UNLIKELY(dex_file_offset == 0U)) {
    639       if (uncompressed_dex_files_ == nullptr) {
    640         // Do not support mixed-mode oat files.
    641         if (i > 0) {
    642           *error_msg = StringPrintf("In oat file '%s', unsupported uncompressed-dex-file for dex "
    643                                         "file %zu (%s)",
    644                                     GetLocation().c_str(),
    645                                     i,
    646                                     dex_file_location.c_str());
    647           return false;
    648         }
    649         uncompressed_dex_files_.reset(new std::vector<std::unique_ptr<const DexFile>>());
    650         // No dex files, load it from location.
    651         const ArtDexFileLoader dex_file_loader;
    652         bool loaded = false;
    653         if (zip_fd != -1) {
    654           loaded = dex_file_loader.OpenZip(zip_fd,
    655                                            dex_file_location,
    656                                            /* verify */ false,
    657                                            /* verify_checksum */ false,
    658                                            error_msg,
    659                                            uncompressed_dex_files_.get());
    660         } else {
    661           loaded = dex_file_loader.Open(dex_file_location.c_str(),
    662                                         dex_file_location,
    663                                         /* verify */ false,
    664                                         /* verify_checksum */ false,
    665                                         error_msg,
    666                                         uncompressed_dex_files_.get());
    667         }
    668         if (!loaded) {
    669           if (Runtime::Current() == nullptr) {
    670             // If there's no runtime, we're running oatdump, so return
    671             // a half constructed oat file that oatdump knows how to deal with.
    672             LOG(WARNING) << "Could not find associated dex files of oat file. "
    673                          << "Oatdump will only dump the header.";
    674             return true;
    675           } else {
    676             return false;
    677           }
    678         }
    679         // The oat file may be out of date wrt/ the dex-file location. We need to be defensive
    680         // here and ensure that at least the number of dex files still matches.
    681         // Note: actual checksum comparisons are the duty of the OatFileAssistant and will be
    682         //       done after loading the OatFile.
    683         if (uncompressed_dex_files_->size() != dex_file_count) {
    684           *error_msg = StringPrintf("In oat file '%s', expected %u uncompressed dex files, but "
    685                                         "found %zu in '%s'",
    686                                     GetLocation().c_str(),
    687                                     dex_file_count,
    688                                     uncompressed_dex_files_->size(),
    689                                     dex_file_location.c_str());
    690           return false;
    691         }
    692       }
    693       dex_file_pointer = uncompressed_dex_files_.get()->at(i)->Begin();
    694     } else {
    695       // Do not support mixed-mode oat files.
    696       if (uncompressed_dex_files_ != nullptr) {
    697         *error_msg = StringPrintf("In oat file '%s', unsupported embedded dex-file for dex file "
    698                                       "%zu (%s)",
    699                                   GetLocation().c_str(),
    700                                   i,
    701                                   dex_file_location.c_str());
    702         return false;
    703       }
    704       if (UNLIKELY(DexSize() - dex_file_offset < sizeof(DexFile::Header))) {
    705         *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "
    706                                       "offset %u of %zu but the size of dex file header is %zu",
    707                                   GetLocation().c_str(),
    708                                   i,
    709                                   dex_file_location.c_str(),
    710                                   dex_file_offset,
    711                                   DexSize(),
    712                                   sizeof(DexFile::Header));
    713         return false;
    714       }
    715       dex_file_pointer = DexBegin() + dex_file_offset;
    716     }
    717 
    718     const bool valid_magic = DexFileLoader::IsMagicValid(dex_file_pointer);
    719     if (UNLIKELY(!valid_magic)) {
    720       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with invalid "
    721                                     "dex file magic '%s'",
    722                                 GetLocation().c_str(),
    723                                 i,
    724                                 dex_file_location.c_str(),
    725                                 dex_file_pointer);
    726       return false;
    727     }
    728     if (UNLIKELY(!DexFileLoader::IsVersionAndMagicValid(dex_file_pointer))) {
    729       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with invalid "
    730                                     "dex file version '%s'",
    731                                 GetLocation().c_str(),
    732                                 i,
    733                                 dex_file_location.c_str(),
    734                                 dex_file_pointer);
    735       return false;
    736     }
    737     const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(dex_file_pointer);
    738     if (dex_file_offset != 0 && (DexSize() - dex_file_offset < header->file_size_)) {
    739       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "
    740                                     "offset %u and size %u truncated at %zu",
    741                                 GetLocation().c_str(),
    742                                 i,
    743                                 dex_file_location.c_str(),
    744                                 dex_file_offset,
    745                                 header->file_size_,
    746                                 DexSize());
    747       return false;
    748     }
    749 
    750     uint32_t class_offsets_offset;
    751     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &class_offsets_offset))) {
    752       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' truncated "
    753                                     "after class offsets offset",
    754                                 GetLocation().c_str(),
    755                                 i,
    756                                 dex_file_location.c_str());
    757       return false;
    758     }
    759     if (UNLIKELY(class_offsets_offset > Size()) ||
    760         UNLIKELY((Size() - class_offsets_offset) / sizeof(uint32_t) < header->class_defs_size_)) {
    761       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with truncated "
    762                                     "class offsets, offset %u of %zu, class defs %u",
    763                                 GetLocation().c_str(),
    764                                 i,
    765                                 dex_file_location.c_str(),
    766                                 class_offsets_offset,
    767                                 Size(),
    768                                 header->class_defs_size_);
    769       return false;
    770     }
    771     if (UNLIKELY(!IsAligned<alignof(uint32_t)>(class_offsets_offset))) {
    772       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with unaligned "
    773                                     "class offsets, offset %u",
    774                                 GetLocation().c_str(),
    775                                 i,
    776                                 dex_file_location.c_str(),
    777                                 class_offsets_offset);
    778       return false;
    779     }
    780     const uint32_t* class_offsets_pointer =
    781         reinterpret_cast<const uint32_t*>(Begin() + class_offsets_offset);
    782 
    783     uint32_t lookup_table_offset;
    784     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &lookup_table_offset))) {
    785       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zd for '%s' truncated "
    786                                     "after lookup table offset",
    787                                 GetLocation().c_str(),
    788                                 i,
    789                                 dex_file_location.c_str());
    790       return false;
    791     }
    792     const uint8_t* lookup_table_data = lookup_table_offset != 0u
    793         ? Begin() + lookup_table_offset
    794         : nullptr;
    795     if (lookup_table_offset != 0u &&
    796         (UNLIKELY(lookup_table_offset > Size()) ||
    797             UNLIKELY(Size() - lookup_table_offset <
    798                      TypeLookupTable::RawDataLength(header->class_defs_size_)))) {
    799       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with truncated "
    800                                     "type lookup table, offset %u of %zu, class defs %u",
    801                                 GetLocation().c_str(),
    802                                 i,
    803                                 dex_file_location.c_str(),
    804                                 lookup_table_offset,
    805                                 Size(),
    806                                 header->class_defs_size_);
    807       return false;
    808     }
    809 
    810     uint32_t dex_layout_sections_offset;
    811     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_layout_sections_offset))) {
    812       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zd for '%s' truncated "
    813                                     "after dex layout sections offset",
    814                                 GetLocation().c_str(),
    815                                 i,
    816                                 dex_file_location.c_str());
    817       return false;
    818     }
    819     const DexLayoutSections* const dex_layout_sections = dex_layout_sections_offset != 0
    820         ? reinterpret_cast<const DexLayoutSections*>(Begin() + dex_layout_sections_offset)
    821         : nullptr;
    822 
    823     const IndexBssMapping* method_bss_mapping;
    824     const IndexBssMapping* type_bss_mapping;
    825     const IndexBssMapping* string_bss_mapping;
    826     if (!ReadIndexBssMapping(
    827             this, &oat, i, dex_file_location, "method", &method_bss_mapping, error_msg) ||
    828         !ReadIndexBssMapping(
    829             this, &oat, i, dex_file_location, "type", &type_bss_mapping, error_msg) ||
    830         !ReadIndexBssMapping(
    831             this, &oat, i, dex_file_location, "string", &string_bss_mapping, error_msg)) {
    832       return false;
    833     }
    834     DCheckIndexToBssMapping(
    835         this, header->method_ids_size_, static_cast<size_t>(pointer_size), method_bss_mapping);
    836     DCheckIndexToBssMapping(
    837         this, header->type_ids_size_, sizeof(GcRoot<mirror::Class>), type_bss_mapping);
    838     DCheckIndexToBssMapping(
    839         this, header->string_ids_size_, sizeof(GcRoot<mirror::String>), string_bss_mapping);
    840 
    841     std::string canonical_location =
    842         DexFileLoader::GetDexCanonicalLocation(dex_file_location.c_str());
    843 
    844     // Create the OatDexFile and add it to the owning container.
    845     OatDexFile* oat_dex_file = new OatDexFile(this,
    846                                               dex_file_location,
    847                                               canonical_location,
    848                                               dex_file_checksum,
    849                                               dex_file_pointer,
    850                                               lookup_table_data,
    851                                               method_bss_mapping,
    852                                               type_bss_mapping,
    853                                               string_bss_mapping,
    854                                               class_offsets_pointer,
    855                                               dex_layout_sections);
    856     oat_dex_files_storage_.push_back(oat_dex_file);
    857 
    858     // Add the location and canonical location (if different) to the oat_dex_files_ table.
    859     StringPiece key(oat_dex_file->GetDexFileLocation());
    860     oat_dex_files_.Put(key, oat_dex_file);
    861     if (canonical_location != dex_file_location) {
    862       StringPiece canonical_key(oat_dex_file->GetCanonicalDexFileLocation());
    863       oat_dex_files_.Put(canonical_key, oat_dex_file);
    864     }
    865   }
    866 
    867   if (boot_image_tables != nullptr) {
    868     Runtime* runtime = Runtime::Current();
    869     if (UNLIKELY(runtime == nullptr)) {
    870       // This must be oatdump without boot image. Make sure the .bss is inaccessible.
    871       CheckedCall(mprotect, "protect bss", const_cast<uint8_t*>(BssBegin()), BssSize(), PROT_NONE);
    872     } else if (!IsExecutable()) {
    873       // Do not try to mmap boot image tables into .bss if the oat file is not executable.
    874     } else {
    875       // Map boot image tables into the .bss. The reserved size must match size of the tables.
    876       size_t reserved_size = static_cast<size_t>(boot_image_tables_end - boot_image_tables);
    877       size_t tables_size = 0u;
    878       for (gc::space::ImageSpace* space : runtime->GetHeap()->GetBootImageSpaces()) {
    879         tables_size += space->GetImageHeader().GetBootImageConstantTablesSize();
    880         DCHECK_ALIGNED(tables_size, kPageSize);
    881       }
    882       if (tables_size != reserved_size) {
    883         *error_msg = StringPrintf("In oat file '%s' found unexpected boot image table sizes, "
    884                                       " %zu bytes, should be %zu.",
    885                                   GetLocation().c_str(),
    886                                   reserved_size,
    887                                   tables_size);
    888         return false;
    889       }
    890       for (gc::space::ImageSpace* space : Runtime::Current()->GetHeap()->GetBootImageSpaces()) {
    891         uint32_t current_tables_size = space->GetImageHeader().GetBootImageConstantTablesSize();
    892         if (current_tables_size != 0u && !MapConstantTables(space, boot_image_tables)) {
    893           return false;
    894         }
    895         boot_image_tables += current_tables_size;
    896       }
    897       DCHECK(boot_image_tables == boot_image_tables_end);
    898     }
    899   }
    900   return true;
    901 }
    902 
    903 ////////////////////////
    904 // OatFile via dlopen //
    905 ////////////////////////
    906 
    907 class DlOpenOatFile FINAL : public OatFileBase {
    908  public:
    909   DlOpenOatFile(const std::string& filename, bool executable)
    910       : OatFileBase(filename, executable),
    911         dlopen_handle_(nullptr),
    912         shared_objects_before_(0) {
    913   }
    914 
    915   ~DlOpenOatFile() {
    916     if (dlopen_handle_ != nullptr) {
    917       if (!kIsTargetBuild) {
    918         MutexLock mu(Thread::Current(), *Locks::host_dlopen_handles_lock_);
    919         host_dlopen_handles_.erase(dlopen_handle_);
    920         dlclose(dlopen_handle_);
    921       } else {
    922         dlclose(dlopen_handle_);
    923       }
    924     }
    925   }
    926 
    927  protected:
    928   const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name,
    929                                           std::string* error_msg) const OVERRIDE {
    930     const uint8_t* ptr =
    931         reinterpret_cast<const uint8_t*>(dlsym(dlopen_handle_, symbol_name.c_str()));
    932     if (ptr == nullptr) {
    933       *error_msg = dlerror();
    934     }
    935     return ptr;
    936   }
    937 
    938   void PreLoad() OVERRIDE;
    939 
    940   bool Load(const std::string& elf_filename,
    941             uint8_t* oat_file_begin,
    942             bool writable,
    943             bool executable,
    944             bool low_4gb,
    945             std::string* error_msg) OVERRIDE;
    946 
    947   bool Load(int, uint8_t*, bool, bool, bool, std::string*) {
    948     return false;
    949   }
    950 
    951   // Ask the linker where it mmaped the file and notify our mmap wrapper of the regions.
    952   void PreSetup(const std::string& elf_filename) OVERRIDE;
    953 
    954  private:
    955   bool Dlopen(const std::string& elf_filename,
    956               uint8_t* oat_file_begin,
    957               std::string* error_msg);
    958 
    959   // On the host, if the same library is loaded again with dlopen the same
    960   // file handle is returned. This differs from the behavior of dlopen on the
    961   // target, where dlopen reloads the library at a different address every
    962   // time you load it. The runtime relies on the target behavior to ensure
    963   // each instance of the loaded library has a unique dex cache. To avoid
    964   // problems, we fall back to our own linker in the case when the same
    965   // library is opened multiple times on host. dlopen_handles_ is used to
    966   // detect that case.
    967   // Guarded by host_dlopen_handles_lock_;
    968   static std::unordered_set<void*> host_dlopen_handles_;
    969 
    970   // dlopen handle during runtime.
    971   void* dlopen_handle_;  // TODO: Unique_ptr with custom deleter.
    972 
    973   // Dummy memory map objects corresponding to the regions mapped by dlopen.
    974   std::vector<std::unique_ptr<MemMap>> dlopen_mmaps_;
    975 
    976   // The number of shared objects the linker told us about before loading. Used to
    977   // (optimistically) optimize the PreSetup stage (see comment there).
    978   size_t shared_objects_before_;
    979 
    980   DISALLOW_COPY_AND_ASSIGN(DlOpenOatFile);
    981 };
    982 
    983 std::unordered_set<void*> DlOpenOatFile::host_dlopen_handles_;
    984 
    985 void DlOpenOatFile::PreLoad() {
    986 #ifdef __APPLE__
    987   UNUSED(shared_objects_before_);
    988   LOG(FATAL) << "Should not reach here.";
    989   UNREACHABLE();
    990 #else
    991   // Count the entries in dl_iterate_phdr we get at this point in time.
    992   struct dl_iterate_context {
    993     static int callback(struct dl_phdr_info *info ATTRIBUTE_UNUSED,
    994                         size_t size ATTRIBUTE_UNUSED,
    995                         void *data) {
    996       reinterpret_cast<dl_iterate_context*>(data)->count++;
    997       return 0;  // Continue iteration.
    998     }
    999     size_t count = 0;
   1000   } context;
   1001 
   1002   dl_iterate_phdr(dl_iterate_context::callback, &context);
   1003   shared_objects_before_ = context.count;
   1004 #endif
   1005 }
   1006 
   1007 bool DlOpenOatFile::Load(const std::string& elf_filename,
   1008                          uint8_t* oat_file_begin,
   1009                          bool writable,
   1010                          bool executable,
   1011                          bool low_4gb,
   1012                          std::string* error_msg) {
   1013   // Use dlopen only when flagged to do so, and when it's OK to load things executable.
   1014   // TODO: Also try when not executable? The issue here could be re-mapping as writable (as
   1015   //       !executable is a sign that we may want to patch), which may not be allowed for
   1016   //       various reasons.
   1017   if (!kUseDlopen) {
   1018     *error_msg = "DlOpen is disabled.";
   1019     return false;
   1020   }
   1021   if (low_4gb) {
   1022     *error_msg = "DlOpen does not support low 4gb loading.";
   1023     return false;
   1024   }
   1025   if (writable) {
   1026     *error_msg = "DlOpen does not support writable loading.";
   1027     return false;
   1028   }
   1029   if (!executable) {
   1030     *error_msg = "DlOpen does not support non-executable loading.";
   1031     return false;
   1032   }
   1033 
   1034   // dlopen always returns the same library if it is already opened on the host. For this reason
   1035   // we only use dlopen if we are the target or we do not already have the dex file opened. Having
   1036   // the same library loaded multiple times at different addresses is required for class unloading
   1037   // and for having dex caches arrays in the .bss section.
   1038   if (!kIsTargetBuild) {
   1039     if (!kUseDlopenOnHost) {
   1040       *error_msg = "DlOpen disabled for host.";
   1041       return false;
   1042     }
   1043   }
   1044 
   1045   bool success = Dlopen(elf_filename, oat_file_begin, error_msg);
   1046   DCHECK(dlopen_handle_ != nullptr || !success);
   1047 
   1048   return success;
   1049 }
   1050 
   1051 bool DlOpenOatFile::Dlopen(const std::string& elf_filename,
   1052                            uint8_t* oat_file_begin,
   1053                            std::string* error_msg) {
   1054 #ifdef __APPLE__
   1055   // The dl_iterate_phdr syscall is missing.  There is similar API on OSX,
   1056   // but let's fallback to the custom loading code for the time being.
   1057   UNUSED(elf_filename, oat_file_begin);
   1058   *error_msg = "Dlopen unsupported on Mac.";
   1059   return false;
   1060 #else
   1061   {
   1062     UniqueCPtr<char> absolute_path(realpath(elf_filename.c_str(), nullptr));
   1063     if (absolute_path == nullptr) {
   1064       *error_msg = StringPrintf("Failed to find absolute path for '%s'", elf_filename.c_str());
   1065       return false;
   1066     }
   1067 #ifdef ART_TARGET_ANDROID
   1068     android_dlextinfo extinfo = {};
   1069     extinfo.flags = ANDROID_DLEXT_FORCE_LOAD |                  // Force-load, don't reuse handle
   1070                                                                 //   (open oat files multiple
   1071                                                                 //    times).
   1072                     ANDROID_DLEXT_FORCE_FIXED_VADDR;            // Take a non-zero vaddr as absolute
   1073                                                                 //   (non-pic boot image).
   1074     if (oat_file_begin != nullptr) {                            //
   1075       extinfo.flags |= ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS;     // Use the requested addr if
   1076       extinfo.reserved_addr = oat_file_begin;                   // vaddr = 0.
   1077     }                                                           //   (pic boot image).
   1078     dlopen_handle_ = android_dlopen_ext(absolute_path.get(), RTLD_NOW, &extinfo);
   1079 #else
   1080     UNUSED(oat_file_begin);
   1081     static_assert(!kIsTargetBuild || kIsTargetLinux, "host_dlopen_handles_ will leak handles");
   1082     MutexLock mu(Thread::Current(), *Locks::host_dlopen_handles_lock_);
   1083     dlopen_handle_ = dlopen(absolute_path.get(), RTLD_NOW);
   1084     if (dlopen_handle_ != nullptr) {
   1085       if (!host_dlopen_handles_.insert(dlopen_handle_).second) {
   1086         dlclose(dlopen_handle_);
   1087         dlopen_handle_ = nullptr;
   1088         *error_msg = StringPrintf("host dlopen re-opened '%s'", elf_filename.c_str());
   1089         return false;
   1090       }
   1091     }
   1092 #endif  // ART_TARGET_ANDROID
   1093   }
   1094   if (dlopen_handle_ == nullptr) {
   1095     *error_msg = StringPrintf("Failed to dlopen '%s': %s", elf_filename.c_str(), dlerror());
   1096     return false;
   1097   }
   1098   return true;
   1099 #endif
   1100 }
   1101 
   1102 void DlOpenOatFile::PreSetup(const std::string& elf_filename) {
   1103 #ifdef __APPLE__
   1104   UNUSED(elf_filename);
   1105   LOG(FATAL) << "Should not reach here.";
   1106   UNREACHABLE();
   1107 #else
   1108   struct dl_iterate_context {
   1109     static int callback(struct dl_phdr_info *info, size_t /* size */, void *data) {
   1110       auto* context = reinterpret_cast<dl_iterate_context*>(data);
   1111       context->shared_objects_seen++;
   1112       if (context->shared_objects_seen < context->shared_objects_before) {
   1113         // We haven't been called yet for anything we haven't seen before. Just continue.
   1114         // Note: this is aggressively optimistic. If another thread was unloading a library,
   1115         //       we may miss out here. However, this does not happen often in practice.
   1116         return 0;
   1117       }
   1118 
   1119       // See whether this callback corresponds to the file which we have just loaded.
   1120       bool contains_begin = false;
   1121       for (int i = 0; i < info->dlpi_phnum; i++) {
   1122         if (info->dlpi_phdr[i].p_type == PT_LOAD) {
   1123           uint8_t* vaddr = reinterpret_cast<uint8_t*>(info->dlpi_addr +
   1124               info->dlpi_phdr[i].p_vaddr);
   1125           size_t memsz = info->dlpi_phdr[i].p_memsz;
   1126           if (vaddr <= context->begin_ && context->begin_ < vaddr + memsz) {
   1127             contains_begin = true;
   1128             break;
   1129           }
   1130         }
   1131       }
   1132       // Add dummy mmaps for this file.
   1133       if (contains_begin) {
   1134         for (int i = 0; i < info->dlpi_phnum; i++) {
   1135           if (info->dlpi_phdr[i].p_type == PT_LOAD) {
   1136             uint8_t* vaddr = reinterpret_cast<uint8_t*>(info->dlpi_addr +
   1137                 info->dlpi_phdr[i].p_vaddr);
   1138             size_t memsz = info->dlpi_phdr[i].p_memsz;
   1139             MemMap* mmap = MemMap::MapDummy(info->dlpi_name, vaddr, memsz);
   1140             context->dlopen_mmaps_->push_back(std::unique_ptr<MemMap>(mmap));
   1141           }
   1142         }
   1143         return 1;  // Stop iteration and return 1 from dl_iterate_phdr.
   1144       }
   1145       return 0;  // Continue iteration and return 0 from dl_iterate_phdr when finished.
   1146     }
   1147     const uint8_t* const begin_;
   1148     std::vector<std::unique_ptr<MemMap>>* const dlopen_mmaps_;
   1149     const size_t shared_objects_before;
   1150     size_t shared_objects_seen;
   1151   };
   1152   dl_iterate_context context = { Begin(), &dlopen_mmaps_, shared_objects_before_, 0};
   1153 
   1154   if (dl_iterate_phdr(dl_iterate_context::callback, &context) == 0) {
   1155     // Hm. Maybe our optimization went wrong. Try another time with shared_objects_before == 0
   1156     // before giving up. This should be unusual.
   1157     VLOG(oat) << "Need a second run in PreSetup, didn't find with shared_objects_before="
   1158               << shared_objects_before_;
   1159     dl_iterate_context context0 = { Begin(), &dlopen_mmaps_, 0, 0};
   1160     if (dl_iterate_phdr(dl_iterate_context::callback, &context0) == 0) {
   1161       // OK, give up and print an error.
   1162       PrintFileToLog("/proc/self/maps", android::base::LogSeverity::WARNING);
   1163       LOG(ERROR) << "File " << elf_filename << " loaded with dlopen but cannot find its mmaps.";
   1164     }
   1165   }
   1166 #endif
   1167 }
   1168 
   1169 ////////////////////////////////////////////////
   1170 // OatFile via our own ElfFile implementation //
   1171 ////////////////////////////////////////////////
   1172 
   1173 class ElfOatFile FINAL : public OatFileBase {
   1174  public:
   1175   ElfOatFile(const std::string& filename, bool executable) : OatFileBase(filename, executable) {}
   1176 
   1177   static ElfOatFile* OpenElfFile(int zip_fd,
   1178                                  File* file,
   1179                                  const std::string& location,
   1180                                  uint8_t* requested_base,
   1181                                  uint8_t* oat_file_begin,  // Override base if not null
   1182                                  bool writable,
   1183                                  bool executable,
   1184                                  bool low_4gb,
   1185                                  const char* abs_dex_location,
   1186                                  std::string* error_msg);
   1187 
   1188   bool InitializeFromElfFile(int zip_fd,
   1189                              ElfFile* elf_file,
   1190                              VdexFile* vdex_file,
   1191                              const char* abs_dex_location,
   1192                              std::string* error_msg);
   1193 
   1194  protected:
   1195   const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name,
   1196                                           std::string* error_msg) const OVERRIDE {
   1197     const uint8_t* ptr = elf_file_->FindDynamicSymbolAddress(symbol_name);
   1198     if (ptr == nullptr) {
   1199       *error_msg = "(Internal implementation could not find symbol)";
   1200     }
   1201     return ptr;
   1202   }
   1203 
   1204   void PreLoad() OVERRIDE {
   1205   }
   1206 
   1207   bool Load(const std::string& elf_filename,
   1208             uint8_t* oat_file_begin,  // Override where the file is loaded to if not null
   1209             bool writable,
   1210             bool executable,
   1211             bool low_4gb,
   1212             std::string* error_msg) OVERRIDE;
   1213 
   1214   bool Load(int oat_fd,
   1215             uint8_t* oat_file_begin,  // Override where the file is loaded to if not null
   1216             bool writable,
   1217             bool executable,
   1218             bool low_4gb,
   1219             std::string* error_msg) OVERRIDE;
   1220 
   1221   void PreSetup(const std::string& elf_filename ATTRIBUTE_UNUSED) OVERRIDE {
   1222   }
   1223 
   1224  private:
   1225   bool ElfFileOpen(File* file,
   1226                    uint8_t* oat_file_begin,  // Override where the file is loaded to if not null
   1227                    bool writable,
   1228                    bool executable,
   1229                    bool low_4gb,
   1230                    std::string* error_msg);
   1231 
   1232  private:
   1233   // Backing memory map for oat file during cross compilation.
   1234   std::unique_ptr<ElfFile> elf_file_;
   1235 
   1236   DISALLOW_COPY_AND_ASSIGN(ElfOatFile);
   1237 };
   1238 
   1239 ElfOatFile* ElfOatFile::OpenElfFile(int zip_fd,
   1240                                     File* file,
   1241                                     const std::string& location,
   1242                                     uint8_t* requested_base,
   1243                                     uint8_t* oat_file_begin,  // Override base if not null
   1244                                     bool writable,
   1245                                     bool executable,
   1246                                     bool low_4gb,
   1247                                     const char* abs_dex_location,
   1248                                     std::string* error_msg) {
   1249   ScopedTrace trace("Open elf file " + location);
   1250   std::unique_ptr<ElfOatFile> oat_file(new ElfOatFile(location, executable));
   1251   bool success = oat_file->ElfFileOpen(file,
   1252                                        oat_file_begin,
   1253                                        writable,
   1254                                        low_4gb,
   1255                                        executable,
   1256                                        error_msg);
   1257   if (!success) {
   1258     CHECK(!error_msg->empty());
   1259     return nullptr;
   1260   }
   1261 
   1262   // Complete the setup.
   1263   if (!oat_file->ComputeFields(requested_base, file->GetPath(), error_msg)) {
   1264     return nullptr;
   1265   }
   1266 
   1267   if (!oat_file->Setup(zip_fd, abs_dex_location, error_msg)) {
   1268     return nullptr;
   1269   }
   1270 
   1271   return oat_file.release();
   1272 }
   1273 
   1274 bool ElfOatFile::InitializeFromElfFile(int zip_fd,
   1275                                        ElfFile* elf_file,
   1276                                        VdexFile* vdex_file,
   1277                                        const char* abs_dex_location,
   1278                                        std::string* error_msg) {
   1279   ScopedTrace trace(__PRETTY_FUNCTION__);
   1280   if (IsExecutable()) {
   1281     *error_msg = "Cannot initialize from elf file in executable mode.";
   1282     return false;
   1283   }
   1284   elf_file_.reset(elf_file);
   1285   SetVdex(vdex_file);
   1286   uint64_t offset, size;
   1287   bool has_section = elf_file->GetSectionOffsetAndSize(".rodata", &offset, &size);
   1288   CHECK(has_section);
   1289   SetBegin(elf_file->Begin() + offset);
   1290   SetEnd(elf_file->Begin() + size + offset);
   1291   // Ignore the optional .bss section when opening non-executable.
   1292   return Setup(zip_fd, abs_dex_location, error_msg);
   1293 }
   1294 
   1295 bool ElfOatFile::Load(const std::string& elf_filename,
   1296                       uint8_t* oat_file_begin,  // Override where the file is loaded to if not null
   1297                       bool writable,
   1298                       bool executable,
   1299                       bool low_4gb,
   1300                       std::string* error_msg) {
   1301   ScopedTrace trace(__PRETTY_FUNCTION__);
   1302   std::unique_ptr<File> file(OS::OpenFileForReading(elf_filename.c_str()));
   1303   if (file == nullptr) {
   1304     *error_msg = StringPrintf("Failed to open oat filename for reading: %s", strerror(errno));
   1305     return false;
   1306   }
   1307   return ElfOatFile::ElfFileOpen(file.get(),
   1308                                  oat_file_begin,
   1309                                  writable,
   1310                                  executable,
   1311                                  low_4gb,
   1312                                  error_msg);
   1313 }
   1314 
   1315 bool ElfOatFile::Load(int oat_fd,
   1316                       uint8_t* oat_file_begin,  // Override where the file is loaded to if not null
   1317                       bool writable,
   1318                       bool executable,
   1319                       bool low_4gb,
   1320                       std::string* error_msg) {
   1321   ScopedTrace trace(__PRETTY_FUNCTION__);
   1322   if (oat_fd != -1) {
   1323     std::unique_ptr<File> file = std::make_unique<File>(oat_fd, false);
   1324     file->DisableAutoClose();
   1325     if (file == nullptr) {
   1326       *error_msg = StringPrintf("Failed to open oat filename for reading: %s",
   1327                                 strerror(errno));
   1328       return false;
   1329     }
   1330     return ElfOatFile::ElfFileOpen(file.get(),
   1331                                    oat_file_begin,
   1332                                    writable,
   1333                                    executable,
   1334                                    low_4gb,
   1335                                    error_msg);
   1336   }
   1337   return false;
   1338 }
   1339 
   1340 bool ElfOatFile::ElfFileOpen(File* file,
   1341                              uint8_t* oat_file_begin,
   1342                              bool writable,
   1343                              bool executable,
   1344                              bool low_4gb,
   1345                              std::string* error_msg) {
   1346   ScopedTrace trace(__PRETTY_FUNCTION__);
   1347   // TODO: rename requested_base to oat_data_begin
   1348   elf_file_.reset(ElfFile::Open(file,
   1349                                 writable,
   1350                                 /*program_header_only*/true,
   1351                                 low_4gb,
   1352                                 error_msg,
   1353                                 oat_file_begin));
   1354   if (elf_file_ == nullptr) {
   1355     DCHECK(!error_msg->empty());
   1356     return false;
   1357   }
   1358   bool loaded = elf_file_->Load(file, executable, low_4gb, error_msg);
   1359   DCHECK(loaded || !error_msg->empty());
   1360   return loaded;
   1361 }
   1362 
   1363 //////////////////////////
   1364 // General OatFile code //
   1365 //////////////////////////
   1366 
   1367 std::string OatFile::ResolveRelativeEncodedDexLocation(
   1368       const char* abs_dex_location, const std::string& rel_dex_location) {
   1369   // For host, we still do resolution as the rel_dex_location might be absolute
   1370   // for a target dex (for example /system/foo/foo.apk).
   1371   if (abs_dex_location != nullptr && (rel_dex_location[0] != '/' || !kIsTargetBuild)) {
   1372     // Strip :classes<N>.dex used for secondary multidex files.
   1373     std::string base = DexFileLoader::GetBaseLocation(rel_dex_location);
   1374     std::string multidex_suffix = DexFileLoader::GetMultiDexSuffix(rel_dex_location);
   1375 
   1376     // Check if the base is a suffix of the provided abs_dex_location.
   1377     std::string target_suffix = ((rel_dex_location[0] != '/') ? "/" : "") + base;
   1378     std::string abs_location(abs_dex_location);
   1379     if (abs_location.size() > target_suffix.size()) {
   1380       size_t pos = abs_location.size() - target_suffix.size();
   1381       if (abs_location.compare(pos, std::string::npos, target_suffix) == 0) {
   1382         return abs_location + multidex_suffix;
   1383       }
   1384     }
   1385   }
   1386   return rel_dex_location;
   1387 }
   1388 
   1389 static void CheckLocation(const std::string& location) {
   1390   CHECK(!location.empty());
   1391 }
   1392 
   1393 OatFile* OatFile::OpenWithElfFile(int zip_fd,
   1394                                   ElfFile* elf_file,
   1395                                   VdexFile* vdex_file,
   1396                                   const std::string& location,
   1397                                   const char* abs_dex_location,
   1398                                   std::string* error_msg) {
   1399   std::unique_ptr<ElfOatFile> oat_file(new ElfOatFile(location, false /* executable */));
   1400   return oat_file->InitializeFromElfFile(zip_fd, elf_file, vdex_file, abs_dex_location, error_msg)
   1401       ? oat_file.release()
   1402       : nullptr;
   1403 }
   1404 
   1405 OatFile* OatFile::Open(int zip_fd,
   1406                        const std::string& oat_filename,
   1407                        const std::string& oat_location,
   1408                        uint8_t* requested_base,
   1409                        uint8_t* oat_file_begin,
   1410                        bool executable,
   1411                        bool low_4gb,
   1412                        const char* abs_dex_location,
   1413                        std::string* error_msg) {
   1414   ScopedTrace trace("Open oat file " + oat_location);
   1415   CHECK(!oat_filename.empty()) << oat_location;
   1416   CheckLocation(oat_location);
   1417 
   1418   std::string vdex_filename = GetVdexFilename(oat_filename);
   1419 
   1420   // Check that the files even exist, fast-fail.
   1421   if (!OS::FileExists(vdex_filename.c_str())) {
   1422     *error_msg = StringPrintf("File %s does not exist.", vdex_filename.c_str());
   1423     return nullptr;
   1424   } else if (!OS::FileExists(oat_filename.c_str())) {
   1425     *error_msg = StringPrintf("File %s does not exist.", oat_filename.c_str());
   1426     return nullptr;
   1427   }
   1428 
   1429   // Try dlopen first, as it is required for native debuggability. This will fail fast if dlopen is
   1430   // disabled.
   1431   OatFile* with_dlopen = OatFileBase::OpenOatFile<DlOpenOatFile>(zip_fd,
   1432                                                                  vdex_filename,
   1433                                                                  oat_filename,
   1434                                                                  oat_location,
   1435                                                                  requested_base,
   1436                                                                  oat_file_begin,
   1437                                                                  false /* writable */,
   1438                                                                  executable,
   1439                                                                  low_4gb,
   1440                                                                  abs_dex_location,
   1441                                                                  error_msg);
   1442   if (with_dlopen != nullptr) {
   1443     return with_dlopen;
   1444   }
   1445   if (kPrintDlOpenErrorMessage) {
   1446     LOG(ERROR) << "Failed to dlopen: " << oat_filename << " with error " << *error_msg;
   1447   }
   1448   // If we aren't trying to execute, we just use our own ElfFile loader for a couple reasons:
   1449   //
   1450   // On target, dlopen may fail when compiling due to selinux restrictions on installd.
   1451   //
   1452   // We use our own ELF loader for Quick to deal with legacy apps that
   1453   // open a generated dex file by name, remove the file, then open
   1454   // another generated dex file with the same name. http://b/10614658
   1455   //
   1456   // On host, dlopen is expected to fail when cross compiling, so fall back to OpenElfFile.
   1457   //
   1458   //
   1459   // Another independent reason is the absolute placement of boot.oat. dlopen on the host usually
   1460   // does honor the virtual address encoded in the ELF file only for ET_EXEC files, not ET_DYN.
   1461   OatFile* with_internal = OatFileBase::OpenOatFile<ElfOatFile>(zip_fd,
   1462                                                                 vdex_filename,
   1463                                                                 oat_filename,
   1464                                                                 oat_location,
   1465                                                                 requested_base,
   1466                                                                 oat_file_begin,
   1467                                                                 false /* writable */,
   1468                                                                 executable,
   1469                                                                 low_4gb,
   1470                                                                 abs_dex_location,
   1471                                                                 error_msg);
   1472   return with_internal;
   1473 }
   1474 
   1475 OatFile* OatFile::Open(int zip_fd,
   1476                        int vdex_fd,
   1477                        int oat_fd,
   1478                        const std::string& oat_location,
   1479                        uint8_t* requested_base,
   1480                        uint8_t* oat_file_begin,
   1481                        bool executable,
   1482                        bool low_4gb,
   1483                        const char* abs_dex_location,
   1484                        std::string* error_msg) {
   1485   CHECK(!oat_location.empty()) << oat_location;
   1486 
   1487   std::string vdex_location = GetVdexFilename(oat_location);
   1488 
   1489   OatFile* with_internal = OatFileBase::OpenOatFile<ElfOatFile>(zip_fd,
   1490                                                                 vdex_fd,
   1491                                                                 oat_fd,
   1492                                                                 vdex_location,
   1493                                                                 oat_location,
   1494                                                                 requested_base,
   1495                                                                 oat_file_begin,
   1496                                                                 false /* writable */,
   1497                                                                 executable,
   1498                                                                 low_4gb,
   1499                                                                 abs_dex_location,
   1500                                                                 error_msg);
   1501   return with_internal;
   1502 }
   1503 
   1504 OatFile* OatFile::OpenWritable(int zip_fd,
   1505                                File* file,
   1506                                const std::string& location,
   1507                                const char* abs_dex_location,
   1508                                std::string* error_msg) {
   1509   CheckLocation(location);
   1510   return ElfOatFile::OpenElfFile(zip_fd,
   1511                                  file,
   1512                                  location,
   1513                                  nullptr,
   1514                                  nullptr,
   1515                                  true,
   1516                                  false,
   1517                                  /*low_4gb*/false,
   1518                                  abs_dex_location,
   1519                                  error_msg);
   1520 }
   1521 
   1522 OatFile* OatFile::OpenReadable(int zip_fd,
   1523                                File* file,
   1524                                const std::string& location,
   1525                                const char* abs_dex_location,
   1526                                std::string* error_msg) {
   1527   CheckLocation(location);
   1528   return ElfOatFile::OpenElfFile(zip_fd,
   1529                                  file,
   1530                                  location,
   1531                                  nullptr,
   1532                                  nullptr,
   1533                                  false,
   1534                                  false,
   1535                                  /*low_4gb*/false,
   1536                                  abs_dex_location,
   1537                                  error_msg);
   1538 }
   1539 
   1540 OatFile::OatFile(const std::string& location, bool is_executable)
   1541     : location_(location),
   1542       vdex_(nullptr),
   1543       begin_(nullptr),
   1544       end_(nullptr),
   1545       bss_begin_(nullptr),
   1546       bss_end_(nullptr),
   1547       bss_methods_(nullptr),
   1548       bss_roots_(nullptr),
   1549       is_executable_(is_executable),
   1550       vdex_begin_(nullptr),
   1551       vdex_end_(nullptr),
   1552       secondary_lookup_lock_("OatFile secondary lookup lock", kOatFileSecondaryLookupLock) {
   1553   CHECK(!location_.empty());
   1554 }
   1555 
   1556 OatFile::~OatFile() {
   1557   STLDeleteElements(&oat_dex_files_storage_);
   1558 }
   1559 
   1560 const OatHeader& OatFile::GetOatHeader() const {
   1561   return *reinterpret_cast<const OatHeader*>(Begin());
   1562 }
   1563 
   1564 const uint8_t* OatFile::Begin() const {
   1565   CHECK(begin_ != nullptr);
   1566   return begin_;
   1567 }
   1568 
   1569 const uint8_t* OatFile::End() const {
   1570   CHECK(end_ != nullptr);
   1571   return end_;
   1572 }
   1573 
   1574 const uint8_t* OatFile::BssBegin() const {
   1575   return bss_begin_;
   1576 }
   1577 
   1578 const uint8_t* OatFile::BssEnd() const {
   1579   return bss_end_;
   1580 }
   1581 
   1582 const uint8_t* OatFile::VdexBegin() const {
   1583   return vdex_begin_;
   1584 }
   1585 
   1586 const uint8_t* OatFile::VdexEnd() const {
   1587   return vdex_end_;
   1588 }
   1589 
   1590 const uint8_t* OatFile::DexBegin() const {
   1591   return vdex_->Begin();
   1592 }
   1593 
   1594 const uint8_t* OatFile::DexEnd() const {
   1595   return vdex_->End();
   1596 }
   1597 
   1598 ArrayRef<ArtMethod*> OatFile::GetBssMethods() const {
   1599   if (bss_methods_ != nullptr) {
   1600     ArtMethod** methods = reinterpret_cast<ArtMethod**>(bss_methods_);
   1601     ArtMethod** methods_end =
   1602         reinterpret_cast<ArtMethod**>(bss_roots_ != nullptr ? bss_roots_ : bss_end_);
   1603     return ArrayRef<ArtMethod*>(methods, methods_end - methods);
   1604   } else {
   1605     return ArrayRef<ArtMethod*>();
   1606   }
   1607 }
   1608 
   1609 ArrayRef<GcRoot<mirror::Object>> OatFile::GetBssGcRoots() const {
   1610   if (bss_roots_ != nullptr) {
   1611     auto* roots = reinterpret_cast<GcRoot<mirror::Object>*>(bss_roots_);
   1612     auto* roots_end = reinterpret_cast<GcRoot<mirror::Object>*>(bss_end_);
   1613     return ArrayRef<GcRoot<mirror::Object>>(roots, roots_end - roots);
   1614   } else {
   1615     return ArrayRef<GcRoot<mirror::Object>>();
   1616   }
   1617 }
   1618 
   1619 const OatFile::OatDexFile* OatFile::GetOatDexFile(const char* dex_location,
   1620                                                   const uint32_t* dex_location_checksum,
   1621                                                   std::string* error_msg) const {
   1622   // NOTE: We assume here that the canonical location for a given dex_location never
   1623   // changes. If it does (i.e. some symlink used by the filename changes) we may return
   1624   // an incorrect OatDexFile. As long as we have a checksum to check, we shall return
   1625   // an identical file or fail; otherwise we may see some unpredictable failures.
   1626 
   1627   // TODO: Additional analysis of usage patterns to see if this can be simplified
   1628   // without any performance loss, for example by not doing the first lock-free lookup.
   1629 
   1630   const OatFile::OatDexFile* oat_dex_file = nullptr;
   1631   StringPiece key(dex_location);
   1632   // Try to find the key cheaply in the oat_dex_files_ map which holds dex locations
   1633   // directly mentioned in the oat file and doesn't require locking.
   1634   auto primary_it = oat_dex_files_.find(key);
   1635   if (primary_it != oat_dex_files_.end()) {
   1636     oat_dex_file = primary_it->second;
   1637     DCHECK(oat_dex_file != nullptr);
   1638   } else {
   1639     // This dex_location is not one of the dex locations directly mentioned in the
   1640     // oat file. The correct lookup is via the canonical location but first see in
   1641     // the secondary_oat_dex_files_ whether we've looked up this location before.
   1642     MutexLock mu(Thread::Current(), secondary_lookup_lock_);
   1643     auto secondary_lb = secondary_oat_dex_files_.lower_bound(key);
   1644     if (secondary_lb != secondary_oat_dex_files_.end() && key == secondary_lb->first) {
   1645       oat_dex_file = secondary_lb->second;  // May be null.
   1646     } else {
   1647       // We haven't seen this dex_location before, we must check the canonical location.
   1648       std::string dex_canonical_location = DexFileLoader::GetDexCanonicalLocation(dex_location);
   1649       if (dex_canonical_location != dex_location) {
   1650         StringPiece canonical_key(dex_canonical_location);
   1651         auto canonical_it = oat_dex_files_.find(canonical_key);
   1652         if (canonical_it != oat_dex_files_.end()) {
   1653           oat_dex_file = canonical_it->second;
   1654         }  // else keep null.
   1655       }  // else keep null.
   1656 
   1657       // Copy the key to the string_cache_ and store the result in secondary map.
   1658       string_cache_.emplace_back(key.data(), key.length());
   1659       StringPiece key_copy(string_cache_.back());
   1660       secondary_oat_dex_files_.PutBefore(secondary_lb, key_copy, oat_dex_file);
   1661     }
   1662   }
   1663 
   1664   if (oat_dex_file == nullptr) {
   1665     if (error_msg != nullptr) {
   1666       std::string dex_canonical_location = DexFileLoader::GetDexCanonicalLocation(dex_location);
   1667       *error_msg = "Failed to find OatDexFile for DexFile " + std::string(dex_location)
   1668           + " (canonical path " + dex_canonical_location + ") in OatFile " + GetLocation();
   1669     }
   1670     return nullptr;
   1671   }
   1672 
   1673   if (dex_location_checksum != nullptr &&
   1674       oat_dex_file->GetDexFileLocationChecksum() != *dex_location_checksum) {
   1675     if (error_msg != nullptr) {
   1676       std::string dex_canonical_location = DexFileLoader::GetDexCanonicalLocation(dex_location);
   1677       std::string checksum = StringPrintf("0x%08x", oat_dex_file->GetDexFileLocationChecksum());
   1678       std::string required_checksum = StringPrintf("0x%08x", *dex_location_checksum);
   1679       *error_msg = "OatDexFile for DexFile " + std::string(dex_location)
   1680           + " (canonical path " + dex_canonical_location + ") in OatFile " + GetLocation()
   1681           + " has checksum " + checksum + " but " + required_checksum + " was required";
   1682     }
   1683     return nullptr;
   1684   }
   1685   return oat_dex_file;
   1686 }
   1687 
   1688 OatFile::OatDexFile::OatDexFile(const OatFile* oat_file,
   1689                                 const std::string& dex_file_location,
   1690                                 const std::string& canonical_dex_file_location,
   1691                                 uint32_t dex_file_location_checksum,
   1692                                 const uint8_t* dex_file_pointer,
   1693                                 const uint8_t* lookup_table_data,
   1694                                 const IndexBssMapping* method_bss_mapping_data,
   1695                                 const IndexBssMapping* type_bss_mapping_data,
   1696                                 const IndexBssMapping* string_bss_mapping_data,
   1697                                 const uint32_t* oat_class_offsets_pointer,
   1698                                 const DexLayoutSections* dex_layout_sections)
   1699     : oat_file_(oat_file),
   1700       dex_file_location_(dex_file_location),
   1701       canonical_dex_file_location_(canonical_dex_file_location),
   1702       dex_file_location_checksum_(dex_file_location_checksum),
   1703       dex_file_pointer_(dex_file_pointer),
   1704       lookup_table_data_(lookup_table_data),
   1705       method_bss_mapping_(method_bss_mapping_data),
   1706       type_bss_mapping_(type_bss_mapping_data),
   1707       string_bss_mapping_(string_bss_mapping_data),
   1708       oat_class_offsets_pointer_(oat_class_offsets_pointer),
   1709       dex_layout_sections_(dex_layout_sections) {
   1710   // Initialize TypeLookupTable.
   1711   if (lookup_table_data_ != nullptr) {
   1712     // Peek the number of classes from the DexFile.
   1713     const DexFile::Header* dex_header = reinterpret_cast<const DexFile::Header*>(dex_file_pointer_);
   1714     const uint32_t num_class_defs = dex_header->class_defs_size_;
   1715     if (lookup_table_data_ + TypeLookupTable::RawDataLength(num_class_defs) > GetOatFile()->End()) {
   1716       LOG(WARNING) << "found truncated lookup table in " << dex_file_location_;
   1717     } else {
   1718       const uint8_t* dex_data = dex_file_pointer_;
   1719       // TODO: Clean this up to create the type lookup table after the dex file has been created?
   1720       if (CompactDexFile::IsMagicValid(dex_header->magic_)) {
   1721         dex_data += dex_header->data_off_;
   1722       }
   1723       lookup_table_ = TypeLookupTable::Open(dex_data, lookup_table_data_, num_class_defs);
   1724     }
   1725   }
   1726 }
   1727 
   1728 OatFile::OatDexFile::OatDexFile(std::unique_ptr<TypeLookupTable>&& lookup_table)
   1729     : lookup_table_(std::move(lookup_table)) {}
   1730 
   1731 OatFile::OatDexFile::~OatDexFile() {}
   1732 
   1733 size_t OatFile::OatDexFile::FileSize() const {
   1734   return reinterpret_cast<const DexFile::Header*>(dex_file_pointer_)->file_size_;
   1735 }
   1736 
   1737 std::unique_ptr<const DexFile> OatFile::OatDexFile::OpenDexFile(std::string* error_msg) const {
   1738   ScopedTrace trace(__PRETTY_FUNCTION__);
   1739   static constexpr bool kVerify = false;
   1740   static constexpr bool kVerifyChecksum = false;
   1741   const ArtDexFileLoader dex_file_loader;
   1742   return dex_file_loader.Open(dex_file_pointer_,
   1743                               FileSize(),
   1744                               dex_file_location_,
   1745                               dex_file_location_checksum_,
   1746                               this,
   1747                               kVerify,
   1748                               kVerifyChecksum,
   1749                               error_msg);
   1750 }
   1751 
   1752 uint32_t OatFile::OatDexFile::GetOatClassOffset(uint16_t class_def_index) const {
   1753   return oat_class_offsets_pointer_[class_def_index];
   1754 }
   1755 
   1756 OatFile::OatClass OatFile::OatDexFile::GetOatClass(uint16_t class_def_index) const {
   1757   uint32_t oat_class_offset = GetOatClassOffset(class_def_index);
   1758 
   1759   const uint8_t* oat_class_pointer = oat_file_->Begin() + oat_class_offset;
   1760   CHECK_LT(oat_class_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1761 
   1762   const uint8_t* status_pointer = oat_class_pointer;
   1763   CHECK_LT(status_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1764   ClassStatus status = enum_cast<ClassStatus>(*reinterpret_cast<const int16_t*>(status_pointer));
   1765   CHECK_LE(status, ClassStatus::kLast);
   1766 
   1767   const uint8_t* type_pointer = status_pointer + sizeof(uint16_t);
   1768   CHECK_LT(type_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1769   OatClassType type = static_cast<OatClassType>(*reinterpret_cast<const uint16_t*>(type_pointer));
   1770   CHECK_LT(type, kOatClassMax);
   1771 
   1772   const uint8_t* after_type_pointer = type_pointer + sizeof(int16_t);
   1773   CHECK_LE(after_type_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1774 
   1775   uint32_t bitmap_size = 0;
   1776   const uint8_t* bitmap_pointer = nullptr;
   1777   const uint8_t* methods_pointer = nullptr;
   1778   if (type != kOatClassNoneCompiled) {
   1779     if (type == kOatClassSomeCompiled) {
   1780       bitmap_size = static_cast<uint32_t>(*reinterpret_cast<const uint32_t*>(after_type_pointer));
   1781       bitmap_pointer = after_type_pointer + sizeof(bitmap_size);
   1782       CHECK_LE(bitmap_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1783       methods_pointer = bitmap_pointer + bitmap_size;
   1784     } else {
   1785       methods_pointer = after_type_pointer;
   1786     }
   1787     CHECK_LE(methods_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1788   }
   1789 
   1790   return OatFile::OatClass(oat_file_,
   1791                            status,
   1792                            type,
   1793                            bitmap_size,
   1794                            reinterpret_cast<const uint32_t*>(bitmap_pointer),
   1795                            reinterpret_cast<const OatMethodOffsets*>(methods_pointer));
   1796 }
   1797 
   1798 const DexFile::ClassDef* OatFile::OatDexFile::FindClassDef(const DexFile& dex_file,
   1799                                                            const char* descriptor,
   1800                                                            size_t hash) {
   1801   const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
   1802   DCHECK_EQ(ComputeModifiedUtf8Hash(descriptor), hash);
   1803   bool used_lookup_table = false;
   1804   const DexFile::ClassDef* lookup_table_classdef = nullptr;
   1805   if (LIKELY((oat_dex_file != nullptr) && (oat_dex_file->GetTypeLookupTable() != nullptr))) {
   1806     used_lookup_table = true;
   1807     const uint32_t class_def_idx = oat_dex_file->GetTypeLookupTable()->Lookup(descriptor, hash);
   1808     lookup_table_classdef = (class_def_idx != dex::kDexNoIndex)
   1809         ? &dex_file.GetClassDef(class_def_idx)
   1810         : nullptr;
   1811     if (!kIsDebugBuild) {
   1812       return lookup_table_classdef;
   1813     }
   1814   }
   1815   // Fast path for rare no class defs case.
   1816   const uint32_t num_class_defs = dex_file.NumClassDefs();
   1817   if (num_class_defs == 0) {
   1818     return nullptr;
   1819   }
   1820   const DexFile::TypeId* type_id = dex_file.FindTypeId(descriptor);
   1821   if (type_id != nullptr) {
   1822     dex::TypeIndex type_idx = dex_file.GetIndexForTypeId(*type_id);
   1823     const DexFile::ClassDef* found_class_def = dex_file.FindClassDef(type_idx);
   1824     if (kIsDebugBuild && used_lookup_table) {
   1825       DCHECK_EQ(found_class_def, lookup_table_classdef);
   1826     }
   1827     return found_class_def;
   1828   }
   1829   return nullptr;
   1830 }
   1831 
   1832 // Madvise the dex file based on the state we are moving to.
   1833 void OatDexFile::MadviseDexFile(const DexFile& dex_file, MadviseState state) {
   1834   Runtime* const runtime = Runtime::Current();
   1835   const bool low_ram = runtime->GetHeap()->IsLowMemoryMode();
   1836   // TODO: Also do madvise hints for non low ram devices.
   1837   if (!low_ram) {
   1838     return;
   1839   }
   1840   if (state == MadviseState::kMadviseStateAtLoad && runtime->MAdviseRandomAccess()) {
   1841     // Default every dex file to MADV_RANDOM when its loaded by default for low ram devices.
   1842     // Other devices have enough page cache to get performance benefits from loading more pages
   1843     // into the page cache.
   1844     DexLayoutSection::MadviseLargestPageAlignedRegion(dex_file.Begin(),
   1845                                                       dex_file.Begin() + dex_file.Size(),
   1846                                                       MADV_RANDOM);
   1847   }
   1848   const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
   1849   if (oat_dex_file != nullptr) {
   1850     // Should always be there.
   1851     const DexLayoutSections* const sections = oat_dex_file->GetDexLayoutSections();
   1852     CHECK(sections != nullptr);
   1853     sections->Madvise(&dex_file, state);
   1854   }
   1855 }
   1856 
   1857 OatFile::OatClass::OatClass(const OatFile* oat_file,
   1858                             ClassStatus status,
   1859                             OatClassType type,
   1860                             uint32_t bitmap_size,
   1861                             const uint32_t* bitmap_pointer,
   1862                             const OatMethodOffsets* methods_pointer)
   1863     : oat_file_(oat_file), status_(status), type_(type),
   1864       bitmap_(bitmap_pointer), methods_pointer_(methods_pointer) {
   1865     switch (type_) {
   1866       case kOatClassAllCompiled: {
   1867         CHECK_EQ(0U, bitmap_size);
   1868         CHECK(bitmap_pointer == nullptr);
   1869         CHECK(methods_pointer != nullptr);
   1870         break;
   1871       }
   1872       case kOatClassSomeCompiled: {
   1873         CHECK_NE(0U, bitmap_size);
   1874         CHECK(bitmap_pointer != nullptr);
   1875         CHECK(methods_pointer != nullptr);
   1876         break;
   1877       }
   1878       case kOatClassNoneCompiled: {
   1879         CHECK_EQ(0U, bitmap_size);
   1880         CHECK(bitmap_pointer == nullptr);
   1881         CHECK(methods_pointer_ == nullptr);
   1882         break;
   1883       }
   1884       case kOatClassMax: {
   1885         LOG(FATAL) << "Invalid OatClassType " << type_;
   1886         break;
   1887       }
   1888     }
   1889 }
   1890 
   1891 uint32_t OatFile::OatClass::GetOatMethodOffsetsOffset(uint32_t method_index) const {
   1892   const OatMethodOffsets* oat_method_offsets = GetOatMethodOffsets(method_index);
   1893   if (oat_method_offsets == nullptr) {
   1894     return 0u;
   1895   }
   1896   return reinterpret_cast<const uint8_t*>(oat_method_offsets) - oat_file_->Begin();
   1897 }
   1898 
   1899 const OatMethodOffsets* OatFile::OatClass::GetOatMethodOffsets(uint32_t method_index) const {
   1900   // NOTE: We don't keep the number of methods and cannot do a bounds check for method_index.
   1901   if (methods_pointer_ == nullptr) {
   1902     CHECK_EQ(kOatClassNoneCompiled, type_);
   1903     return nullptr;
   1904   }
   1905   size_t methods_pointer_index;
   1906   if (bitmap_ == nullptr) {
   1907     CHECK_EQ(kOatClassAllCompiled, type_);
   1908     methods_pointer_index = method_index;
   1909   } else {
   1910     CHECK_EQ(kOatClassSomeCompiled, type_);
   1911     if (!BitVector::IsBitSet(bitmap_, method_index)) {
   1912       return nullptr;
   1913     }
   1914     size_t num_set_bits = BitVector::NumSetBits(bitmap_, method_index);
   1915     methods_pointer_index = num_set_bits;
   1916   }
   1917   const OatMethodOffsets& oat_method_offsets = methods_pointer_[methods_pointer_index];
   1918   return &oat_method_offsets;
   1919 }
   1920 
   1921 const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index) const {
   1922   const OatMethodOffsets* oat_method_offsets = GetOatMethodOffsets(method_index);
   1923   if (oat_method_offsets == nullptr) {
   1924     return OatMethod(nullptr, 0);
   1925   }
   1926   if (oat_file_->IsExecutable() ||
   1927       Runtime::Current() == nullptr ||        // This case applies for oatdump.
   1928       Runtime::Current()->IsAotCompiler()) {
   1929     return OatMethod(oat_file_->Begin(), oat_method_offsets->code_offset_);
   1930   }
   1931   // We aren't allowed to use the compiled code. We just force it down the interpreted / jit
   1932   // version.
   1933   return OatMethod(oat_file_->Begin(), 0);
   1934 }
   1935 
   1936 void OatFile::OatMethod::LinkMethod(ArtMethod* method) const {
   1937   CHECK(method != nullptr);
   1938   method->SetEntryPointFromQuickCompiledCode(GetQuickCode());
   1939 }
   1940 
   1941 bool OatFile::IsPic() const {
   1942   return GetOatHeader().IsPic();
   1943   // TODO: Check against oat_patches. b/18144996
   1944 }
   1945 
   1946 bool OatFile::IsDebuggable() const {
   1947   return GetOatHeader().IsDebuggable();
   1948 }
   1949 
   1950 CompilerFilter::Filter OatFile::GetCompilerFilter() const {
   1951   return GetOatHeader().GetCompilerFilter();
   1952 }
   1953 
   1954 std::string OatFile::GetClassLoaderContext() const {
   1955   return GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey);
   1956 }
   1957 
   1958 const char* OatFile::GetCompilationReason() const {
   1959   return GetOatHeader().GetStoreValueByKey(OatHeader::kCompilationReasonKey);
   1960 }
   1961 
   1962 OatFile::OatClass OatFile::FindOatClass(const DexFile& dex_file,
   1963                                         uint16_t class_def_idx,
   1964                                         bool* found) {
   1965   DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
   1966   const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
   1967   if (oat_dex_file == nullptr || oat_dex_file->GetOatFile() == nullptr) {
   1968     *found = false;
   1969     return OatFile::OatClass::Invalid();
   1970   }
   1971   *found = true;
   1972   return oat_dex_file->GetOatClass(class_def_idx);
   1973 }
   1974 
   1975 void OatFile::OatDexFile::AssertAotCompiler() {
   1976   CHECK(Runtime::Current()->IsAotCompiler());
   1977 }
   1978 
   1979 }  // namespace art
   1980