12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 17e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "oat.h" 18e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 1922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe#include <string.h> 20e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include <zlib.h> 21e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 2246ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe#include "android-base/stringprintf.h" 2346ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 24d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "arch/instruction_set_features.h" 2580afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/bit_utils.h" 26f45d61c0866461c9476f17644b27dc0664d507c5Andreas Gampe#include "base/strlcpy.h" 27d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 28e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromnamespace art { 29e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 3046ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampeusing android::base::StringPrintf; 3146ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 322bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampeconstexpr uint8_t OatHeader::kOatMagic[4]; 332bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampeconstexpr uint8_t OatHeader::kOatVersion[4]; 340de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertzconstexpr const char OatHeader::kTrueValue[]; 350de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertzconstexpr const char OatHeader::kFalseValue[]; 36e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 3722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampestatic size_t ComputeOatHeaderSize(const SafeMap<std::string, std::string>* variable_data) { 3822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe size_t estimate = 0U; 3922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (variable_data != nullptr) { 4022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string>::const_iterator it = variable_data->begin(); 4122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string>::const_iterator end = variable_data->end(); 4222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe for ( ; it != end; ++it) { 4322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe estimate += it->first.length() + 1; 4422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe estimate += it->second.length() + 1; 4522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 4622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 4722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return sizeof(OatHeader) + estimate; 4822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 4922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 5022f8e5c82d12951be38cd893426e13bee33fd69dAndreas GampeOatHeader* OatHeader::Create(InstructionSet instruction_set, 516f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers const InstructionSetFeatures* instruction_set_features, 5249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko uint32_t dex_file_count, 5322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const SafeMap<std::string, std::string>* variable_data) { 5422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Estimate size of optional data. 5522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe size_t needed_size = ComputeOatHeaderSize(variable_data); 5622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 5722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Reserve enough memory. 5822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe void* memory = operator new (needed_size); 5922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 6022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Create the OatHeader in-place. 6122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return new (memory) OatHeader(instruction_set, 6222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe instruction_set_features, 6349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko dex_file_count, 6422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe variable_data); 65a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes} 66a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes 6781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian CarlstromOatHeader::OatHeader(InstructionSet instruction_set, 686f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers const InstructionSetFeatures* instruction_set_features, 6949b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko uint32_t dex_file_count, 7049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko const SafeMap<std::string, std::string>* variable_data) 7149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko : adler32_checksum_(adler32(0L, Z_NULL, 0)), 7249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko instruction_set_(instruction_set), 7349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko instruction_set_features_bitmap_(instruction_set_features->AsBitmap()), 7449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko dex_file_count_(dex_file_count), 750eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko oat_dex_files_offset_(0), 7649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko executable_offset_(0), 7749b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko interpreter_to_interpreter_bridge_offset_(0), 7849b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko interpreter_to_compiled_code_bridge_offset_(0), 7949b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko jni_dlsym_lookup_offset_(0), 8049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko quick_generic_jni_trampoline_offset_(0), 8149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko quick_imt_conflict_trampoline_offset_(0), 8249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko quick_resolution_trampoline_offset_(0), 8349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko quick_to_interpreter_bridge_offset_(0), 8449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko image_patch_delta_(0), 8549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko image_file_location_oat_checksum_(0), 8649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko image_file_location_oat_data_begin_(0) { 872bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe // Don't want asserts in header as they would be checked in each file that includes it. But the 882bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe // fields are private, so we check inside a method. 892bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(magic_) == sizeof(kOatMagic), 902bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe "Oat magic and magic_ have different lengths."); 912bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(version_) == sizeof(kOatVersion), 922bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe "Oat version and version_ have different lengths."); 932bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe 94e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom memcpy(magic_, kOatMagic, sizeof(kOatMagic)); 95e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom memcpy(version_, kOatVersion, sizeof(kOatVersion)); 9681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 9733bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko CHECK_NE(instruction_set, InstructionSet::kNone); 9881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 9922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Flatten the map. Will also update variable_size_data_size_. 10022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe Flatten(variable_data); 101e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 102e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 103e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatHeader::IsValid() const { 104f852fb2921128d3b71a76e6b17c78d10fb7085e2Brian Carlstrom if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) { 105e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 106e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 107f852fb2921128d3b71a76e6b17c78d10fb7085e2Brian Carlstrom if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) { 108e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 109e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 110a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light if (!IsAligned<kPageSize>(executable_offset_)) { 111a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light return false; 112a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light } 113a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light if (!IsAligned<kPageSize>(image_patch_delta_)) { 114a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light return false; 115a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light } 11609d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko if (!IsValidInstructionSet(instruction_set_)) { 11709d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko return false; 11809d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko } 119e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 120e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 121e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 1222bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampestd::string OatHeader::GetValidationErrorMessage() const { 1232bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) { 1242bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(kOatMagic) == 4, "kOatMagic has unexpected length"); 1252bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return StringPrintf("Invalid oat magic, expected 0x%x%x%x%x, got 0x%x%x%x%x.", 1262bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe kOatMagic[0], kOatMagic[1], kOatMagic[2], kOatMagic[3], 1272bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe magic_[0], magic_[1], magic_[2], magic_[3]); 1282bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 1292bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) { 1302bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(kOatVersion) == 4, "kOatVersion has unexpected length"); 1312bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return StringPrintf("Invalid oat version, expected 0x%x%x%x%x, got 0x%x%x%x%x.", 1322bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe kOatVersion[0], kOatVersion[1], kOatVersion[2], kOatVersion[3], 1332bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe version_[0], version_[1], version_[2], version_[3]); 1342bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 1352bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (!IsAligned<kPageSize>(executable_offset_)) { 1362bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return "Executable offset not page-aligned."; 1372bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 1382bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (!IsAligned<kPageSize>(image_patch_delta_)) { 1392bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return "Image patch delta not page-aligned."; 1402bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 14109d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko if (!IsValidInstructionSet(instruction_set_)) { 14209d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko return StringPrintf("Invalid instruction set, %d.", static_cast<int>(instruction_set_)); 14309d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko } 1442bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return ""; 1452bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe} 1462bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe 147e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromconst char* OatHeader::GetMagic() const { 148e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(IsValid()); 149e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return reinterpret_cast<const char*>(magic_); 150e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 151e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 152e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromuint32_t OatHeader::GetChecksum() const { 153e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(IsValid()); 154e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return adler32_checksum_; 155e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 156e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 15749b0f45d5a9023653ab00c355735910aa51ee0baVladimir Markovoid OatHeader::UpdateChecksumWithHeaderData() { 15849b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&instruction_set_, sizeof(instruction_set_)); 15949b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&instruction_set_features_bitmap_, sizeof(instruction_set_features_bitmap_)); 16049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&dex_file_count_, sizeof(dex_file_count_)); 16149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&image_file_location_oat_checksum_, sizeof(image_file_location_oat_checksum_)); 16249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&image_file_location_oat_data_begin_, sizeof(image_file_location_oat_data_begin_)); 16349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 16449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko // Update checksum for variable data size. 16549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&key_value_store_size_, sizeof(key_value_store_size_)); 16649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 16749b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko // Update for data, if existing. 16849b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko if (key_value_store_size_ > 0U) { 16949b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&key_value_store_, key_value_store_size_); 17049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko } 17149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 17249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&executable_offset_, sizeof(executable_offset_)); 17349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&interpreter_to_interpreter_bridge_offset_, 17449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(interpreter_to_interpreter_bridge_offset_)); 17549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&interpreter_to_compiled_code_bridge_offset_, 17649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(interpreter_to_compiled_code_bridge_offset_)); 17749b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&jni_dlsym_lookup_offset_, sizeof(jni_dlsym_lookup_offset_)); 17849b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&quick_generic_jni_trampoline_offset_, 17949b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(quick_generic_jni_trampoline_offset_)); 18049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&quick_imt_conflict_trampoline_offset_, 18149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(quick_imt_conflict_trampoline_offset_)); 18249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&quick_resolution_trampoline_offset_, 18349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(quick_resolution_trampoline_offset_)); 18449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&quick_to_interpreter_bridge_offset_, 18549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(quick_to_interpreter_bridge_offset_)); 18649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko} 18749b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 188e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatHeader::UpdateChecksum(const void* data, size_t length) { 189e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom DCHECK(IsValid()); 1902c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao if (data != nullptr) { 1912c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data); 1922c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao adler32_checksum_ = adler32(adler32_checksum_, bytes, length); 1932c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao } else { 1942c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao DCHECK_EQ(0U, length); 1952c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao } 196e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 197e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 198a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott HughesInstructionSet OatHeader::GetInstructionSet() const { 199a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes CHECK(IsValid()); 200a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes return instruction_set_; 201a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes} 202a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes 2036f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogersuint32_t OatHeader::GetInstructionSetFeaturesBitmap() const { 2047020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison CHECK(IsValid()); 2056f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers return instruction_set_features_bitmap_; 2067020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison} 2077020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison 2080eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Markouint32_t OatHeader::GetOatDexFilesOffset() const { 2090eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko DCHECK(IsValid()); 2100eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko DCHECK_GT(oat_dex_files_offset_, sizeof(OatHeader)); 2110eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko return oat_dex_files_offset_; 2120eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko} 2130eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko 2140eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Markovoid OatHeader::SetOatDexFilesOffset(uint32_t oat_dex_files_offset) { 2150eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko DCHECK_GT(oat_dex_files_offset, sizeof(OatHeader)); 2160eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko DCHECK(IsValid()); 2170eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko DCHECK_EQ(oat_dex_files_offset_, 0u); 2180eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko 2190eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko oat_dex_files_offset_ = oat_dex_files_offset; 2200eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko} 2210eb882bfc5d260e8014c26adfda11602065aa5d8Vladimir Marko 222e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromuint32_t OatHeader::GetExecutableOffset() const { 223e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom DCHECK(IsValid()); 22406b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes DCHECK_ALIGNED(executable_offset_, kPageSize); 225e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK_GT(executable_offset_, sizeof(OatHeader)); 226e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return executable_offset_; 227e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 228e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 2290aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haovoid OatHeader::SetExecutableOffset(uint32_t executable_offset) { 2300aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK_ALIGNED(executable_offset, kPageSize); 2310aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao CHECK_GT(executable_offset, sizeof(OatHeader)); 2320aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 2330aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK_EQ(executable_offset_, 0U); 2340aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 2350aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao executable_offset_ = executable_offset; 2360aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2370aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 238468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetInterpreterToInterpreterBridge() const { 239468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToInterpreterBridgeOffset(); 2400aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2410aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 242468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetInterpreterToInterpreterBridgeOffset() const { 2430aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 244c6104ae36351591157fa09c482796256f82daddcDave Allison CHECK(interpreter_to_interpreter_bridge_offset_ == 0 || 245c6104ae36351591157fa09c482796256f82daddcDave Allison interpreter_to_interpreter_bridge_offset_ >= executable_offset_); 246468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return interpreter_to_interpreter_bridge_offset_; 2470aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2480aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 249468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetInterpreterToInterpreterBridgeOffset(uint32_t offset) { 2500aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao CHECK(offset == 0 || offset >= executable_offset_); 2510aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 252468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(interpreter_to_interpreter_bridge_offset_, 0U) << offset; 2530aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 254468532ea115657709bc32ee498e701a4c71762d4Ian Rogers interpreter_to_interpreter_bridge_offset_ = offset; 2550aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2560aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 257468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetInterpreterToCompiledCodeBridge() const { 258468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToCompiledCodeBridgeOffset(); 2590aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2600aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 261468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetInterpreterToCompiledCodeBridgeOffset() const { 2620aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 263468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK_GE(interpreter_to_compiled_code_bridge_offset_, interpreter_to_interpreter_bridge_offset_); 264468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return interpreter_to_compiled_code_bridge_offset_; 2650aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2660aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 267468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetInterpreterToCompiledCodeBridgeOffset(uint32_t offset) { 268468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK(offset == 0 || offset >= interpreter_to_interpreter_bridge_offset_); 2690aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 270468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(interpreter_to_compiled_code_bridge_offset_, 0U) << offset; 2710aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 272468532ea115657709bc32ee498e701a4c71762d4Ian Rogers interpreter_to_compiled_code_bridge_offset_ = offset; 273468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 274468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 275468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetJniDlsymLookup() const { 276468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetJniDlsymLookupOffset(); 277468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 278468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 279468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetJniDlsymLookupOffset() const { 280468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 281468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK_GE(jni_dlsym_lookup_offset_, interpreter_to_compiled_code_bridge_offset_); 282468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return jni_dlsym_lookup_offset_; 283468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 284468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 285468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetJniDlsymLookupOffset(uint32_t offset) { 286468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK(offset == 0 || offset >= interpreter_to_compiled_code_bridge_offset_); 287468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 288468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(jni_dlsym_lookup_offset_, 0U) << offset; 289468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 290468532ea115657709bc32ee498e701a4c71762d4Ian Rogers jni_dlsym_lookup_offset_ = offset; 2910aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2920aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 2932da882315a61072664f7ce3c212307342e907207Andreas Gampeconst void* OatHeader::GetQuickGenericJniTrampoline() const { 2942da882315a61072664f7ce3c212307342e907207Andreas Gampe return reinterpret_cast<const uint8_t*>(this) + GetQuickGenericJniTrampolineOffset(); 2952da882315a61072664f7ce3c212307342e907207Andreas Gampe} 2962da882315a61072664f7ce3c212307342e907207Andreas Gampe 2972da882315a61072664f7ce3c212307342e907207Andreas Gampeuint32_t OatHeader::GetQuickGenericJniTrampolineOffset() const { 2982da882315a61072664f7ce3c212307342e907207Andreas Gampe DCHECK(IsValid()); 299956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes CHECK_GE(quick_generic_jni_trampoline_offset_, jni_dlsym_lookup_offset_); 3002da882315a61072664f7ce3c212307342e907207Andreas Gampe return quick_generic_jni_trampoline_offset_; 3012da882315a61072664f7ce3c212307342e907207Andreas Gampe} 3022da882315a61072664f7ce3c212307342e907207Andreas Gampe 3032da882315a61072664f7ce3c212307342e907207Andreas Gampevoid OatHeader::SetQuickGenericJniTrampolineOffset(uint32_t offset) { 304956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes CHECK(offset == 0 || offset >= jni_dlsym_lookup_offset_); 3052da882315a61072664f7ce3c212307342e907207Andreas Gampe DCHECK(IsValid()); 3062da882315a61072664f7ce3c212307342e907207Andreas Gampe DCHECK_EQ(quick_generic_jni_trampoline_offset_, 0U) << offset; 3072da882315a61072664f7ce3c212307342e907207Andreas Gampe 3082da882315a61072664f7ce3c212307342e907207Andreas Gampe quick_generic_jni_trampoline_offset_ = offset; 3092da882315a61072664f7ce3c212307342e907207Andreas Gampe} 3102da882315a61072664f7ce3c212307342e907207Andreas Gampe 31188474b416eb257078e590bf9bc7957cee604a186Jeff Haoconst void* OatHeader::GetQuickImtConflictTrampoline() const { 31288474b416eb257078e590bf9bc7957cee604a186Jeff Hao return reinterpret_cast<const uint8_t*>(this) + GetQuickImtConflictTrampolineOffset(); 31388474b416eb257078e590bf9bc7957cee604a186Jeff Hao} 31488474b416eb257078e590bf9bc7957cee604a186Jeff Hao 31588474b416eb257078e590bf9bc7957cee604a186Jeff Haouint32_t OatHeader::GetQuickImtConflictTrampolineOffset() const { 31688474b416eb257078e590bf9bc7957cee604a186Jeff Hao DCHECK(IsValid()); 3172da882315a61072664f7ce3c212307342e907207Andreas Gampe CHECK_GE(quick_imt_conflict_trampoline_offset_, quick_generic_jni_trampoline_offset_); 31888474b416eb257078e590bf9bc7957cee604a186Jeff Hao return quick_imt_conflict_trampoline_offset_; 31988474b416eb257078e590bf9bc7957cee604a186Jeff Hao} 32088474b416eb257078e590bf9bc7957cee604a186Jeff Hao 32188474b416eb257078e590bf9bc7957cee604a186Jeff Haovoid OatHeader::SetQuickImtConflictTrampolineOffset(uint32_t offset) { 3222da882315a61072664f7ce3c212307342e907207Andreas Gampe CHECK(offset == 0 || offset >= quick_generic_jni_trampoline_offset_); 32388474b416eb257078e590bf9bc7957cee604a186Jeff Hao DCHECK(IsValid()); 32488474b416eb257078e590bf9bc7957cee604a186Jeff Hao DCHECK_EQ(quick_imt_conflict_trampoline_offset_, 0U) << offset; 32588474b416eb257078e590bf9bc7957cee604a186Jeff Hao 32688474b416eb257078e590bf9bc7957cee604a186Jeff Hao quick_imt_conflict_trampoline_offset_ = offset; 32788474b416eb257078e590bf9bc7957cee604a186Jeff Hao} 32888474b416eb257078e590bf9bc7957cee604a186Jeff Hao 3290aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haoconst void* OatHeader::GetQuickResolutionTrampoline() const { 3300aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao return reinterpret_cast<const uint8_t*>(this) + GetQuickResolutionTrampolineOffset(); 3310aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 3320aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 3330aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haouint32_t OatHeader::GetQuickResolutionTrampolineOffset() const { 3340aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 33588474b416eb257078e590bf9bc7957cee604a186Jeff Hao CHECK_GE(quick_resolution_trampoline_offset_, quick_imt_conflict_trampoline_offset_); 3360aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao return quick_resolution_trampoline_offset_; 3370aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 3380aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 3390aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haovoid OatHeader::SetQuickResolutionTrampolineOffset(uint32_t offset) { 34088474b416eb257078e590bf9bc7957cee604a186Jeff Hao CHECK(offset == 0 || offset >= quick_imt_conflict_trampoline_offset_); 3410aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 3420aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK_EQ(quick_resolution_trampoline_offset_, 0U) << offset; 3430aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 3440aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao quick_resolution_trampoline_offset_ = offset; 3450aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 3460aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 347468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetQuickToInterpreterBridge() const { 348468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetQuickToInterpreterBridgeOffset(); 349468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 350468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 351468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetQuickToInterpreterBridgeOffset() const { 352468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 353468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK_GE(quick_to_interpreter_bridge_offset_, quick_resolution_trampoline_offset_); 354468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return quick_to_interpreter_bridge_offset_; 355468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 356468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 357468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetQuickToInterpreterBridgeOffset(uint32_t offset) { 358468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK(offset == 0 || offset >= quick_resolution_trampoline_offset_); 359468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 360468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(quick_to_interpreter_bridge_offset_, 0U) << offset; 361468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 362468532ea115657709bc32ee498e701a4c71762d4Ian Rogers quick_to_interpreter_bridge_offset_ = offset; 363468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 364468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 365a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Lightint32_t OatHeader::GetImagePatchDelta() const { 366a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK(IsValid()); 367a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light return image_patch_delta_; 368a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light} 369a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light 370a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Lightvoid OatHeader::RelocateOat(off_t delta) { 371a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK(IsValid()); 372a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK_ALIGNED(delta, kPageSize); 373a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light image_patch_delta_ += delta; 374a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light if (image_file_location_oat_data_begin_ != 0) { 375a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light image_file_location_oat_data_begin_ += delta; 376a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light } 377a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light} 378a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light 379a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Lightvoid OatHeader::SetImagePatchDelta(int32_t off) { 380a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK(IsValid()); 381a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK_ALIGNED(off, kPageSize); 382a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light image_patch_delta_ = off; 383a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light} 384a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light 38528db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstromuint32_t OatHeader::GetImageFileLocationOatChecksum() const { 38628db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom CHECK(IsValid()); 38728db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom return image_file_location_oat_checksum_; 38828db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom} 38928db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom 39049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Markovoid OatHeader::SetImageFileLocationOatChecksum(uint32_t image_file_location_oat_checksum) { 39149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko CHECK(IsValid()); 39249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko image_file_location_oat_checksum_ = image_file_location_oat_checksum; 39349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko} 39449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 395700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromuint32_t OatHeader::GetImageFileLocationOatDataBegin() const { 39681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom CHECK(IsValid()); 397700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom return image_file_location_oat_data_begin_; 39881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom} 39981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 40049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Markovoid OatHeader::SetImageFileLocationOatDataBegin(uint32_t image_file_location_oat_data_begin) { 40149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko CHECK(IsValid()); 40249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko CHECK_ALIGNED(image_file_location_oat_data_begin, kPageSize); 40349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko image_file_location_oat_data_begin_ = image_file_location_oat_data_begin; 40449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko} 40549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 40622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampeuint32_t OatHeader::GetKeyValueStoreSize() const { 40781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom CHECK(IsValid()); 40822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return key_value_store_size_; 40981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom} 41081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 41122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampeconst uint8_t* OatHeader::GetKeyValueStore() const { 41281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom CHECK(IsValid()); 41322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return key_value_store_; 414c87d27b25994da8670d82a8f7bad6327b693bfffAndreas Gampe} 415c87d27b25994da8670d82a8f7bad6327b693bfffAndreas Gampe 41622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe// Advance start until it is either end or \0. 41722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampestatic const char* ParseString(const char* start, const char* end) { 41822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe while (start < end && *start != 0) { 41922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe start++; 42022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 42122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return start; 42222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 42322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 42422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampeconst char* OatHeader::GetStoreValueByKey(const char* key) const { 42522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* ptr = reinterpret_cast<const char*>(&key_value_store_); 42622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* end = ptr + key_value_store_size_; 42722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 42822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe while (ptr < end) { 42922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Scan for a closing zero. 43022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* str_end = ParseString(ptr, end); 43122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (str_end < end) { 43222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (strcmp(key, ptr) == 0) { 43322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Same as key. Check if value is OK. 43422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (ParseString(str_end + 1, end) < end) { 43522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return str_end + 1; 43622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 43722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 43822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Different from key. Advance over the value. 43922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe ptr = ParseString(str_end + 1, end) + 1; 44022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 44122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 44222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe break; 44322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 44422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 44522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Not found. 44622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return nullptr; 44722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 44822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 44922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampebool OatHeader::GetStoreKeyValuePairByIndex(size_t index, const char** key, 45022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char** value) const { 45122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* ptr = reinterpret_cast<const char*>(&key_value_store_); 45222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* end = ptr + key_value_store_size_; 45322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe ssize_t counter = static_cast<ssize_t>(index); 45422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 45522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe while (ptr < end && counter >= 0) { 45622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Scan for a closing zero. 45722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* str_end = ParseString(ptr, end); 45822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (str_end < end) { 45922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* maybe_key = ptr; 46022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe ptr = ParseString(str_end + 1, end) + 1; 46122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (ptr <= end) { 46222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (counter == 0) { 46322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe *key = maybe_key; 46422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe *value = str_end + 1; 46522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return true; 46622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 46722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe counter--; 46822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 46922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 47022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return false; 47122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 47222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 47322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe break; 47422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 47522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 47622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Not found. 47722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return false; 47822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 47922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 48022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampesize_t OatHeader::GetHeaderSize() const { 48122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return sizeof(OatHeader) + key_value_store_size_; 48222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 48322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 48446774767fcf7780d1455e755729198648d08742eIgor Murashkinbool OatHeader::IsPic() const { 4850de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz return IsKeyEnabled(OatHeader::kPicKey); 4860de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz} 4870de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz 4880de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertzbool OatHeader::IsDebuggable() const { 4890de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz return IsKeyEnabled(OatHeader::kDebuggableKey); 4900de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz} 4910de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz 492f8cd890d86e2a136966d878fea1d0dae6a9c4ad0Andreas Gampebool OatHeader::IsConcurrentCopying() const { 493f8cd890d86e2a136966d878fea1d0dae6a9c4ad0Andreas Gampe return IsKeyEnabled(OatHeader::kConcurrentCopying); 494f8cd890d86e2a136966d878fea1d0dae6a9c4ad0Andreas Gampe} 495f8cd890d86e2a136966d878fea1d0dae6a9c4ad0Andreas Gampe 4965d950769b607b4f76413212db640a32d796911deDavid Srbeckybool OatHeader::IsNativeDebuggable() const { 4975d950769b607b4f76413212db640a32d796911deDavid Srbecky return IsKeyEnabled(OatHeader::kNativeDebuggableKey); 4985d950769b607b4f76413212db640a32d796911deDavid Srbecky} 4995d950769b607b4f76413212db640a32d796911deDavid Srbecky 5007bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeCompilerFilter::Filter OatHeader::GetCompilerFilter() const { 5017bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe CompilerFilter::Filter filter; 5027bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe const char* key_value = GetStoreValueByKey(kCompilerFilter); 5037bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe CHECK(key_value != nullptr) << "compiler-filter not found in oat header"; 5047bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe CHECK(CompilerFilter::ParseCompilerFilter(key_value, &filter)) 5057bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe << "Invalid compiler-filter in oat header: " << key_value; 5067bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe return filter; 507b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle} 508b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle 509b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravlebool OatHeader::KeyHasValue(const char* key, const char* value, size_t value_size) const { 5100de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz const char* key_value = GetStoreValueByKey(key); 511b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle return (key_value != nullptr && strncmp(key_value, value, value_size) == 0); 512b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle} 513b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle 514b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravlebool OatHeader::IsKeyEnabled(const char* key) const { 515b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle return KeyHasValue(key, kTrueValue, sizeof(kTrueValue)); 51646774767fcf7780d1455e755729198648d08742eIgor Murashkin} 51746774767fcf7780d1455e755729198648d08742eIgor Murashkin 51822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampevoid OatHeader::Flatten(const SafeMap<std::string, std::string>* key_value_store) { 51922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe char* data_ptr = reinterpret_cast<char*>(&key_value_store_); 52022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (key_value_store != nullptr) { 52122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string>::const_iterator it = key_value_store->begin(); 52222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string>::const_iterator end = key_value_store->end(); 52322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe for ( ; it != end; ++it) { 524f45d61c0866461c9476f17644b27dc0664d507c5Andreas Gampe strlcpy(data_ptr, it->first.c_str(), it->first.length() + 1); 52522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe data_ptr += it->first.length() + 1; 526f45d61c0866461c9476f17644b27dc0664d507c5Andreas Gampe strlcpy(data_ptr, it->second.c_str(), it->second.length() + 1); 52722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe data_ptr += it->second.length() + 1; 52822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 52922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 53022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe key_value_store_size_ = data_ptr - reinterpret_cast<char*>(&key_value_store_); 53181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom} 53281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 533957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu ChartierOatMethodOffsets::OatMethodOffsets(uint32_t code_offset) : code_offset_(code_offset) { 534957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier} 5353320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 5363320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromOatMethodOffsets::~OatMethodOffsets() {} 5373320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 538e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} // namespace art 539