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
67namespace art {
68
69using android::base::StringPrintf;
70
71// Whether OatFile::Open will try dlopen. Fallback is our own ELF loader.
72static 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.
78static constexpr bool kUseDlopenOnHost = true;
79
80// For debugging, Open will print DlOpen error message if set to true.
81static 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
95class 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
185template <typename kOatFileBaseSubType>
186OatFileBase* 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
227template <typename kOatFileBaseSubType>
228OatFileBase* 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
268bool 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
289bool 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
319bool 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.
389template <typename T>
390inline 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
406static 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
437static 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
483static 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
510bool 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
907class 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
983std::unordered_set<void*> DlOpenOatFile::host_dlopen_handles_;
984
985void 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
1007bool 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
1051bool 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
1102void 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
1173class 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
1239ElfOatFile* 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
1274bool 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
1295bool 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
1315bool 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
1340bool 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
1367std::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
1389static void CheckLocation(const std::string& location) {
1390  CHECK(!location.empty());
1391}
1392
1393OatFile* 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
1405OatFile* 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
1475OatFile* 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
1504OatFile* 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
1522OatFile* 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
1540OatFile::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
1556OatFile::~OatFile() {
1557  STLDeleteElements(&oat_dex_files_storage_);
1558}
1559
1560const OatHeader& OatFile::GetOatHeader() const {
1561  return *reinterpret_cast<const OatHeader*>(Begin());
1562}
1563
1564const uint8_t* OatFile::Begin() const {
1565  CHECK(begin_ != nullptr);
1566  return begin_;
1567}
1568
1569const uint8_t* OatFile::End() const {
1570  CHECK(end_ != nullptr);
1571  return end_;
1572}
1573
1574const uint8_t* OatFile::BssBegin() const {
1575  return bss_begin_;
1576}
1577
1578const uint8_t* OatFile::BssEnd() const {
1579  return bss_end_;
1580}
1581
1582const uint8_t* OatFile::VdexBegin() const {
1583  return vdex_begin_;
1584}
1585
1586const uint8_t* OatFile::VdexEnd() const {
1587  return vdex_end_;
1588}
1589
1590const uint8_t* OatFile::DexBegin() const {
1591  return vdex_->Begin();
1592}
1593
1594const uint8_t* OatFile::DexEnd() const {
1595  return vdex_->End();
1596}
1597
1598ArrayRef<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
1609ArrayRef<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
1619const 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
1688OatFile::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
1728OatFile::OatDexFile::OatDexFile(std::unique_ptr<TypeLookupTable>&& lookup_table)
1729    : lookup_table_(std::move(lookup_table)) {}
1730
1731OatFile::OatDexFile::~OatDexFile() {}
1732
1733size_t OatFile::OatDexFile::FileSize() const {
1734  return reinterpret_cast<const DexFile::Header*>(dex_file_pointer_)->file_size_;
1735}
1736
1737std::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
1752uint32_t OatFile::OatDexFile::GetOatClassOffset(uint16_t class_def_index) const {
1753  return oat_class_offsets_pointer_[class_def_index];
1754}
1755
1756OatFile::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
1798const 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.
1833void 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
1857OatFile::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
1891uint32_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
1899const 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
1921const 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
1936void OatFile::OatMethod::LinkMethod(ArtMethod* method) const {
1937  CHECK(method != nullptr);
1938  method->SetEntryPointFromQuickCompiledCode(GetQuickCode());
1939}
1940
1941bool OatFile::IsPic() const {
1942  return GetOatHeader().IsPic();
1943  // TODO: Check against oat_patches. b/18144996
1944}
1945
1946bool OatFile::IsDebuggable() const {
1947  return GetOatHeader().IsDebuggable();
1948}
1949
1950CompilerFilter::Filter OatFile::GetCompilerFilter() const {
1951  return GetOatHeader().GetCompilerFilter();
1952}
1953
1954std::string OatFile::GetClassLoaderContext() const {
1955  return GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey);
1956}
1957
1958const char* OatFile::GetCompilationReason() const {
1959  return GetOatHeader().GetStoreValueByKey(OatHeader::kCompilationReasonKey);
1960}
1961
1962OatFile::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
1975void OatFile::OatDexFile::AssertAotCompiler() {
1976  CHECK(Runtime::Current()->IsAotCompiler());
1977}
1978
1979}  // namespace art
1980