• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 
17 #include "oat.h"
18 #include "utils.h"
19 
20 #include <zlib.h>
21 
22 namespace art {
23 
24 const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
25 const uint8_t OatHeader::kOatVersion[] = { '0', '0', '8', '\0' };
26 
OatHeader()27 OatHeader::OatHeader() {
28   memset(this, 0, sizeof(*this));
29 }
30 
OatHeader(InstructionSet instruction_set,const std::vector<const DexFile * > * dex_files,uint32_t image_file_location_oat_checksum,uint32_t image_file_location_oat_data_begin,const std::string & image_file_location)31 OatHeader::OatHeader(InstructionSet instruction_set,
32                      const std::vector<const DexFile*>* dex_files,
33                      uint32_t image_file_location_oat_checksum,
34                      uint32_t image_file_location_oat_data_begin,
35                      const std::string& image_file_location) {
36   memcpy(magic_, kOatMagic, sizeof(kOatMagic));
37   memcpy(version_, kOatVersion, sizeof(kOatVersion));
38 
39   adler32_checksum_ = adler32(0L, Z_NULL, 0);
40 
41   CHECK_NE(instruction_set, kNone);
42   instruction_set_ = instruction_set;
43   UpdateChecksum(&instruction_set_, sizeof(instruction_set_));
44 
45   dex_file_count_ = dex_files->size();
46   UpdateChecksum(&dex_file_count_, sizeof(dex_file_count_));
47 
48   image_file_location_oat_checksum_ = image_file_location_oat_checksum;
49   UpdateChecksum(&image_file_location_oat_checksum_, sizeof(image_file_location_oat_checksum_));
50 
51   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_));
54 
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 
59   executable_offset_ = 0;
60   interpreter_to_interpreter_bridge_offset_ = 0;
61   interpreter_to_compiled_code_bridge_offset_ = 0;
62   jni_dlsym_lookup_offset_ = 0;
63   portable_resolution_trampoline_offset_ = 0;
64   portable_to_interpreter_bridge_offset_ = 0;
65   quick_resolution_trampoline_offset_ = 0;
66   quick_to_interpreter_bridge_offset_ = 0;
67 }
68 
IsValid() const69 bool OatHeader::IsValid() const {
70   if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) {
71     return false;
72   }
73   if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) {
74     return false;
75   }
76   return true;
77 }
78 
GetMagic() const79 const char* OatHeader::GetMagic() const {
80   CHECK(IsValid());
81   return reinterpret_cast<const char*>(magic_);
82 }
83 
GetChecksum() const84 uint32_t OatHeader::GetChecksum() const {
85   CHECK(IsValid());
86   return adler32_checksum_;
87 }
88 
UpdateChecksum(const void * data,size_t length)89 void 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 
GetInstructionSet() const95 InstructionSet OatHeader::GetInstructionSet() const {
96   CHECK(IsValid());
97   return instruction_set_;
98 }
99 
GetExecutableOffset() const100 uint32_t OatHeader::GetExecutableOffset() const {
101   DCHECK(IsValid());
102   DCHECK_ALIGNED(executable_offset_, kPageSize);
103   CHECK_GT(executable_offset_, sizeof(OatHeader));
104   return executable_offset_;
105 }
106 
SetExecutableOffset(uint32_t executable_offset)107 void 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 
GetInterpreterToInterpreterBridge() const117 const void* OatHeader::GetInterpreterToInterpreterBridge() const {
118   return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToInterpreterBridgeOffset();
119 }
120 
GetInterpreterToInterpreterBridgeOffset() const121 uint32_t OatHeader::GetInterpreterToInterpreterBridgeOffset() const {
122   DCHECK(IsValid());
123   CHECK_GE(interpreter_to_interpreter_bridge_offset_, executable_offset_);
124   return interpreter_to_interpreter_bridge_offset_;
125 }
126 
SetInterpreterToInterpreterBridgeOffset(uint32_t offset)127 void OatHeader::SetInterpreterToInterpreterBridgeOffset(uint32_t offset) {
128   CHECK(offset == 0 || offset >= executable_offset_);
129   DCHECK(IsValid());
130   DCHECK_EQ(interpreter_to_interpreter_bridge_offset_, 0U) << offset;
131 
132   interpreter_to_interpreter_bridge_offset_ = offset;
133   UpdateChecksum(&interpreter_to_interpreter_bridge_offset_, sizeof(offset));
134 }
135 
GetInterpreterToCompiledCodeBridge() const136 const void* OatHeader::GetInterpreterToCompiledCodeBridge() const {
137   return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToCompiledCodeBridgeOffset();
138 }
139 
GetInterpreterToCompiledCodeBridgeOffset() const140 uint32_t OatHeader::GetInterpreterToCompiledCodeBridgeOffset() const {
141   DCHECK(IsValid());
142   CHECK_GE(interpreter_to_compiled_code_bridge_offset_, interpreter_to_interpreter_bridge_offset_);
143   return interpreter_to_compiled_code_bridge_offset_;
144 }
145 
SetInterpreterToCompiledCodeBridgeOffset(uint32_t offset)146 void OatHeader::SetInterpreterToCompiledCodeBridgeOffset(uint32_t offset) {
147   CHECK(offset == 0 || offset >= interpreter_to_interpreter_bridge_offset_);
148   DCHECK(IsValid());
149   DCHECK_EQ(interpreter_to_compiled_code_bridge_offset_, 0U) << offset;
150 
151   interpreter_to_compiled_code_bridge_offset_ = offset;
152   UpdateChecksum(&interpreter_to_compiled_code_bridge_offset_, sizeof(offset));
153 }
154 
GetJniDlsymLookup() const155 const void* OatHeader::GetJniDlsymLookup() const {
156   return reinterpret_cast<const uint8_t*>(this) + GetJniDlsymLookupOffset();
157 }
158 
GetJniDlsymLookupOffset() const159 uint32_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 
SetJniDlsymLookupOffset(uint32_t offset)165 void 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));
172 }
173 
GetPortableResolutionTrampoline() const174 const void* OatHeader::GetPortableResolutionTrampoline() const {
175   return reinterpret_cast<const uint8_t*>(this) + GetPortableResolutionTrampolineOffset();
176 }
177 
GetPortableResolutionTrampolineOffset() const178 uint32_t OatHeader::GetPortableResolutionTrampolineOffset() const {
179   DCHECK(IsValid());
180   CHECK_GE(portable_resolution_trampoline_offset_, jni_dlsym_lookup_offset_);
181   return portable_resolution_trampoline_offset_;
182 }
183 
SetPortableResolutionTrampolineOffset(uint32_t offset)184 void OatHeader::SetPortableResolutionTrampolineOffset(uint32_t offset) {
185   CHECK(offset == 0 || offset >= jni_dlsym_lookup_offset_);
186   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 
GetPortableToInterpreterBridge() const193 const void* OatHeader::GetPortableToInterpreterBridge() const {
194   return reinterpret_cast<const uint8_t*>(this) + GetPortableToInterpreterBridgeOffset();
195 }
196 
GetPortableToInterpreterBridgeOffset() const197 uint32_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 
SetPortableToInterpreterBridgeOffset(uint32_t offset)203 void 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 
GetQuickResolutionTrampoline() const212 const void* OatHeader::GetQuickResolutionTrampoline() const {
213   return reinterpret_cast<const uint8_t*>(this) + GetQuickResolutionTrampolineOffset();
214 }
215 
GetQuickResolutionTrampolineOffset() const216 uint32_t OatHeader::GetQuickResolutionTrampolineOffset() const {
217   DCHECK(IsValid());
218   CHECK_GE(quick_resolution_trampoline_offset_, portable_to_interpreter_bridge_offset_);
219   return quick_resolution_trampoline_offset_;
220 }
221 
SetQuickResolutionTrampolineOffset(uint32_t offset)222 void OatHeader::SetQuickResolutionTrampolineOffset(uint32_t offset) {
223   CHECK(offset == 0 || offset >= portable_to_interpreter_bridge_offset_);
224   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 
GetQuickToInterpreterBridge() const231 const void* OatHeader::GetQuickToInterpreterBridge() const {
232   return reinterpret_cast<const uint8_t*>(this) + GetQuickToInterpreterBridgeOffset();
233 }
234 
GetQuickToInterpreterBridgeOffset() const235 uint32_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 
SetQuickToInterpreterBridgeOffset(uint32_t offset)241 void 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 
GetImageFileLocationOatChecksum() const250 uint32_t OatHeader::GetImageFileLocationOatChecksum() const {
251   CHECK(IsValid());
252   return image_file_location_oat_checksum_;
253 }
254 
GetImageFileLocationOatDataBegin() const255 uint32_t OatHeader::GetImageFileLocationOatDataBegin() const {
256   CHECK(IsValid());
257   return image_file_location_oat_data_begin_;
258 }
259 
GetImageFileLocationSize() const260 uint32_t OatHeader::GetImageFileLocationSize() const {
261   CHECK(IsValid());
262   return image_file_location_size_;
263 }
264 
GetImageFileLocationData() const265 const uint8_t* OatHeader::GetImageFileLocationData() const {
266   CHECK(IsValid());
267   return image_file_location_data_;
268 }
269 
GetImageFileLocation() const270 std::string OatHeader::GetImageFileLocation() const {
271   CHECK(IsValid());
272   return std::string(reinterpret_cast<const char*>(GetImageFileLocationData()),
273                      GetImageFileLocationSize());
274 }
275 
OatMethodOffsets()276 OatMethodOffsets::OatMethodOffsets()
277   : code_offset_(0),
278     frame_size_in_bytes_(0),
279     core_spill_mask_(0),
280     fp_spill_mask_(0),
281     mapping_table_offset_(0),
282     vmap_table_offset_(0),
283     gc_map_offset_(0)
284 {}
285 
OatMethodOffsets(uint32_t code_offset,uint32_t frame_size_in_bytes,uint32_t core_spill_mask,uint32_t fp_spill_mask,uint32_t mapping_table_offset,uint32_t vmap_table_offset,uint32_t gc_map_offset)286 OatMethodOffsets::OatMethodOffsets(uint32_t code_offset,
287                                    uint32_t frame_size_in_bytes,
288                                    uint32_t core_spill_mask,
289                                    uint32_t fp_spill_mask,
290                                    uint32_t mapping_table_offset,
291                                    uint32_t vmap_table_offset,
292                                    uint32_t gc_map_offset
293                                    )
294   : code_offset_(code_offset),
295     frame_size_in_bytes_(frame_size_in_bytes),
296     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),
300     gc_map_offset_(gc_map_offset)
301 {}
302 
~OatMethodOffsets()303 OatMethodOffsets::~OatMethodOffsets() {}
304 
305 }  // namespace art
306