oat_file.h revision 2cebb24bfc3247d3e9be138a3350106737455918
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 243f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko#include "base/mutex.h" 25539690a351d8c325707368729aafa2b4fa134d4cVladimir Marko#include "base/stringpiece.h" 262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "dex_file.h" 272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "invoke_type.h" 282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mem_map.h" 2998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang#include "mirror/class.h" 302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "oat.h" 31700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom#include "os.h" 32e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 33e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromnamespace art { 34e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 35ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstromclass BitVector; 36700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromclass ElfFile; 37700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromclass MemMap; 38700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromclass OatMethodOffsets; 3933e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogersclass OatHeader; 4007b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhlerclass OatDexFile; 41700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 4207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhlerclass OatFile FINAL { 43e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom public: 4407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler typedef art::OatDexFile OatDexFile; 4507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 4684d7605f93f1e6e86a16e02017e305c90e93117aAlex Light // Opens an oat file contained within the given elf file. This is always opened as 4784d7605f93f1e6e86a16e02017e305c90e93117aAlex Light // non-executable at the moment. 4884d7605f93f1e6e86a16e02017e305c90e93117aAlex Light static OatFile* OpenWithElfFile(ElfFile* elf_file, const std::string& location, 49e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler const char* abs_dex_location, 5084d7605f93f1e6e86a16e02017e305c90e93117aAlex Light std::string* error_msg); 512cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Open an oat file. Returns null on failure. Requested base can 52e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // optionally be used to request where the file should be loaded. 53e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // See the ResolveRelativeEncodedDexLocation for a description of how the 54e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // abs_dex_location argument is used. 55e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom static OatFile* Open(const std::string& filename, 56a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const std::string& location, 5713735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* requested_base, 5846774767fcf7780d1455e755729198648d08742eIgor Murashkin uint8_t* oat_file_begin, 598d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers bool executable, 60e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler const char* abs_dex_location, 618d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string* error_msg); 62e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 63700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // Open an oat file from an already opened File. 64265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // Does not use dlopen underneath so cannot be used for runtime use 65265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // where relocations may be required. Currently used from 66265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // ImageWriter which wants to open a writable version from an existing 67265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // file descriptor for patching. 68e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler static OatFile* OpenWritable(File* file, const std::string& location, 69e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler const char* abs_dex_location, 70e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::string* error_msg); 71a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE. 72e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler static OatFile* OpenReadable(File* file, const std::string& location, 73e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler const char* abs_dex_location, 74e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::string* error_msg); 75700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 76e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom ~OatFile(); 77e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 789dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light bool IsExecutable() const { 799dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light return is_executable_; 809dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light } 819dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light 827ba649636c4475c3992fa15a57acd2546d69ff38Andreas Gampe bool IsPic() const; 837ba649636c4475c3992fa15a57acd2546d69ff38Andreas Gampe 8453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light ElfFile* GetElfFile() const { 8553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light CHECK_NE(reinterpret_cast<uintptr_t>(elf_file_.get()), reinterpret_cast<uintptr_t>(nullptr)) 8653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light << "Cannot get an elf file from " << GetLocation(); 8753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light return elf_file_.get(); 8853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light } 8953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 90e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const std::string& GetLocation() const { 91e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return location_; 92e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 93e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 94e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const OatHeader& GetOatHeader() const; 95e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 9607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler class OatMethod FINAL { 973320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom public: 98b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers void LinkMethod(mirror::ArtMethod* method) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 99ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 100ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom uint32_t GetCodeOffset() const { 101ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return code_offset_; 102ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 103ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 104ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers const void* GetQuickCode() const { 105956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes return GetOatPointer<const void*>(code_offset_); 106ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 1072cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom 1082cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom // Returns size of quick code. 109ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers uint32_t GetQuickCodeSize() const; 1102cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom uint32_t GetQuickCodeSizeOffset() const; 1112cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom 1122cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom // Returns OatQuickMethodHeader for debugging. Most callers should 1132cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom // use more specific methods such as GetQuickCodeSize. 1142cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom const OatQuickMethodHeader* GetOatQuickMethodHeader() const; 1152cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom uint32_t GetOatQuickMethodHeaderOffset() const; 1160c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien 1177624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko size_t GetFrameSizeInBytes() const; 1187624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko uint32_t GetCoreSpillMask() const; 1197624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko uint32_t GetFpSpillMask() const; 1202cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom 1218a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko const uint8_t* GetMappingTable() const; 1222cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom uint32_t GetMappingTableOffset() const; 1232cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom uint32_t GetMappingTableOffsetOffset() const; 1242cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom 1258a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko const uint8_t* GetVmapTable() const; 1262cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom uint32_t GetVmapTableOffset() const; 1272cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom uint32_t GetVmapTableOffsetOffset() const; 1288a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko 129957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier const uint8_t* GetGcMap() const; 130957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier uint32_t GetGcMapOffset() const; 131957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier uint32_t GetGcMapOffsetOffset() const; 132957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier 133ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // Create an OatMethod with offsets relative to the given base address 134957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier OatMethod(const uint8_t* base, const uint32_t code_offset) 135957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier : begin_(base), code_offset_(code_offset) { 13697b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers } 137758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe OatMethod(const OatMethod&) = default; 13897b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers ~OatMethod() {} 1393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 140758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe OatMethod& operator=(const OatMethod&) = default; 141758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe 14297b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers // A representation of an invalid OatMethod, used when an OatMethod or OatClass can't be found. 14397b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers // See ClassLinker::FindOatMethodFor. 14497b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers static const OatMethod Invalid() { 145957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier return OatMethod(nullptr, -1); 14697b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers } 1474fcdc94d22a4608e355aa8df36240181149d10e8Nicolas Geoffray 148ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom private: 149ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom template<class T> 150ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom T GetOatPointer(uint32_t offset) const { 151ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (offset == 0) { 1522cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier return nullptr; 153ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 15430fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers return reinterpret_cast<T>(begin_ + offset); 155ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 1563320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 157e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier const uint8_t* begin_; 158e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier uint32_t code_offset_; 159ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 160ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom friend class OatClass; 1613320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom }; 1623320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 16307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler class OatClass FINAL { 164e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom public: 165ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom mirror::Class::Status GetStatus() const { 166ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom return status_; 167ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom } 168ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom 169ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom OatClassType GetType() const { 170ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom return type_; 171ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom } 1720755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom 173eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // Get the OatMethod entry based on its index into the class 1742cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom // defintion. Direct methods come first, followed by virtual 1752cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom // methods. Note that runtime created methods such as miranda 176e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // methods are not included. 177aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const OatMethod GetOatMethod(uint32_t method_index) const; 178e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 1792cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom // Return a pointer to the OatMethodOffsets for the requested 1802cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // method_index, or null if none is present. Note that most 1812cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom // callers should use GetOatMethod. 1822cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const; 1832cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom 1842cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom // Return the offset from the start of the OatFile to the 1852cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom // OatMethodOffsets for the requested method_index, or 0 if none 1862cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom // is present. Note that most callers should use GetOatMethod. 1872cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const; 1882cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom 18997b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers // A representation of an invalid OatClass, used when an OatClass can't be found. 19097b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers // See ClassLinker::FindOatClass. 19197b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers static OatClass Invalid() { 19297b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers return OatClass(nullptr, mirror::Class::kStatusError, kOatClassNoneCompiled, 0, nullptr, 19397b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers nullptr); 19497b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers } 1954fcdc94d22a4608e355aa8df36240181149d10e8Nicolas Geoffray 196e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom private: 1970755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom OatClass(const OatFile* oat_file, 1982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class::Status status, 199ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom OatClassType type, 200ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom uint32_t bitmap_size, 201ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom const uint32_t* bitmap_pointer, 2020755ec5ea1dce0b549fc1adefeb52d89f119ebecBrian Carlstrom const OatMethodOffsets* methods_pointer); 2033320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 20497b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers const OatFile* const oat_file_; 205ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom 20697b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers const mirror::Class::Status status_; 207ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom 20897b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers const OatClassType type_; 209ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom 21097b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers const uint32_t* const bitmap_; 211ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom 21297b52f89e5e0b52a08d4b9a3953d0973a3cf5636Ian Rogers const OatMethodOffsets* const methods_pointer_; 213e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 21407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler friend class art::OatDexFile; 215e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom }; 2168d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers const OatDexFile* GetOatDexFile(const char* dex_location, 217756ee4e090bc1e1812b41fb7b4661df601a32ef9Brian Carlstrom const uint32_t* const dex_location_checksum, 2183f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko bool exception_if_not_found = true) const 2193f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko LOCKS_EXCLUDED(secondary_lookup_lock_); 2208d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 221aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko const std::vector<const OatDexFile*>& GetOatDexFiles() const { 222aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko return oat_dex_files_storage_; 223aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko } 224e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 22530fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers size_t Size() const { 22630fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers return End() - Begin(); 227e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 228e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 2295c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko size_t BssSize() const { 2305c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko return BssEnd() - BssBegin(); 2315c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko } 2325c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko 23313735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* Begin() const; 23413735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* End() const; 23553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 2365c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko const uint8_t* BssBegin() const; 2375c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko const uint8_t* BssEnd() const; 2385c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko 239e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // Returns the absolute dex location for the encoded relative dex location. 240e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // 2412cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // If not null, abs_dex_location is used to resolve the absolute dex 242e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // location of relative dex locations encoded in the oat file. 243e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // For example, given absolute location "/data/app/foo/base.apk", encoded 244e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // dex locations "base.apk", "base.apk:classes2.dex", etc. would be resolved 245e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // to "/data/app/foo/base.apk", "/data/app/foo/base.apk:classes2.dex", etc. 246e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // Relative encoded dex locations that don't match the given abs_dex_location 247e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // are left unchanged. 248e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler static std::string ResolveRelativeEncodedDexLocation( 249e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler const char* abs_dex_location, const std::string& rel_dex_location); 250e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 2517848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe // Create a dependency list (dex locations and checksums) for the given dex files. 2527848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe static std::string EncodeDexFileDependencies(const std::vector<const DexFile*>& dex_files); 2537848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe 2547848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe // Check the given dependency list against their dex files - thus the name "Static," this does 2557848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe // not check the class-loader environment, only whether there have been file updates. 2567848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe static bool CheckStaticDexFileDependencies(const char* dex_dependencies, std::string* msg); 2577848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe 2587848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe // Get the dex locations of a dependency list. Note: this is *not* cleaned for synthetic 2597848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe // locations of multidex files. 2607848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe static bool GetDexLocationsFromDependencies(const char* dex_dependencies, 2617848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe std::vector<std::string>* locations); 2627848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe 263e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom private: 264700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom static void CheckLocation(const std::string& location); 265700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 266fa8429b967fe2260ece572337534c9dda6c50d8aAndreas Gampe static OatFile* OpenDlopen(const std::string& elf_filename, 267fa8429b967fe2260ece572337534c9dda6c50d8aAndreas Gampe const std::string& location, 268fa8429b967fe2260ece572337534c9dda6c50d8aAndreas Gampe uint8_t* requested_base, 269fa8429b967fe2260ece572337534c9dda6c50d8aAndreas Gampe const char* abs_dex_location, 270fa8429b967fe2260ece572337534c9dda6c50d8aAndreas Gampe std::string* error_msg); 271fa8429b967fe2260ece572337534c9dda6c50d8aAndreas Gampe 272700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom static OatFile* OpenElfFile(File* file, 273700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom const std::string& location, 27413735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* requested_base, 27546774767fcf7780d1455e755729198648d08742eIgor Murashkin uint8_t* oat_file_begin, // Override base if not null 276f1d3455064792ac1c486a4a9c24279a37b4af473Brian Carlstrom bool writable, 2778d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers bool executable, 278e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler const char* abs_dex_location, 2798d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string* error_msg); 280700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 2819dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light explicit OatFile(const std::string& filename, bool executable); 282fa8429b967fe2260ece572337534c9dda6c50d8aAndreas Gampe bool Dlopen(const std::string& elf_filename, uint8_t* requested_base, 283fa8429b967fe2260ece572337534c9dda6c50d8aAndreas Gampe const char* abs_dex_location, std::string* error_msg); 28446774767fcf7780d1455e755729198648d08742eIgor Murashkin bool ElfFileOpen(File* file, uint8_t* requested_base, 28546774767fcf7780d1455e755729198648d08742eIgor Murashkin uint8_t* oat_file_begin, // Override where the file is loaded to if not null 28646774767fcf7780d1455e755729198648d08742eIgor Murashkin bool writable, bool executable, 287e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler const char* abs_dex_location, 2888d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string* error_msg); 289e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 290e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler bool Setup(const char* abs_dex_location, std::string* error_msg); 291e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 292e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // The oat file name. 293e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // 294e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // The image will embed this to link its associated oat file. 295e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const std::string location_; 296e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 297700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // Pointer to OatHeader. 29813735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* begin_; 299700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 300700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // Pointer to end of oat region for bounds checking. 30113735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* end_; 302700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 3032cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Pointer to the .bss section, if present, otherwise null. 3045c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko const uint8_t* bss_begin_; 3055c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko 3062cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Pointer to the end of the .bss section, if present, otherwise null. 3075c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko const uint8_t* bss_end_; 3085c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko 3099dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light // Was this oat_file loaded executable? 3109dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light const bool is_executable_; 3119dcc4572949f6a8231a1b4ed859676ba6f411726Alex Light 312700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // Backing memory map for oat file during when opened by ElfWriter during initial compilation. 313700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<MemMap> mem_map_; 314e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 315700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // Backing memory map for oat file during cross compilation. 316700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<ElfFile> elf_file_; 317700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 318700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom // dlopen handle during runtime. 319700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom void* dlopen_handle_; 320700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 321aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko // Owning storage for the OatDexFile objects. 322aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko std::vector<const OatDexFile*> oat_dex_files_storage_; 323aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko 3243f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // NOTE: We use a StringPiece as the key type to avoid a memory allocation on every 3253f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // lookup with a const char* key. The StringPiece doesn't own its backing storage, 3263f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // therefore we're using the OatDexFile::dex_file_location_ as the backing storage 3273f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage 3283f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_. 329bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier typedef AllocationTrackingSafeMap<StringPiece, const OatDexFile*, kAllocatorTagOatFile> Table; 3303f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko 331aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko // Map each location and canonical location (if different) retrieved from the 332aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko // oat file to its OatDexFile. This map doesn't change after it's constructed in Setup() 333aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko // and therefore doesn't need any locking and provides the cheapest dex file lookup 3342cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // for GetOatDexFile() for a very frequent use case. Never contains a null value. 335aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko Table oat_dex_files_; 3363f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko 3373f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // Lock guarding all members needed for secondary lookup in GetOatDexFile(). 3383f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 3393f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko 3403f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores 3413f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // the results of all previous secondary lookups, whether successful (non-null) or 3423f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // failed (null). If it doesn't contain an entry we need to calculate the canonical 3433f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // location and use oat_dex_files_by_canonical_location_. 3443f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_); 3453f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko 3463f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_ 3473f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // and the lazily initialized oat_dex_files_by_canonical_location_. 3483f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // NOTE: We're keeping references to contained strings in form of StringPiece and adding 3493f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // new strings to the end. The adding of a new element must not touch any previously stored 3503f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't. 3513f5838d7d0b9fc63db0ccc35c2ea05ed29264986Vladimir Marko mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_); 352e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 353e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom friend class OatClass; 35407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler friend class art::OatDexFile; 355e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes friend class OatDumper; // For GetBase and GetLimit 356e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom DISALLOW_COPY_AND_ASSIGN(OatFile); 357e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}; 358e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 35907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler// OatDexFile should be an inner class of OatFile. Unfortunately, C++ doesn't 36007b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler// support forward declarations of inner classes, and we want to 36107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler// forward-declare OatDexFile so that we can store an opaque pointer to an 36207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler// OatDexFile in DexFile. 36307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhlerclass OatDexFile FINAL { 36407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler public: 36507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler // Opens the DexFile referred to by this OatDexFile from within the containing OatFile. 36607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const; 36707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 36807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const OatFile* GetOatFile() const { 36907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler return oat_file_; 37007b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler } 37107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 37207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler // Returns the size of the DexFile refered to by this OatDexFile. 37307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler size_t FileSize() const; 37407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 37507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler // Returns original path of DexFile that was the source of this OatDexFile. 37607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const std::string& GetDexFileLocation() const { 37707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler return dex_file_location_; 37807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler } 37907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 38007b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler // Returns the canonical location of DexFile that was the source of this OatDexFile. 38107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const std::string& GetCanonicalDexFileLocation() const { 38207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler return canonical_dex_file_location_; 38307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler } 38407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 38507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler // Returns checksum of original DexFile that was the source of this OatDexFile; 38607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler uint32_t GetDexFileLocationChecksum() const { 38707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler return dex_file_location_checksum_; 38807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler } 38907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 39007b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler // Returns the OatClass for the class specified by the given DexFile class_def_index. 39107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler OatFile::OatClass GetOatClass(uint16_t class_def_index) const; 39207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 39307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler // Returns the offset to the OatClass information. Most callers should use GetOatClass. 39407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler uint32_t GetOatClassOffset(uint16_t class_def_index) const; 39507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 39607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler ~OatDexFile(); 39707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 39807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler private: 39907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler OatDexFile(const OatFile* oat_file, 40007b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const std::string& dex_file_location, 40107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const std::string& canonical_dex_file_location, 40207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler uint32_t dex_file_checksum, 40307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const uint8_t* dex_file_pointer, 40407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const uint32_t* oat_class_offsets_pointer); 40507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 40607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const OatFile* const oat_file_; 40707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const std::string dex_file_location_; 40807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const std::string canonical_dex_file_location_; 40907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const uint32_t dex_file_location_checksum_; 41007b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const uint8_t* const dex_file_pointer_; 41107b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler const uint32_t* const oat_class_offsets_pointer_; 41207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 41307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler friend class OatFile; 41407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler DISALLOW_COPY_AND_ASSIGN(OatDexFile); 41507b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler}; 41607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler 417e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} // namespace art 418e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 419fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_OAT_FILE_H_ 420