blob: c01f77c364599ebc1e9c353c14c330106eb07f34 [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' };
Ian Rogers468532e2013-08-05 10:56:33 -070025const uint8_t OatHeader::kOatVersion[] = { '0', '0', '7', '\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 Hao0aba0ba2013-06-03 14:49:28 -070063 portable_resolution_trampoline_offset_ = 0;
Ian Rogers468532e2013-08-05 10:56:33 -070064 portable_to_interpreter_bridge_offset_ = 0;
Jeff Hao0aba0ba2013-06-03 14:49:28 -070065 quick_resolution_trampoline_offset_ = 0;
Ian Rogers468532e2013-08-05 10:56:33 -070066 quick_to_interpreter_bridge_offset_ = 0;
Brian Carlstrome24fa612011-09-29 00:53:55 -070067}
68
69bool OatHeader::IsValid() const {
Brian Carlstromf852fb22012-10-19 11:01:58 -070070 if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070071 return false;
72 }
Brian Carlstromf852fb22012-10-19 11:01:58 -070073 if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070074 return false;
75 }
76 return true;
77}
78
79const char* OatHeader::GetMagic() const {
80 CHECK(IsValid());
81 return reinterpret_cast<const char*>(magic_);
82}
83
Brian Carlstrome24fa612011-09-29 00:53:55 -070084uint32_t OatHeader::GetChecksum() const {
85 CHECK(IsValid());
86 return adler32_checksum_;
87}
88
89void OatHeader::UpdateChecksum(const void* data, size_t length) {
90 DCHECK(IsValid());
91 const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
92 adler32_checksum_ = adler32(adler32_checksum_, bytes, length);
93}
94
Elliott Hughesa72ec822012-03-05 17:12:22 -080095InstructionSet OatHeader::GetInstructionSet() const {
96 CHECK(IsValid());
97 return instruction_set_;
98}
99
Brian Carlstrome24fa612011-09-29 00:53:55 -0700100uint32_t OatHeader::GetExecutableOffset() const {
101 DCHECK(IsValid());
Elliott Hughes06b37d92011-10-16 11:51:29 -0700102 DCHECK_ALIGNED(executable_offset_, kPageSize);
Brian Carlstrome24fa612011-09-29 00:53:55 -0700103 CHECK_GT(executable_offset_, sizeof(OatHeader));
104 return executable_offset_;
105}
106
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700107void OatHeader::SetExecutableOffset(uint32_t executable_offset) {
108 DCHECK_ALIGNED(executable_offset, kPageSize);
109 CHECK_GT(executable_offset, sizeof(OatHeader));
110 DCHECK(IsValid());
111 DCHECK_EQ(executable_offset_, 0U);
112
113 executable_offset_ = executable_offset;
114 UpdateChecksum(&executable_offset_, sizeof(executable_offset));
115}
116
Ian Rogers468532e2013-08-05 10:56:33 -0700117const void* OatHeader::GetInterpreterToInterpreterBridge() const {
118 return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToInterpreterBridgeOffset();
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700119}
120
Ian Rogers468532e2013-08-05 10:56:33 -0700121uint32_t OatHeader::GetInterpreterToInterpreterBridgeOffset() const {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700122 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700123 CHECK_GE(interpreter_to_interpreter_bridge_offset_, executable_offset_);
124 return interpreter_to_interpreter_bridge_offset_;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700125}
126
Ian Rogers468532e2013-08-05 10:56:33 -0700127void OatHeader::SetInterpreterToInterpreterBridgeOffset(uint32_t offset) {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700128 CHECK(offset == 0 || offset >= executable_offset_);
129 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700130 DCHECK_EQ(interpreter_to_interpreter_bridge_offset_, 0U) << offset;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700131
Ian Rogers468532e2013-08-05 10:56:33 -0700132 interpreter_to_interpreter_bridge_offset_ = offset;
133 UpdateChecksum(&interpreter_to_interpreter_bridge_offset_, sizeof(offset));
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700134}
135
Ian Rogers468532e2013-08-05 10:56:33 -0700136const void* OatHeader::GetInterpreterToCompiledCodeBridge() const {
137 return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToCompiledCodeBridgeOffset();
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700138}
139
Ian Rogers468532e2013-08-05 10:56:33 -0700140uint32_t OatHeader::GetInterpreterToCompiledCodeBridgeOffset() const {
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700141 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700142 CHECK_GE(interpreter_to_compiled_code_bridge_offset_, interpreter_to_interpreter_bridge_offset_);
143 return interpreter_to_compiled_code_bridge_offset_;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700144}
145
Ian Rogers468532e2013-08-05 10:56:33 -0700146void OatHeader::SetInterpreterToCompiledCodeBridgeOffset(uint32_t offset) {
147 CHECK(offset == 0 || offset >= interpreter_to_interpreter_bridge_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700148 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700149 DCHECK_EQ(interpreter_to_compiled_code_bridge_offset_, 0U) << offset;
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700150
Ian Rogers468532e2013-08-05 10:56:33 -0700151 interpreter_to_compiled_code_bridge_offset_ = offset;
152 UpdateChecksum(&interpreter_to_compiled_code_bridge_offset_, sizeof(offset));
153}
154
155const void* OatHeader::GetJniDlsymLookup() const {
156 return reinterpret_cast<const uint8_t*>(this) + GetJniDlsymLookupOffset();
157}
158
159uint32_t OatHeader::GetJniDlsymLookupOffset() const {
160 DCHECK(IsValid());
161 CHECK_GE(jni_dlsym_lookup_offset_, interpreter_to_compiled_code_bridge_offset_);
162 return jni_dlsym_lookup_offset_;
163}
164
165void OatHeader::SetJniDlsymLookupOffset(uint32_t offset) {
166 CHECK(offset == 0 || offset >= interpreter_to_compiled_code_bridge_offset_);
167 DCHECK(IsValid());
168 DCHECK_EQ(jni_dlsym_lookup_offset_, 0U) << offset;
169
170 jni_dlsym_lookup_offset_ = offset;
171 UpdateChecksum(&jni_dlsym_lookup_offset_, sizeof(offset));
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700172}
173
174const void* OatHeader::GetPortableResolutionTrampoline() const {
175 return reinterpret_cast<const uint8_t*>(this) + GetPortableResolutionTrampolineOffset();
176}
177
178uint32_t OatHeader::GetPortableResolutionTrampolineOffset() const {
179 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700180 CHECK_GE(portable_resolution_trampoline_offset_, jni_dlsym_lookup_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700181 return portable_resolution_trampoline_offset_;
182}
183
184void OatHeader::SetPortableResolutionTrampolineOffset(uint32_t offset) {
Ian Rogers468532e2013-08-05 10:56:33 -0700185 CHECK(offset == 0 || offset >= jni_dlsym_lookup_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700186 DCHECK(IsValid());
187 DCHECK_EQ(portable_resolution_trampoline_offset_, 0U) << offset;
188
189 portable_resolution_trampoline_offset_ = offset;
190 UpdateChecksum(&portable_resolution_trampoline_offset_, sizeof(offset));
191}
192
Ian Rogers468532e2013-08-05 10:56:33 -0700193const void* OatHeader::GetPortableToInterpreterBridge() const {
194 return reinterpret_cast<const uint8_t*>(this) + GetPortableToInterpreterBridgeOffset();
195}
196
197uint32_t OatHeader::GetPortableToInterpreterBridgeOffset() const {
198 DCHECK(IsValid());
199 CHECK_GE(portable_to_interpreter_bridge_offset_, portable_resolution_trampoline_offset_);
200 return portable_to_interpreter_bridge_offset_;
201}
202
203void OatHeader::SetPortableToInterpreterBridgeOffset(uint32_t offset) {
204 CHECK(offset == 0 || offset >= portable_resolution_trampoline_offset_);
205 DCHECK(IsValid());
206 DCHECK_EQ(portable_to_interpreter_bridge_offset_, 0U) << offset;
207
208 portable_to_interpreter_bridge_offset_ = offset;
209 UpdateChecksum(&portable_to_interpreter_bridge_offset_, sizeof(offset));
210}
211
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700212const void* OatHeader::GetQuickResolutionTrampoline() const {
213 return reinterpret_cast<const uint8_t*>(this) + GetQuickResolutionTrampolineOffset();
214}
215
216uint32_t OatHeader::GetQuickResolutionTrampolineOffset() const {
217 DCHECK(IsValid());
Ian Rogers468532e2013-08-05 10:56:33 -0700218 CHECK_GE(quick_resolution_trampoline_offset_, portable_to_interpreter_bridge_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700219 return quick_resolution_trampoline_offset_;
220}
221
222void OatHeader::SetQuickResolutionTrampolineOffset(uint32_t offset) {
Ian Rogers468532e2013-08-05 10:56:33 -0700223 CHECK(offset == 0 || offset >= portable_to_interpreter_bridge_offset_);
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700224 DCHECK(IsValid());
225 DCHECK_EQ(quick_resolution_trampoline_offset_, 0U) << offset;
226
227 quick_resolution_trampoline_offset_ = offset;
228 UpdateChecksum(&quick_resolution_trampoline_offset_, sizeof(offset));
229}
230
Ian Rogers468532e2013-08-05 10:56:33 -0700231const void* OatHeader::GetQuickToInterpreterBridge() const {
232 return reinterpret_cast<const uint8_t*>(this) + GetQuickToInterpreterBridgeOffset();
233}
234
235uint32_t OatHeader::GetQuickToInterpreterBridgeOffset() const {
236 DCHECK(IsValid());
237 CHECK_GE(quick_to_interpreter_bridge_offset_, quick_resolution_trampoline_offset_);
238 return quick_to_interpreter_bridge_offset_;
239}
240
241void OatHeader::SetQuickToInterpreterBridgeOffset(uint32_t offset) {
242 CHECK(offset == 0 || offset >= quick_resolution_trampoline_offset_);
243 DCHECK(IsValid());
244 DCHECK_EQ(quick_to_interpreter_bridge_offset_, 0U) << offset;
245
246 quick_to_interpreter_bridge_offset_ = offset;
247 UpdateChecksum(&quick_to_interpreter_bridge_offset_, sizeof(offset));
248}
249
Brian Carlstrom28db0122012-10-18 16:20:41 -0700250uint32_t OatHeader::GetImageFileLocationOatChecksum() const {
Brian Carlstrom81f3ca12012-03-17 00:27:35 -0700251 CHECK(IsValid());
Brian Carlstrom28db0122012-10-18 16:20:41 -0700252 return image_file_location_oat_checksum_;
253}
254
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800255uint32_t OatHeader::GetImageFileLocationOatDataBegin() const {
Brian Carlstrom28db0122012-10-18 16:20:41 -0700256 CHECK(IsValid());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800257 return image_file_location_oat_data_begin_;
Brian Carlstrom81f3ca12012-03-17 00:27:35 -0700258}
259
260uint32_t OatHeader::GetImageFileLocationSize() const {
261 CHECK(IsValid());
262 return image_file_location_size_;
263}
264
265const uint8_t* OatHeader::GetImageFileLocationData() const {
266 CHECK(IsValid());
267 return image_file_location_data_;
268}
269
270std::string OatHeader::GetImageFileLocation() const {
271 CHECK(IsValid());
272 return std::string(reinterpret_cast<const char*>(GetImageFileLocationData()),
273 GetImageFileLocationSize());
274}
275
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700276OatMethodOffsets::OatMethodOffsets()
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700277 : code_offset_(0),
278 frame_size_in_bytes_(0),
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700279 core_spill_mask_(0),
280 fp_spill_mask_(0),
281 mapping_table_offset_(0),
282 vmap_table_offset_(0),
Jeff Hao74180ca2013-03-27 15:29:11 -0700283 gc_map_offset_(0)
Logan Chienccb7bf12012-03-28 12:52:32 +0800284{}
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700285
286OatMethodOffsets::OatMethodOffsets(uint32_t code_offset,
287 uint32_t frame_size_in_bytes,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700288 uint32_t core_spill_mask,
289 uint32_t fp_spill_mask,
290 uint32_t mapping_table_offset,
291 uint32_t vmap_table_offset,
Jeff Hao74180ca2013-03-27 15:29:11 -0700292 uint32_t gc_map_offset
Logan Chienccb7bf12012-03-28 12:52:32 +0800293 )
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700294 : code_offset_(code_offset),
295 frame_size_in_bytes_(frame_size_in_bytes),
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700296 core_spill_mask_(core_spill_mask),
297 fp_spill_mask_(fp_spill_mask),
298 mapping_table_offset_(mapping_table_offset),
299 vmap_table_offset_(vmap_table_offset),
Jeff Hao74180ca2013-03-27 15:29:11 -0700300 gc_map_offset_(gc_map_offset)
Logan Chienccb7bf12012-03-28 12:52:32 +0800301{}
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700302
303OatMethodOffsets::~OatMethodOffsets() {}
304
Brian Carlstrome24fa612011-09-29 00:53:55 -0700305} // namespace art