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