blob: 81d45405a7d613d0ed5bf52c4926a87d0bcde998 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian Carlstrome24fa612011-09-29 00:53:55 -070016
17#include "oat.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080018#include "utils.h"
Brian Carlstrome24fa612011-09-29 00:53:55 -070019
20#include <zlib.h>
21
22namespace art {
23
24const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
Brian Carlstrom7f9d66c2014-01-28 18:21:49 -080025const uint8_t OatHeader::kOatVersion[] = { '0', '1', '4', '\0' };
Brian Carlstrome24fa612011-09-29 00:53:55 -070026
Elliott Hughesa72ec822012-03-05 17:12:22 -080027OatHeader::OatHeader() {
28 memset(this, 0, sizeof(*this));
29}
30
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070031OatHeader::OatHeader(InstructionSet instruction_set,
Dave Allison70202782013-10-22 17:52:19 -070032 const InstructionSetFeatures& instruction_set_features,
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070033 const std::vector<const DexFile*>* dex_files,
Brian Carlstrom28db0122012-10-18 16:20:41 -070034 uint32_t image_file_location_oat_checksum,
Brian Carlstrom700c8d32012-11-05 10:42:02 -080035 uint32_t image_file_location_oat_data_begin,
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070036 const std::string& image_file_location) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070037 memcpy(magic_, kOatMagic, sizeof(kOatMagic));
38 memcpy(version_, kOatVersion, sizeof(kOatVersion));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070039
Brian Carlstrome24fa612011-09-29 00:53:55 -070040 adler32_checksum_ = adler32(0L, Z_NULL, 0);
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070041
Brian Carlstromf852fb22012-10-19 11:01:58 -070042 CHECK_NE(instruction_set, kNone);
Elliott Hughesa72ec822012-03-05 17:12:22 -080043 instruction_set_ = instruction_set;
44 UpdateChecksum(&instruction_set_, sizeof(instruction_set_));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070045
Dave Allison70202782013-10-22 17:52:19 -070046 instruction_set_features_ = instruction_set_features;
47 UpdateChecksum(&instruction_set_features_, sizeof(instruction_set_features_));
48
Brian Carlstrome24fa612011-09-29 00:53:55 -070049 dex_file_count_ = dex_files->size();
50 UpdateChecksum(&dex_file_count_, sizeof(dex_file_count_));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070051
Brian Carlstrom28db0122012-10-18 16:20:41 -070052 image_file_location_oat_checksum_ = image_file_location_oat_checksum;
53 UpdateChecksum(&image_file_location_oat_checksum_, sizeof(image_file_location_oat_checksum_));
54
Brian Carlstrom700c8d32012-11-05 10:42:02 -080055 CHECK(IsAligned<kPageSize>(image_file_location_oat_data_begin));
56 image_file_location_oat_data_begin_ = image_file_location_oat_data_begin;
57 UpdateChecksum(&image_file_location_oat_data_begin_, sizeof(image_file_location_oat_data_begin_));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070058
59 image_file_location_size_ = image_file_location.size();
60 UpdateChecksum(&image_file_location_size_, sizeof(image_file_location_size_));
61 UpdateChecksum(image_file_location.data(), image_file_location_size_);
62
Brian Carlstrome24fa612011-09-29 00:53:55 -070063 executable_offset_ = 0;
Ian Rogers468532e2013-08-05 10:56:33 -070064 interpreter_to_interpreter_bridge_offset_ = 0;
65 interpreter_to_compiled_code_bridge_offset_ = 0;
66 jni_dlsym_lookup_offset_ = 0;
Jeff Hao88474b42013-10-23 16:24:40 -070067 portable_imt_conflict_trampoline_offset_ = 0;
Jeff Hao0aba0ba2013-06-03 14:49:28 -070068 portable_resolution_trampoline_offset_ = 0;
Ian Rogers468532e2013-08-05 10:56:33 -070069 portable_to_interpreter_bridge_offset_ = 0;
Jeff Hao88474b42013-10-23 16:24:40 -070070 quick_imt_conflict_trampoline_offset_ = 0;
Jeff Hao0aba0ba2013-06-03 14:49:28 -070071 quick_resolution_trampoline_offset_ = 0;
Ian Rogers468532e2013-08-05 10:56:33 -070072 quick_to_interpreter_bridge_offset_ = 0;
Brian Carlstrome24fa612011-09-29 00:53:55 -070073}
74
75bool OatHeader::IsValid() const {
Brian Carlstromf852fb22012-10-19 11:01:58 -070076 if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070077 return false;
78 }
Brian Carlstromf852fb22012-10-19 11:01:58 -070079 if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070080 return false;
81 }
82 return true;
83}
84
85const char* OatHeader::GetMagic() const {
86 CHECK(IsValid());
87 return reinterpret_cast<const char*>(magic_);
88}
89
Brian Carlstrome24fa612011-09-29 00:53:55 -070090uint32_t OatHeader::GetChecksum() const {
91 CHECK(IsValid());
92 return adler32_checksum_;
93}
94
95void OatHeader::UpdateChecksum(const void* data, size_t length) {
96 DCHECK(IsValid());
97 const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
98 adler32_checksum_ = adler32(adler32_checksum_, bytes, length);
99}
100
Elliott Hughesa72ec822012-03-05 17:12:22 -0800101InstructionSet OatHeader::GetInstructionSet() const {
102 CHECK(IsValid());
103 return instruction_set_;
104}
105
Dave Allison70202782013-10-22 17:52:19 -0700106const InstructionSetFeatures& OatHeader::GetInstructionSetFeatures() const {
107 CHECK(IsValid());
108 return instruction_set_features_;
109}
110
Brian Carlstrome24fa612011-09-29 00:53:55 -0700111uint32_t OatHeader::GetExecutableOffset() const {
112 DCHECK(IsValid());
Elliott Hughes06b37d92011-10-16 11:51:29 -0700113 DCHECK_ALIGNED(executable_offset_, kPageSize);
Brian Carlstrome24fa612011-09-29 00:53:55 -0700114 CHECK_GT(executable_offset_, sizeof(OatHeader));
115 return executable_offset_;
116}
117
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700118void OatHeader::SetExecutableOffset(uint32_t executable_offset) {
119 DCHECK_ALIGNED(executable_offset, kPageSize);
120 CHECK_GT(executable_offset, sizeof(OatHeader));
121 DCHECK(IsValid());
122 DCHECK_EQ(executable_offset_, 0U);
123
124 executable_offset_ = executable_offset;
125 UpdateChecksum(&executable_offset_, sizeof(executable_offset));
126}
127
Ian Rogers468532e2013-08-05 10:56:33 -0700128const void* OatHeader::GetInterpreterToInterpreterBridge() const {
129 return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToInterpreterBridgeOffset();
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700130}
131
Ian Rogers468532e2013-08-05 10:56:33 -0700132uint32_t OatHeader::GetInterpreterToInterpreterBridgeOffset() const {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700133 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700134 CHECK_GE(interpreter_to_interpreter_bridge_offset_, executable_offset_);
135 return interpreter_to_interpreter_bridge_offset_;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700136}
137
Ian Rogers468532e2013-08-05 10:56:33 -0700138void OatHeader::SetInterpreterToInterpreterBridgeOffset(uint32_t offset) {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700139 CHECK(offset == 0 || offset >= executable_offset_);
140 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700141 DCHECK_EQ(interpreter_to_interpreter_bridge_offset_, 0U) << offset;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700142
Ian Rogers468532e2013-08-05 10:56:33 -0700143 interpreter_to_interpreter_bridge_offset_ = offset;
144 UpdateChecksum(&interpreter_to_interpreter_bridge_offset_, sizeof(offset));
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700145}
146
Ian Rogers468532e2013-08-05 10:56:33 -0700147const void* OatHeader::GetInterpreterToCompiledCodeBridge() const {
148 return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToCompiledCodeBridgeOffset();
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700149}
150
Ian Rogers468532e2013-08-05 10:56:33 -0700151uint32_t OatHeader::GetInterpreterToCompiledCodeBridgeOffset() const {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700152 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700153 CHECK_GE(interpreter_to_compiled_code_bridge_offset_, interpreter_to_interpreter_bridge_offset_);
154 return interpreter_to_compiled_code_bridge_offset_;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700155}
156
Ian Rogers468532e2013-08-05 10:56:33 -0700157void OatHeader::SetInterpreterToCompiledCodeBridgeOffset(uint32_t offset) {
158 CHECK(offset == 0 || offset >= interpreter_to_interpreter_bridge_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700159 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700160 DCHECK_EQ(interpreter_to_compiled_code_bridge_offset_, 0U) << offset;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700161
Ian Rogers468532e2013-08-05 10:56:33 -0700162 interpreter_to_compiled_code_bridge_offset_ = offset;
163 UpdateChecksum(&interpreter_to_compiled_code_bridge_offset_, sizeof(offset));
164}
165
166const void* OatHeader::GetJniDlsymLookup() const {
167 return reinterpret_cast<const uint8_t*>(this) + GetJniDlsymLookupOffset();
168}
169
170uint32_t OatHeader::GetJniDlsymLookupOffset() const {
171 DCHECK(IsValid());
172 CHECK_GE(jni_dlsym_lookup_offset_, interpreter_to_compiled_code_bridge_offset_);
173 return jni_dlsym_lookup_offset_;
174}
175
176void OatHeader::SetJniDlsymLookupOffset(uint32_t offset) {
177 CHECK(offset == 0 || offset >= interpreter_to_compiled_code_bridge_offset_);
178 DCHECK(IsValid());
179 DCHECK_EQ(jni_dlsym_lookup_offset_, 0U) << offset;
180
181 jni_dlsym_lookup_offset_ = offset;
182 UpdateChecksum(&jni_dlsym_lookup_offset_, sizeof(offset));
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700183}
184
Jeff Hao88474b42013-10-23 16:24:40 -0700185const void* OatHeader::GetPortableImtConflictTrampoline() const {
186 return reinterpret_cast<const uint8_t*>(this) + GetPortableImtConflictTrampolineOffset();
187}
188
189uint32_t OatHeader::GetPortableImtConflictTrampolineOffset() const {
190 DCHECK(IsValid());
191 CHECK_GE(portable_imt_conflict_trampoline_offset_, jni_dlsym_lookup_offset_);
192 return portable_imt_conflict_trampoline_offset_;
193}
194
195void OatHeader::SetPortableImtConflictTrampolineOffset(uint32_t offset) {
196 CHECK(offset == 0 || offset >= jni_dlsym_lookup_offset_);
197 DCHECK(IsValid());
198 DCHECK_EQ(portable_imt_conflict_trampoline_offset_, 0U) << offset;
199
200 portable_imt_conflict_trampoline_offset_ = offset;
201 UpdateChecksum(&portable_imt_conflict_trampoline_offset_, sizeof(offset));
202}
203
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700204const void* OatHeader::GetPortableResolutionTrampoline() const {
205 return reinterpret_cast<const uint8_t*>(this) + GetPortableResolutionTrampolineOffset();
206}
207
208uint32_t OatHeader::GetPortableResolutionTrampolineOffset() const {
209 DCHECK(IsValid());
Jeff Hao88474b42013-10-23 16:24:40 -0700210 CHECK_GE(portable_resolution_trampoline_offset_, portable_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700211 return portable_resolution_trampoline_offset_;
212}
213
214void OatHeader::SetPortableResolutionTrampolineOffset(uint32_t offset) {
Jeff Hao88474b42013-10-23 16:24:40 -0700215 CHECK(offset == 0 || offset >= portable_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700216 DCHECK(IsValid());
217 DCHECK_EQ(portable_resolution_trampoline_offset_, 0U) << offset;
218
219 portable_resolution_trampoline_offset_ = offset;
220 UpdateChecksum(&portable_resolution_trampoline_offset_, sizeof(offset));
221}
222
Ian Rogers468532e2013-08-05 10:56:33 -0700223const void* OatHeader::GetPortableToInterpreterBridge() const {
224 return reinterpret_cast<const uint8_t*>(this) + GetPortableToInterpreterBridgeOffset();
225}
226
227uint32_t OatHeader::GetPortableToInterpreterBridgeOffset() const {
228 DCHECK(IsValid());
229 CHECK_GE(portable_to_interpreter_bridge_offset_, portable_resolution_trampoline_offset_);
230 return portable_to_interpreter_bridge_offset_;
231}
232
233void OatHeader::SetPortableToInterpreterBridgeOffset(uint32_t offset) {
234 CHECK(offset == 0 || offset >= portable_resolution_trampoline_offset_);
235 DCHECK(IsValid());
236 DCHECK_EQ(portable_to_interpreter_bridge_offset_, 0U) << offset;
237
238 portable_to_interpreter_bridge_offset_ = offset;
239 UpdateChecksum(&portable_to_interpreter_bridge_offset_, sizeof(offset));
240}
241
Jeff Hao88474b42013-10-23 16:24:40 -0700242const void* OatHeader::GetQuickImtConflictTrampoline() const {
243 return reinterpret_cast<const uint8_t*>(this) + GetQuickImtConflictTrampolineOffset();
244}
245
246uint32_t OatHeader::GetQuickImtConflictTrampolineOffset() const {
247 DCHECK(IsValid());
248 CHECK_GE(quick_imt_conflict_trampoline_offset_, portable_to_interpreter_bridge_offset_);
249 return quick_imt_conflict_trampoline_offset_;
250}
251
252void OatHeader::SetQuickImtConflictTrampolineOffset(uint32_t offset) {
253 CHECK(offset == 0 || offset >= portable_to_interpreter_bridge_offset_);
254 DCHECK(IsValid());
255 DCHECK_EQ(quick_imt_conflict_trampoline_offset_, 0U) << offset;
256
257 quick_imt_conflict_trampoline_offset_ = offset;
258 UpdateChecksum(&quick_imt_conflict_trampoline_offset_, sizeof(offset));
259}
260
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700261const void* OatHeader::GetQuickResolutionTrampoline() const {
262 return reinterpret_cast<const uint8_t*>(this) + GetQuickResolutionTrampolineOffset();
263}
264
265uint32_t OatHeader::GetQuickResolutionTrampolineOffset() const {
266 DCHECK(IsValid());
Jeff Hao88474b42013-10-23 16:24:40 -0700267 CHECK_GE(quick_resolution_trampoline_offset_, quick_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700268 return quick_resolution_trampoline_offset_;
269}
270
271void OatHeader::SetQuickResolutionTrampolineOffset(uint32_t offset) {
Jeff Hao88474b42013-10-23 16:24:40 -0700272 CHECK(offset == 0 || offset >= quick_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700273 DCHECK(IsValid());
274 DCHECK_EQ(quick_resolution_trampoline_offset_, 0U) << offset;
275
276 quick_resolution_trampoline_offset_ = offset;
277 UpdateChecksum(&quick_resolution_trampoline_offset_, sizeof(offset));
278}
279
Ian Rogers468532e2013-08-05 10:56:33 -0700280const void* OatHeader::GetQuickToInterpreterBridge() const {
281 return reinterpret_cast<const uint8_t*>(this) + GetQuickToInterpreterBridgeOffset();
282}
283
284uint32_t OatHeader::GetQuickToInterpreterBridgeOffset() const {
285 DCHECK(IsValid());
286 CHECK_GE(quick_to_interpreter_bridge_offset_, quick_resolution_trampoline_offset_);
287 return quick_to_interpreter_bridge_offset_;
288}
289
290void OatHeader::SetQuickToInterpreterBridgeOffset(uint32_t offset) {
291 CHECK(offset == 0 || offset >= quick_resolution_trampoline_offset_);
292 DCHECK(IsValid());
293 DCHECK_EQ(quick_to_interpreter_bridge_offset_, 0U) << offset;
294
295 quick_to_interpreter_bridge_offset_ = offset;
296 UpdateChecksum(&quick_to_interpreter_bridge_offset_, sizeof(offset));
297}
298
Brian Carlstrom28db0122012-10-18 16:20:41 -0700299uint32_t OatHeader::GetImageFileLocationOatChecksum() const {
Brian Carlstrom81f3ca12012-03-17 00:27:35 -0700300 CHECK(IsValid());
Brian Carlstrom28db0122012-10-18 16:20:41 -0700301 return image_file_location_oat_checksum_;
302}
303
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800304uint32_t OatHeader::GetImageFileLocationOatDataBegin() const {
Brian Carlstrom28db0122012-10-18 16:20:41 -0700305 CHECK(IsValid());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800306 return image_file_location_oat_data_begin_;
Brian Carlstrom81f3ca12012-03-17 00:27:35 -0700307}
308
309uint32_t OatHeader::GetImageFileLocationSize() const {
310 CHECK(IsValid());
311 return image_file_location_size_;
312}
313
314const uint8_t* OatHeader::GetImageFileLocationData() const {
315 CHECK(IsValid());
316 return image_file_location_data_;
317}
318
319std::string OatHeader::GetImageFileLocation() const {
320 CHECK(IsValid());
321 return std::string(reinterpret_cast<const char*>(GetImageFileLocationData()),
322 GetImageFileLocationSize());
323}
324
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700325OatMethodOffsets::OatMethodOffsets()
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700326 : code_offset_(0),
327 frame_size_in_bytes_(0),
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700328 core_spill_mask_(0),
329 fp_spill_mask_(0),
330 mapping_table_offset_(0),
331 vmap_table_offset_(0),
Jeff Hao74180ca2013-03-27 15:29:11 -0700332 gc_map_offset_(0)
Logan Chienccb7bf12012-03-28 12:52:32 +0800333{}
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700334
335OatMethodOffsets::OatMethodOffsets(uint32_t code_offset,
336 uint32_t frame_size_in_bytes,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700337 uint32_t core_spill_mask,
338 uint32_t fp_spill_mask,
339 uint32_t mapping_table_offset,
340 uint32_t vmap_table_offset,
Jeff Hao74180ca2013-03-27 15:29:11 -0700341 uint32_t gc_map_offset
Logan Chienccb7bf12012-03-28 12:52:32 +0800342 )
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700343 : code_offset_(code_offset),
344 frame_size_in_bytes_(frame_size_in_bytes),
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700345 core_spill_mask_(core_spill_mask),
346 fp_spill_mask_(fp_spill_mask),
347 mapping_table_offset_(mapping_table_offset),
348 vmap_table_offset_(vmap_table_offset),
Jeff Hao74180ca2013-03-27 15:29:11 -0700349 gc_map_offset_(gc_map_offset)
Logan Chienccb7bf12012-03-28 12:52:32 +0800350{}
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700351
352OatMethodOffsets::~OatMethodOffsets() {}
353
Brian Carlstrome24fa612011-09-29 00:53:55 -0700354} // namespace art