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"
2467bf42e89592c3a1c648f927f2ce3ccb189a1161David Sehr#include "base/safe_map.h"
2529d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe#include "compiler_filter.h"
269e734c7ab4599d7747a05db0dc73c7b668cb6683David Sehr#include "dex/dex_file.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' };
354d17987da58d9411adbed1a18203d76d6119612dVladimir Marko  // Last oat version changed reason: Math.pow() intrinsic.
364d17987da58d9411adbed1a18203d76d6119612dVladimir Marko  static constexpr uint8_t kOatVersion[] = { '1', '3', '8', '\0' };
377c3d13aebdd8611cae58a1048bffb13cbdc465cbBrian Carlstrom
3822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  static constexpr const char* kImageLocationKey = "image-location";
3922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
4022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  static constexpr const char* kDex2OatHostKey = "dex2oat-host";
417ba649636c4475c3992fa15a57acd2546d69ff38Andreas Gampe  static constexpr const char* kPicKey = "pic";
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";
46f0192c86a58b2f43378c9a2113007538dd38ddbfJeff Hao  static constexpr const char* kBootClassPathKey = "bootclasspath";
47f8cd890d86e2a136966d878fea1d0dae6a9c4ad0Andreas Gampe  static constexpr const char* kConcurrentCopying = "concurrent-copying";
480e09dfc9cbdd6c2510dbe50dba95cf9d2d815e79Calin Juravle  static constexpr const char* kCompilationReasonKey = "compilation-reason";
4922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
500de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  static constexpr const char kTrueValue[] = "true";
510de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  static constexpr const char kFalseValue[] = "false";
52b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle
530de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz
5422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  static OatHeader* Create(InstructionSet instruction_set,
556f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers                           const InstructionSetFeatures* instruction_set_features,
5649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko                           uint32_t dex_file_count,
5722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                           const SafeMap<std::string, std::string>* variable_data);
58e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
59e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  bool IsValid() const;
602bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe  std::string GetValidationErrorMessage() const;
61e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  const char* GetMagic() const;
62e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint32_t GetChecksum() const;
6349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko  void UpdateChecksumWithHeaderData();
64e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  void UpdateChecksum(const void* data, size_t length);
654f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers  uint32_t GetDexFileCount() const {
664f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers    DCHECK(IsValid());
674f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers    return dex_file_count_;
684f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers  }
690eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko  uint32_t GetOatDexFilesOffset() const;
700eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko  void SetOatDexFilesOffset(uint32_t oat_dex_files_offset);
71e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint32_t GetExecutableOffset() const;
72e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  void SetExecutableOffset(uint32_t executable_offset);
73468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
74468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  const void* GetInterpreterToInterpreterBridge() const;
75468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t GetInterpreterToInterpreterBridgeOffset() const;
76468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  void SetInterpreterToInterpreterBridgeOffset(uint32_t offset);
77468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  const void* GetInterpreterToCompiledCodeBridge() const;
78468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t GetInterpreterToCompiledCodeBridgeOffset() const;
79468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  void SetInterpreterToCompiledCodeBridgeOffset(uint32_t offset);
80468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
81468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  const void* GetJniDlsymLookup() const;
82468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t GetJniDlsymLookupOffset() const;
83468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  void SetJniDlsymLookupOffset(uint32_t offset);
84468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
852da882315a61072664f7ce3c212307342e907207Andreas Gampe  const void* GetQuickGenericJniTrampoline() const;
862da882315a61072664f7ce3c212307342e907207Andreas Gampe  uint32_t GetQuickGenericJniTrampolineOffset() const;
872da882315a61072664f7ce3c212307342e907207Andreas Gampe  void SetQuickGenericJniTrampolineOffset(uint32_t offset);
880aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao  const void* GetQuickResolutionTrampoline() const;
890aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao  uint32_t GetQuickResolutionTrampolineOffset() const;
900aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao  void SetQuickResolutionTrampolineOffset(uint32_t offset);
9188474b416eb257078e590bf9bc7957cee604a186Jeff Hao  const void* GetQuickImtConflictTrampoline() const;
9288474b416eb257078e590bf9bc7957cee604a186Jeff Hao  uint32_t GetQuickImtConflictTrampolineOffset() const;
9388474b416eb257078e590bf9bc7957cee604a186Jeff Hao  void SetQuickImtConflictTrampolineOffset(uint32_t offset);
94468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  const void* GetQuickToInterpreterBridge() const;
95468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t GetQuickToInterpreterBridgeOffset() const;
96468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  void SetQuickToInterpreterBridgeOffset(uint32_t offset);
97468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
98a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  int32_t GetImagePatchDelta() const;
99a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  void RelocateOat(off_t delta);
100a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  void SetImagePatchDelta(int32_t off);
101a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
1020aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao  InstructionSet GetInstructionSet() const;
1036f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers  uint32_t GetInstructionSetFeaturesBitmap() const;
10449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko
10528db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom  uint32_t GetImageFileLocationOatChecksum() const;
10649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko  void SetImageFileLocationOatChecksum(uint32_t image_file_location_oat_checksum);
107700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  uint32_t GetImageFileLocationOatDataBegin() const;
10849b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko  void SetImageFileLocationOatDataBegin(uint32_t image_file_location_oat_data_begin);
10922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
11022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  uint32_t GetKeyValueStoreSize() const;
11122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  const uint8_t* GetKeyValueStore() const;
11222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  const char* GetStoreValueByKey(const char* key) const;
11322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  bool GetStoreKeyValuePairByIndex(size_t index, const char** key, const char** value) const;
11422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
11522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  size_t GetHeaderSize() const;
11646774767fcf7780d1455e755729198648d08742eIgor Murashkin  bool IsPic() const;
1170de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  bool IsDebuggable() const;
1185d950769b607b4f76413212db640a32d796911deDavid Srbecky  bool IsNativeDebuggable() const;
11929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  CompilerFilter::Filter GetCompilerFilter() const;
120f8cd890d86e2a136966d878fea1d0dae6a9c4ad0Andreas Gampe  bool IsConcurrentCopying() const;
121e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
122e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom private:
123b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle  bool KeyHasValue(const char* key, const char* value, size_t value_size) const;
124b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle
12522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  OatHeader(InstructionSet instruction_set,
1266f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers            const InstructionSetFeatures* instruction_set_features,
12749b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko            uint32_t dex_file_count,
12822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe            const SafeMap<std::string, std::string>* variable_data);
12922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
1300de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  // Returns true if the value of the given key is "true", false otherwise.
1310de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  bool IsKeyEnabled(const char* key) const;
1320de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz
13322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  void Flatten(const SafeMap<std::string, std::string>* variable_data);
13422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
135e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint8_t magic_[4];
136e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint8_t version_[4];
137e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint32_t adler32_checksum_;
138a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes
139a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes  InstructionSet instruction_set_;
1406f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers  uint32_t instruction_set_features_bitmap_;
141e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint32_t dex_file_count_;
1420eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko  uint32_t oat_dex_files_offset_;
143e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  uint32_t executable_offset_;
144468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t interpreter_to_interpreter_bridge_offset_;
145468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t interpreter_to_compiled_code_bridge_offset_;
146468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t jni_dlsym_lookup_offset_;
1472da882315a61072664f7ce3c212307342e907207Andreas Gampe  uint32_t quick_generic_jni_trampoline_offset_;
14888474b416eb257078e590bf9bc7957cee604a186Jeff Hao  uint32_t quick_imt_conflict_trampoline_offset_;
1490aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao  uint32_t quick_resolution_trampoline_offset_;
150468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  uint32_t quick_to_interpreter_bridge_offset_;
151e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
152a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // The amount that the image this oat is associated with has been patched.
153a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  int32_t image_patch_delta_;
154a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
15528db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom  uint32_t image_file_location_oat_checksum_;
156700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  uint32_t image_file_location_oat_data_begin_;
15722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
15822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  uint32_t key_value_store_size_;
15922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  uint8_t key_value_store_[0];  // note variable width data at end
16081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
161e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  DISALLOW_COPY_AND_ASSIGN(OatHeader);
162e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom};
163e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
1648a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko// OatMethodOffsets are currently 5x32-bits=160-bits long, so if we can
165ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom// save even one OatMethodOffsets struct, the more complicated encoding
1668a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko// using a bitmap pays for itself since few classes will have 160
167ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom// methods.
168ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstromenum OatClassType {
169ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom  kOatClassAllCompiled = 0,   // OatClass is followed by an OatMethodOffsets for each method.
170ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom  kOatClassSomeCompiled = 1,  // A bitmap of which OatMethodOffsets are present follows the OatClass.
1717b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  kOatClassNoneCompiled = 2,  // All methods are interpreted so no OatMethodOffsets are necessary.
172ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom  kOatClassMax = 3,
173ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom};
174ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom
175ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstromstd::ostream& operator<<(std::ostream& os, const OatClassType& rhs);
176ba150c37d582eeeb8c11ba5245edc281cf31793cBrian Carlstrom
177df1ce91ba97bc79a0637e5504b39318fb1c9f577Ian Rogersclass PACKED(4) OatMethodOffsets {
1783320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom public:
179a5931185c97c7b17981a9fc5016834a0bdd9480bChih-Hung Hsieh  explicit OatMethodOffsets(uint32_t code_offset = 0);
180971bf3f9184010d68b9a3ad30b396fa401af91a3Logan Chien
1813320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  ~OatMethodOffsets();
1823320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1832665bc8159698429f20a08f814e63c434910d608Yi Kong  OatMethodOffsets(const OatMethodOffsets&) = default;
184758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe  OatMethodOffsets& operator=(const OatMethodOffsets&) = default;
185758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe
1863320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  uint32_t code_offset_;
1873320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom};
1883320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
189e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}  // namespace art
190e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
191fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_OAT_H_
192