blob: 1e9d820716139ce2766420468ebe2679bda93f6e [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_file.h"
18
Brian Carlstrome24fa612011-09-29 00:53:55 -070019#include "file.h"
20#include "os.h"
21#include "stl_util.h"
22
23namespace art {
24
jeffhao262bf462011-10-20 18:36:32 -070025std::string OatFile::DexFilenameToOatFilename(const std::string& location) {
jeffhao262bf462011-10-20 18:36:32 -070026 CHECK(IsValidDexFilename(location) || IsValidZipFilename(location));
Brian Carlstroma6cc8932012-01-04 14:44:07 -080027 std::string oat_location(location);
28 oat_location += ".oat";
jeffhao262bf462011-10-20 18:36:32 -070029 return oat_location;
Brian Carlstromb7bbba42011-10-13 14:58:47 -070030}
31
Brian Carlstrome24fa612011-09-29 00:53:55 -070032OatFile* OatFile::Open(const std::string& filename,
Brian Carlstroma004aa92012-02-08 18:05:09 -080033 const std::string& location,
Brian Carlstromf5822582012-03-19 22:34:31 -070034 byte* requested_base,
Logan Chien0c717dd2012-03-28 18:31:07 +080035 RelocationBehavior reloc,
Brian Carlstromf5822582012-03-19 22:34:31 -070036 bool writable) {
Brian Carlstrom7a967b32012-03-28 15:23:10 -070037 CHECK(!filename.empty()) << location;
Brian Carlstromf5822582012-03-19 22:34:31 -070038 UniquePtr<File> file(OS::OpenFile(filename.c_str(), writable, false));
Brian Carlstrom5b332c82012-02-01 15:02:31 -080039 if (file.get() == NULL) {
Brian Carlstromf5822582012-03-19 22:34:31 -070040 return NULL;
Brian Carlstrom5b332c82012-02-01 15:02:31 -080041 }
Logan Chien0c717dd2012-03-28 18:31:07 +080042 return Open(*file.get(), location, requested_base, reloc, writable);
Brian Carlstrom5b332c82012-02-01 15:02:31 -080043}
Brian Carlstrome24fa612011-09-29 00:53:55 -070044
Brian Carlstrom5b332c82012-02-01 15:02:31 -080045OatFile* OatFile::Open(File& file,
46 const std::string& location,
Brian Carlstromf5822582012-03-19 22:34:31 -070047 byte* requested_base,
Logan Chien0c717dd2012-03-28 18:31:07 +080048 RelocationBehavior reloc,
Brian Carlstromf5822582012-03-19 22:34:31 -070049 bool writable) {
Brian Carlstrom7a967b32012-03-28 15:23:10 -070050 CHECK(!location.empty());
51 if (!IsValidOatFilename(location)) {
Brian Carlstromf852fb22012-10-19 11:01:58 -070052 LOG(WARNING) << "Attempting to open oat file with unknown extension '" << location << "'";
Brian Carlstrom7a967b32012-03-28 15:23:10 -070053 }
Brian Carlstrom5b332c82012-02-01 15:02:31 -080054 UniquePtr<OatFile> oat_file(new OatFile(location));
Logan Chien0c717dd2012-03-28 18:31:07 +080055 bool success = oat_file->Map(file, requested_base, reloc, writable);
Brian Carlstrome24fa612011-09-29 00:53:55 -070056 if (!success) {
57 return NULL;
58 }
59 return oat_file.release();
60}
61
Logan Chien0c717dd2012-03-28 18:31:07 +080062OatFile::OatFile(const std::string& location)
Logan Chien971bf3f2012-05-01 15:47:55 +080063 : location_(location) {
Brian Carlstroma004aa92012-02-08 18:05:09 -080064 CHECK(!location_.empty());
65}
Brian Carlstrome24fa612011-09-29 00:53:55 -070066
67OatFile::~OatFile() {
68 STLDeleteValues(&oat_dex_files_);
69}
70
Logan Chien0c717dd2012-03-28 18:31:07 +080071bool OatFile::Map(File& file,
72 byte* requested_base,
73#if defined(ART_USE_LLVM_COMPILER)
74 RelocationBehavior reloc,
75#else
76 RelocationBehavior /*UNUSED*/,
77#endif
78 bool writable) {
Brian Carlstrome24fa612011-09-29 00:53:55 -070079 OatHeader oat_header;
Brian Carlstrom5b332c82012-02-01 15:02:31 -080080 bool success = file.ReadFully(&oat_header, sizeof(oat_header));
Brian Carlstrome24fa612011-09-29 00:53:55 -070081 if (!success || !oat_header.IsValid()) {
Brian Carlstrom5b332c82012-02-01 15:02:31 -080082 LOG(WARNING) << "Invalid oat header " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -070083 return false;
84 }
85
Brian Carlstromf5822582012-03-19 22:34:31 -070086 int flags = 0;
87 int prot = 0;
88 if (writable) {
89 flags |= MAP_SHARED; // So changes will write through to file
90 prot |= (PROT_READ | PROT_WRITE);
91 } else {
92 flags |= MAP_PRIVATE;
93 prot |= PROT_READ;
94 }
95 if (requested_base != NULL) {
96 flags |= MAP_FIXED;
97 }
Brian Carlstrom89521892011-12-07 22:05:07 -080098 UniquePtr<MemMap> map(MemMap::MapFileAtAddress(requested_base,
Brian Carlstrom5b332c82012-02-01 15:02:31 -080099 file.Length(),
Brian Carlstromf5822582012-03-19 22:34:31 -0700100 prot,
Brian Carlstrom89521892011-12-07 22:05:07 -0800101 flags,
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800102 file.Fd(),
Brian Carlstrom89521892011-12-07 22:05:07 -0800103 0));
Brian Carlstrome24fa612011-09-29 00:53:55 -0700104 if (map.get() == NULL) {
Brian Carlstromf852fb22012-10-19 11:01:58 -0700105 LOG(WARNING) << "Failed to map oat file from " << file.name() << " for " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700106 return false;
107 }
Ian Rogers30fab402012-01-23 15:43:46 -0800108 CHECK(requested_base == 0 || requested_base == map->Begin())
Brian Carlstromf852fb22012-10-19 11:01:58 -0700109 << file.name() << " for " << GetLocation() << " " << reinterpret_cast<void*>(map->Begin());
110 DCHECK_EQ(0, memcmp(&oat_header, map->Begin(), sizeof(OatHeader)))
111 << file.name() << " for " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700112
Elliott Hughese689d512012-01-18 23:39:47 -0800113 off_t code_offset = oat_header.GetExecutableOffset();
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800114 if (code_offset < file.Length()) {
Ian Rogers30fab402012-01-23 15:43:46 -0800115 byte* code_address = map->Begin() + code_offset;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800116 size_t code_length = file.Length() - code_offset;
Brian Carlstromf5822582012-03-19 22:34:31 -0700117 if (mprotect(code_address, code_length, prot | PROT_EXEC) != 0) {
Brian Carlstromf852fb22012-10-19 11:01:58 -0700118 PLOG(ERROR) << "Failed to make oat code executable in "
119 << file.name() << " for " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700120 return false;
121 }
122 } else {
123 // its possible to have no code if all the methods were abstract, native, etc
Brian Carlstromf852fb22012-10-19 11:01:58 -0700124 DCHECK_EQ(code_offset, RoundUp(file.Length(), kPageSize))
125 << file.name() << " for " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700126 }
127
Ian Rogers30fab402012-01-23 15:43:46 -0800128 const byte* oat = map->Begin();
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800129
Brian Carlstrome24fa612011-09-29 00:53:55 -0700130 oat += sizeof(OatHeader);
Brian Carlstrom81f3ca12012-03-17 00:27:35 -0700131 oat += oat_header.GetImageFileLocationSize();
132
133 CHECK_LE(oat, map->End())
134 << reinterpret_cast<void*>(map->Begin())
135 << "+" << sizeof(OatHeader)
136 << "+" << oat_header.GetImageFileLocationSize()
137 << "<=" << reinterpret_cast<void*>(map->End())
Brian Carlstromf852fb22012-10-19 11:01:58 -0700138 << " " << file.name() << " for " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700139 for (size_t i = 0; i < oat_header.GetDexFileCount(); i++) {
140 size_t dex_file_location_size = *reinterpret_cast<const uint32_t*>(oat);
Brian Carlstromf852fb22012-10-19 11:01:58 -0700141 CHECK_GT(dex_file_location_size, 0U) << file.name() << " for " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700142 oat += sizeof(dex_file_location_size);
Brian Carlstromf852fb22012-10-19 11:01:58 -0700143 CHECK_LT(oat, map->End()) << file.name() << " for " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700144
145 const char* dex_file_location_data = reinterpret_cast<const char*>(oat);
146 oat += dex_file_location_size;
Brian Carlstromf852fb22012-10-19 11:01:58 -0700147 CHECK_LT(oat, map->End()) << file.name() << " for " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700148
149 std::string dex_file_location(dex_file_location_data, dex_file_location_size);
150
151 uint32_t dex_file_checksum = *reinterpret_cast<const uint32_t*>(oat);
152 oat += sizeof(dex_file_checksum);
Brian Carlstromf852fb22012-10-19 11:01:58 -0700153 CHECK_LT(oat, map->End()) << file.name() << " for " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700154
Brian Carlstrom89521892011-12-07 22:05:07 -0800155 uint32_t dex_file_offset = *reinterpret_cast<const uint32_t*>(oat);
Brian Carlstromf852fb22012-10-19 11:01:58 -0700156 CHECK_GT(dex_file_offset, 0U) << file.name() << " for " << GetLocation();
157 CHECK_LT(dex_file_offset, static_cast<uint32_t>(file.Length()))
158 << file.name() << " for " << GetLocation();
Brian Carlstrom89521892011-12-07 22:05:07 -0800159 oat += sizeof(dex_file_offset);
Brian Carlstromf852fb22012-10-19 11:01:58 -0700160 CHECK_LT(oat, map->End()) << file.name() << " for " << GetLocation();
Brian Carlstrom89521892011-12-07 22:05:07 -0800161
Ian Rogers30fab402012-01-23 15:43:46 -0800162 uint8_t* dex_file_pointer = map->Begin() + dex_file_offset;
Brian Carlstromf852fb22012-10-19 11:01:58 -0700163 CHECK(DexFile::IsMagicValid(dex_file_pointer))
164 << file.name() << " for " << GetLocation() << " " << dex_file_pointer;
165 CHECK(DexFile::IsVersionValid(dex_file_pointer))
166 << file.name() << " for " << GetLocation() << " " << dex_file_pointer;
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800167 const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(dex_file_pointer);
168 const uint32_t* methods_offsets_pointer = reinterpret_cast<const uint32_t*>(oat);
Brian Carlstrom89521892011-12-07 22:05:07 -0800169
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800170 oat += (sizeof(*methods_offsets_pointer) * header->class_defs_size_);
Brian Carlstromf852fb22012-10-19 11:01:58 -0700171 CHECK_LE(oat, map->End()) << file.name() << " for " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700172
Elliott Hughesa0e18062012-04-13 15:59:59 -0700173 oat_dex_files_.Put(dex_file_location, new OatDexFile(this,
174 dex_file_location,
175 dex_file_checksum,
176 dex_file_pointer,
177 methods_offsets_pointer));
Brian Carlstrome24fa612011-09-29 00:53:55 -0700178 }
179
180 mem_map_.reset(map.release());
181 return true;
182}
183
184const OatHeader& OatFile::GetOatHeader() const {
Ian Rogers30fab402012-01-23 15:43:46 -0800185 return *reinterpret_cast<const OatHeader*>(Begin());
Brian Carlstrome24fa612011-09-29 00:53:55 -0700186}
187
Ian Rogers30fab402012-01-23 15:43:46 -0800188const byte* OatFile::Begin() const {
189 CHECK(mem_map_->Begin() != NULL);
190 return mem_map_->Begin();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700191}
192
Ian Rogers30fab402012-01-23 15:43:46 -0800193const byte* OatFile::End() const {
194 CHECK(mem_map_->End() != NULL);
195 return mem_map_->End();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700196}
197
Ian Rogers7fe2c692011-12-06 16:35:59 -0800198const OatFile::OatDexFile* OatFile::GetOatDexFile(const std::string& dex_file_location,
199 bool warn_if_not_found) const {
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700200 Table::const_iterator it = oat_dex_files_.find(dex_file_location);
Brian Carlstrome24fa612011-09-29 00:53:55 -0700201 if (it == oat_dex_files_.end()) {
Ian Rogers7fe2c692011-12-06 16:35:59 -0800202 if (warn_if_not_found) {
203 LOG(WARNING) << "Failed to find OatDexFile for DexFile " << dex_file_location;
204 }
Brian Carlstromaded5f72011-10-07 17:15:04 -0700205 return NULL;
Brian Carlstrome24fa612011-09-29 00:53:55 -0700206 }
Brian Carlstromaded5f72011-10-07 17:15:04 -0700207 return it->second;
208}
209
210std::vector<const OatFile::OatDexFile*> OatFile::GetOatDexFiles() const {
211 std::vector<const OatFile::OatDexFile*> result;
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700212 for (Table::const_iterator it = oat_dex_files_.begin(); it != oat_dex_files_.end(); ++it) {
Brian Carlstromaded5f72011-10-07 17:15:04 -0700213 result.push_back(it->second);
214 }
215 return result;
Brian Carlstrome24fa612011-09-29 00:53:55 -0700216}
217
Logan Chien0c717dd2012-03-28 18:31:07 +0800218void OatFile::RelocateExecutable() {
Shih-wei Liaoab646f92012-06-27 23:02:11 -0700219#if defined(ART_USE_LLVM_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800220 UNIMPLEMENTED(WARNING) << "Relocate the executable";
Shih-wei Liaoab646f92012-06-27 23:02:11 -0700221#endif
Logan Chien0c717dd2012-03-28 18:31:07 +0800222}
223
Brian Carlstrome24fa612011-09-29 00:53:55 -0700224OatFile::OatDexFile::OatDexFile(const OatFile* oat_file,
Elliott Hughesaa6a5882012-01-13 19:39:16 -0800225 const std::string& dex_file_location,
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800226 uint32_t dex_file_location_checksum,
Brian Carlstrom89521892011-12-07 22:05:07 -0800227 byte* dex_file_pointer,
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800228 const uint32_t* oat_class_offsets_pointer)
Brian Carlstrome24fa612011-09-29 00:53:55 -0700229 : oat_file_(oat_file),
230 dex_file_location_(dex_file_location),
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800231 dex_file_location_checksum_(dex_file_location_checksum),
Brian Carlstrom89521892011-12-07 22:05:07 -0800232 dex_file_pointer_(dex_file_pointer),
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800233 oat_class_offsets_pointer_(oat_class_offsets_pointer) {}
Brian Carlstrome24fa612011-09-29 00:53:55 -0700234
235OatFile::OatDexFile::~OatDexFile() {}
236
Brian Carlstrom89521892011-12-07 22:05:07 -0800237const DexFile* OatFile::OatDexFile::OpenDexFile() const {
238 size_t length = reinterpret_cast<const DexFile::Header*>(dex_file_pointer_)->file_size_;
Brian Carlstrom28db0122012-10-18 16:20:41 -0700239 return DexFile::Open(dex_file_pointer_, length, dex_file_location_,
240 dex_file_location_checksum_);
Brian Carlstrom89521892011-12-07 22:05:07 -0800241}
242
Brian Carlstromaded5f72011-10-07 17:15:04 -0700243const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint32_t class_def_index) const {
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800244 uint32_t oat_class_offset = oat_class_offsets_pointer_[class_def_index];
245
Ian Rogers30fab402012-01-23 15:43:46 -0800246 const byte* oat_class_pointer = oat_file_->Begin() + oat_class_offset;
247 CHECK_LT(oat_class_pointer, oat_file_->End());
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800248 Class::Status status = *reinterpret_cast<const Class::Status*>(oat_class_pointer);
249
250 const byte* methods_pointer = oat_class_pointer + sizeof(status);
Ian Rogers30fab402012-01-23 15:43:46 -0800251 CHECK_LT(methods_pointer, oat_file_->End());
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800252
253 return new OatClass(oat_file_,
254 status,
255 reinterpret_cast<const OatMethodOffsets*>(methods_pointer));
Brian Carlstrome24fa612011-09-29 00:53:55 -0700256}
257
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800258OatFile::OatClass::OatClass(const OatFile* oat_file,
259 Class::Status status,
260 const OatMethodOffsets* methods_pointer)
261 : oat_file_(oat_file), status_(status), methods_pointer_(methods_pointer) {}
Brian Carlstrome24fa612011-09-29 00:53:55 -0700262
263OatFile::OatClass::~OatClass() {}
264
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800265Class::Status OatFile::OatClass::GetStatus() const {
266 return status_;
267}
268
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700269const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index) const {
270 const OatMethodOffsets& oat_method_offsets = methods_pointer_[method_index];
271 return OatMethod(
Ian Rogers30fab402012-01-23 15:43:46 -0800272 oat_file_->Begin(),
Brian Carlstromae826982011-11-09 01:33:42 -0800273 oat_method_offsets.code_offset_,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700274 oat_method_offsets.frame_size_in_bytes_,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700275 oat_method_offsets.core_spill_mask_,
276 oat_method_offsets.fp_spill_mask_,
Brian Carlstromae826982011-11-09 01:33:42 -0800277 oat_method_offsets.mapping_table_offset_,
278 oat_method_offsets.vmap_table_offset_,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800279 oat_method_offsets.gc_map_offset_,
Logan Chien0c717dd2012-03-28 18:31:07 +0800280 oat_method_offsets.invoke_stub_offset_
281#if defined(ART_USE_LLVM_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800282 , oat_method_offsets.proxy_stub_offset_
Logan Chien0c717dd2012-03-28 18:31:07 +0800283#endif
284 );
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700285}
286
Brian Carlstromae826982011-11-09 01:33:42 -0800287OatFile::OatMethod::OatMethod(const byte* base,
288 const uint32_t code_offset,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700289 const size_t frame_size_in_bytes,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700290 const uint32_t core_spill_mask,
291 const uint32_t fp_spill_mask,
Brian Carlstromae826982011-11-09 01:33:42 -0800292 const uint32_t mapping_table_offset,
293 const uint32_t vmap_table_offset,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800294 const uint32_t gc_map_offset,
Logan Chien0c717dd2012-03-28 18:31:07 +0800295 const uint32_t invoke_stub_offset
296#if defined(ART_USE_LLVM_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800297 , const uint32_t proxy_stub_offset
Logan Chien0c717dd2012-03-28 18:31:07 +0800298#endif
299 )
Ian Rogers30fab402012-01-23 15:43:46 -0800300 : begin_(base),
Brian Carlstromae826982011-11-09 01:33:42 -0800301 code_offset_(code_offset),
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700302 frame_size_in_bytes_(frame_size_in_bytes),
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700303 core_spill_mask_(core_spill_mask),
304 fp_spill_mask_(fp_spill_mask),
Brian Carlstromae826982011-11-09 01:33:42 -0800305 mapping_table_offset_(mapping_table_offset),
306 vmap_table_offset_(vmap_table_offset),
Ian Rogers0c7abda2012-09-19 13:33:42 -0700307 native_gc_map_offset_(gc_map_offset),
Logan Chien0c717dd2012-03-28 18:31:07 +0800308 invoke_stub_offset_(invoke_stub_offset)
309#if defined(ART_USE_LLVM_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800310 , proxy_stub_offset_(proxy_stub_offset)
Logan Chien0c717dd2012-03-28 18:31:07 +0800311#endif
312{
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700313#ifndef NDEBUG
Brian Carlstromae826982011-11-09 01:33:42 -0800314 if (mapping_table_offset_ != 0) { // implies non-native, non-stub code
315 if (vmap_table_offset_ == 0) {
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700316 DCHECK_EQ(0U, static_cast<uint32_t>(__builtin_popcount(core_spill_mask_) + __builtin_popcount(fp_spill_mask_)));
317 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800318 const uint16_t* vmap_table_ = reinterpret_cast<const uint16_t*>(begin_ + vmap_table_offset_);
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700319 DCHECK_EQ(vmap_table_[0], static_cast<uint32_t>(__builtin_popcount(core_spill_mask_) + __builtin_popcount(fp_spill_mask_)));
320 }
321 } else {
Elliott Hughesba8eee12012-01-24 20:25:24 -0800322 DCHECK_EQ(vmap_table_offset_, 0U);
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700323 }
324#endif
325}
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700326
327OatFile::OatMethod::~OatMethod() {}
328
Logan Chien0c717dd2012-03-28 18:31:07 +0800329const void* OatFile::OatMethod::GetCode() const {
Logan Chien971bf3f2012-05-01 15:47:55 +0800330 return GetOatPointer<const void*>(code_offset_);
Logan Chien0c717dd2012-03-28 18:31:07 +0800331}
332
333uint32_t OatFile::OatMethod::GetCodeSize() const {
Logan Chien971bf3f2012-05-01 15:47:55 +0800334 uintptr_t code = reinterpret_cast<uint32_t>(GetCode());
Logan Chien0c717dd2012-03-28 18:31:07 +0800335
Logan Chien971bf3f2012-05-01 15:47:55 +0800336 if (code == 0) {
Logan Chien0c717dd2012-03-28 18:31:07 +0800337 return 0;
338 }
Logan Chien971bf3f2012-05-01 15:47:55 +0800339 // TODO: make this Thumb2 specific
340 code &= ~0x1;
341 return reinterpret_cast<uint32_t*>(code)[-1];
Logan Chien0c717dd2012-03-28 18:31:07 +0800342}
343
Mathieu Chartier66f19252012-09-18 08:57:04 -0700344AbstractMethod::InvokeStub* OatFile::OatMethod::GetInvokeStub() const {
Ian Rogers1b09b092012-08-20 15:35:52 -0700345 const byte* stub = GetOatPointer<const byte*>(invoke_stub_offset_);
Mathieu Chartier66f19252012-09-18 08:57:04 -0700346 return reinterpret_cast<AbstractMethod::InvokeStub*>(const_cast<byte*>(stub));
Logan Chien0c717dd2012-03-28 18:31:07 +0800347}
348
349uint32_t OatFile::OatMethod::GetInvokeStubSize() const {
Logan Chien971bf3f2012-05-01 15:47:55 +0800350 uintptr_t code = reinterpret_cast<uint32_t>(GetInvokeStub());
351 if (code == 0) {
Logan Chien0c717dd2012-03-28 18:31:07 +0800352 return 0;
353 }
Logan Chien971bf3f2012-05-01 15:47:55 +0800354 // TODO: make this Thumb2 specific
355 code &= ~0x1;
356 return reinterpret_cast<uint32_t*>(code)[-1];
Logan Chien0c717dd2012-03-28 18:31:07 +0800357}
358
TDYa127eead4ac2012-06-03 07:15:25 -0700359#if defined(ART_USE_LLVM_COMPILER)
360const void* OatFile::OatMethod::GetProxyStub() const {
Logan Chien971bf3f2012-05-01 15:47:55 +0800361 return GetOatPointer<const void*>(proxy_stub_offset_);
TDYa127eead4ac2012-06-03 07:15:25 -0700362}
363#endif
364
Mathieu Chartier66f19252012-09-18 08:57:04 -0700365void OatFile::OatMethod::LinkMethodPointers(AbstractMethod* method) const {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700366 CHECK(method != NULL);
Brian Carlstromae826982011-11-09 01:33:42 -0800367 method->SetCode(GetCode());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700368 method->SetFrameSizeInBytes(frame_size_in_bytes_);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700369 method->SetCoreSpillMask(core_spill_mask_);
370 method->SetFpSpillMask(fp_spill_mask_);
Brian Carlstromae826982011-11-09 01:33:42 -0800371 method->SetMappingTable(GetMappingTable());
372 method->SetVmapTable(GetVmapTable());
Ian Rogers0c7abda2012-09-19 13:33:42 -0700373 method->SetNativeGcMap(GetNativeGcMap()); // Note, used by native methods in work around JNI mode.
Brian Carlstromae826982011-11-09 01:33:42 -0800374 method->SetInvokeStub(GetInvokeStub());
375}
376
Mathieu Chartier66f19252012-09-18 08:57:04 -0700377void OatFile::OatMethod::LinkMethodOffsets(AbstractMethod* method) const {
Brian Carlstromae826982011-11-09 01:33:42 -0800378 CHECK(method != NULL);
379 method->SetOatCodeOffset(GetCodeOffset());
380 method->SetFrameSizeInBytes(GetFrameSizeInBytes());
381 method->SetCoreSpillMask(GetCoreSpillMask());
382 method->SetFpSpillMask(GetFpSpillMask());
383 method->SetOatMappingTableOffset(GetMappingTableOffset());
384 method->SetOatVmapTableOffset(GetVmapTableOffset());
Ian Rogers0c7abda2012-09-19 13:33:42 -0700385 method->SetOatNativeGcMapOffset(GetNativeGcMapOffset());
Brian Carlstromae826982011-11-09 01:33:42 -0800386 method->SetOatInvokeStubOffset(GetInvokeStubOffset());
Brian Carlstrome24fa612011-09-29 00:53:55 -0700387}
388
Brian Carlstrome24fa612011-09-29 00:53:55 -0700389} // namespace art