12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
16e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_OAT_FILE_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_OAT_FILE_H_
19e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
203f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko#include <list>
21700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom#include <string>
22e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include <vector>
23e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
24aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko#include "base/array_ref.h"
253f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko#include "base/mutex.h"
268f4b056427a9d2321e3aa4f21ca8ffb18b3e5ae6David Sehr#include "base/os.h"
2767bf42e89592c3a1c648f927f2ce3ccb189a1161David Sehr#include "base/safe_map.h"
28539690a351d8c325707368729aafa2b4fa134d4cVladimir Marko#include "base/stringpiece.h"
2967bf42e89592c3a1c648f927f2ce3ccb189a1161David Sehr#include "base/tracking_safe_map.h"
308f4b056427a9d2321e3aa4f21ca8ffb18b3e5ae6David Sehr#include "base/utils.h"
312c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko#include "class_status.h"
3297d7e1cd7f733cb33a0e238bec6d7ed525638cd1Vladimir Marko#include "compiler_filter.h"
339e734c7ab4599d7747a05db0dc73c7b668cb6683David Sehr#include "dex/dex_file.h"
349e734c7ab4599d7747a05db0dc73c7b668cb6683David Sehr#include "dex/dex_file_layout.h"
350225f8e2939a9340cb7dcebfcfe7996a2bd9bce9David Sehr#include "dex/utf.h"
36f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko#include "index_bss_mapping.h"
372c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko#include "mirror/object.h"
382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "oat.h"
399aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr#include "type_lookup_table.h"
40e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
41e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromnamespace art {
42e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
43ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstromclass BitVector;
44700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromclass ElfFile;
45120aa286ab6adf3e76a31bc61fb4e583e5158d71Mathieu Chartierclass DexLayoutSections;
46aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Markotemplate <class MirrorType> class GcRoot;
47700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromclass MemMap;
4807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhlerclass OatDexFile;
49513061a792b22c417c938d31c19581390709561cAndreas Gampeclass OatHeader;
50513061a792b22c417c938d31c19581390709561cAndreas Gampeclass OatMethodOffsets;
51513061a792b22c417c938d31c19581390709561cAndreas Gampeclass OatQuickMethodHeader;
5297d7e1cd7f733cb33a0e238bec6d7ed525638cd1Vladimir Markoclass VdexFile;
53700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
545351da0225d027a19420153615634a1c78966bcaMathieu Chartiernamespace gc {
555351da0225d027a19420153615634a1c78966bcaMathieu Chartiernamespace collector {
565351da0225d027a19420153615634a1c78966bcaMathieu Chartierclass DummyOatFile;
575351da0225d027a19420153615634a1c78966bcaMathieu Chartier}  // namespace collector
585351da0225d027a19420153615634a1c78966bcaMathieu Chartier}  // namespace gc
595351da0225d027a19420153615634a1c78966bcaMathieu Chartier
607b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil// Runtime representation of the OAT file format which holds compiler output.
617b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil// The class opens an OAT file from storage and maps it to memory, typically with
627b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil// dlopen and provides access to its internal data structures (see OatWriter for
637b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil// for more details about the OAT format).
647b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil// In the process of loading OAT, the class also loads the associated VDEX file
657b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil// with the input DEX files (see VdexFile for details about the VDEX format).
667b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil// The raw DEX data are accessible transparently through the OatDexFile objects.
677b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil
68049cff0ed5e28aa17a17e456efe3121b6d58910fAndreas Gampeclass OatFile {
69e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom public:
70f0192c86a58b2f43378c9a2113007538dd38ddbfJeff Hao  // Special classpath that skips shared library check.
71f0192c86a58b2f43378c9a2113007538dd38ddbfJeff Hao  static constexpr const char* kSpecialSharedLibrary = "&";
72f0192c86a58b2f43378c9a2113007538dd38ddbfJeff Hao
7307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  typedef art::OatDexFile OatDexFile;
7407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
7584d7605f93f1e6e86a16e02017e305c90e93117aAlex Light  // Opens an oat file contained within the given elf file. This is always opened as
7684d7605f93f1e6e86a16e02017e305c90e93117aAlex Light  // non-executable at the moment.
7796dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray  static OatFile* OpenWithElfFile(int zip_fd,
7896dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray                                  ElfFile* elf_file,
79c93b3be140f6a57a572f2a4cdaf46aba87235a02David Brazdil                                  VdexFile* vdex_file,
80c93b3be140f6a57a572f2a4cdaf46aba87235a02David Brazdil                                  const std::string& location,
81e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler                                  const char* abs_dex_location,
82b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin                                  std::string* error_msg);
832cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // Open an oat file. Returns null on failure.  Requested base can
84e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  // optionally be used to request where the file should be loaded.
85e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // See the ResolveRelativeEncodedDexLocation for a description of how the
86e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // abs_dex_location argument is used.
8796dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray  static OatFile* Open(int zip_fd,
8896dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray                       const std::string& filename,
89a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom                       const std::string& location,
9013735955f39b3b304c37d2b2840663c131262c18Ian Rogers                       uint8_t* requested_base,
9146774767fcf7780d1455e755729198648d08742eIgor Murashkin                       uint8_t* oat_file_begin,
928d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                       bool executable,
930b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                       bool low_4gb,
94e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler                       const char* abs_dex_location,
95b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin                       std::string* error_msg);
96e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
97b22dea05178034a40b84953a661f3ea613395d16Shubham Ajmera  // Similar to OatFile::Open(const std::string...), but accepts input vdex and
9896dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray  // odex files as file descriptors. We also take zip_fd in case the vdex does not
9996dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray  // contain the dex code, and we need to read it from the zip file.
10096dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray  static OatFile* Open(int zip_fd,
10196dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray                       int vdex_fd,
102b22dea05178034a40b84953a661f3ea613395d16Shubham Ajmera                       int oat_fd,
103b22dea05178034a40b84953a661f3ea613395d16Shubham Ajmera                       const std::string& oat_location,
104b22dea05178034a40b84953a661f3ea613395d16Shubham Ajmera                       uint8_t* requested_base,
105b22dea05178034a40b84953a661f3ea613395d16Shubham Ajmera                       uint8_t* oat_file_begin,
106b22dea05178034a40b84953a661f3ea613395d16Shubham Ajmera                       bool executable,
107b22dea05178034a40b84953a661f3ea613395d16Shubham Ajmera                       bool low_4gb,
108b22dea05178034a40b84953a661f3ea613395d16Shubham Ajmera                       const char* abs_dex_location,
109b22dea05178034a40b84953a661f3ea613395d16Shubham Ajmera                       std::string* error_msg);
110b22dea05178034a40b84953a661f3ea613395d16Shubham Ajmera
111700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Open an oat file from an already opened File.
112265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // Does not use dlopen underneath so cannot be used for runtime use
113265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // where relocations may be required. Currently used from
114265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // ImageWriter which wants to open a writable version from an existing
115265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // file descriptor for patching.
11696dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray  static OatFile* OpenWritable(int zip_fd,
11796dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray                               File* file,
11896dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray                               const std::string& location,
119e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler                               const char* abs_dex_location,
120b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin                               std::string* error_msg);
12158cc1cb66c1a96ffba4a314edb2c5b4e8b235d5bNicolas Geoffray  // Open an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE.
12296dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray  static OatFile* OpenReadable(int zip_fd,
12396dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray                               File* file,
12496dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray                               const std::string& location,
125e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler                               const char* abs_dex_location,
126b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin                               std::string* error_msg);
127700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
128049cff0ed5e28aa17a17e456efe3121b6d58910fAndreas Gampe  virtual ~OatFile();
129e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
1309dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light  bool IsExecutable() const {
1319dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light    return is_executable_;
1329dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light  }
1339dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light
1347ba649636c4475c3992fa15a57acd2546d69ff38Andreas Gampe  bool IsPic() const;
1357ba649636c4475c3992fa15a57acd2546d69ff38Andreas Gampe
1360de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  // Indicates whether the oat file was compiled with full debugging capability.
1370de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  bool IsDebuggable() const;
1380de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz
13929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  CompilerFilter::Filter GetCompilerFilter() const;
140b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle
14144e5efa4ae79cf76c65f37fc41c1fa0ed431ec4aCalin Juravle  std::string GetClassLoaderContext() const;
14244e5efa4ae79cf76c65f37fc41c1fa0ed431ec4aCalin Juravle
1430e09dfc9cbdd6c2510dbe50dba95cf9d2d815e79Calin Juravle  const char* GetCompilationReason() const;
1440e09dfc9cbdd6c2510dbe50dba95cf9d2d815e79Calin Juravle
145e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  const std::string& GetLocation() const {
146e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    return location_;
147e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
148e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
149e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  const OatHeader& GetOatHeader() const;
150e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
15107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  class OatMethod FINAL {
1523320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom   public:
153e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    void LinkMethod(ArtMethod* method) const;
154ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
155c04c800e7bda94abfadc8c2d30f58c50b261b612Nicolas Geoffray    uint32_t GetCodeOffset() const;
156ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
157c04c800e7bda94abfadc8c2d30f58c50b261b612Nicolas Geoffray    const void* GetQuickCode() const;
1582cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom
1592cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    // Returns size of quick code.
160ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uint32_t GetQuickCodeSize() const;
1612cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    uint32_t GetQuickCodeSizeOffset() const;
1622cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom
1632cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    // Returns OatQuickMethodHeader for debugging. Most callers should
1642cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    // use more specific methods such as GetQuickCodeSize.
1652cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    const OatQuickMethodHeader* GetOatQuickMethodHeader() const;
1662cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    uint32_t GetOatQuickMethodHeaderOffset() const;
1670c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien
1687624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko    size_t GetFrameSizeInBytes() const;
1697624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko    uint32_t GetCoreSpillMask() const;
1707624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko    uint32_t GetFpSpillMask() const;
1712cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom
1728a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko    const uint8_t* GetVmapTable() const;
1732cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    uint32_t GetVmapTableOffset() const;
1742cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    uint32_t GetVmapTableOffsetOffset() const;
1758a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko
176ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    // Create an OatMethod with offsets relative to the given base address
177957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier    OatMethod(const uint8_t* base, const uint32_t code_offset)
178957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier        : begin_(base), code_offset_(code_offset) {
17997b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    }
180758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe    OatMethod(const OatMethod&) = default;
18197b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    ~OatMethod() {}
1823320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
183758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe    OatMethod& operator=(const OatMethod&) = default;
184758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe
18597b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    // A representation of an invalid OatMethod, used when an OatMethod or OatClass can't be found.
18697b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    // See ClassLinker::FindOatMethodFor.
18797b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    static const OatMethod Invalid() {
188957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier      return OatMethod(nullptr, -1);
18997b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    }
1904fcdc94d22a4608e355aa8df36240181149d10e8Nicolas Geoffray
191ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom   private:
192ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    template<class T>
193ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    T GetOatPointer(uint32_t offset) const {
194ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (offset == 0) {
1952cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier        return nullptr;
196ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
19730fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers      return reinterpret_cast<T>(begin_ + offset);
198ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
1993320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
200e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    const uint8_t* begin_;
201e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    uint32_t code_offset_;
202ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
203ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    friend class OatClass;
2043320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  };
2053320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
20607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  class OatClass FINAL {
207e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom   public:
2082c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko    ClassStatus GetStatus() const {
209ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom      return status_;
210ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom    }
211ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom
212ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom    OatClassType GetType() const {
213ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom      return type_;
214ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom    }
2150755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom
216eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    // Get the OatMethod entry based on its index into the class
2172cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    // defintion. Direct methods come first, followed by virtual
2182cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    // methods. Note that runtime created methods such as miranda
219e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    // methods are not included.
220aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    const OatMethod GetOatMethod(uint32_t method_index) const;
221e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
2222cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    // Return a pointer to the OatMethodOffsets for the requested
2232cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    // method_index, or null if none is present. Note that most
2242cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    // callers should use GetOatMethod.
2252cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const;
2262cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom
2272cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    // Return the offset from the start of the OatFile to the
2282cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    // OatMethodOffsets for the requested method_index, or 0 if none
2292cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    // is present. Note that most callers should use GetOatMethod.
2302cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const;
2312cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom
23297b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    // A representation of an invalid OatClass, used when an OatClass can't be found.
23397d7e1cd7f733cb33a0e238bec6d7ed525638cd1Vladimir Marko    // See FindOatClass().
23497b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    static OatClass Invalid() {
23572ab684871f870aead76b23cb67deb046107b380Vladimir Marko      return OatClass(/* oat_file */ nullptr,
2362c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko                      ClassStatus::kErrorUnresolved,
23772ab684871f870aead76b23cb67deb046107b380Vladimir Marko                      kOatClassNoneCompiled,
23872ab684871f870aead76b23cb67deb046107b380Vladimir Marko                      /* bitmap_size */ 0,
23972ab684871f870aead76b23cb67deb046107b380Vladimir Marko                      /* bitmap_pointer */ nullptr,
24072ab684871f870aead76b23cb67deb046107b380Vladimir Marko                      /* methods_pointer */ nullptr);
24197b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    }
2424fcdc94d22a4608e355aa8df36240181149d10e8Nicolas Geoffray
243e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom   private:
2440755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom    OatClass(const OatFile* oat_file,
2452c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko             ClassStatus status,
246ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom             OatClassType type,
247ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom             uint32_t bitmap_size,
248ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom             const uint32_t* bitmap_pointer,
2490755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom             const OatMethodOffsets* methods_pointer);
2503320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
25197b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    const OatFile* const oat_file_;
252ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom
2532c64a837e62c2839521c89060b5bb0dcb237dddaVladimir Marko    const ClassStatus status_;
254ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom
25597b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    const OatClassType type_;
256ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom
25797b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    const uint32_t* const bitmap_;
258ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom
25997b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers    const OatMethodOffsets* const methods_pointer_;
260e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
26107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    friend class art::OatDexFile;
262e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  };
2639a37efc6e1a8dd9fe6978f209fb493510267c528Richard Uhler
2649a37efc6e1a8dd9fe6978f209fb493510267c528Richard Uhler  // Get the OatDexFile for the given dex_location within this oat file.
2659a37efc6e1a8dd9fe6978f209fb493510267c528Richard Uhler  // If dex_location_checksum is non-null, the OatDexFile will only be
2669a37efc6e1a8dd9fe6978f209fb493510267c528Richard Uhler  // returned if it has a matching checksum.
2679a37efc6e1a8dd9fe6978f209fb493510267c528Richard Uhler  // If error_msg is non-null and no OatDexFile is returned, error_msg will
2689a37efc6e1a8dd9fe6978f209fb493510267c528Richard Uhler  // be updated with a description of why no OatDexFile was returned.
2698d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  const OatDexFile* GetOatDexFile(const char* dex_location,
270756ee4e090bc1e1812b41fb7b4661df601a32ef9Brian Carlstrom                                  const uint32_t* const dex_location_checksum,
2719a37efc6e1a8dd9fe6978f209fb493510267c528Richard Uhler                                  /*out*/std::string* error_msg = nullptr) const
27290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!secondary_lookup_lock_);
2738d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers
274aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko  const std::vector<const OatDexFile*>& GetOatDexFiles() const {
275aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko    return oat_dex_files_storage_;
276aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko  }
277e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
27830fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers  size_t Size() const {
27930fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    return End() - Begin();
280e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
281e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
2826ea1a0e2168c8d9b6d97c075c73a72d84080f45bMingyao Yang  bool Contains(const void* p) const {
2836ea1a0e2168c8d9b6d97c075c73a72d84080f45bMingyao Yang    return p >= Begin() && p < End();
2846ea1a0e2168c8d9b6d97c075c73a72d84080f45bMingyao Yang  }
2856ea1a0e2168c8d9b6d97c075c73a72d84080f45bMingyao Yang
2865c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko  size_t BssSize() const {
2875c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko    return BssEnd() - BssBegin();
2885c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko  }
2895c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko
290ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky  size_t VdexSize() const {
291ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky    return VdexEnd() - VdexBegin();
292ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky  }
293ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky
2940eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko  size_t BssMethodsOffset() const {
2950eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko    // Note: This is used only for symbolizer and needs to return a valid .bss offset.
2960eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko    return (bss_methods_ != nullptr) ? bss_methods_ - BssBegin() : BssRootsOffset();
2970eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko  }
2980eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko
299aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko  size_t BssRootsOffset() const {
3000eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko    // Note: This is used only for symbolizer and needs to return a valid .bss offset.
3010eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko    return (bss_roots_ != nullptr) ? bss_roots_ - BssBegin() : BssSize();
302aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko  }
303aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko
3047b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil  size_t DexSize() const {
3057b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil    return DexEnd() - DexBegin();
3067b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil  }
3077b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil
30813735955f39b3b304c37d2b2840663c131262c18Ian Rogers  const uint8_t* Begin() const;
30913735955f39b3b304c37d2b2840663c131262c18Ian Rogers  const uint8_t* End() const;
31053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
3115c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko  const uint8_t* BssBegin() const;
3125c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko  const uint8_t* BssEnd() const;
3135c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko
314ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky  const uint8_t* VdexBegin() const;
315ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky  const uint8_t* VdexEnd() const;
316ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky
3177b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil  const uint8_t* DexBegin() const;
3187b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil  const uint8_t* DexEnd() const;
3197b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil
3200eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko  ArrayRef<ArtMethod*> GetBssMethods() const;
321aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko  ArrayRef<GcRoot<mirror::Object>> GetBssGcRoots() const;
322aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko
323e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Returns the absolute dex location for the encoded relative dex location.
324e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  //
3252cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // If not null, abs_dex_location is used to resolve the absolute dex
326e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // location of relative dex locations encoded in the oat file.
327e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // For example, given absolute location "/data/app/foo/base.apk", encoded
328a308a327884920cbb1e3e62964c4b5a01c29af8cCalin Juravle  // dex locations "base.apk", "base.apk!classes2.dex", etc. would be resolved
329a308a327884920cbb1e3e62964c4b5a01c29af8cCalin Juravle  // to "/data/app/foo/base.apk", "/data/app/foo/base.apk!classes2.dex", etc.
330e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Relative encoded dex locations that don't match the given abs_dex_location
331e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // are left unchanged.
332e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  static std::string ResolveRelativeEncodedDexLocation(
333e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler      const char* abs_dex_location, const std::string& rel_dex_location);
334e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
33597d7e1cd7f733cb33a0e238bec6d7ed525638cd1Vladimir Marko  // Finds the associated oat class for a dex_file and descriptor. Returns an invalid OatClass on
33697d7e1cd7f733cb33a0e238bec6d7ed525638cd1Vladimir Marko  // error and sets found to false.
33797d7e1cd7f733cb33a0e238bec6d7ed525638cd1Vladimir Marko  static OatClass FindOatClass(const DexFile& dex_file, uint16_t class_def_idx, bool* found);
33897d7e1cd7f733cb33a0e238bec6d7ed525638cd1Vladimir Marko
3394acefd33064d37b41ca55c3c9355345a20e5f9c2Nicolas Geoffray  VdexFile* GetVdexFile() const {
3404acefd33064d37b41ca55c3c9355345a20e5f9c2Nicolas Geoffray    return vdex_.get();
3414acefd33064d37b41ca55c3c9355345a20e5f9c2Nicolas Geoffray  }
3424acefd33064d37b41ca55c3c9355345a20e5f9c2Nicolas Geoffray
343f30752709e1131ae1a4c16f22cc7a0960c198e77Nicolas Geoffray  // Whether the OatFile embeds the Dex code.
344f30752709e1131ae1a4c16f22cc7a0960c198e77Nicolas Geoffray  bool ContainsDexCode() const {
345f30752709e1131ae1a4c16f22cc7a0960c198e77Nicolas Geoffray    return uncompressed_dex_files_ == nullptr;
346f30752709e1131ae1a4c16f22cc7a0960c198e77Nicolas Geoffray  }
347f30752709e1131ae1a4c16f22cc7a0960c198e77Nicolas Geoffray
348049cff0ed5e28aa17a17e456efe3121b6d58910fAndreas Gampe protected:
349049cff0ed5e28aa17a17e456efe3121b6d58910fAndreas Gampe  OatFile(const std::string& filename, bool executable);
350e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
351049cff0ed5e28aa17a17e456efe3121b6d58910fAndreas Gampe private:
352e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  // The oat file name.
353e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  //
354e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  // The image will embed this to link its associated oat file.
355e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  const std::string location_;
356e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
3577b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil  // Pointer to the Vdex file with the Dex files for this Oat file.
3587b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil  std::unique_ptr<VdexFile> vdex_;
3597b49e6cade09bc65b3b5f22d45fc9d0a7184e4f2David Brazdil
360700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Pointer to OatHeader.
36113735955f39b3b304c37d2b2840663c131262c18Ian Rogers  const uint8_t* begin_;
362700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
363700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Pointer to end of oat region for bounds checking.
36413735955f39b3b304c37d2b2840663c131262c18Ian Rogers  const uint8_t* end_;
365700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
3662cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // Pointer to the .bss section, if present, otherwise null.
36706d7aaa75f3d6d21fe904d54208b28e486673d97Vladimir Marko  uint8_t* bss_begin_;
3685c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko
3692cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // Pointer to the end of the .bss section, if present, otherwise null.
37006d7aaa75f3d6d21fe904d54208b28e486673d97Vladimir Marko  uint8_t* bss_end_;
3715c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko
3720eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko  // Pointer to the beginning of the ArtMethod*s in .bss section, if present, otherwise null.
3730eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko  uint8_t* bss_methods_;
3740eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko
375aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko  // Pointer to the beginning of the GC roots in .bss section, if present, otherwise null.
376aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko  uint8_t* bss_roots_;
377aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko
3789dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light  // Was this oat_file loaded executable?
3799dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light  const bool is_executable_;
3809dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light
381ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky  // Pointer to the .vdex section, if present, otherwise null.
382ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky  uint8_t* vdex_begin_;
383ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky
384ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky  // Pointer to the end of the .vdex section, if present, otherwise null.
385ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky  uint8_t* vdex_end_;
386ec2cdf4286921131a5f9b3ed12060657ec40f636David Srbecky
387aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko  // Owning storage for the OatDexFile objects.
388aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko  std::vector<const OatDexFile*> oat_dex_files_storage_;
389aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko
3903f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every
3913f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // lookup with a const char* key. The StringPiece doesn't own its backing storage,
3923f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // therefore we're using the OatDexFile::dex_file_location_ as the backing storage
3933f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage
3943f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_.
395bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier  typedef AllocationTrackingSafeMap<StringPiece, const OatDexFile*, kAllocatorTagOatFile> Table;
3963f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko
397aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko  // Map each location and canonical location (if different) retrieved from the
398aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko  // oat file to its OatDexFile. This map doesn't change after it's constructed in Setup()
399aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko  // and therefore doesn't need any locking and provides the cheapest dex file lookup
4002cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // for GetOatDexFile() for a very frequent use case. Never contains a null value.
401aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko  Table oat_dex_files_;
4023f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko
4033f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // Lock guarding all members needed for secondary lookup in GetOatDexFile().
4043f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
4053f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko
4063f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores
4073f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // the results of all previous secondary lookups, whether successful (non-null) or
4083f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // failed (null). If it doesn't contain an entry we need to calculate the canonical
4093f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // location and use oat_dex_files_by_canonical_location_.
4103f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_);
4113f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko
4123f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_
4133f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // and the lazily initialized oat_dex_files_by_canonical_location_.
4143f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // NOTE: We're keeping references to contained strings in form of StringPiece and adding
4153f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // new strings to the end. The adding of a new element must not touch any previously stored
4163f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't.
4173f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko  mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_);
418e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
419f30752709e1131ae1a4c16f22cc7a0960c198e77Nicolas Geoffray  // Cache of dex files mapped directly from a location, in case the OatFile does
420f30752709e1131ae1a4c16f22cc7a0960c198e77Nicolas Geoffray  // not embed the dex code.
421f30752709e1131ae1a4c16f22cc7a0960c198e77Nicolas Geoffray  std::unique_ptr<std::vector<std::unique_ptr<const DexFile>>> uncompressed_dex_files_;
422f30752709e1131ae1a4c16f22cc7a0960c198e77Nicolas Geoffray
4235351da0225d027a19420153615634a1c78966bcaMathieu Chartier  friend class gc::collector::DummyOatFile;  // For modifying begin_ and end_.
424e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  friend class OatClass;
42507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  friend class art::OatDexFile;
426e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes  friend class OatDumper;  // For GetBase and GetLimit
427049cff0ed5e28aa17a17e456efe3121b6d58910fAndreas Gampe  friend class OatFileBase;
428e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  DISALLOW_COPY_AND_ASSIGN(OatFile);
429e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom};
430e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
43107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler// OatDexFile should be an inner class of OatFile. Unfortunately, C++ doesn't
43207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler// support forward declarations of inner classes, and we want to
43307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler// forward-declare OatDexFile so that we can store an opaque pointer to an
43407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler// OatDexFile in DexFile.
43507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhlerclass OatDexFile FINAL {
43607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler public:
43707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  // Opens the DexFile referred to by this OatDexFile from within the containing OatFile.
438b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const;
43907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
4401b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier  // May return null if the OatDexFile only contains a type lookup table. This case only happens
4411b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier  // for the compiler to speed up compilation.
44207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  const OatFile* GetOatFile() const {
4431b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier    // Avoid pulling in runtime.h in the header file.
4441b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier    if (kIsDebugBuild && oat_file_ == nullptr) {
4451b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier      AssertAotCompiler();
4461b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier    }
44707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    return oat_file_;
44807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  }
44907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
45007b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  // Returns the size of the DexFile refered to by this OatDexFile.
45107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  size_t FileSize() const;
45207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
45307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  // Returns original path of DexFile that was the source of this OatDexFile.
45407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  const std::string& GetDexFileLocation() const {
45507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    return dex_file_location_;
45607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  }
45707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
45807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  // Returns the canonical location of DexFile that was the source of this OatDexFile.
45907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  const std::string& GetCanonicalDexFileLocation() const {
46007b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    return canonical_dex_file_location_;
46107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  }
46207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
46307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  // Returns checksum of original DexFile that was the source of this OatDexFile;
46407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  uint32_t GetDexFileLocationChecksum() const {
46507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    return dex_file_location_checksum_;
46607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  }
46707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
46807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  // Returns the OatClass for the class specified by the given DexFile class_def_index.
46907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  OatFile::OatClass GetOatClass(uint16_t class_def_index) const;
47007b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
47107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  // Returns the offset to the OatClass information. Most callers should use GetOatClass.
47207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  uint32_t GetOatClassOffset(uint16_t class_def_index) const;
47307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
474d9786b0e5be23ea0258405165098b4216579209cArtem Udovichenko  const uint8_t* GetLookupTableData() const {
475d9786b0e5be23ea0258405165098b4216579209cArtem Udovichenko    return lookup_table_data_;
476d9786b0e5be23ea0258405165098b4216579209cArtem Udovichenko  }
477d9786b0e5be23ea0258405165098b4216579209cArtem Udovichenko
478f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko  const IndexBssMapping* GetMethodBssMapping() const {
4790eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko    return method_bss_mapping_;
4800eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko  }
4810eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko
482f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko  const IndexBssMapping* GetTypeBssMapping() const {
483f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko    return type_bss_mapping_;
484f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko  }
485f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko
486f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko  const IndexBssMapping* GetStringBssMapping() const {
487f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko    return string_bss_mapping_;
488f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko  }
489f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko
4902ba8895b4257d0e32a7b269bc2e7f6a3ec39a86aAndreas Gampe  const uint8_t* GetDexFilePointer() const {
4912ba8895b4257d0e32a7b269bc2e7f6a3ec39a86aAndreas Gampe    return dex_file_pointer_;
4922ba8895b4257d0e32a7b269bc2e7f6a3ec39a86aAndreas Gampe  }
4932ba8895b4257d0e32a7b269bc2e7f6a3ec39a86aAndreas Gampe
4949aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr  // Looks up a class definition by its class descriptor. Hash must be
4959aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr  // ComputeModifiedUtf8Hash(descriptor).
4969aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr  static const DexFile::ClassDef* FindClassDef(const DexFile& dex_file,
4979aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr                                               const char* descriptor,
4989aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr                                               size_t hash);
4999aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr
500120aa286ab6adf3e76a31bc61fb4e583e5158d71Mathieu Chartier  // Madvise the dex file based on the state we are moving to.
501120aa286ab6adf3e76a31bc61fb4e583e5158d71Mathieu Chartier  static void MadviseDexFile(const DexFile& dex_file, MadviseState state);
502120aa286ab6adf3e76a31bc61fb4e583e5158d71Mathieu Chartier
5039aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr  TypeLookupTable* GetTypeLookupTable() const {
5049aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr    return lookup_table_.get();
5059aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr  }
5069aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr
50707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  ~OatDexFile();
50807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
5091b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier  // Create only with a type lookup table, used by the compiler to speed up compilation.
5101b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier  explicit OatDexFile(std::unique_ptr<TypeLookupTable>&& lookup_table);
5111b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier
512120aa286ab6adf3e76a31bc61fb4e583e5158d71Mathieu Chartier  // Return the dex layout sections.
513120aa286ab6adf3e76a31bc61fb4e583e5158d71Mathieu Chartier  const DexLayoutSections* GetDexLayoutSections() const {
514120aa286ab6adf3e76a31bc61fb4e583e5158d71Mathieu Chartier    return dex_layout_sections_;
515120aa286ab6adf3e76a31bc61fb4e583e5158d71Mathieu Chartier  }
516120aa286ab6adf3e76a31bc61fb4e583e5158d71Mathieu Chartier
51707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler private:
51807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  OatDexFile(const OatFile* oat_file,
51907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler             const std::string& dex_file_location,
52007b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler             const std::string& canonical_dex_file_location,
52107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler             uint32_t dex_file_checksum,
52207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler             const uint8_t* dex_file_pointer,
523d9786b0e5be23ea0258405165098b4216579209cArtem Udovichenko             const uint8_t* lookup_table_data,
524f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko             const IndexBssMapping* method_bss_mapping,
525f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko             const IndexBssMapping* type_bss_mapping,
526f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko             const IndexBssMapping* string_bss_mapping,
52709d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko             const uint32_t* oat_class_offsets_pointer,
528120aa286ab6adf3e76a31bc61fb4e583e5158d71Mathieu Chartier             const DexLayoutSections* dex_layout_sections);
52907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
5301b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier  static void AssertAotCompiler();
5311b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier
5321b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier  const OatFile* const oat_file_ = nullptr;
53307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  const std::string dex_file_location_;
53407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  const std::string canonical_dex_file_location_;
5351b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier  const uint32_t dex_file_location_checksum_ = 0u;
5361b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier  const uint8_t* const dex_file_pointer_ = nullptr;
5370eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko  const uint8_t* const lookup_table_data_ = nullptr;
538f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko  const IndexBssMapping* const method_bss_mapping_ = nullptr;
539f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko  const IndexBssMapping* const type_bss_mapping_ = nullptr;
540f3c52b42a035902245d00a619fed0275afb063d2Vladimir Marko  const IndexBssMapping* const string_bss_mapping_ = nullptr;
5411b868498a176705b867e2572cc1bcbd58dbd62d6Mathieu Chartier  const uint32_t* const oat_class_offsets_pointer_ = 0u;
5429aa352e92b6ca0f2250cb7f54dfbf4b1be714c19David Sehr  mutable std::unique_ptr<TypeLookupTable> lookup_table_;
543120aa286ab6adf3e76a31bc61fb4e583e5158d71Mathieu Chartier  const DexLayoutSections* const dex_layout_sections_ = nullptr;
54407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
54507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  friend class OatFile;
546049cff0ed5e28aa17a17e456efe3121b6d58910fAndreas Gampe  friend class OatFileBase;
54707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler  DISALLOW_COPY_AND_ASSIGN(OatDexFile);
54807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler};
54907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler
550e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}  // namespace art
551e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
552fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_OAT_FILE_H_
553