blob: 6f96e982e772c2796b83874043424907fc245d04 [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)) {
52 LOG(WARNING) << "Attempting to open dex file with unknown extension '" << location << "'";
53 }
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 Carlstrom5b332c82012-02-01 15:02:31 -0800105 LOG(WARNING) << "Failed to map oat file " << 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 Carlstromf8bbb842012-03-14 03:01:42 -0700109 << GetLocation() << " " << reinterpret_cast<void*>(map->Begin());
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800110 DCHECK_EQ(0, memcmp(&oat_header, map->Begin(), sizeof(OatHeader))) << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700111
Elliott Hughese689d512012-01-18 23:39:47 -0800112 off_t code_offset = oat_header.GetExecutableOffset();
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800113 if (code_offset < file.Length()) {
Ian Rogers30fab402012-01-23 15:43:46 -0800114 byte* code_address = map->Begin() + code_offset;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800115 size_t code_length = file.Length() - code_offset;
Brian Carlstromf5822582012-03-19 22:34:31 -0700116 if (mprotect(code_address, code_length, prot | PROT_EXEC) != 0) {
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800117 PLOG(ERROR) << "Failed to make oat code executable in " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700118 return false;
119 }
120 } else {
121 // its possible to have no code if all the methods were abstract, native, etc
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800122 DCHECK_EQ(code_offset, RoundUp(file.Length(), kPageSize)) << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700123 }
124
Ian Rogers30fab402012-01-23 15:43:46 -0800125 const byte* oat = map->Begin();
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800126
Brian Carlstrome24fa612011-09-29 00:53:55 -0700127 oat += sizeof(OatHeader);
Brian Carlstrom81f3ca12012-03-17 00:27:35 -0700128 oat += oat_header.GetImageFileLocationSize();
129
130 CHECK_LE(oat, map->End())
131 << reinterpret_cast<void*>(map->Begin())
132 << "+" << sizeof(OatHeader)
133 << "+" << oat_header.GetImageFileLocationSize()
134 << "<=" << reinterpret_cast<void*>(map->End())
135 << " " << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700136 for (size_t i = 0; i < oat_header.GetDexFileCount(); i++) {
137 size_t dex_file_location_size = *reinterpret_cast<const uint32_t*>(oat);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800138 CHECK_GT(dex_file_location_size, 0U) << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700139 oat += sizeof(dex_file_location_size);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800140 CHECK_LT(oat, map->End()) << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700141
142 const char* dex_file_location_data = reinterpret_cast<const char*>(oat);
143 oat += dex_file_location_size;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800144 CHECK_LT(oat, map->End()) << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700145
146 std::string dex_file_location(dex_file_location_data, dex_file_location_size);
147
148 uint32_t dex_file_checksum = *reinterpret_cast<const uint32_t*>(oat);
149 oat += sizeof(dex_file_checksum);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800150 CHECK_LT(oat, map->End()) << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700151
Brian Carlstrom89521892011-12-07 22:05:07 -0800152 uint32_t dex_file_offset = *reinterpret_cast<const uint32_t*>(oat);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800153 CHECK_GT(dex_file_offset, 0U) << GetLocation();
154 CHECK_LT(dex_file_offset, static_cast<uint32_t>(file.Length())) << GetLocation();
Brian Carlstrom89521892011-12-07 22:05:07 -0800155 oat += sizeof(dex_file_offset);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800156 CHECK_LT(oat, map->End()) << GetLocation();
Brian Carlstrom89521892011-12-07 22:05:07 -0800157
Ian Rogers30fab402012-01-23 15:43:46 -0800158 uint8_t* dex_file_pointer = map->Begin() + dex_file_offset;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800159 CHECK(DexFile::IsMagicValid(dex_file_pointer)) << GetLocation() << " " << dex_file_pointer;
160 CHECK(DexFile::IsVersionValid(dex_file_pointer)) << GetLocation() << " " << dex_file_pointer;
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800161 const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(dex_file_pointer);
162 const uint32_t* methods_offsets_pointer = reinterpret_cast<const uint32_t*>(oat);
Brian Carlstrom89521892011-12-07 22:05:07 -0800163
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800164 oat += (sizeof(*methods_offsets_pointer) * header->class_defs_size_);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800165 CHECK_LE(oat, map->End()) << GetLocation();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700166
Elliott Hughesa0e18062012-04-13 15:59:59 -0700167 oat_dex_files_.Put(dex_file_location, new OatDexFile(this,
168 dex_file_location,
169 dex_file_checksum,
170 dex_file_pointer,
171 methods_offsets_pointer));
Brian Carlstrome24fa612011-09-29 00:53:55 -0700172 }
173
174 mem_map_.reset(map.release());
175 return true;
176}
177
178const OatHeader& OatFile::GetOatHeader() const {
Ian Rogers30fab402012-01-23 15:43:46 -0800179 return *reinterpret_cast<const OatHeader*>(Begin());
Brian Carlstrome24fa612011-09-29 00:53:55 -0700180}
181
Ian Rogers30fab402012-01-23 15:43:46 -0800182const byte* OatFile::Begin() const {
183 CHECK(mem_map_->Begin() != NULL);
184 return mem_map_->Begin();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700185}
186
Ian Rogers30fab402012-01-23 15:43:46 -0800187const byte* OatFile::End() const {
188 CHECK(mem_map_->End() != NULL);
189 return mem_map_->End();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700190}
191
Ian Rogers7fe2c692011-12-06 16:35:59 -0800192const OatFile::OatDexFile* OatFile::GetOatDexFile(const std::string& dex_file_location,
193 bool warn_if_not_found) const {
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700194 Table::const_iterator it = oat_dex_files_.find(dex_file_location);
Brian Carlstrome24fa612011-09-29 00:53:55 -0700195 if (it == oat_dex_files_.end()) {
Ian Rogers7fe2c692011-12-06 16:35:59 -0800196 if (warn_if_not_found) {
197 LOG(WARNING) << "Failed to find OatDexFile for DexFile " << dex_file_location;
198 }
Brian Carlstromaded5f72011-10-07 17:15:04 -0700199 return NULL;
Brian Carlstrome24fa612011-09-29 00:53:55 -0700200 }
Brian Carlstromaded5f72011-10-07 17:15:04 -0700201 return it->second;
202}
203
204std::vector<const OatFile::OatDexFile*> OatFile::GetOatDexFiles() const {
205 std::vector<const OatFile::OatDexFile*> result;
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700206 for (Table::const_iterator it = oat_dex_files_.begin(); it != oat_dex_files_.end(); ++it) {
Brian Carlstromaded5f72011-10-07 17:15:04 -0700207 result.push_back(it->second);
208 }
209 return result;
Brian Carlstrome24fa612011-09-29 00:53:55 -0700210}
211
Logan Chien0c717dd2012-03-28 18:31:07 +0800212void OatFile::RelocateExecutable() {
Shih-wei Liaoab646f92012-06-27 23:02:11 -0700213#if defined(ART_USE_LLVM_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800214 UNIMPLEMENTED(WARNING) << "Relocate the executable";
Shih-wei Liaoab646f92012-06-27 23:02:11 -0700215#endif
Logan Chien0c717dd2012-03-28 18:31:07 +0800216}
217
Brian Carlstrome24fa612011-09-29 00:53:55 -0700218OatFile::OatDexFile::OatDexFile(const OatFile* oat_file,
Elliott Hughesaa6a5882012-01-13 19:39:16 -0800219 const std::string& dex_file_location,
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800220 uint32_t dex_file_location_checksum,
Brian Carlstrom89521892011-12-07 22:05:07 -0800221 byte* dex_file_pointer,
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800222 const uint32_t* oat_class_offsets_pointer)
Brian Carlstrome24fa612011-09-29 00:53:55 -0700223 : oat_file_(oat_file),
224 dex_file_location_(dex_file_location),
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800225 dex_file_location_checksum_(dex_file_location_checksum),
Brian Carlstrom89521892011-12-07 22:05:07 -0800226 dex_file_pointer_(dex_file_pointer),
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800227 oat_class_offsets_pointer_(oat_class_offsets_pointer) {}
Brian Carlstrome24fa612011-09-29 00:53:55 -0700228
229OatFile::OatDexFile::~OatDexFile() {}
230
Brian Carlstrom89521892011-12-07 22:05:07 -0800231const DexFile* OatFile::OatDexFile::OpenDexFile() const {
232 size_t length = reinterpret_cast<const DexFile::Header*>(dex_file_pointer_)->file_size_;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800233 return DexFile::Open(dex_file_pointer_, length, dex_file_location_, dex_file_location_checksum_);
Brian Carlstrom89521892011-12-07 22:05:07 -0800234}
235
Brian Carlstromaded5f72011-10-07 17:15:04 -0700236const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint32_t class_def_index) const {
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800237 uint32_t oat_class_offset = oat_class_offsets_pointer_[class_def_index];
238
Ian Rogers30fab402012-01-23 15:43:46 -0800239 const byte* oat_class_pointer = oat_file_->Begin() + oat_class_offset;
240 CHECK_LT(oat_class_pointer, oat_file_->End());
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800241 Class::Status status = *reinterpret_cast<const Class::Status*>(oat_class_pointer);
242
243 const byte* methods_pointer = oat_class_pointer + sizeof(status);
Ian Rogers30fab402012-01-23 15:43:46 -0800244 CHECK_LT(methods_pointer, oat_file_->End());
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800245
246 return new OatClass(oat_file_,
247 status,
248 reinterpret_cast<const OatMethodOffsets*>(methods_pointer));
Brian Carlstrome24fa612011-09-29 00:53:55 -0700249}
250
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800251OatFile::OatClass::OatClass(const OatFile* oat_file,
252 Class::Status status,
253 const OatMethodOffsets* methods_pointer)
254 : oat_file_(oat_file), status_(status), methods_pointer_(methods_pointer) {}
Brian Carlstrome24fa612011-09-29 00:53:55 -0700255
256OatFile::OatClass::~OatClass() {}
257
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800258Class::Status OatFile::OatClass::GetStatus() const {
259 return status_;
260}
261
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700262const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index) const {
263 const OatMethodOffsets& oat_method_offsets = methods_pointer_[method_index];
264 return OatMethod(
Ian Rogers30fab402012-01-23 15:43:46 -0800265 oat_file_->Begin(),
Brian Carlstromae826982011-11-09 01:33:42 -0800266 oat_method_offsets.code_offset_,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700267 oat_method_offsets.frame_size_in_bytes_,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700268 oat_method_offsets.core_spill_mask_,
269 oat_method_offsets.fp_spill_mask_,
Brian Carlstromae826982011-11-09 01:33:42 -0800270 oat_method_offsets.mapping_table_offset_,
271 oat_method_offsets.vmap_table_offset_,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800272 oat_method_offsets.gc_map_offset_,
Logan Chien0c717dd2012-03-28 18:31:07 +0800273 oat_method_offsets.invoke_stub_offset_
274#if defined(ART_USE_LLVM_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800275 , oat_method_offsets.proxy_stub_offset_
Logan Chien0c717dd2012-03-28 18:31:07 +0800276#endif
277 );
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700278}
279
Brian Carlstromae826982011-11-09 01:33:42 -0800280OatFile::OatMethod::OatMethod(const byte* base,
281 const uint32_t code_offset,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700282 const size_t frame_size_in_bytes,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700283 const uint32_t core_spill_mask,
284 const uint32_t fp_spill_mask,
Brian Carlstromae826982011-11-09 01:33:42 -0800285 const uint32_t mapping_table_offset,
286 const uint32_t vmap_table_offset,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800287 const uint32_t gc_map_offset,
Logan Chien0c717dd2012-03-28 18:31:07 +0800288 const uint32_t invoke_stub_offset
289#if defined(ART_USE_LLVM_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800290 , const uint32_t proxy_stub_offset
Logan Chien0c717dd2012-03-28 18:31:07 +0800291#endif
292 )
Ian Rogers30fab402012-01-23 15:43:46 -0800293 : begin_(base),
Brian Carlstromae826982011-11-09 01:33:42 -0800294 code_offset_(code_offset),
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700295 frame_size_in_bytes_(frame_size_in_bytes),
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700296 core_spill_mask_(core_spill_mask),
297 fp_spill_mask_(fp_spill_mask),
Brian Carlstromae826982011-11-09 01:33:42 -0800298 mapping_table_offset_(mapping_table_offset),
299 vmap_table_offset_(vmap_table_offset),
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800300 gc_map_offset_(gc_map_offset),
Logan Chien0c717dd2012-03-28 18:31:07 +0800301 invoke_stub_offset_(invoke_stub_offset)
302#if defined(ART_USE_LLVM_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800303 , proxy_stub_offset_(proxy_stub_offset)
Logan Chien0c717dd2012-03-28 18:31:07 +0800304#endif
305{
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700306#ifndef NDEBUG
Brian Carlstromae826982011-11-09 01:33:42 -0800307 if (mapping_table_offset_ != 0) { // implies non-native, non-stub code
308 if (vmap_table_offset_ == 0) {
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700309 DCHECK_EQ(0U, static_cast<uint32_t>(__builtin_popcount(core_spill_mask_) + __builtin_popcount(fp_spill_mask_)));
310 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800311 const uint16_t* vmap_table_ = reinterpret_cast<const uint16_t*>(begin_ + vmap_table_offset_);
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700312 DCHECK_EQ(vmap_table_[0], static_cast<uint32_t>(__builtin_popcount(core_spill_mask_) + __builtin_popcount(fp_spill_mask_)));
313 }
314 } else {
Elliott Hughesba8eee12012-01-24 20:25:24 -0800315 DCHECK_EQ(vmap_table_offset_, 0U);
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -0700316 }
317#endif
318}
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700319
320OatFile::OatMethod::~OatMethod() {}
321
Logan Chien0c717dd2012-03-28 18:31:07 +0800322const void* OatFile::OatMethod::GetCode() const {
Logan Chien971bf3f2012-05-01 15:47:55 +0800323 return GetOatPointer<const void*>(code_offset_);
Logan Chien0c717dd2012-03-28 18:31:07 +0800324}
325
326uint32_t OatFile::OatMethod::GetCodeSize() const {
Logan Chien971bf3f2012-05-01 15:47:55 +0800327 uintptr_t code = reinterpret_cast<uint32_t>(GetCode());
Logan Chien0c717dd2012-03-28 18:31:07 +0800328
Logan Chien971bf3f2012-05-01 15:47:55 +0800329 if (code == 0) {
Logan Chien0c717dd2012-03-28 18:31:07 +0800330 return 0;
331 }
Logan Chien971bf3f2012-05-01 15:47:55 +0800332 // TODO: make this Thumb2 specific
333 code &= ~0x1;
334 return reinterpret_cast<uint32_t*>(code)[-1];
Logan Chien0c717dd2012-03-28 18:31:07 +0800335}
336
337const Method::InvokeStub* OatFile::OatMethod::GetInvokeStub() const {
Logan Chien971bf3f2012-05-01 15:47:55 +0800338 return GetOatPointer<const Method::InvokeStub*>(invoke_stub_offset_);
Logan Chien0c717dd2012-03-28 18:31:07 +0800339}
340
341uint32_t OatFile::OatMethod::GetInvokeStubSize() const {
Logan Chien971bf3f2012-05-01 15:47:55 +0800342 uintptr_t code = reinterpret_cast<uint32_t>(GetInvokeStub());
343 if (code == 0) {
Logan Chien0c717dd2012-03-28 18:31:07 +0800344 return 0;
345 }
Logan Chien971bf3f2012-05-01 15:47:55 +0800346 // TODO: make this Thumb2 specific
347 code &= ~0x1;
348 return reinterpret_cast<uint32_t*>(code)[-1];
Logan Chien0c717dd2012-03-28 18:31:07 +0800349}
350
TDYa127eead4ac2012-06-03 07:15:25 -0700351#if defined(ART_USE_LLVM_COMPILER)
352const void* OatFile::OatMethod::GetProxyStub() const {
Logan Chien971bf3f2012-05-01 15:47:55 +0800353 return GetOatPointer<const void*>(proxy_stub_offset_);
TDYa127eead4ac2012-06-03 07:15:25 -0700354}
355#endif
356
Brian Carlstromae826982011-11-09 01:33:42 -0800357void OatFile::OatMethod::LinkMethodPointers(Method* method) const {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700358 CHECK(method != NULL);
Brian Carlstromae826982011-11-09 01:33:42 -0800359 method->SetCode(GetCode());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700360 method->SetFrameSizeInBytes(frame_size_in_bytes_);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700361 method->SetCoreSpillMask(core_spill_mask_);
362 method->SetFpSpillMask(fp_spill_mask_);
Brian Carlstromae826982011-11-09 01:33:42 -0800363 method->SetMappingTable(GetMappingTable());
364 method->SetVmapTable(GetVmapTable());
Ian Rogers19846512012-02-24 11:42:47 -0800365 method->SetGcMap(GetGcMap()); // Note, used by native methods in work around JNI mode.
Brian Carlstromae826982011-11-09 01:33:42 -0800366 method->SetInvokeStub(GetInvokeStub());
367}
368
369void OatFile::OatMethod::LinkMethodOffsets(Method* method) const {
370 CHECK(method != NULL);
371 method->SetOatCodeOffset(GetCodeOffset());
372 method->SetFrameSizeInBytes(GetFrameSizeInBytes());
373 method->SetCoreSpillMask(GetCoreSpillMask());
374 method->SetFpSpillMask(GetFpSpillMask());
375 method->SetOatMappingTableOffset(GetMappingTableOffset());
376 method->SetOatVmapTableOffset(GetVmapTableOffset());
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800377 method->SetOatGcMapOffset(GetGcMapOffset());
Brian Carlstromae826982011-11-09 01:33:42 -0800378 method->SetOatInvokeStubOffset(GetInvokeStubOffset());
Brian Carlstrome24fa612011-09-29 00:53:55 -0700379}
380
Brian Carlstrome24fa612011-09-29 00:53:55 -0700381} // namespace art