blob: defda6bb1a5e1b3fb63f180f9d9fcfb07f85c8cb [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' };
Jeff Hao88474b42013-10-23 16:24:40 -070025const uint8_t OatHeader::kOatVersion[] = { '0', '0', '9', '\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,
32 const std::vector<const DexFile*>* dex_files,
Brian Carlstrom28db0122012-10-18 16:20:41 -070033 uint32_t image_file_location_oat_checksum,
Brian Carlstrom700c8d32012-11-05 10:42:02 -080034 uint32_t image_file_location_oat_data_begin,
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070035 const std::string& image_file_location) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070036 memcpy(magic_, kOatMagic, sizeof(kOatMagic));
37 memcpy(version_, kOatVersion, sizeof(kOatVersion));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070038
Brian Carlstrome24fa612011-09-29 00:53:55 -070039 adler32_checksum_ = adler32(0L, Z_NULL, 0);
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070040
Brian Carlstromf852fb22012-10-19 11:01:58 -070041 CHECK_NE(instruction_set, kNone);
Elliott Hughesa72ec822012-03-05 17:12:22 -080042 instruction_set_ = instruction_set;
43 UpdateChecksum(&instruction_set_, sizeof(instruction_set_));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070044
Brian Carlstrome24fa612011-09-29 00:53:55 -070045 dex_file_count_ = dex_files->size();
46 UpdateChecksum(&dex_file_count_, sizeof(dex_file_count_));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070047
Brian Carlstrom28db0122012-10-18 16:20:41 -070048 image_file_location_oat_checksum_ = image_file_location_oat_checksum;
49 UpdateChecksum(&image_file_location_oat_checksum_, sizeof(image_file_location_oat_checksum_));
50
Brian Carlstrom700c8d32012-11-05 10:42:02 -080051 CHECK(IsAligned<kPageSize>(image_file_location_oat_data_begin));
52 image_file_location_oat_data_begin_ = image_file_location_oat_data_begin;
53 UpdateChecksum(&image_file_location_oat_data_begin_, sizeof(image_file_location_oat_data_begin_));
Brian Carlstrom81f3ca12012-03-17 00:27:35 -070054
55 image_file_location_size_ = image_file_location.size();
56 UpdateChecksum(&image_file_location_size_, sizeof(image_file_location_size_));
57 UpdateChecksum(image_file_location.data(), image_file_location_size_);
58
Brian Carlstrome24fa612011-09-29 00:53:55 -070059 executable_offset_ = 0;
Ian Rogers468532e2013-08-05 10:56:33 -070060 interpreter_to_interpreter_bridge_offset_ = 0;
61 interpreter_to_compiled_code_bridge_offset_ = 0;
62 jni_dlsym_lookup_offset_ = 0;
Jeff Hao88474b42013-10-23 16:24:40 -070063 portable_imt_conflict_trampoline_offset_ = 0;
Jeff Hao0aba0ba2013-06-03 14:49:28 -070064 portable_resolution_trampoline_offset_ = 0;
Ian Rogers468532e2013-08-05 10:56:33 -070065 portable_to_interpreter_bridge_offset_ = 0;
Jeff Hao88474b42013-10-23 16:24:40 -070066 quick_imt_conflict_trampoline_offset_ = 0;
Jeff Hao0aba0ba2013-06-03 14:49:28 -070067 quick_resolution_trampoline_offset_ = 0;
Ian Rogers468532e2013-08-05 10:56:33 -070068 quick_to_interpreter_bridge_offset_ = 0;
Brian Carlstrome24fa612011-09-29 00:53:55 -070069}
70
71bool OatHeader::IsValid() const {
Brian Carlstromf852fb22012-10-19 11:01:58 -070072 if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070073 return false;
74 }
Brian Carlstromf852fb22012-10-19 11:01:58 -070075 if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070076 return false;
77 }
78 return true;
79}
80
81const char* OatHeader::GetMagic() const {
82 CHECK(IsValid());
83 return reinterpret_cast<const char*>(magic_);
84}
85
Brian Carlstrome24fa612011-09-29 00:53:55 -070086uint32_t OatHeader::GetChecksum() const {
87 CHECK(IsValid());
88 return adler32_checksum_;
89}
90
91void OatHeader::UpdateChecksum(const void* data, size_t length) {
92 DCHECK(IsValid());
93 const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
94 adler32_checksum_ = adler32(adler32_checksum_, bytes, length);
95}
96
Elliott Hughesa72ec822012-03-05 17:12:22 -080097InstructionSet OatHeader::GetInstructionSet() const {
98 CHECK(IsValid());
99 return instruction_set_;
100}
101
Brian Carlstrome24fa612011-09-29 00:53:55 -0700102uint32_t OatHeader::GetExecutableOffset() const {
103 DCHECK(IsValid());
Elliott Hughes06b37d92011-10-16 11:51:29 -0700104 DCHECK_ALIGNED(executable_offset_, kPageSize);
Brian Carlstrome24fa612011-09-29 00:53:55 -0700105 CHECK_GT(executable_offset_, sizeof(OatHeader));
106 return executable_offset_;
107}
108
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700109void OatHeader::SetExecutableOffset(uint32_t executable_offset) {
110 DCHECK_ALIGNED(executable_offset, kPageSize);
111 CHECK_GT(executable_offset, sizeof(OatHeader));
112 DCHECK(IsValid());
113 DCHECK_EQ(executable_offset_, 0U);
114
115 executable_offset_ = executable_offset;
116 UpdateChecksum(&executable_offset_, sizeof(executable_offset));
117}
118
Ian Rogers468532e2013-08-05 10:56:33 -0700119const void* OatHeader::GetInterpreterToInterpreterBridge() const {
120 return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToInterpreterBridgeOffset();
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700121}
122
Ian Rogers468532e2013-08-05 10:56:33 -0700123uint32_t OatHeader::GetInterpreterToInterpreterBridgeOffset() const {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700124 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700125 CHECK_GE(interpreter_to_interpreter_bridge_offset_, executable_offset_);
126 return interpreter_to_interpreter_bridge_offset_;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700127}
128
Ian Rogers468532e2013-08-05 10:56:33 -0700129void OatHeader::SetInterpreterToInterpreterBridgeOffset(uint32_t offset) {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700130 CHECK(offset == 0 || offset >= executable_offset_);
131 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700132 DCHECK_EQ(interpreter_to_interpreter_bridge_offset_, 0U) << offset;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700133
Ian Rogers468532e2013-08-05 10:56:33 -0700134 interpreter_to_interpreter_bridge_offset_ = offset;
135 UpdateChecksum(&interpreter_to_interpreter_bridge_offset_, sizeof(offset));
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700136}
137
Ian Rogers468532e2013-08-05 10:56:33 -0700138const void* OatHeader::GetInterpreterToCompiledCodeBridge() const {
139 return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToCompiledCodeBridgeOffset();
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700140}
141
Ian Rogers468532e2013-08-05 10:56:33 -0700142uint32_t OatHeader::GetInterpreterToCompiledCodeBridgeOffset() const {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700143 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700144 CHECK_GE(interpreter_to_compiled_code_bridge_offset_, interpreter_to_interpreter_bridge_offset_);
145 return interpreter_to_compiled_code_bridge_offset_;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700146}
147
Ian Rogers468532e2013-08-05 10:56:33 -0700148void OatHeader::SetInterpreterToCompiledCodeBridgeOffset(uint32_t offset) {
149 CHECK(offset == 0 || offset >= interpreter_to_interpreter_bridge_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700150 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700151 DCHECK_EQ(interpreter_to_compiled_code_bridge_offset_, 0U) << offset;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700152
Ian Rogers468532e2013-08-05 10:56:33 -0700153 interpreter_to_compiled_code_bridge_offset_ = offset;
154 UpdateChecksum(&interpreter_to_compiled_code_bridge_offset_, sizeof(offset));
155}
156
157const void* OatHeader::GetJniDlsymLookup() const {
158 return reinterpret_cast<const uint8_t*>(this) + GetJniDlsymLookupOffset();
159}
160
161uint32_t OatHeader::GetJniDlsymLookupOffset() const {
162 DCHECK(IsValid());
163 CHECK_GE(jni_dlsym_lookup_offset_, interpreter_to_compiled_code_bridge_offset_);
164 return jni_dlsym_lookup_offset_;
165}
166
167void OatHeader::SetJniDlsymLookupOffset(uint32_t offset) {
168 CHECK(offset == 0 || offset >= interpreter_to_compiled_code_bridge_offset_);
169 DCHECK(IsValid());
170 DCHECK_EQ(jni_dlsym_lookup_offset_, 0U) << offset;
171
172 jni_dlsym_lookup_offset_ = offset;
173 UpdateChecksum(&jni_dlsym_lookup_offset_, sizeof(offset));
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700174}
175
Jeff Hao88474b42013-10-23 16:24:40 -0700176const void* OatHeader::GetPortableImtConflictTrampoline() const {
177 return reinterpret_cast<const uint8_t*>(this) + GetPortableImtConflictTrampolineOffset();
178}
179
180uint32_t OatHeader::GetPortableImtConflictTrampolineOffset() const {
181 DCHECK(IsValid());
182 CHECK_GE(portable_imt_conflict_trampoline_offset_, jni_dlsym_lookup_offset_);
183 return portable_imt_conflict_trampoline_offset_;
184}
185
186void OatHeader::SetPortableImtConflictTrampolineOffset(uint32_t offset) {
187 CHECK(offset == 0 || offset >= jni_dlsym_lookup_offset_);
188 DCHECK(IsValid());
189 DCHECK_EQ(portable_imt_conflict_trampoline_offset_, 0U) << offset;
190
191 portable_imt_conflict_trampoline_offset_ = offset;
192 UpdateChecksum(&portable_imt_conflict_trampoline_offset_, sizeof(offset));
193}
194
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700195const void* OatHeader::GetPortableResolutionTrampoline() const {
196 return reinterpret_cast<const uint8_t*>(this) + GetPortableResolutionTrampolineOffset();
197}
198
199uint32_t OatHeader::GetPortableResolutionTrampolineOffset() const {
200 DCHECK(IsValid());
Jeff Hao88474b42013-10-23 16:24:40 -0700201 CHECK_GE(portable_resolution_trampoline_offset_, portable_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700202 return portable_resolution_trampoline_offset_;
203}
204
205void OatHeader::SetPortableResolutionTrampolineOffset(uint32_t offset) {
Jeff Hao88474b42013-10-23 16:24:40 -0700206 CHECK(offset == 0 || offset >= portable_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700207 DCHECK(IsValid());
208 DCHECK_EQ(portable_resolution_trampoline_offset_, 0U) << offset;
209
210 portable_resolution_trampoline_offset_ = offset;
211 UpdateChecksum(&portable_resolution_trampoline_offset_, sizeof(offset));
212}
213
Ian Rogers468532e2013-08-05 10:56:33 -0700214const void* OatHeader::GetPortableToInterpreterBridge() const {
215 return reinterpret_cast<const uint8_t*>(this) + GetPortableToInterpreterBridgeOffset();
216}
217
218uint32_t OatHeader::GetPortableToInterpreterBridgeOffset() const {
219 DCHECK(IsValid());
220 CHECK_GE(portable_to_interpreter_bridge_offset_, portable_resolution_trampoline_offset_);
221 return portable_to_interpreter_bridge_offset_;
222}
223
224void OatHeader::SetPortableToInterpreterBridgeOffset(uint32_t offset) {
225 CHECK(offset == 0 || offset >= portable_resolution_trampoline_offset_);
226 DCHECK(IsValid());
227 DCHECK_EQ(portable_to_interpreter_bridge_offset_, 0U) << offset;
228
229 portable_to_interpreter_bridge_offset_ = offset;
230 UpdateChecksum(&portable_to_interpreter_bridge_offset_, sizeof(offset));
231}
232
Jeff Hao88474b42013-10-23 16:24:40 -0700233const void* OatHeader::GetQuickImtConflictTrampoline() const {
234 return reinterpret_cast<const uint8_t*>(this) + GetQuickImtConflictTrampolineOffset();
235}
236
237uint32_t OatHeader::GetQuickImtConflictTrampolineOffset() const {
238 DCHECK(IsValid());
239 CHECK_GE(quick_imt_conflict_trampoline_offset_, portable_to_interpreter_bridge_offset_);
240 return quick_imt_conflict_trampoline_offset_;
241}
242
243void OatHeader::SetQuickImtConflictTrampolineOffset(uint32_t offset) {
244 CHECK(offset == 0 || offset >= portable_to_interpreter_bridge_offset_);
245 DCHECK(IsValid());
246 DCHECK_EQ(quick_imt_conflict_trampoline_offset_, 0U) << offset;
247
248 quick_imt_conflict_trampoline_offset_ = offset;
249 UpdateChecksum(&quick_imt_conflict_trampoline_offset_, sizeof(offset));
250}
251
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700252const void* OatHeader::GetQuickResolutionTrampoline() const {
253 return reinterpret_cast<const uint8_t*>(this) + GetQuickResolutionTrampolineOffset();
254}
255
256uint32_t OatHeader::GetQuickResolutionTrampolineOffset() const {
257 DCHECK(IsValid());
Jeff Hao88474b42013-10-23 16:24:40 -0700258 CHECK_GE(quick_resolution_trampoline_offset_, quick_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700259 return quick_resolution_trampoline_offset_;
260}
261
262void OatHeader::SetQuickResolutionTrampolineOffset(uint32_t offset) {
Jeff Hao88474b42013-10-23 16:24:40 -0700263 CHECK(offset == 0 || offset >= quick_imt_conflict_trampoline_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700264 DCHECK(IsValid());
265 DCHECK_EQ(quick_resolution_trampoline_offset_, 0U) << offset;
266
267 quick_resolution_trampoline_offset_ = offset;
268 UpdateChecksum(&quick_resolution_trampoline_offset_, sizeof(offset));
269}
270
Ian Rogers468532e2013-08-05 10:56:33 -0700271const void* OatHeader::GetQuickToInterpreterBridge() const {
272 return reinterpret_cast<const uint8_t*>(this) + GetQuickToInterpreterBridgeOffset();
273}
274
275uint32_t OatHeader::GetQuickToInterpreterBridgeOffset() const {
276 DCHECK(IsValid());
277 CHECK_GE(quick_to_interpreter_bridge_offset_, quick_resolution_trampoline_offset_);
278 return quick_to_interpreter_bridge_offset_;
279}
280
281void OatHeader::SetQuickToInterpreterBridgeOffset(uint32_t offset) {
282 CHECK(offset == 0 || offset >= quick_resolution_trampoline_offset_);
283 DCHECK(IsValid());
284 DCHECK_EQ(quick_to_interpreter_bridge_offset_, 0U) << offset;
285
286 quick_to_interpreter_bridge_offset_ = offset;
287 UpdateChecksum(&quick_to_interpreter_bridge_offset_, sizeof(offset));
288}
289
Brian Carlstrom28db0122012-10-18 16:20:41 -0700290uint32_t OatHeader::GetImageFileLocationOatChecksum() const {
Brian Carlstrom81f3ca12012-03-17 00:27:35 -0700291 CHECK(IsValid());
Brian Carlstrom28db0122012-10-18 16:20:41 -0700292 return image_file_location_oat_checksum_;
293}
294
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800295uint32_t OatHeader::GetImageFileLocationOatDataBegin() const {
Brian Carlstrom28db0122012-10-18 16:20:41 -0700296 CHECK(IsValid());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800297 return image_file_location_oat_data_begin_;
Brian Carlstrom81f3ca12012-03-17 00:27:35 -0700298}
299
300uint32_t OatHeader::GetImageFileLocationSize() const {
301 CHECK(IsValid());
302 return image_file_location_size_;
303}
304
305const uint8_t* OatHeader::GetImageFileLocationData() const {
306 CHECK(IsValid());
307 return image_file_location_data_;
308}
309
310std::string OatHeader::GetImageFileLocation() const {
311 CHECK(IsValid());
312 return std::string(reinterpret_cast<const char*>(GetImageFileLocationData()),
313 GetImageFileLocationSize());
314}
315
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700316OatMethodOffsets::OatMethodOffsets()
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700317 : code_offset_(0),
318 frame_size_in_bytes_(0),
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700319 core_spill_mask_(0),
320 fp_spill_mask_(0),
321 mapping_table_offset_(0),
322 vmap_table_offset_(0),
Jeff Hao74180ca2013-03-27 15:29:11 -0700323 gc_map_offset_(0)
Logan Chienccb7bf12012-03-28 12:52:32 +0800324{}
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700325
326OatMethodOffsets::OatMethodOffsets(uint32_t code_offset,
327 uint32_t frame_size_in_bytes,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700328 uint32_t core_spill_mask,
329 uint32_t fp_spill_mask,
330 uint32_t mapping_table_offset,
331 uint32_t vmap_table_offset,
Jeff Hao74180ca2013-03-27 15:29:11 -0700332 uint32_t gc_map_offset
Logan Chienccb7bf12012-03-28 12:52:32 +0800333 )
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700334 : code_offset_(code_offset),
335 frame_size_in_bytes_(frame_size_in_bytes),
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700336 core_spill_mask_(core_spill_mask),
337 fp_spill_mask_(fp_spill_mask),
338 mapping_table_offset_(mapping_table_offset),
339 vmap_table_offset_(vmap_table_offset),
Jeff Hao74180ca2013-03-27 15:29:11 -0700340 gc_map_offset_(gc_map_offset)
Logan Chienccb7bf12012-03-28 12:52:32 +0800341{}
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700342
343OatMethodOffsets::~OatMethodOffsets() {}
344
Brian Carlstrome24fa612011-09-29 00:53:55 -0700345} // namespace art