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 #include <string.h>
     21 #include <type_traits>
     22 #include <unistd.h>
     23 
     24 #include <cstdlib>
     25 #ifndef __APPLE__
     26 #include <link.h>  // for dl_iterate_phdr.
     27 #endif
     28 #include <sstream>
     29 
     30 // dlopen_ext support from bionic.
     31 #ifdef ART_TARGET_ANDROID
     32 #include "android/dlext.h"
     33 #endif
     34 
     35 #include "android-base/stringprintf.h"
     36 
     37 #include "art_method.h"
     38 #include "base/bit_vector.h"
     39 #include "base/enums.h"
     40 #include "base/stl_util.h"
     41 #include "base/systrace.h"
     42 #include "base/unix_file/fd_file.h"
     43 #include "dex_file_types.h"
     44 #include "elf_file.h"
     45 #include "elf_utils.h"
     46 #include "gc_root.h"
     47 #include "oat.h"
     48 #include "mem_map.h"
     49 #include "mirror/class.h"
     50 #include "mirror/object-inl.h"
     51 #include "oat_file-inl.h"
     52 #include "oat_file_manager.h"
     53 #include "os.h"
     54 #include "runtime.h"
     55 #include "type_lookup_table.h"
     56 #include "utf-inl.h"
     57 #include "utils.h"
     58 #include "utils/dex_cache_arrays_layout-inl.h"
     59 #include "vdex_file.h"
     60 
     61 namespace art {
     62 
     63 using android::base::StringPrintf;
     64 
     65 // Whether OatFile::Open will try dlopen. Fallback is our own ELF loader.
     66 static constexpr bool kUseDlopen = true;
     67 
     68 // Whether OatFile::Open will try dlopen on the host. On the host we're not linking against
     69 // bionic, so cannot take advantage of the support for changed semantics (loading the same soname
     70 // multiple times). However, if/when we switch the above, we likely want to switch this, too,
     71 // to get test coverage of the code paths.
     72 static constexpr bool kUseDlopenOnHost = true;
     73 
     74 // For debugging, Open will print DlOpen error message if set to true.
     75 static constexpr bool kPrintDlOpenErrorMessage = false;
     76 
     77 // Note for OatFileBase and descendents:
     78 //
     79 // These are used in OatFile::Open to try all our loaders.
     80 //
     81 // The process is simple:
     82 //
     83 // 1) Allocate an instance through the standard constructor (location, executable)
     84 // 2) Load() to try to open the file.
     85 // 3) ComputeFields() to populate the OatFile fields like begin_, using FindDynamicSymbolAddress.
     86 // 4) PreSetup() for any steps that should be done before the final setup.
     87 // 5) Setup() to complete the procedure.
     88 
     89 class OatFileBase : public OatFile {
     90  public:
     91   virtual ~OatFileBase() {}
     92 
     93   template <typename kOatFileBaseSubType>
     94   static OatFileBase* OpenOatFile(const std::string& vdex_filename,
     95                                   const std::string& elf_filename,
     96                                   const std::string& location,
     97                                   uint8_t* requested_base,
     98                                   uint8_t* oat_file_begin,
     99                                   bool writable,
    100                                   bool executable,
    101                                   bool low_4gb,
    102                                   const char* abs_dex_location,
    103                                   std::string* error_msg);
    104 
    105  protected:
    106   OatFileBase(const std::string& filename, bool executable) : OatFile(filename, executable) {}
    107 
    108   virtual const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name,
    109                                                   std::string* error_msg) const = 0;
    110 
    111   virtual void PreLoad() = 0;
    112 
    113   bool LoadVdex(const std::string& vdex_filename,
    114                 bool writable,
    115                 bool low_4gb,
    116                 std::string* error_msg);
    117 
    118   virtual bool Load(const std::string& elf_filename,
    119                     uint8_t* oat_file_begin,
    120                     bool writable,
    121                     bool executable,
    122                     bool low_4gb,
    123                     std::string* error_msg) = 0;
    124 
    125   bool ComputeFields(uint8_t* requested_base,
    126                      const std::string& file_path,
    127                      std::string* error_msg);
    128 
    129   virtual void PreSetup(const std::string& elf_filename) = 0;
    130 
    131   bool Setup(const char* abs_dex_location, std::string* error_msg);
    132 
    133   // Setters exposed for ElfOatFile.
    134 
    135   void SetBegin(const uint8_t* begin) {
    136     begin_ = begin;
    137   }
    138 
    139   void SetEnd(const uint8_t* end) {
    140     end_ = end;
    141   }
    142 
    143   void SetVdex(VdexFile* vdex) {
    144     vdex_.reset(vdex);
    145   }
    146 
    147  private:
    148   DISALLOW_COPY_AND_ASSIGN(OatFileBase);
    149 };
    150 
    151 template <typename kOatFileBaseSubType>
    152 OatFileBase* OatFileBase::OpenOatFile(const std::string& vdex_filename,
    153                                       const std::string& elf_filename,
    154                                       const std::string& location,
    155                                       uint8_t* requested_base,
    156                                       uint8_t* oat_file_begin,
    157                                       bool writable,
    158                                       bool executable,
    159                                       bool low_4gb,
    160                                       const char* abs_dex_location,
    161                                       std::string* error_msg) {
    162   std::unique_ptr<OatFileBase> ret(new kOatFileBaseSubType(location, executable));
    163 
    164   ret->PreLoad();
    165 
    166   if (kIsVdexEnabled && !ret->LoadVdex(vdex_filename, writable, low_4gb, error_msg)) {
    167     return nullptr;
    168   }
    169 
    170   if (!ret->Load(elf_filename,
    171                  oat_file_begin,
    172                  writable,
    173                  executable,
    174                  low_4gb,
    175                  error_msg)) {
    176     return nullptr;
    177   }
    178 
    179   if (!ret->ComputeFields(requested_base, elf_filename, error_msg)) {
    180     return nullptr;
    181   }
    182 
    183   ret->PreSetup(elf_filename);
    184 
    185   if (!ret->Setup(abs_dex_location, error_msg)) {
    186     return nullptr;
    187   }
    188 
    189   return ret.release();
    190 }
    191 
    192 bool OatFileBase::LoadVdex(const std::string& vdex_filename,
    193                            bool writable,
    194                            bool low_4gb,
    195                            std::string* error_msg) {
    196   vdex_ = VdexFile::Open(vdex_filename, writable, low_4gb, /* unquicken*/ false, error_msg);
    197   if (vdex_.get() == nullptr) {
    198     *error_msg = StringPrintf("Failed to load vdex file '%s' %s",
    199                               vdex_filename.c_str(),
    200                               error_msg->c_str());
    201     return false;
    202   }
    203   return true;
    204 }
    205 
    206 bool OatFileBase::ComputeFields(uint8_t* requested_base,
    207                                 const std::string& file_path,
    208                                 std::string* error_msg) {
    209   std::string symbol_error_msg;
    210   begin_ = FindDynamicSymbolAddress("oatdata", &symbol_error_msg);
    211   if (begin_ == nullptr) {
    212     *error_msg = StringPrintf("Failed to find oatdata symbol in '%s' %s",
    213                               file_path.c_str(),
    214                               symbol_error_msg.c_str());
    215     return false;
    216   }
    217   if (requested_base != nullptr && begin_ != requested_base) {
    218     // Host can fail this check. Do not dump there to avoid polluting the output.
    219     if (kIsTargetBuild && (kIsDebugBuild || VLOG_IS_ON(oat))) {
    220       PrintFileToLog("/proc/self/maps", LogSeverity::WARNING);
    221     }
    222     *error_msg = StringPrintf("Failed to find oatdata symbol at expected address: "
    223         "oatdata=%p != expected=%p. See process maps in the log.",
    224         begin_, requested_base);
    225     return false;
    226   }
    227   end_ = FindDynamicSymbolAddress("oatlastword", &symbol_error_msg);
    228   if (end_ == nullptr) {
    229     *error_msg = StringPrintf("Failed to find oatlastword symbol in '%s' %s",
    230                               file_path.c_str(),
    231                               symbol_error_msg.c_str());
    232     return false;
    233   }
    234   // Readjust to be non-inclusive upper bound.
    235   end_ += sizeof(uint32_t);
    236 
    237   bss_begin_ = const_cast<uint8_t*>(FindDynamicSymbolAddress("oatbss", &symbol_error_msg));
    238   if (bss_begin_ == nullptr) {
    239     // No .bss section.
    240     bss_end_ = nullptr;
    241   } else {
    242     bss_end_ = const_cast<uint8_t*>(FindDynamicSymbolAddress("oatbsslastword", &symbol_error_msg));
    243     if (bss_end_ == nullptr) {
    244       *error_msg = StringPrintf("Failed to find oatbasslastword symbol in '%s'", file_path.c_str());
    245       return false;
    246     }
    247     // Readjust to be non-inclusive upper bound.
    248     bss_end_ += sizeof(uint32_t);
    249     // Find bss roots if present.
    250     bss_roots_ = const_cast<uint8_t*>(FindDynamicSymbolAddress("oatbssroots", &symbol_error_msg));
    251   }
    252 
    253   return true;
    254 }
    255 
    256 // Read an unaligned entry from the OatDexFile data in OatFile and advance the read
    257 // position by the number of bytes read, i.e. sizeof(T).
    258 // Return true on success, false if the read would go beyond the end of the OatFile.
    259 template <typename T>
    260 inline static bool ReadOatDexFileData(const OatFile& oat_file,
    261                                       /*inout*/const uint8_t** oat,
    262                                       /*out*/T* value) {
    263   DCHECK(oat != nullptr);
    264   DCHECK(value != nullptr);
    265   DCHECK_LE(*oat, oat_file.End());
    266   if (UNLIKELY(static_cast<size_t>(oat_file.End() - *oat) < sizeof(T))) {
    267     return false;
    268   }
    269   static_assert(std::is_trivial<T>::value, "T must be a trivial type");
    270   typedef __attribute__((__aligned__(1))) T unaligned_type;
    271   *value = *reinterpret_cast<const unaligned_type*>(*oat);
    272   *oat += sizeof(T);
    273   return true;
    274 }
    275 
    276 static bool FindDexFileMapItem(const uint8_t* dex_begin,
    277                                const uint8_t* dex_end,
    278                                DexFile::MapItemType map_item_type,
    279                                const DexFile::MapItem** result_item) {
    280   *result_item = nullptr;
    281 
    282   const DexFile::Header* header =
    283       BoundsCheckedCast<const DexFile::Header*>(dex_begin, dex_begin, dex_end);
    284   if (nullptr == header) return false;
    285 
    286   if (!DexFile::IsMagicValid(header->magic_)) return true;  // Not a dex file, not an error.
    287 
    288   const DexFile::MapList* map_list =
    289       BoundsCheckedCast<const DexFile::MapList*>(dex_begin + header->map_off_, dex_begin, dex_end);
    290   if (nullptr == map_list) return false;
    291 
    292   const DexFile::MapItem* map_item = map_list->list_;
    293   size_t count = map_list->size_;
    294   while (count--) {
    295     if (map_item->type_ == static_cast<uint16_t>(map_item_type)) {
    296       *result_item = map_item;
    297       break;
    298     }
    299     map_item = BoundsCheckedCast<const DexFile::MapItem*>(map_item + 1, dex_begin, dex_end);
    300     if (nullptr == map_item) return false;
    301   }
    302 
    303   return true;
    304 }
    305 
    306 bool OatFileBase::Setup(const char* abs_dex_location, std::string* error_msg) {
    307   if (!GetOatHeader().IsValid()) {
    308     std::string cause = GetOatHeader().GetValidationErrorMessage();
    309     *error_msg = StringPrintf("Invalid oat header for '%s': %s",
    310                               GetLocation().c_str(),
    311                               cause.c_str());
    312     return false;
    313   }
    314   const uint8_t* oat = Begin();
    315   oat += sizeof(OatHeader);
    316   if (oat > End()) {
    317     *error_msg = StringPrintf("In oat file '%s' found truncated OatHeader", GetLocation().c_str());
    318     return false;
    319   }
    320 
    321   oat += GetOatHeader().GetKeyValueStoreSize();
    322   if (oat > End()) {
    323     *error_msg = StringPrintf("In oat file '%s' found truncated variable-size data: "
    324                                   "%p + %zu + %u <= %p",
    325                               GetLocation().c_str(),
    326                               Begin(),
    327                               sizeof(OatHeader),
    328                               GetOatHeader().GetKeyValueStoreSize(),
    329                               End());
    330     return false;
    331   }
    332 
    333   if (!IsAligned<alignof(GcRoot<mirror::Object>)>(bss_begin_) ||
    334       !IsAligned<alignof(GcRoot<mirror::Object>)>(bss_roots_) ||
    335       !IsAligned<alignof(GcRoot<mirror::Object>)>(bss_end_)) {
    336     *error_msg = StringPrintf("In oat file '%s' found unaligned bss symbol(s): "
    337                                   "begin = %p, roots = %p, end = %p",
    338                               GetLocation().c_str(),
    339                               bss_begin_,
    340                               bss_roots_,
    341                               bss_end_);
    342     return false;
    343   }
    344 
    345   if (bss_roots_ != nullptr && (bss_roots_ < bss_begin_ || bss_roots_ > bss_end_)) {
    346     *error_msg = StringPrintf("In oat file '%s' found bss roots outside .bss: "
    347                                   "%p is outside range [%p, %p]",
    348                               GetLocation().c_str(),
    349                               bss_roots_,
    350                               bss_begin_,
    351                               bss_end_);
    352     return false;
    353   }
    354 
    355   PointerSize pointer_size = GetInstructionSetPointerSize(GetOatHeader().GetInstructionSet());
    356   uint8_t* dex_cache_arrays = (bss_begin_ == bss_roots_) ? nullptr : bss_begin_;
    357   uint8_t* dex_cache_arrays_end =
    358       (bss_begin_ == bss_roots_) ? nullptr : (bss_roots_ != nullptr) ? bss_roots_ : bss_end_;
    359   DCHECK_EQ(dex_cache_arrays != nullptr, dex_cache_arrays_end != nullptr);
    360   uint32_t dex_file_count = GetOatHeader().GetDexFileCount();
    361   oat_dex_files_storage_.reserve(dex_file_count);
    362   for (size_t i = 0; i < dex_file_count; i++) {
    363     uint32_t dex_file_location_size;
    364     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_file_location_size))) {
    365       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu truncated after dex file "
    366                                     "location size",
    367                                 GetLocation().c_str(),
    368                                 i);
    369       return false;
    370     }
    371     if (UNLIKELY(dex_file_location_size == 0U)) {
    372       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu with empty location name",
    373                                 GetLocation().c_str(),
    374                                 i);
    375       return false;
    376     }
    377     if (UNLIKELY(static_cast<size_t>(End() - oat) < dex_file_location_size)) {
    378       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu with truncated dex file "
    379                                     "location",
    380                                 GetLocation().c_str(),
    381                                 i);
    382       return false;
    383     }
    384     const char* dex_file_location_data = reinterpret_cast<const char*>(oat);
    385     oat += dex_file_location_size;
    386 
    387     std::string dex_file_location = ResolveRelativeEncodedDexLocation(
    388         abs_dex_location,
    389         std::string(dex_file_location_data, dex_file_location_size));
    390 
    391     uint32_t dex_file_checksum;
    392     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_file_checksum))) {
    393       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' truncated after "
    394                                     "dex file checksum",
    395                                 GetLocation().c_str(),
    396                                 i,
    397                                 dex_file_location.c_str());
    398       return false;
    399     }
    400 
    401     uint32_t dex_file_offset;
    402     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_file_offset))) {
    403       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' truncated "
    404                                     "after dex file offsets",
    405                                 GetLocation().c_str(),
    406                                 i,
    407                                 dex_file_location.c_str());
    408       return false;
    409     }
    410     if (UNLIKELY(dex_file_offset == 0U)) {
    411       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with zero dex "
    412                                     "file offset",
    413                                 GetLocation().c_str(),
    414                                 i,
    415                                 dex_file_location.c_str());
    416       return false;
    417     }
    418     if (UNLIKELY(dex_file_offset > DexSize())) {
    419       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "
    420                                     "offset %u > %zu",
    421                                 GetLocation().c_str(),
    422                                 i,
    423                                 dex_file_location.c_str(),
    424                                 dex_file_offset,
    425                                 DexSize());
    426       return false;
    427     }
    428     if (UNLIKELY(DexSize() - dex_file_offset < sizeof(DexFile::Header))) {
    429       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "
    430                                     "offset %u of %zu but the size of dex file header is %zu",
    431                                 GetLocation().c_str(),
    432                                 i,
    433                                 dex_file_location.c_str(),
    434                                 dex_file_offset,
    435                                 DexSize(),
    436                                 sizeof(DexFile::Header));
    437       return false;
    438     }
    439 
    440     const uint8_t* dex_file_pointer = DexBegin() + dex_file_offset;
    441     if (UNLIKELY(!DexFile::IsMagicValid(dex_file_pointer))) {
    442       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with invalid "
    443                                     "dex file magic '%s'",
    444                                 GetLocation().c_str(),
    445                                 i,
    446                                 dex_file_location.c_str(),
    447                                 dex_file_pointer);
    448       return false;
    449     }
    450     if (UNLIKELY(!DexFile::IsVersionValid(dex_file_pointer))) {
    451       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with invalid "
    452                                     "dex file version '%s'",
    453                                 GetLocation().c_str(),
    454                                 i,
    455                                 dex_file_location.c_str(),
    456                                 dex_file_pointer);
    457       return false;
    458     }
    459     const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(dex_file_pointer);
    460     if (DexSize() - dex_file_offset < header->file_size_) {
    461       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "
    462                                     "offset %u and size %u truncated at %zu",
    463                                 GetLocation().c_str(),
    464                                 i,
    465                                 dex_file_location.c_str(),
    466                                 dex_file_offset,
    467                                 header->file_size_,
    468                                 DexSize());
    469       return false;
    470     }
    471 
    472     uint32_t class_offsets_offset;
    473     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &class_offsets_offset))) {
    474       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' truncated "
    475                                     "after class offsets offset",
    476                                 GetLocation().c_str(),
    477                                 i,
    478                                 dex_file_location.c_str());
    479       return false;
    480     }
    481     if (UNLIKELY(class_offsets_offset > Size()) ||
    482         UNLIKELY((Size() - class_offsets_offset) / sizeof(uint32_t) < header->class_defs_size_)) {
    483       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with truncated "
    484                                     "class offsets, offset %u of %zu, class defs %u",
    485                                 GetLocation().c_str(),
    486                                 i,
    487                                 dex_file_location.c_str(),
    488                                 class_offsets_offset,
    489                                 Size(),
    490                                 header->class_defs_size_);
    491       return false;
    492     }
    493     if (UNLIKELY(!IsAligned<alignof(uint32_t)>(class_offsets_offset))) {
    494       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with unaligned "
    495                                     "class offsets, offset %u",
    496                                 GetLocation().c_str(),
    497                                 i,
    498                                 dex_file_location.c_str(),
    499                                 class_offsets_offset);
    500       return false;
    501     }
    502     const uint32_t* class_offsets_pointer =
    503         reinterpret_cast<const uint32_t*>(Begin() + class_offsets_offset);
    504 
    505     uint32_t lookup_table_offset;
    506     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &lookup_table_offset))) {
    507       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zd for '%s' truncated "
    508                                     "after lookup table offset",
    509                                 GetLocation().c_str(),
    510                                 i,
    511                                 dex_file_location.c_str());
    512       return false;
    513     }
    514     const uint8_t* lookup_table_data = lookup_table_offset != 0u
    515         ? Begin() + lookup_table_offset
    516         : nullptr;
    517     if (lookup_table_offset != 0u &&
    518         (UNLIKELY(lookup_table_offset > Size()) ||
    519             UNLIKELY(Size() - lookup_table_offset <
    520                      TypeLookupTable::RawDataLength(header->class_defs_size_)))) {
    521       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with truncated "
    522                                     "type lookup table, offset %u of %zu, class defs %u",
    523                                 GetLocation().c_str(),
    524                                 i,
    525                                 dex_file_location.c_str(),
    526                                 lookup_table_offset,
    527                                 Size(),
    528                                 header->class_defs_size_);
    529       return false;
    530     }
    531 
    532     uint8_t* current_dex_cache_arrays = nullptr;
    533     if (dex_cache_arrays != nullptr) {
    534       // All DexCache types except for CallSite have their instance counts in the
    535       // DexFile header. For CallSites, we need to read the info from the MapList.
    536       const DexFile::MapItem* call_sites_item = nullptr;
    537       if (!FindDexFileMapItem(DexBegin(),
    538                               DexEnd(),
    539                               DexFile::MapItemType::kDexTypeCallSiteIdItem,
    540                               &call_sites_item)) {
    541         *error_msg = StringPrintf("In oat file '%s' could not read data from truncated DexFile map",
    542                                   GetLocation().c_str());
    543         return false;
    544       }
    545       size_t num_call_sites = call_sites_item == nullptr ? 0 : call_sites_item->size_;
    546       DexCacheArraysLayout layout(pointer_size, *header, num_call_sites);
    547       if (layout.Size() != 0u) {
    548         if (static_cast<size_t>(dex_cache_arrays_end - dex_cache_arrays) < layout.Size()) {
    549           *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with "
    550                                         "truncated dex cache arrays, %zu < %zu.",
    551                                     GetLocation().c_str(),
    552                                     i,
    553                                     dex_file_location.c_str(),
    554                                     static_cast<size_t>(dex_cache_arrays_end - dex_cache_arrays),
    555                                     layout.Size());
    556           return false;
    557         }
    558         current_dex_cache_arrays = dex_cache_arrays;
    559         dex_cache_arrays += layout.Size();
    560       }
    561     }
    562 
    563     std::string canonical_location = DexFile::GetDexCanonicalLocation(dex_file_location.c_str());
    564 
    565     // Create the OatDexFile and add it to the owning container.
    566     OatDexFile* oat_dex_file = new OatDexFile(this,
    567                                               dex_file_location,
    568                                               canonical_location,
    569                                               dex_file_checksum,
    570                                               dex_file_pointer,
    571                                               lookup_table_data,
    572                                               class_offsets_pointer,
    573                                               current_dex_cache_arrays);
    574     oat_dex_files_storage_.push_back(oat_dex_file);
    575 
    576     // Add the location and canonical location (if different) to the oat_dex_files_ table.
    577     StringPiece key(oat_dex_file->GetDexFileLocation());
    578     oat_dex_files_.Put(key, oat_dex_file);
    579     if (canonical_location != dex_file_location) {
    580       StringPiece canonical_key(oat_dex_file->GetCanonicalDexFileLocation());
    581       oat_dex_files_.Put(canonical_key, oat_dex_file);
    582     }
    583   }
    584 
    585   if (dex_cache_arrays != dex_cache_arrays_end) {
    586     // We expect the bss section to be either empty (dex_cache_arrays and bss_end_
    587     // both null) or contain just the dex cache arrays and optionally some GC roots.
    588     *error_msg = StringPrintf("In oat file '%s' found unexpected bss size bigger by %zu bytes.",
    589                               GetLocation().c_str(),
    590                               static_cast<size_t>(bss_end_ - dex_cache_arrays));
    591     return false;
    592   }
    593   return true;
    594 }
    595 
    596 ////////////////////////
    597 // OatFile via dlopen //
    598 ////////////////////////
    599 
    600 class DlOpenOatFile FINAL : public OatFileBase {
    601  public:
    602   DlOpenOatFile(const std::string& filename, bool executable)
    603       : OatFileBase(filename, executable),
    604         dlopen_handle_(nullptr),
    605         shared_objects_before_(0) {
    606   }
    607 
    608   ~DlOpenOatFile() {
    609     if (dlopen_handle_ != nullptr) {
    610       if (!kIsTargetBuild) {
    611         MutexLock mu(Thread::Current(), *Locks::host_dlopen_handles_lock_);
    612         host_dlopen_handles_.erase(dlopen_handle_);
    613         dlclose(dlopen_handle_);
    614       } else {
    615         dlclose(dlopen_handle_);
    616       }
    617     }
    618   }
    619 
    620  protected:
    621   const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name,
    622                                           std::string* error_msg) const OVERRIDE {
    623     const uint8_t* ptr =
    624         reinterpret_cast<const uint8_t*>(dlsym(dlopen_handle_, symbol_name.c_str()));
    625     if (ptr == nullptr) {
    626       *error_msg = dlerror();
    627     }
    628     return ptr;
    629   }
    630 
    631   void PreLoad() OVERRIDE;
    632 
    633   bool Load(const std::string& elf_filename,
    634             uint8_t* oat_file_begin,
    635             bool writable,
    636             bool executable,
    637             bool low_4gb,
    638             std::string* error_msg) OVERRIDE;
    639 
    640   // Ask the linker where it mmaped the file and notify our mmap wrapper of the regions.
    641   void PreSetup(const std::string& elf_filename) OVERRIDE;
    642 
    643  private:
    644   bool Dlopen(const std::string& elf_filename,
    645               uint8_t* oat_file_begin,
    646               std::string* error_msg);
    647 
    648   // On the host, if the same library is loaded again with dlopen the same
    649   // file handle is returned. This differs from the behavior of dlopen on the
    650   // target, where dlopen reloads the library at a different address every
    651   // time you load it. The runtime relies on the target behavior to ensure
    652   // each instance of the loaded library has a unique dex cache. To avoid
    653   // problems, we fall back to our own linker in the case when the same
    654   // library is opened multiple times on host. dlopen_handles_ is used to
    655   // detect that case.
    656   // Guarded by host_dlopen_handles_lock_;
    657   static std::unordered_set<void*> host_dlopen_handles_;
    658 
    659   // dlopen handle during runtime.
    660   void* dlopen_handle_;  // TODO: Unique_ptr with custom deleter.
    661 
    662   // Dummy memory map objects corresponding to the regions mapped by dlopen.
    663   std::vector<std::unique_ptr<MemMap>> dlopen_mmaps_;
    664 
    665   // The number of shared objects the linker told us about before loading. Used to
    666   // (optimistically) optimize the PreSetup stage (see comment there).
    667   size_t shared_objects_before_;
    668 
    669   DISALLOW_COPY_AND_ASSIGN(DlOpenOatFile);
    670 };
    671 
    672 std::unordered_set<void*> DlOpenOatFile::host_dlopen_handles_;
    673 
    674 void DlOpenOatFile::PreLoad() {
    675 #ifdef __APPLE__
    676   UNUSED(shared_objects_before_);
    677   LOG(FATAL) << "Should not reach here.";
    678   UNREACHABLE();
    679 #else
    680   // Count the entries in dl_iterate_phdr we get at this point in time.
    681   struct dl_iterate_context {
    682     static int callback(struct dl_phdr_info *info ATTRIBUTE_UNUSED,
    683                         size_t size ATTRIBUTE_UNUSED,
    684                         void *data) {
    685       reinterpret_cast<dl_iterate_context*>(data)->count++;
    686       return 0;  // Continue iteration.
    687     }
    688     size_t count = 0;
    689   } context;
    690 
    691   dl_iterate_phdr(dl_iterate_context::callback, &context);
    692   shared_objects_before_ = context.count;
    693 #endif
    694 }
    695 
    696 bool DlOpenOatFile::Load(const std::string& elf_filename,
    697                          uint8_t* oat_file_begin,
    698                          bool writable,
    699                          bool executable,
    700                          bool low_4gb,
    701                          std::string* error_msg) {
    702   // Use dlopen only when flagged to do so, and when it's OK to load things executable.
    703   // TODO: Also try when not executable? The issue here could be re-mapping as writable (as
    704   //       !executable is a sign that we may want to patch), which may not be allowed for
    705   //       various reasons.
    706   if (!kUseDlopen) {
    707     *error_msg = "DlOpen is disabled.";
    708     return false;
    709   }
    710   if (low_4gb) {
    711     *error_msg = "DlOpen does not support low 4gb loading.";
    712     return false;
    713   }
    714   if (writable) {
    715     *error_msg = "DlOpen does not support writable loading.";
    716     return false;
    717   }
    718   if (!executable) {
    719     *error_msg = "DlOpen does not support non-executable loading.";
    720     return false;
    721   }
    722 
    723   // dlopen always returns the same library if it is already opened on the host. For this reason
    724   // we only use dlopen if we are the target or we do not already have the dex file opened. Having
    725   // the same library loaded multiple times at different addresses is required for class unloading
    726   // and for having dex caches arrays in the .bss section.
    727   if (!kIsTargetBuild) {
    728     if (!kUseDlopenOnHost) {
    729       *error_msg = "DlOpen disabled for host.";
    730       return false;
    731     }
    732   }
    733 
    734   bool success = Dlopen(elf_filename, oat_file_begin, error_msg);
    735   DCHECK(dlopen_handle_ != nullptr || !success);
    736 
    737   return success;
    738 }
    739 
    740 bool DlOpenOatFile::Dlopen(const std::string& elf_filename,
    741                            uint8_t* oat_file_begin,
    742                            std::string* error_msg) {
    743 #ifdef __APPLE__
    744   // The dl_iterate_phdr syscall is missing.  There is similar API on OSX,
    745   // but let's fallback to the custom loading code for the time being.
    746   UNUSED(elf_filename, oat_file_begin);
    747   *error_msg = "Dlopen unsupported on Mac.";
    748   return false;
    749 #else
    750   {
    751     UniqueCPtr<char> absolute_path(realpath(elf_filename.c_str(), nullptr));
    752     if (absolute_path == nullptr) {
    753       *error_msg = StringPrintf("Failed to find absolute path for '%s'", elf_filename.c_str());
    754       return false;
    755     }
    756 #ifdef ART_TARGET_ANDROID
    757     android_dlextinfo extinfo = {};
    758     extinfo.flags = ANDROID_DLEXT_FORCE_LOAD |                  // Force-load, don't reuse handle
    759                                                                 //   (open oat files multiple
    760                                                                 //    times).
    761                     ANDROID_DLEXT_FORCE_FIXED_VADDR;            // Take a non-zero vaddr as absolute
    762                                                                 //   (non-pic boot image).
    763     if (oat_file_begin != nullptr) {                            //
    764       extinfo.flags |= ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS;     // Use the requested addr if
    765       extinfo.reserved_addr = oat_file_begin;                   // vaddr = 0.
    766     }                                                           //   (pic boot image).
    767     dlopen_handle_ = android_dlopen_ext(absolute_path.get(), RTLD_NOW, &extinfo);
    768 #else
    769     UNUSED(oat_file_begin);
    770     static_assert(!kIsTargetBuild || kIsTargetLinux, "host_dlopen_handles_ will leak handles");
    771     MutexLock mu(Thread::Current(), *Locks::host_dlopen_handles_lock_);
    772     dlopen_handle_ = dlopen(absolute_path.get(), RTLD_NOW);
    773     if (dlopen_handle_ != nullptr) {
    774       if (!host_dlopen_handles_.insert(dlopen_handle_).second) {
    775         dlclose(dlopen_handle_);
    776         dlopen_handle_ = nullptr;
    777         *error_msg = StringPrintf("host dlopen re-opened '%s'", elf_filename.c_str());
    778         return false;
    779       }
    780     }
    781 #endif  // ART_TARGET_ANDROID
    782   }
    783   if (dlopen_handle_ == nullptr) {
    784     *error_msg = StringPrintf("Failed to dlopen '%s': %s", elf_filename.c_str(), dlerror());
    785     return false;
    786   }
    787   return true;
    788 #endif
    789 }
    790 
    791 void DlOpenOatFile::PreSetup(const std::string& elf_filename) {
    792 #ifdef __APPLE__
    793   UNUSED(elf_filename);
    794   LOG(FATAL) << "Should not reach here.";
    795   UNREACHABLE();
    796 #else
    797   struct dl_iterate_context {
    798     static int callback(struct dl_phdr_info *info, size_t /* size */, void *data) {
    799       auto* context = reinterpret_cast<dl_iterate_context*>(data);
    800       context->shared_objects_seen++;
    801       if (context->shared_objects_seen < context->shared_objects_before) {
    802         // We haven't been called yet for anything we haven't seen before. Just continue.
    803         // Note: this is aggressively optimistic. If another thread was unloading a library,
    804         //       we may miss out here. However, this does not happen often in practice.
    805         return 0;
    806       }
    807 
    808       // See whether this callback corresponds to the file which we have just loaded.
    809       bool contains_begin = false;
    810       for (int i = 0; i < info->dlpi_phnum; i++) {
    811         if (info->dlpi_phdr[i].p_type == PT_LOAD) {
    812           uint8_t* vaddr = reinterpret_cast<uint8_t*>(info->dlpi_addr +
    813               info->dlpi_phdr[i].p_vaddr);
    814           size_t memsz = info->dlpi_phdr[i].p_memsz;
    815           if (vaddr <= context->begin_ && context->begin_ < vaddr + memsz) {
    816             contains_begin = true;
    817             break;
    818           }
    819         }
    820       }
    821       // Add dummy mmaps for this file.
    822       if (contains_begin) {
    823         for (int i = 0; i < info->dlpi_phnum; i++) {
    824           if (info->dlpi_phdr[i].p_type == PT_LOAD) {
    825             uint8_t* vaddr = reinterpret_cast<uint8_t*>(info->dlpi_addr +
    826                 info->dlpi_phdr[i].p_vaddr);
    827             size_t memsz = info->dlpi_phdr[i].p_memsz;
    828             MemMap* mmap = MemMap::MapDummy(info->dlpi_name, vaddr, memsz);
    829             context->dlopen_mmaps_->push_back(std::unique_ptr<MemMap>(mmap));
    830           }
    831         }
    832         return 1;  // Stop iteration and return 1 from dl_iterate_phdr.
    833       }
    834       return 0;  // Continue iteration and return 0 from dl_iterate_phdr when finished.
    835     }
    836     const uint8_t* const begin_;
    837     std::vector<std::unique_ptr<MemMap>>* const dlopen_mmaps_;
    838     const size_t shared_objects_before;
    839     size_t shared_objects_seen;
    840   };
    841   dl_iterate_context context = { Begin(), &dlopen_mmaps_, shared_objects_before_, 0};
    842 
    843   if (dl_iterate_phdr(dl_iterate_context::callback, &context) == 0) {
    844     // Hm. Maybe our optimization went wrong. Try another time with shared_objects_before == 0
    845     // before giving up. This should be unusual.
    846     VLOG(oat) << "Need a second run in PreSetup, didn't find with shared_objects_before="
    847               << shared_objects_before_;
    848     dl_iterate_context context0 = { Begin(), &dlopen_mmaps_, 0, 0};
    849     if (dl_iterate_phdr(dl_iterate_context::callback, &context0) == 0) {
    850       // OK, give up and print an error.
    851       PrintFileToLog("/proc/self/maps", LogSeverity::WARNING);
    852       LOG(ERROR) << "File " << elf_filename << " loaded with dlopen but cannot find its mmaps.";
    853     }
    854   }
    855 #endif
    856 }
    857 
    858 ////////////////////////////////////////////////
    859 // OatFile via our own ElfFile implementation //
    860 ////////////////////////////////////////////////
    861 
    862 class ElfOatFile FINAL : public OatFileBase {
    863  public:
    864   ElfOatFile(const std::string& filename, bool executable) : OatFileBase(filename, executable) {}
    865 
    866   static ElfOatFile* OpenElfFile(File* file,
    867                                  const std::string& location,
    868                                  uint8_t* requested_base,
    869                                  uint8_t* oat_file_begin,  // Override base if not null
    870                                  bool writable,
    871                                  bool executable,
    872                                  bool low_4gb,
    873                                  const char* abs_dex_location,
    874                                  std::string* error_msg);
    875 
    876   bool InitializeFromElfFile(ElfFile* elf_file,
    877                              VdexFile* vdex_file,
    878                              const char* abs_dex_location,
    879                              std::string* error_msg);
    880 
    881  protected:
    882   const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name,
    883                                           std::string* error_msg) const OVERRIDE {
    884     const uint8_t* ptr = elf_file_->FindDynamicSymbolAddress(symbol_name);
    885     if (ptr == nullptr) {
    886       *error_msg = "(Internal implementation could not find symbol)";
    887     }
    888     return ptr;
    889   }
    890 
    891   void PreLoad() OVERRIDE {
    892   }
    893 
    894   bool Load(const std::string& elf_filename,
    895             uint8_t* oat_file_begin,  // Override where the file is loaded to if not null
    896             bool writable,
    897             bool executable,
    898             bool low_4gb,
    899             std::string* error_msg) OVERRIDE;
    900 
    901   void PreSetup(const std::string& elf_filename ATTRIBUTE_UNUSED) OVERRIDE {
    902   }
    903 
    904  private:
    905   bool ElfFileOpen(File* file,
    906                    uint8_t* oat_file_begin,  // Override where the file is loaded to if not null
    907                    bool writable,
    908                    bool executable,
    909                    bool low_4gb,
    910                    std::string* error_msg);
    911 
    912  private:
    913   // Backing memory map for oat file during cross compilation.
    914   std::unique_ptr<ElfFile> elf_file_;
    915 
    916   DISALLOW_COPY_AND_ASSIGN(ElfOatFile);
    917 };
    918 
    919 ElfOatFile* ElfOatFile::OpenElfFile(File* file,
    920                                     const std::string& location,
    921                                     uint8_t* requested_base,
    922                                     uint8_t* oat_file_begin,  // Override base if not null
    923                                     bool writable,
    924                                     bool executable,
    925                                     bool low_4gb,
    926                                     const char* abs_dex_location,
    927                                     std::string* error_msg) {
    928   ScopedTrace trace("Open elf file " + location);
    929   std::unique_ptr<ElfOatFile> oat_file(new ElfOatFile(location, executable));
    930   bool success = oat_file->ElfFileOpen(file,
    931                                        oat_file_begin,
    932                                        writable,
    933                                        low_4gb,
    934                                        executable,
    935                                        error_msg);
    936   if (!success) {
    937     CHECK(!error_msg->empty());
    938     return nullptr;
    939   }
    940 
    941   // Complete the setup.
    942   if (!oat_file->ComputeFields(requested_base, file->GetPath(), error_msg)) {
    943     return nullptr;
    944   }
    945 
    946   if (!oat_file->Setup(abs_dex_location, error_msg)) {
    947     return nullptr;
    948   }
    949 
    950   return oat_file.release();
    951 }
    952 
    953 bool ElfOatFile::InitializeFromElfFile(ElfFile* elf_file,
    954                                        VdexFile* vdex_file,
    955                                        const char* abs_dex_location,
    956                                        std::string* error_msg) {
    957   ScopedTrace trace(__PRETTY_FUNCTION__);
    958   if (IsExecutable()) {
    959     *error_msg = "Cannot initialize from elf file in executable mode.";
    960     return false;
    961   }
    962   elf_file_.reset(elf_file);
    963   SetVdex(vdex_file);
    964   uint64_t offset, size;
    965   bool has_section = elf_file->GetSectionOffsetAndSize(".rodata", &offset, &size);
    966   CHECK(has_section);
    967   SetBegin(elf_file->Begin() + offset);
    968   SetEnd(elf_file->Begin() + size + offset);
    969   // Ignore the optional .bss section when opening non-executable.
    970   return Setup(abs_dex_location, error_msg);
    971 }
    972 
    973 bool ElfOatFile::Load(const std::string& elf_filename,
    974                       uint8_t* oat_file_begin,  // Override where the file is loaded to if not null
    975                       bool writable,
    976                       bool executable,
    977                       bool low_4gb,
    978                       std::string* error_msg) {
    979   ScopedTrace trace(__PRETTY_FUNCTION__);
    980   std::unique_ptr<File> file(OS::OpenFileForReading(elf_filename.c_str()));
    981   if (file == nullptr) {
    982     *error_msg = StringPrintf("Failed to open oat filename for reading: %s", strerror(errno));
    983     return false;
    984   }
    985   return ElfOatFile::ElfFileOpen(file.get(),
    986                                  oat_file_begin,
    987                                  writable,
    988                                  executable,
    989                                  low_4gb,
    990                                  error_msg);
    991 }
    992 
    993 bool ElfOatFile::ElfFileOpen(File* file,
    994                              uint8_t* oat_file_begin,
    995                              bool writable,
    996                              bool executable,
    997                              bool low_4gb,
    998                              std::string* error_msg) {
    999   ScopedTrace trace(__PRETTY_FUNCTION__);
   1000   // TODO: rename requested_base to oat_data_begin
   1001   elf_file_.reset(ElfFile::Open(file,
   1002                                 writable,
   1003                                 /*program_header_only*/true,
   1004                                 low_4gb,
   1005                                 error_msg,
   1006                                 oat_file_begin));
   1007   if (elf_file_ == nullptr) {
   1008     DCHECK(!error_msg->empty());
   1009     return false;
   1010   }
   1011   bool loaded = elf_file_->Load(file, executable, low_4gb, error_msg);
   1012   DCHECK(loaded || !error_msg->empty());
   1013   return loaded;
   1014 }
   1015 
   1016 //////////////////////////
   1017 // General OatFile code //
   1018 //////////////////////////
   1019 
   1020 std::string OatFile::ResolveRelativeEncodedDexLocation(
   1021       const char* abs_dex_location, const std::string& rel_dex_location) {
   1022   if (abs_dex_location != nullptr && rel_dex_location[0] != '/') {
   1023     // Strip :classes<N>.dex used for secondary multidex files.
   1024     std::string base = DexFile::GetBaseLocation(rel_dex_location);
   1025     std::string multidex_suffix = DexFile::GetMultiDexSuffix(rel_dex_location);
   1026 
   1027     // Check if the base is a suffix of the provided abs_dex_location.
   1028     std::string target_suffix = "/" + base;
   1029     std::string abs_location(abs_dex_location);
   1030     if (abs_location.size() > target_suffix.size()) {
   1031       size_t pos = abs_location.size() - target_suffix.size();
   1032       if (abs_location.compare(pos, std::string::npos, target_suffix) == 0) {
   1033         return abs_location + multidex_suffix;
   1034       }
   1035     }
   1036   }
   1037   return rel_dex_location;
   1038 }
   1039 
   1040 static void CheckLocation(const std::string& location) {
   1041   CHECK(!location.empty());
   1042 }
   1043 
   1044 OatFile* OatFile::OpenWithElfFile(ElfFile* elf_file,
   1045                                   VdexFile* vdex_file,
   1046                                   const std::string& location,
   1047                                   const char* abs_dex_location,
   1048                                   std::string* error_msg) {
   1049   std::unique_ptr<ElfOatFile> oat_file(new ElfOatFile(location, false /* executable */));
   1050   return oat_file->InitializeFromElfFile(elf_file, vdex_file, abs_dex_location, error_msg)
   1051       ? oat_file.release()
   1052       : nullptr;
   1053 }
   1054 
   1055 OatFile* OatFile::Open(const std::string& oat_filename,
   1056                        const std::string& oat_location,
   1057                        uint8_t* requested_base,
   1058                        uint8_t* oat_file_begin,
   1059                        bool executable,
   1060                        bool low_4gb,
   1061                        const char* abs_dex_location,
   1062                        std::string* error_msg) {
   1063   ScopedTrace trace("Open oat file " + oat_location);
   1064   CHECK(!oat_filename.empty()) << oat_location;
   1065   CheckLocation(oat_location);
   1066 
   1067   std::string vdex_filename = GetVdexFilename(oat_filename);
   1068 
   1069   // Check that the files even exist, fast-fail.
   1070   if (kIsVdexEnabled && !OS::FileExists(vdex_filename.c_str())) {
   1071     *error_msg = StringPrintf("File %s does not exist.", vdex_filename.c_str());
   1072     return nullptr;
   1073   } else if (!OS::FileExists(oat_filename.c_str())) {
   1074     *error_msg = StringPrintf("File %s does not exist.", oat_filename.c_str());
   1075     return nullptr;
   1076   }
   1077 
   1078   // Try dlopen first, as it is required for native debuggability. This will fail fast if dlopen is
   1079   // disabled.
   1080   OatFile* with_dlopen = OatFileBase::OpenOatFile<DlOpenOatFile>(vdex_filename,
   1081                                                                  oat_filename,
   1082                                                                  oat_location,
   1083                                                                  requested_base,
   1084                                                                  oat_file_begin,
   1085                                                                  false /* writable */,
   1086                                                                  executable,
   1087                                                                  low_4gb,
   1088                                                                  abs_dex_location,
   1089                                                                  error_msg);
   1090   if (with_dlopen != nullptr) {
   1091     return with_dlopen;
   1092   }
   1093   if (kPrintDlOpenErrorMessage) {
   1094     LOG(ERROR) << "Failed to dlopen: " << oat_filename << " with error " << *error_msg;
   1095   }
   1096   // If we aren't trying to execute, we just use our own ElfFile loader for a couple reasons:
   1097   //
   1098   // On target, dlopen may fail when compiling due to selinux restrictions on installd.
   1099   //
   1100   // We use our own ELF loader for Quick to deal with legacy apps that
   1101   // open a generated dex file by name, remove the file, then open
   1102   // another generated dex file with the same name. http://b/10614658
   1103   //
   1104   // On host, dlopen is expected to fail when cross compiling, so fall back to OpenElfFile.
   1105   //
   1106   //
   1107   // Another independent reason is the absolute placement of boot.oat. dlopen on the host usually
   1108   // does honor the virtual address encoded in the ELF file only for ET_EXEC files, not ET_DYN.
   1109   OatFile* with_internal = OatFileBase::OpenOatFile<ElfOatFile>(vdex_filename,
   1110                                                                 oat_filename,
   1111                                                                 oat_location,
   1112                                                                 requested_base,
   1113                                                                 oat_file_begin,
   1114                                                                 false /* writable */,
   1115                                                                 executable,
   1116                                                                 low_4gb,
   1117                                                                 abs_dex_location,
   1118                                                                 error_msg);
   1119   return with_internal;
   1120 }
   1121 
   1122 OatFile* OatFile::OpenWritable(File* file,
   1123                                const std::string& location,
   1124                                const char* abs_dex_location,
   1125                                std::string* error_msg) {
   1126   CheckLocation(location);
   1127   return ElfOatFile::OpenElfFile(file,
   1128                                  location,
   1129                                  nullptr,
   1130                                  nullptr,
   1131                                  true,
   1132                                  false,
   1133                                  /*low_4gb*/false,
   1134                                  abs_dex_location,
   1135                                  error_msg);
   1136 }
   1137 
   1138 OatFile* OatFile::OpenReadable(File* file,
   1139                                const std::string& location,
   1140                                const char* abs_dex_location,
   1141                                std::string* error_msg) {
   1142   CheckLocation(location);
   1143   return ElfOatFile::OpenElfFile(file,
   1144                                  location,
   1145                                  nullptr,
   1146                                  nullptr,
   1147                                  false,
   1148                                  false,
   1149                                  /*low_4gb*/false,
   1150                                  abs_dex_location,
   1151                                  error_msg);
   1152 }
   1153 
   1154 OatFile::OatFile(const std::string& location, bool is_executable)
   1155     : location_(location),
   1156       vdex_(nullptr),
   1157       begin_(nullptr),
   1158       end_(nullptr),
   1159       bss_begin_(nullptr),
   1160       bss_end_(nullptr),
   1161       bss_roots_(nullptr),
   1162       is_executable_(is_executable),
   1163       secondary_lookup_lock_("OatFile secondary lookup lock", kOatFileSecondaryLookupLock) {
   1164   CHECK(!location_.empty());
   1165 }
   1166 
   1167 OatFile::~OatFile() {
   1168   STLDeleteElements(&oat_dex_files_storage_);
   1169 }
   1170 
   1171 const OatHeader& OatFile::GetOatHeader() const {
   1172   return *reinterpret_cast<const OatHeader*>(Begin());
   1173 }
   1174 
   1175 const uint8_t* OatFile::Begin() const {
   1176   CHECK(begin_ != nullptr);
   1177   return begin_;
   1178 }
   1179 
   1180 const uint8_t* OatFile::End() const {
   1181   CHECK(end_ != nullptr);
   1182   return end_;
   1183 }
   1184 
   1185 const uint8_t* OatFile::BssBegin() const {
   1186   return bss_begin_;
   1187 }
   1188 
   1189 const uint8_t* OatFile::BssEnd() const {
   1190   return bss_end_;
   1191 }
   1192 
   1193 const uint8_t* OatFile::DexBegin() const {
   1194   return kIsVdexEnabled ? vdex_->Begin() : Begin();
   1195 }
   1196 
   1197 const uint8_t* OatFile::DexEnd() const {
   1198   return kIsVdexEnabled ? vdex_->End() : End();
   1199 }
   1200 
   1201 ArrayRef<GcRoot<mirror::Object>> OatFile::GetBssGcRoots() const {
   1202   if (bss_roots_ != nullptr) {
   1203     auto* roots = reinterpret_cast<GcRoot<mirror::Object>*>(bss_roots_);
   1204     auto* roots_end = reinterpret_cast<GcRoot<mirror::Object>*>(bss_end_);
   1205     return ArrayRef<GcRoot<mirror::Object>>(roots, roots_end - roots);
   1206   } else {
   1207     return ArrayRef<GcRoot<mirror::Object>>();
   1208   }
   1209 }
   1210 
   1211 const OatFile::OatDexFile* OatFile::GetOatDexFile(const char* dex_location,
   1212                                                   const uint32_t* dex_location_checksum,
   1213                                                   std::string* error_msg) const {
   1214   // NOTE: We assume here that the canonical location for a given dex_location never
   1215   // changes. If it does (i.e. some symlink used by the filename changes) we may return
   1216   // an incorrect OatDexFile. As long as we have a checksum to check, we shall return
   1217   // an identical file or fail; otherwise we may see some unpredictable failures.
   1218 
   1219   // TODO: Additional analysis of usage patterns to see if this can be simplified
   1220   // without any performance loss, for example by not doing the first lock-free lookup.
   1221 
   1222   const OatFile::OatDexFile* oat_dex_file = nullptr;
   1223   StringPiece key(dex_location);
   1224   // Try to find the key cheaply in the oat_dex_files_ map which holds dex locations
   1225   // directly mentioned in the oat file and doesn't require locking.
   1226   auto primary_it = oat_dex_files_.find(key);
   1227   if (primary_it != oat_dex_files_.end()) {
   1228     oat_dex_file = primary_it->second;
   1229     DCHECK(oat_dex_file != nullptr);
   1230   } else {
   1231     // This dex_location is not one of the dex locations directly mentioned in the
   1232     // oat file. The correct lookup is via the canonical location but first see in
   1233     // the secondary_oat_dex_files_ whether we've looked up this location before.
   1234     MutexLock mu(Thread::Current(), secondary_lookup_lock_);
   1235     auto secondary_lb = secondary_oat_dex_files_.lower_bound(key);
   1236     if (secondary_lb != secondary_oat_dex_files_.end() && key == secondary_lb->first) {
   1237       oat_dex_file = secondary_lb->second;  // May be null.
   1238     } else {
   1239       // We haven't seen this dex_location before, we must check the canonical location.
   1240       std::string dex_canonical_location = DexFile::GetDexCanonicalLocation(dex_location);
   1241       if (dex_canonical_location != dex_location) {
   1242         StringPiece canonical_key(dex_canonical_location);
   1243         auto canonical_it = oat_dex_files_.find(canonical_key);
   1244         if (canonical_it != oat_dex_files_.end()) {
   1245           oat_dex_file = canonical_it->second;
   1246         }  // else keep null.
   1247       }  // else keep null.
   1248 
   1249       // Copy the key to the string_cache_ and store the result in secondary map.
   1250       string_cache_.emplace_back(key.data(), key.length());
   1251       StringPiece key_copy(string_cache_.back());
   1252       secondary_oat_dex_files_.PutBefore(secondary_lb, key_copy, oat_dex_file);
   1253     }
   1254   }
   1255 
   1256   if (oat_dex_file == nullptr) {
   1257     if (error_msg != nullptr) {
   1258       std::string dex_canonical_location = DexFile::GetDexCanonicalLocation(dex_location);
   1259       *error_msg = "Failed to find OatDexFile for DexFile " + std::string(dex_location)
   1260           + " (canonical path " + dex_canonical_location + ") in OatFile " + GetLocation();
   1261     }
   1262     return nullptr;
   1263   }
   1264 
   1265   if (dex_location_checksum != nullptr &&
   1266       oat_dex_file->GetDexFileLocationChecksum() != *dex_location_checksum) {
   1267     if (error_msg != nullptr) {
   1268       std::string dex_canonical_location = DexFile::GetDexCanonicalLocation(dex_location);
   1269       std::string checksum = StringPrintf("0x%08x", oat_dex_file->GetDexFileLocationChecksum());
   1270       std::string required_checksum = StringPrintf("0x%08x", *dex_location_checksum);
   1271       *error_msg = "OatDexFile for DexFile " + std::string(dex_location)
   1272           + " (canonical path " + dex_canonical_location + ") in OatFile " + GetLocation()
   1273           + " has checksum " + checksum + " but " + required_checksum + " was required";
   1274     }
   1275     return nullptr;
   1276   }
   1277   return oat_dex_file;
   1278 }
   1279 
   1280 OatFile::OatDexFile::OatDexFile(const OatFile* oat_file,
   1281                                 const std::string& dex_file_location,
   1282                                 const std::string& canonical_dex_file_location,
   1283                                 uint32_t dex_file_location_checksum,
   1284                                 const uint8_t* dex_file_pointer,
   1285                                 const uint8_t* lookup_table_data,
   1286                                 const uint32_t* oat_class_offsets_pointer,
   1287                                 uint8_t* dex_cache_arrays)
   1288     : oat_file_(oat_file),
   1289       dex_file_location_(dex_file_location),
   1290       canonical_dex_file_location_(canonical_dex_file_location),
   1291       dex_file_location_checksum_(dex_file_location_checksum),
   1292       dex_file_pointer_(dex_file_pointer),
   1293       lookup_table_data_(lookup_table_data),
   1294       oat_class_offsets_pointer_(oat_class_offsets_pointer),
   1295       dex_cache_arrays_(dex_cache_arrays) {
   1296   // Initialize TypeLookupTable.
   1297   if (lookup_table_data_ != nullptr) {
   1298     // Peek the number of classes from the DexFile.
   1299     const DexFile::Header* dex_header = reinterpret_cast<const DexFile::Header*>(dex_file_pointer_);
   1300     const uint32_t num_class_defs = dex_header->class_defs_size_;
   1301     if (lookup_table_data_ + TypeLookupTable::RawDataLength(num_class_defs) > GetOatFile()->End()) {
   1302       LOG(WARNING) << "found truncated lookup table in " << dex_file_location_;
   1303     } else {
   1304       lookup_table_ = TypeLookupTable::Open(dex_file_pointer_, lookup_table_data_, num_class_defs);
   1305     }
   1306   }
   1307 }
   1308 
   1309 OatFile::OatDexFile::OatDexFile(std::unique_ptr<TypeLookupTable>&& lookup_table)
   1310     : lookup_table_(std::move(lookup_table)) {}
   1311 
   1312 OatFile::OatDexFile::~OatDexFile() {}
   1313 
   1314 size_t OatFile::OatDexFile::FileSize() const {
   1315   return reinterpret_cast<const DexFile::Header*>(dex_file_pointer_)->file_size_;
   1316 }
   1317 
   1318 std::unique_ptr<const DexFile> OatFile::OatDexFile::OpenDexFile(std::string* error_msg) const {
   1319   ScopedTrace trace(__PRETTY_FUNCTION__);
   1320   static constexpr bool kVerify = false;
   1321   static constexpr bool kVerifyChecksum = false;
   1322   return DexFile::Open(dex_file_pointer_,
   1323                        FileSize(),
   1324                        dex_file_location_,
   1325                        dex_file_location_checksum_,
   1326                        this,
   1327                        kVerify,
   1328                        kVerifyChecksum,
   1329                        error_msg);
   1330 }
   1331 
   1332 uint32_t OatFile::OatDexFile::GetOatClassOffset(uint16_t class_def_index) const {
   1333   return oat_class_offsets_pointer_[class_def_index];
   1334 }
   1335 
   1336 OatFile::OatClass OatFile::OatDexFile::GetOatClass(uint16_t class_def_index) const {
   1337   uint32_t oat_class_offset = GetOatClassOffset(class_def_index);
   1338 
   1339   const uint8_t* oat_class_pointer = oat_file_->Begin() + oat_class_offset;
   1340   CHECK_LT(oat_class_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1341 
   1342   const uint8_t* status_pointer = oat_class_pointer;
   1343   CHECK_LT(status_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1344   mirror::Class::Status status =
   1345       static_cast<mirror::Class::Status>(*reinterpret_cast<const int16_t*>(status_pointer));
   1346   CHECK_LT(status, mirror::Class::kStatusMax);
   1347 
   1348   const uint8_t* type_pointer = status_pointer + sizeof(uint16_t);
   1349   CHECK_LT(type_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1350   OatClassType type = static_cast<OatClassType>(*reinterpret_cast<const uint16_t*>(type_pointer));
   1351   CHECK_LT(type, kOatClassMax);
   1352 
   1353   const uint8_t* after_type_pointer = type_pointer + sizeof(int16_t);
   1354   CHECK_LE(after_type_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1355 
   1356   uint32_t bitmap_size = 0;
   1357   const uint8_t* bitmap_pointer = nullptr;
   1358   const uint8_t* methods_pointer = nullptr;
   1359   if (type != kOatClassNoneCompiled) {
   1360     if (type == kOatClassSomeCompiled) {
   1361       bitmap_size = static_cast<uint32_t>(*reinterpret_cast<const uint32_t*>(after_type_pointer));
   1362       bitmap_pointer = after_type_pointer + sizeof(bitmap_size);
   1363       CHECK_LE(bitmap_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1364       methods_pointer = bitmap_pointer + bitmap_size;
   1365     } else {
   1366       methods_pointer = after_type_pointer;
   1367     }
   1368     CHECK_LE(methods_pointer, oat_file_->End()) << oat_file_->GetLocation();
   1369   }
   1370 
   1371   return OatFile::OatClass(oat_file_,
   1372                            status,
   1373                            type,
   1374                            bitmap_size,
   1375                            reinterpret_cast<const uint32_t*>(bitmap_pointer),
   1376                            reinterpret_cast<const OatMethodOffsets*>(methods_pointer));
   1377 }
   1378 
   1379 const DexFile::ClassDef* OatFile::OatDexFile::FindClassDef(const DexFile& dex_file,
   1380                                                            const char* descriptor,
   1381                                                            size_t hash) {
   1382   const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
   1383   DCHECK_EQ(ComputeModifiedUtf8Hash(descriptor), hash);
   1384   if (LIKELY((oat_dex_file != nullptr) && (oat_dex_file->GetTypeLookupTable() != nullptr))) {
   1385     const uint32_t class_def_idx = oat_dex_file->GetTypeLookupTable()->Lookup(descriptor, hash);
   1386     return (class_def_idx != DexFile::kDexNoIndex) ? &dex_file.GetClassDef(class_def_idx) : nullptr;
   1387   }
   1388   // Fast path for rare no class defs case.
   1389   const uint32_t num_class_defs = dex_file.NumClassDefs();
   1390   if (num_class_defs == 0) {
   1391     return nullptr;
   1392   }
   1393   const DexFile::TypeId* type_id = dex_file.FindTypeId(descriptor);
   1394   if (type_id != nullptr) {
   1395     dex::TypeIndex type_idx = dex_file.GetIndexForTypeId(*type_id);
   1396     return dex_file.FindClassDef(type_idx);
   1397   }
   1398   return nullptr;
   1399 }
   1400 
   1401 OatFile::OatClass::OatClass(const OatFile* oat_file,
   1402                             mirror::Class::Status status,
   1403                             OatClassType type,
   1404                             uint32_t bitmap_size,
   1405                             const uint32_t* bitmap_pointer,
   1406                             const OatMethodOffsets* methods_pointer)
   1407     : oat_file_(oat_file), status_(status), type_(type),
   1408       bitmap_(bitmap_pointer), methods_pointer_(methods_pointer) {
   1409     switch (type_) {
   1410       case kOatClassAllCompiled: {
   1411         CHECK_EQ(0U, bitmap_size);
   1412         CHECK(bitmap_pointer == nullptr);
   1413         CHECK(methods_pointer != nullptr);
   1414         break;
   1415       }
   1416       case kOatClassSomeCompiled: {
   1417         CHECK_NE(0U, bitmap_size);
   1418         CHECK(bitmap_pointer != nullptr);
   1419         CHECK(methods_pointer != nullptr);
   1420         break;
   1421       }
   1422       case kOatClassNoneCompiled: {
   1423         CHECK_EQ(0U, bitmap_size);
   1424         CHECK(bitmap_pointer == nullptr);
   1425         CHECK(methods_pointer_ == nullptr);
   1426         break;
   1427       }
   1428       case kOatClassMax: {
   1429         LOG(FATAL) << "Invalid OatClassType " << type_;
   1430         break;
   1431       }
   1432     }
   1433 }
   1434 
   1435 uint32_t OatFile::OatClass::GetOatMethodOffsetsOffset(uint32_t method_index) const {
   1436   const OatMethodOffsets* oat_method_offsets = GetOatMethodOffsets(method_index);
   1437   if (oat_method_offsets == nullptr) {
   1438     return 0u;
   1439   }
   1440   return reinterpret_cast<const uint8_t*>(oat_method_offsets) - oat_file_->Begin();
   1441 }
   1442 
   1443 const OatMethodOffsets* OatFile::OatClass::GetOatMethodOffsets(uint32_t method_index) const {
   1444   // NOTE: We don't keep the number of methods and cannot do a bounds check for method_index.
   1445   if (methods_pointer_ == nullptr) {
   1446     CHECK_EQ(kOatClassNoneCompiled, type_);
   1447     return nullptr;
   1448   }
   1449   size_t methods_pointer_index;
   1450   if (bitmap_ == nullptr) {
   1451     CHECK_EQ(kOatClassAllCompiled, type_);
   1452     methods_pointer_index = method_index;
   1453   } else {
   1454     CHECK_EQ(kOatClassSomeCompiled, type_);
   1455     if (!BitVector::IsBitSet(bitmap_, method_index)) {
   1456       return nullptr;
   1457     }
   1458     size_t num_set_bits = BitVector::NumSetBits(bitmap_, method_index);
   1459     methods_pointer_index = num_set_bits;
   1460   }
   1461   const OatMethodOffsets& oat_method_offsets = methods_pointer_[methods_pointer_index];
   1462   return &oat_method_offsets;
   1463 }
   1464 
   1465 const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index) const {
   1466   const OatMethodOffsets* oat_method_offsets = GetOatMethodOffsets(method_index);
   1467   if (oat_method_offsets == nullptr) {
   1468     return OatMethod(nullptr, 0);
   1469   }
   1470   if (oat_file_->IsExecutable() ||
   1471       Runtime::Current() == nullptr ||        // This case applies for oatdump.
   1472       Runtime::Current()->IsAotCompiler()) {
   1473     return OatMethod(oat_file_->Begin(), oat_method_offsets->code_offset_);
   1474   }
   1475   // We aren't allowed to use the compiled code. We just force it down the interpreted / jit
   1476   // version.
   1477   return OatMethod(oat_file_->Begin(), 0);
   1478 }
   1479 
   1480 void OatFile::OatMethod::LinkMethod(ArtMethod* method) const {
   1481   CHECK(method != nullptr);
   1482   method->SetEntryPointFromQuickCompiledCode(GetQuickCode());
   1483 }
   1484 
   1485 bool OatFile::IsPic() const {
   1486   return GetOatHeader().IsPic();
   1487   // TODO: Check against oat_patches. b/18144996
   1488 }
   1489 
   1490 bool OatFile::IsDebuggable() const {
   1491   return GetOatHeader().IsDebuggable();
   1492 }
   1493 
   1494 CompilerFilter::Filter OatFile::GetCompilerFilter() const {
   1495   return GetOatHeader().GetCompilerFilter();
   1496 }
   1497 
   1498 static constexpr char kDexClassPathEncodingSeparator = '*';
   1499 
   1500 std::string OatFile::EncodeDexFileDependencies(const std::vector<const DexFile*>& dex_files,
   1501                                                std::string& base_dir) {
   1502   std::ostringstream out;
   1503 
   1504   for (const DexFile* dex_file : dex_files) {
   1505     const std::string& location = dex_file->GetLocation();
   1506     // Find paths that were relative and convert them back from absolute.
   1507     if (!base_dir.empty() && location.substr(0, base_dir.length()) == base_dir) {
   1508       out << location.substr(base_dir.length() + 1).c_str();
   1509     } else {
   1510       out << dex_file->GetLocation().c_str();
   1511     }
   1512     out << kDexClassPathEncodingSeparator;
   1513     out << dex_file->GetLocationChecksum();
   1514     out << kDexClassPathEncodingSeparator;
   1515   }
   1516 
   1517   return out.str();
   1518 }
   1519 
   1520 OatFile::OatClass OatFile::FindOatClass(const DexFile& dex_file,
   1521                                         uint16_t class_def_idx,
   1522                                         bool* found) {
   1523   DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
   1524   const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
   1525   if (oat_dex_file == nullptr || oat_dex_file->GetOatFile() == nullptr) {
   1526     *found = false;
   1527     return OatFile::OatClass::Invalid();
   1528   }
   1529   *found = true;
   1530   return oat_dex_file->GetOatClass(class_def_idx);
   1531 }
   1532 
   1533 void OatFile::OatDexFile::AssertAotCompiler() {
   1534   CHECK(Runtime::Current()->IsAotCompiler());
   1535 }
   1536 
   1537 }  // namespace art
   1538