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_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_OAT_H_
19e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
20e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include <vector>
21e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
22d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "arch/instruction_set.h"
23761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h"
2429d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe#include "compiler_filter.h"
25e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "dex_file.h"
2622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe#include "safe_map.h"
27e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
28e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromnamespace art {
29e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
30d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersclass InstructionSetFeatures;
31d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers
32df1ce91ba97bc79a0637e5504b39318fb1c9f577Ian Rogersclass PACKED(4) OatHeader {
33e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom public:
342bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe  static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
35ae444410cca87be3942bc5491c98d4c1b8a4a4a5Alex Light  static constexpr uint8_t kOatVersion[] = { '0', '8', '8', '\0' };
367c3d13aebdd8611cae58a1048bffb13cbdc465cbBrian Carlstrom
3722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  static constexpr const char* kImageLocationKey = "image-location";
3822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
3922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  static constexpr const char* kDex2OatHostKey = "dex2oat-host";
407ba649636c4475c3992fa15a57acd2546d69ff38Andreas Gampe  static constexpr const char* kPicKey = "pic";
41d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler  static constexpr const char* kHasPatchInfoKey = "has-patch-info";
420de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  static constexpr const char* kDebuggableKey = "debuggable";
435d950769b607b4f76413212db640a32d796911deDavid Srbecky  static constexpr const char* kNativeDebuggableKey = "native-debuggable";
4429d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  static constexpr const char* kCompilerFilter = "compiler-filter";
457848da48a0a4241dedc1cc83ac4931e61575eb92Andreas Gampe  static constexpr const char* kClassPathKey = "classpath";
465872d7cd6ceffe67550d0b021191ec66f1a34c5dJeff Hao  static constexpr const char* kBootClassPathKey = "bootclasspath";
4722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
480de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  static constexpr const char kTrueValue[] = "true";
490de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  static constexpr const char kFalseValue[] = "false";
50b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle
510de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz
5222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  static OatHeader* Create(InstructionSet instruction_set,
536f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers                           const InstructionSetFeatures* instruction_set_features,
5449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko                           uint32_t dex_file_count,
5522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                           const SafeMap<std::string, std::string>* variable_data);
56e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
57e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  bool IsValid() const;
582bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe  std::string GetValidationErrorMessage() const;
59e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  const char* GetMagic() const;
60e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint32_t GetChecksum() const;
6149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko  void UpdateChecksumWithHeaderData();
62e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  void UpdateChecksum(const void* data, size_t length);
634f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers  uint32_t GetDexFileCount() const {
644f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers    DCHECK(IsValid());
654f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers    return dex_file_count_;
664f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers  }
67e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint32_t GetExecutableOffset() const;
68e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  void SetExecutableOffset(uint32_t executable_offset);
69468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
70468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  const void* GetInterpreterToInterpreterBridge() const;
71468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t GetInterpreterToInterpreterBridgeOffset() const;
72468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  void SetInterpreterToInterpreterBridgeOffset(uint32_t offset);
73468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  const void* GetInterpreterToCompiledCodeBridge() const;
74468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t GetInterpreterToCompiledCodeBridgeOffset() const;
75468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  void SetInterpreterToCompiledCodeBridgeOffset(uint32_t offset);
76468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
77468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  const void* GetJniDlsymLookup() const;
78468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t GetJniDlsymLookupOffset() const;
79468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  void SetJniDlsymLookupOffset(uint32_t offset);
80468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
812da882315a61072664f7ce3c212307342e907207Andreas Gampe  const void* GetQuickGenericJniTrampoline() const;
822da882315a61072664f7ce3c212307342e907207Andreas Gampe  uint32_t GetQuickGenericJniTrampolineOffset() const;
832da882315a61072664f7ce3c212307342e907207Andreas Gampe  void SetQuickGenericJniTrampolineOffset(uint32_t offset);
840aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao  const void* GetQuickResolutionTrampoline() const;
850aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao  uint32_t GetQuickResolutionTrampolineOffset() const;
860aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao  void SetQuickResolutionTrampolineOffset(uint32_t offset);
8788474b416eb257078e590bf9bc7957cee604a186Jeff Hao  const void* GetQuickImtConflictTrampoline() const;
8888474b416eb257078e590bf9bc7957cee604a186Jeff Hao  uint32_t GetQuickImtConflictTrampolineOffset() const;
8988474b416eb257078e590bf9bc7957cee604a186Jeff Hao  void SetQuickImtConflictTrampolineOffset(uint32_t offset);
90468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  const void* GetQuickToInterpreterBridge() const;
91468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t GetQuickToInterpreterBridgeOffset() const;
92468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  void SetQuickToInterpreterBridgeOffset(uint32_t offset);
93468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
94a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  int32_t GetImagePatchDelta() const;
95a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  void RelocateOat(off_t delta);
96a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  void SetImagePatchDelta(int32_t off);
97a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
980aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao  InstructionSet GetInstructionSet() const;
996f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers  uint32_t GetInstructionSetFeaturesBitmap() const;
10049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko
10128db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom  uint32_t GetImageFileLocationOatChecksum() const;
10249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko  void SetImageFileLocationOatChecksum(uint32_t image_file_location_oat_checksum);
103700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  uint32_t GetImageFileLocationOatDataBegin() const;
10449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko  void SetImageFileLocationOatDataBegin(uint32_t image_file_location_oat_data_begin);
10522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
10622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  uint32_t GetKeyValueStoreSize() const;
10722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  const uint8_t* GetKeyValueStore() const;
10822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  const char* GetStoreValueByKey(const char* key) const;
10922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  bool GetStoreKeyValuePairByIndex(size_t index, const char** key, const char** value) const;
11022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
11122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  size_t GetHeaderSize() const;
11246774767fcf7780d1455e755729198648d08742eIgor Murashkin  bool IsPic() const;
113d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler  bool HasPatchInfo() const;
1140de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  bool IsDebuggable() const;
1155d950769b607b4f76413212db640a32d796911deDavid Srbecky  bool IsNativeDebuggable() const;
11629d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  CompilerFilter::Filter GetCompilerFilter() const;
117e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
118e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom private:
119b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle  bool KeyHasValue(const char* key, const char* value, size_t value_size) const;
120b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle
12122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  OatHeader(InstructionSet instruction_set,
1226f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers            const InstructionSetFeatures* instruction_set_features,
12349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko            uint32_t dex_file_count,
12422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe            const SafeMap<std::string, std::string>* variable_data);
12522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
1260de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  // Returns true if the value of the given key is "true", false otherwise.
1270de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  bool IsKeyEnabled(const char* key) const;
1280de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz
12922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  void Flatten(const SafeMap<std::string, std::string>* variable_data);
13022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
131e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint8_t magic_[4];
132e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint8_t version_[4];
133e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint32_t adler32_checksum_;
134a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes
135a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes  InstructionSet instruction_set_;
1366f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers  uint32_t instruction_set_features_bitmap_;
137e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint32_t dex_file_count_;
138e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint32_t executable_offset_;
139468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t interpreter_to_interpreter_bridge_offset_;
140468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t interpreter_to_compiled_code_bridge_offset_;
141468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t jni_dlsym_lookup_offset_;
1422da882315a61072664f7ce3c212307342e907207Andreas Gampe  uint32_t quick_generic_jni_trampoline_offset_;
14388474b416eb257078e590bf9bc7957cee604a186Jeff Hao  uint32_t quick_imt_conflict_trampoline_offset_;
1440aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao  uint32_t quick_resolution_trampoline_offset_;
145468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t quick_to_interpreter_bridge_offset_;
146e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
147a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // The amount that the image this oat is associated with has been patched.
148a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  int32_t image_patch_delta_;
149a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
15028db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom  uint32_t image_file_location_oat_checksum_;
151700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  uint32_t image_file_location_oat_data_begin_;
15222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
15322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  uint32_t key_value_store_size_;
15422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  uint8_t key_value_store_[0];  // note variable width data at end
15581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
156e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  DISALLOW_COPY_AND_ASSIGN(OatHeader);
157e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom};
158e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
1598a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko// OatMethodOffsets are currently 5x32-bits=160-bits long, so if we can
160ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom// save even one OatMethodOffsets struct, the more complicated encoding
1618a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko// using a bitmap pays for itself since few classes will have 160
162ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom// methods.
163ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstromenum OatClassType {
164ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom  kOatClassAllCompiled = 0,   // OatClass is followed by an OatMethodOffsets for each method.
165ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom  kOatClassSomeCompiled = 1,  // A bitmap of which OatMethodOffsets are present follows the OatClass.
1667b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  kOatClassNoneCompiled = 2,  // All methods are interpreted so no OatMethodOffsets are necessary.
167ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom  kOatClassMax = 3,
168ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom};
169ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom
170ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstromstd::ostream& operator<<(std::ostream& os, const OatClassType& rhs);
171ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom
172df1ce91ba97bc79a0637e5504b39318fb1c9f577Ian Rogersclass PACKED(4) OatMethodOffsets {
1733320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom public:
174957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier  OatMethodOffsets(uint32_t code_offset = 0);
175971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien
1763320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  ~OatMethodOffsets();
1773320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
178758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe  OatMethodOffsets& operator=(const OatMethodOffsets&) = default;
179758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe
1803320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  uint32_t code_offset_;
1813320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom};
1823320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
183e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}  // namespace art
184e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
185fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_OAT_H_
186