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 22d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "arch/instruction_set_features.h" 2380afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/bit_utils.h" 242bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe#include "base/stringprintf.h" 25d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 26e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromnamespace art { 27e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 282bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampeconstexpr uint8_t OatHeader::kOatMagic[4]; 292bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampeconstexpr uint8_t OatHeader::kOatVersion[4]; 300de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertzconstexpr const char OatHeader::kTrueValue[]; 310de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertzconstexpr const char OatHeader::kFalseValue[]; 32e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 3322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampestatic size_t ComputeOatHeaderSize(const SafeMap<std::string, std::string>* variable_data) { 3422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe size_t estimate = 0U; 3522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (variable_data != nullptr) { 3622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string>::const_iterator it = variable_data->begin(); 3722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string>::const_iterator end = variable_data->end(); 3822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe for ( ; it != end; ++it) { 3922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe estimate += it->first.length() + 1; 4022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe estimate += it->second.length() + 1; 4122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 4222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 4322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return sizeof(OatHeader) + estimate; 4422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 4522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 4622f8e5c82d12951be38cd893426e13bee33fd69dAndreas GampeOatHeader* OatHeader::Create(InstructionSet instruction_set, 476f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers const InstructionSetFeatures* instruction_set_features, 4849b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko uint32_t dex_file_count, 4922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const SafeMap<std::string, std::string>* variable_data) { 5022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Estimate size of optional data. 5122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe size_t needed_size = ComputeOatHeaderSize(variable_data); 5222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 5322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Reserve enough memory. 5422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe void* memory = operator new (needed_size); 5522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 5622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Create the OatHeader in-place. 5722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return new (memory) OatHeader(instruction_set, 5822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe instruction_set_features, 5949b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko dex_file_count, 6022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe variable_data); 61a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes} 62a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes 6381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian CarlstromOatHeader::OatHeader(InstructionSet instruction_set, 646f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers const InstructionSetFeatures* instruction_set_features, 6549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko uint32_t dex_file_count, 6649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko const SafeMap<std::string, std::string>* variable_data) 6749b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko : adler32_checksum_(adler32(0L, Z_NULL, 0)), 6849b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko instruction_set_(instruction_set), 6949b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko instruction_set_features_bitmap_(instruction_set_features->AsBitmap()), 7049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko dex_file_count_(dex_file_count), 7149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko executable_offset_(0), 7249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko interpreter_to_interpreter_bridge_offset_(0), 7349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko interpreter_to_compiled_code_bridge_offset_(0), 7449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko jni_dlsym_lookup_offset_(0), 7549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko quick_generic_jni_trampoline_offset_(0), 7649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko quick_imt_conflict_trampoline_offset_(0), 7749b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko quick_resolution_trampoline_offset_(0), 7849b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko quick_to_interpreter_bridge_offset_(0), 7949b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko image_patch_delta_(0), 8049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko image_file_location_oat_checksum_(0), 8149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko image_file_location_oat_data_begin_(0) { 822bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe // Don't want asserts in header as they would be checked in each file that includes it. But the 832bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe // fields are private, so we check inside a method. 842bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(magic_) == sizeof(kOatMagic), 852bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe "Oat magic and magic_ have different lengths."); 862bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(version_) == sizeof(kOatVersion), 872bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe "Oat version and version_ have different lengths."); 882bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe 89e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom memcpy(magic_, kOatMagic, sizeof(kOatMagic)); 90e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom memcpy(version_, kOatVersion, sizeof(kOatVersion)); 9181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 92f852fb2921128d3b71a76e6b17c78d10fb7085e2Brian Carlstrom CHECK_NE(instruction_set, kNone); 9381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 9422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Flatten the map. Will also update variable_size_data_size_. 9522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe Flatten(variable_data); 96e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 97e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 98e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatHeader::IsValid() const { 99f852fb2921128d3b71a76e6b17c78d10fb7085e2Brian Carlstrom if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) { 100e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 101e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 102f852fb2921128d3b71a76e6b17c78d10fb7085e2Brian Carlstrom if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) { 103e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 104e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 105a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light if (!IsAligned<kPageSize>(executable_offset_)) { 106a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light return false; 107a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light } 108a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light if (!IsAligned<kPageSize>(image_patch_delta_)) { 109a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light return false; 110a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light } 11109d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko if (!IsValidInstructionSet(instruction_set_)) { 11209d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko return false; 11309d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko } 114e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 115e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 116e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 1172bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampestd::string OatHeader::GetValidationErrorMessage() const { 1182bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) { 1192bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(kOatMagic) == 4, "kOatMagic has unexpected length"); 1202bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return StringPrintf("Invalid oat magic, expected 0x%x%x%x%x, got 0x%x%x%x%x.", 1212bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe kOatMagic[0], kOatMagic[1], kOatMagic[2], kOatMagic[3], 1222bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe magic_[0], magic_[1], magic_[2], magic_[3]); 1232bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 1242bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) { 1252bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(kOatVersion) == 4, "kOatVersion has unexpected length"); 1262bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return StringPrintf("Invalid oat version, expected 0x%x%x%x%x, got 0x%x%x%x%x.", 1272bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe kOatVersion[0], kOatVersion[1], kOatVersion[2], kOatVersion[3], 1282bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe version_[0], version_[1], version_[2], version_[3]); 1292bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 1302bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (!IsAligned<kPageSize>(executable_offset_)) { 1312bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return "Executable offset not page-aligned."; 1322bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 1332bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (!IsAligned<kPageSize>(image_patch_delta_)) { 1342bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return "Image patch delta not page-aligned."; 1352bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 13609d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko if (!IsValidInstructionSet(instruction_set_)) { 13709d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko return StringPrintf("Invalid instruction set, %d.", static_cast<int>(instruction_set_)); 13809d0943f5efe92c1f3a6b9dbdf255adb0f960a22Vladimir Marko } 1392bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return ""; 1402bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe} 1412bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe 142e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromconst char* OatHeader::GetMagic() const { 143e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(IsValid()); 144e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return reinterpret_cast<const char*>(magic_); 145e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 146e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 147e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromuint32_t OatHeader::GetChecksum() const { 148e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(IsValid()); 149e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return adler32_checksum_; 150e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 151e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 15249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Markovoid OatHeader::UpdateChecksumWithHeaderData() { 15349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&instruction_set_, sizeof(instruction_set_)); 15449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&instruction_set_features_bitmap_, sizeof(instruction_set_features_bitmap_)); 15549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&dex_file_count_, sizeof(dex_file_count_)); 15649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&image_file_location_oat_checksum_, sizeof(image_file_location_oat_checksum_)); 15749b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&image_file_location_oat_data_begin_, sizeof(image_file_location_oat_data_begin_)); 15849b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 15949b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko // Update checksum for variable data size. 16049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&key_value_store_size_, sizeof(key_value_store_size_)); 16149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 16249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko // Update for data, if existing. 16349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko if (key_value_store_size_ > 0U) { 16449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&key_value_store_, key_value_store_size_); 16549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko } 16649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 16749b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&executable_offset_, sizeof(executable_offset_)); 16849b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&interpreter_to_interpreter_bridge_offset_, 16949b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(interpreter_to_interpreter_bridge_offset_)); 17049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&interpreter_to_compiled_code_bridge_offset_, 17149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(interpreter_to_compiled_code_bridge_offset_)); 17249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&jni_dlsym_lookup_offset_, sizeof(jni_dlsym_lookup_offset_)); 17349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&quick_generic_jni_trampoline_offset_, 17449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(quick_generic_jni_trampoline_offset_)); 17549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&quick_imt_conflict_trampoline_offset_, 17649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(quick_imt_conflict_trampoline_offset_)); 17749b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&quick_resolution_trampoline_offset_, 17849b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(quick_resolution_trampoline_offset_)); 17949b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko UpdateChecksum(&quick_to_interpreter_bridge_offset_, 18049b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko sizeof(quick_to_interpreter_bridge_offset_)); 18149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko} 18249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 183e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatHeader::UpdateChecksum(const void* data, size_t length) { 184e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom DCHECK(IsValid()); 1852c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao if (data != nullptr) { 1862c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data); 1872c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao adler32_checksum_ = adler32(adler32_checksum_, bytes, length); 1882c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao } else { 1892c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao DCHECK_EQ(0U, length); 1902c6b49498e2f084ce217fcd3327103eadc1e0c37Jeff Hao } 191e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 192e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 193a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott HughesInstructionSet OatHeader::GetInstructionSet() const { 194a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes CHECK(IsValid()); 195a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes return instruction_set_; 196a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes} 197a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes 1986f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogersuint32_t OatHeader::GetInstructionSetFeaturesBitmap() const { 1997020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison CHECK(IsValid()); 2006f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers return instruction_set_features_bitmap_; 2017020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison} 2027020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison 203e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromuint32_t OatHeader::GetExecutableOffset() const { 204e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom DCHECK(IsValid()); 20506b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes DCHECK_ALIGNED(executable_offset_, kPageSize); 206e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK_GT(executable_offset_, sizeof(OatHeader)); 207e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return executable_offset_; 208e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 209e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 2100aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haovoid OatHeader::SetExecutableOffset(uint32_t executable_offset) { 2110aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK_ALIGNED(executable_offset, kPageSize); 2120aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao CHECK_GT(executable_offset, sizeof(OatHeader)); 2130aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 2140aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK_EQ(executable_offset_, 0U); 2150aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 2160aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao executable_offset_ = executable_offset; 2170aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2180aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 219468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetInterpreterToInterpreterBridge() const { 220468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToInterpreterBridgeOffset(); 2210aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2220aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 223468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetInterpreterToInterpreterBridgeOffset() const { 2240aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 225c6104ae36351591157fa09c482796256f82daddcDave Allison CHECK(interpreter_to_interpreter_bridge_offset_ == 0 || 226c6104ae36351591157fa09c482796256f82daddcDave Allison interpreter_to_interpreter_bridge_offset_ >= executable_offset_); 227468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return interpreter_to_interpreter_bridge_offset_; 2280aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2290aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 230468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetInterpreterToInterpreterBridgeOffset(uint32_t offset) { 2310aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao CHECK(offset == 0 || offset >= executable_offset_); 2320aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 233468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(interpreter_to_interpreter_bridge_offset_, 0U) << offset; 2340aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 235468532ea115657709bc32ee498e701a4c71762d4Ian Rogers interpreter_to_interpreter_bridge_offset_ = offset; 2360aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2370aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 238468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetInterpreterToCompiledCodeBridge() const { 239468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToCompiledCodeBridgeOffset(); 2400aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2410aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 242468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetInterpreterToCompiledCodeBridgeOffset() const { 2430aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 244468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK_GE(interpreter_to_compiled_code_bridge_offset_, interpreter_to_interpreter_bridge_offset_); 245468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return interpreter_to_compiled_code_bridge_offset_; 2460aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2470aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 248468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetInterpreterToCompiledCodeBridgeOffset(uint32_t offset) { 249468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK(offset == 0 || offset >= interpreter_to_interpreter_bridge_offset_); 2500aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 251468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(interpreter_to_compiled_code_bridge_offset_, 0U) << offset; 2520aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 253468532ea115657709bc32ee498e701a4c71762d4Ian Rogers interpreter_to_compiled_code_bridge_offset_ = offset; 254468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 255468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 256468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetJniDlsymLookup() const { 257468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetJniDlsymLookupOffset(); 258468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 259468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 260468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetJniDlsymLookupOffset() const { 261468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 262468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK_GE(jni_dlsym_lookup_offset_, interpreter_to_compiled_code_bridge_offset_); 263468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return jni_dlsym_lookup_offset_; 264468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 265468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 266468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetJniDlsymLookupOffset(uint32_t offset) { 267468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK(offset == 0 || offset >= interpreter_to_compiled_code_bridge_offset_); 268468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 269468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(jni_dlsym_lookup_offset_, 0U) << offset; 270468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 271468532ea115657709bc32ee498e701a4c71762d4Ian Rogers jni_dlsym_lookup_offset_ = offset; 2720aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2730aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 2742da882315a61072664f7ce3c212307342e907207Andreas Gampeconst void* OatHeader::GetQuickGenericJniTrampoline() const { 2752da882315a61072664f7ce3c212307342e907207Andreas Gampe return reinterpret_cast<const uint8_t*>(this) + GetQuickGenericJniTrampolineOffset(); 2762da882315a61072664f7ce3c212307342e907207Andreas Gampe} 2772da882315a61072664f7ce3c212307342e907207Andreas Gampe 2782da882315a61072664f7ce3c212307342e907207Andreas Gampeuint32_t OatHeader::GetQuickGenericJniTrampolineOffset() const { 2792da882315a61072664f7ce3c212307342e907207Andreas Gampe DCHECK(IsValid()); 280956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes CHECK_GE(quick_generic_jni_trampoline_offset_, jni_dlsym_lookup_offset_); 2812da882315a61072664f7ce3c212307342e907207Andreas Gampe return quick_generic_jni_trampoline_offset_; 2822da882315a61072664f7ce3c212307342e907207Andreas Gampe} 2832da882315a61072664f7ce3c212307342e907207Andreas Gampe 2842da882315a61072664f7ce3c212307342e907207Andreas Gampevoid OatHeader::SetQuickGenericJniTrampolineOffset(uint32_t offset) { 285956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes CHECK(offset == 0 || offset >= jni_dlsym_lookup_offset_); 2862da882315a61072664f7ce3c212307342e907207Andreas Gampe DCHECK(IsValid()); 2872da882315a61072664f7ce3c212307342e907207Andreas Gampe DCHECK_EQ(quick_generic_jni_trampoline_offset_, 0U) << offset; 2882da882315a61072664f7ce3c212307342e907207Andreas Gampe 2892da882315a61072664f7ce3c212307342e907207Andreas Gampe quick_generic_jni_trampoline_offset_ = offset; 2902da882315a61072664f7ce3c212307342e907207Andreas Gampe} 2912da882315a61072664f7ce3c212307342e907207Andreas Gampe 29288474b416eb257078e590bf9bc7957cee604a186Jeff Haoconst void* OatHeader::GetQuickImtConflictTrampoline() const { 29388474b416eb257078e590bf9bc7957cee604a186Jeff Hao return reinterpret_cast<const uint8_t*>(this) + GetQuickImtConflictTrampolineOffset(); 29488474b416eb257078e590bf9bc7957cee604a186Jeff Hao} 29588474b416eb257078e590bf9bc7957cee604a186Jeff Hao 29688474b416eb257078e590bf9bc7957cee604a186Jeff Haouint32_t OatHeader::GetQuickImtConflictTrampolineOffset() const { 29788474b416eb257078e590bf9bc7957cee604a186Jeff Hao DCHECK(IsValid()); 2982da882315a61072664f7ce3c212307342e907207Andreas Gampe CHECK_GE(quick_imt_conflict_trampoline_offset_, quick_generic_jni_trampoline_offset_); 29988474b416eb257078e590bf9bc7957cee604a186Jeff Hao return quick_imt_conflict_trampoline_offset_; 30088474b416eb257078e590bf9bc7957cee604a186Jeff Hao} 30188474b416eb257078e590bf9bc7957cee604a186Jeff Hao 30288474b416eb257078e590bf9bc7957cee604a186Jeff Haovoid OatHeader::SetQuickImtConflictTrampolineOffset(uint32_t offset) { 3032da882315a61072664f7ce3c212307342e907207Andreas Gampe CHECK(offset == 0 || offset >= quick_generic_jni_trampoline_offset_); 30488474b416eb257078e590bf9bc7957cee604a186Jeff Hao DCHECK(IsValid()); 30588474b416eb257078e590bf9bc7957cee604a186Jeff Hao DCHECK_EQ(quick_imt_conflict_trampoline_offset_, 0U) << offset; 30688474b416eb257078e590bf9bc7957cee604a186Jeff Hao 30788474b416eb257078e590bf9bc7957cee604a186Jeff Hao quick_imt_conflict_trampoline_offset_ = offset; 30888474b416eb257078e590bf9bc7957cee604a186Jeff Hao} 30988474b416eb257078e590bf9bc7957cee604a186Jeff Hao 3100aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haoconst void* OatHeader::GetQuickResolutionTrampoline() const { 3110aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao return reinterpret_cast<const uint8_t*>(this) + GetQuickResolutionTrampolineOffset(); 3120aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 3130aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 3140aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haouint32_t OatHeader::GetQuickResolutionTrampolineOffset() const { 3150aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 31688474b416eb257078e590bf9bc7957cee604a186Jeff Hao CHECK_GE(quick_resolution_trampoline_offset_, quick_imt_conflict_trampoline_offset_); 3170aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao return quick_resolution_trampoline_offset_; 3180aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 3190aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 3200aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haovoid OatHeader::SetQuickResolutionTrampolineOffset(uint32_t offset) { 32188474b416eb257078e590bf9bc7957cee604a186Jeff Hao CHECK(offset == 0 || offset >= quick_imt_conflict_trampoline_offset_); 3220aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 3230aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK_EQ(quick_resolution_trampoline_offset_, 0U) << offset; 3240aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 3250aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao quick_resolution_trampoline_offset_ = offset; 3260aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 3270aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 328468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetQuickToInterpreterBridge() const { 329468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetQuickToInterpreterBridgeOffset(); 330468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 331468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 332468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetQuickToInterpreterBridgeOffset() const { 333468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 334468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK_GE(quick_to_interpreter_bridge_offset_, quick_resolution_trampoline_offset_); 335468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return quick_to_interpreter_bridge_offset_; 336468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 337468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 338468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetQuickToInterpreterBridgeOffset(uint32_t offset) { 339468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK(offset == 0 || offset >= quick_resolution_trampoline_offset_); 340468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 341468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(quick_to_interpreter_bridge_offset_, 0U) << offset; 342468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 343468532ea115657709bc32ee498e701a4c71762d4Ian Rogers quick_to_interpreter_bridge_offset_ = offset; 344468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 345468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 346a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Lightint32_t OatHeader::GetImagePatchDelta() const { 347a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK(IsValid()); 348a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light return image_patch_delta_; 349a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light} 350a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light 351a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Lightvoid OatHeader::RelocateOat(off_t delta) { 352a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK(IsValid()); 353a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK_ALIGNED(delta, kPageSize); 354a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light image_patch_delta_ += delta; 355a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light if (image_file_location_oat_data_begin_ != 0) { 356a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light image_file_location_oat_data_begin_ += delta; 357a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light } 358a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light} 359a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light 360a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Lightvoid OatHeader::SetImagePatchDelta(int32_t off) { 361a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK(IsValid()); 362a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK_ALIGNED(off, kPageSize); 363a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light image_patch_delta_ = off; 364a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light} 365a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light 36628db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstromuint32_t OatHeader::GetImageFileLocationOatChecksum() const { 36728db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom CHECK(IsValid()); 36828db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom return image_file_location_oat_checksum_; 36928db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom} 37028db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom 37149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Markovoid OatHeader::SetImageFileLocationOatChecksum(uint32_t image_file_location_oat_checksum) { 37249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko CHECK(IsValid()); 37349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko image_file_location_oat_checksum_ = image_file_location_oat_checksum; 37449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko} 37549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 376700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromuint32_t OatHeader::GetImageFileLocationOatDataBegin() const { 37781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom CHECK(IsValid()); 378700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom return image_file_location_oat_data_begin_; 37981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom} 38081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 38149b0f45d5a9023653ab00c355735910aa51ee0baVladimir Markovoid OatHeader::SetImageFileLocationOatDataBegin(uint32_t image_file_location_oat_data_begin) { 38249b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko CHECK(IsValid()); 38349b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko CHECK_ALIGNED(image_file_location_oat_data_begin, kPageSize); 38449b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko image_file_location_oat_data_begin_ = image_file_location_oat_data_begin; 38549b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko} 38649b0f45d5a9023653ab00c355735910aa51ee0baVladimir Marko 38722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampeuint32_t OatHeader::GetKeyValueStoreSize() const { 38881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom CHECK(IsValid()); 38922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return key_value_store_size_; 39081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom} 39181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 39222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampeconst uint8_t* OatHeader::GetKeyValueStore() const { 39381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom CHECK(IsValid()); 39422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return key_value_store_; 395c87d27b25994da8670d82a8f7bad6327b693bfffAndreas Gampe} 396c87d27b25994da8670d82a8f7bad6327b693bfffAndreas Gampe 39722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe// Advance start until it is either end or \0. 39822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampestatic const char* ParseString(const char* start, const char* end) { 39922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe while (start < end && *start != 0) { 40022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe start++; 40122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 40222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return start; 40322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 40422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 40522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampeconst char* OatHeader::GetStoreValueByKey(const char* key) const { 40622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* ptr = reinterpret_cast<const char*>(&key_value_store_); 40722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* end = ptr + key_value_store_size_; 40822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 40922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe while (ptr < end) { 41022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Scan for a closing zero. 41122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* str_end = ParseString(ptr, end); 41222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (str_end < end) { 41322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (strcmp(key, ptr) == 0) { 41422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Same as key. Check if value is OK. 41522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (ParseString(str_end + 1, end) < end) { 41622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return str_end + 1; 41722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 41822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 41922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Different from key. Advance over the value. 42022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe ptr = ParseString(str_end + 1, end) + 1; 42122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 42222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 42322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe break; 42422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 42522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 42622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Not found. 42722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return nullptr; 42822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 42922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 43022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampebool OatHeader::GetStoreKeyValuePairByIndex(size_t index, const char** key, 43122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char** value) const { 43222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* ptr = reinterpret_cast<const char*>(&key_value_store_); 43322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* end = ptr + key_value_store_size_; 43422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe ssize_t counter = static_cast<ssize_t>(index); 43522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 43622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe while (ptr < end && counter >= 0) { 43722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Scan for a closing zero. 43822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* str_end = ParseString(ptr, end); 43922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (str_end < end) { 44022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* maybe_key = ptr; 44122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe ptr = ParseString(str_end + 1, end) + 1; 44222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (ptr <= end) { 44322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (counter == 0) { 44422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe *key = maybe_key; 44522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe *value = str_end + 1; 44622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return true; 44722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 44822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe counter--; 44922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 45022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 45122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return false; 45222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 45322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 45422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe break; 45522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 45622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 45722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Not found. 45822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return false; 45922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 46022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 46122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampesize_t OatHeader::GetHeaderSize() const { 46222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return sizeof(OatHeader) + key_value_store_size_; 46322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 46422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 46546774767fcf7780d1455e755729198648d08742eIgor Murashkinbool OatHeader::IsPic() const { 4660de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz return IsKeyEnabled(OatHeader::kPicKey); 4670de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz} 4680de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz 4691c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhlerbool OatHeader::HasPatchInfo() const { 4701c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler return IsKeyEnabled(OatHeader::kHasPatchInfoKey); 4711c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler} 4721c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler 4730de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertzbool OatHeader::IsDebuggable() const { 4740de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz return IsKeyEnabled(OatHeader::kDebuggableKey); 4750de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz} 4760de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz 4775d950769b607b4f76413212db640a32d796911deDavid Srbeckybool OatHeader::IsNativeDebuggable() const { 4785d950769b607b4f76413212db640a32d796911deDavid Srbecky return IsKeyEnabled(OatHeader::kNativeDebuggableKey); 4795d950769b607b4f76413212db640a32d796911deDavid Srbecky} 4805d950769b607b4f76413212db640a32d796911deDavid Srbecky 4817bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeCompilerFilter::Filter OatHeader::GetCompilerFilter() const { 4827bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe CompilerFilter::Filter filter; 4837bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe const char* key_value = GetStoreValueByKey(kCompilerFilter); 4847bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe CHECK(key_value != nullptr) << "compiler-filter not found in oat header"; 4857bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe CHECK(CompilerFilter::ParseCompilerFilter(key_value, &filter)) 4867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe << "Invalid compiler-filter in oat header: " << key_value; 4877bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe return filter; 488b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle} 489b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle 490b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravlebool OatHeader::KeyHasValue(const char* key, const char* value, size_t value_size) const { 4910de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz const char* key_value = GetStoreValueByKey(key); 492b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle return (key_value != nullptr && strncmp(key_value, value, value_size) == 0); 493b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle} 494b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle 495b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravlebool OatHeader::IsKeyEnabled(const char* key) const { 496b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle return KeyHasValue(key, kTrueValue, sizeof(kTrueValue)); 49746774767fcf7780d1455e755729198648d08742eIgor Murashkin} 49846774767fcf7780d1455e755729198648d08742eIgor Murashkin 49922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampevoid OatHeader::Flatten(const SafeMap<std::string, std::string>* key_value_store) { 50022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe char* data_ptr = reinterpret_cast<char*>(&key_value_store_); 50122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (key_value_store != nullptr) { 50222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string>::const_iterator it = key_value_store->begin(); 50322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string>::const_iterator end = key_value_store->end(); 50422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe for ( ; it != end; ++it) { 50522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe strcpy(data_ptr, it->first.c_str()); 50622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe data_ptr += it->first.length() + 1; 50722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe strcpy(data_ptr, it->second.c_str()); 50822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe data_ptr += it->second.length() + 1; 50922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 51022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 51122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe key_value_store_size_ = data_ptr - reinterpret_cast<char*>(&key_value_store_); 51281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom} 51381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 514957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu ChartierOatMethodOffsets::OatMethodOffsets(uint32_t code_offset) : code_offset_(code_offset) { 515957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier} 5163320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 5173320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromOatMethodOffsets::~OatMethodOffsets() {} 5183320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 519e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} // namespace art 520