oat.cc revision 80afd02024d20e60b197d3adfbb43cc303cf29e0
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, 4822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const std::vector<const DexFile*>* dex_files, 4922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe uint32_t image_file_location_oat_checksum, 5022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe uint32_t image_file_location_oat_data_begin, 5122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const SafeMap<std::string, std::string>* variable_data) { 5222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Estimate size of optional data. 5322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe size_t needed_size = ComputeOatHeaderSize(variable_data); 5422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 5522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Reserve enough memory. 5622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe void* memory = operator new (needed_size); 5722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 5822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Create the OatHeader in-place. 5922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return new (memory) OatHeader(instruction_set, 6022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe instruction_set_features, 6122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe dex_files, 6222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe image_file_location_oat_checksum, 6322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe image_file_location_oat_data_begin, 6422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe variable_data); 65a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes} 66a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes 6781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian CarlstromOatHeader::OatHeader(InstructionSet instruction_set, 686f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers const InstructionSetFeatures* instruction_set_features, 6981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom const std::vector<const DexFile*>* dex_files, 7028db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom uint32_t image_file_location_oat_checksum, 71700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom uint32_t image_file_location_oat_data_begin, 7222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const SafeMap<std::string, std::string>* variable_data) { 732bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe // Don't want asserts in header as they would be checked in each file that includes it. But the 742bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe // fields are private, so we check inside a method. 752bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(magic_) == sizeof(kOatMagic), 762bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe "Oat magic and magic_ have different lengths."); 772bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(version_) == sizeof(kOatVersion), 782bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe "Oat version and version_ have different lengths."); 792bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe 80e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom memcpy(magic_, kOatMagic, sizeof(kOatMagic)); 81e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom memcpy(version_, kOatVersion, sizeof(kOatVersion)); 82a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light executable_offset_ = 0; 83a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light image_patch_delta_ = 0; 8481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 85e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom adler32_checksum_ = adler32(0L, Z_NULL, 0); 8681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 87f852fb2921128d3b71a76e6b17c78d10fb7085e2Brian Carlstrom CHECK_NE(instruction_set, kNone); 88a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes instruction_set_ = instruction_set; 89a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes UpdateChecksum(&instruction_set_, sizeof(instruction_set_)); 9081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 916f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers instruction_set_features_bitmap_ = instruction_set_features->AsBitmap(); 926f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers UpdateChecksum(&instruction_set_features_bitmap_, sizeof(instruction_set_features_bitmap_)); 937020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison 94e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom dex_file_count_ = dex_files->size(); 95e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom UpdateChecksum(&dex_file_count_, sizeof(dex_file_count_)); 9681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 9728db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom image_file_location_oat_checksum_ = image_file_location_oat_checksum; 9828db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom UpdateChecksum(&image_file_location_oat_checksum_, sizeof(image_file_location_oat_checksum_)); 9928db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom 100700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom CHECK(IsAligned<kPageSize>(image_file_location_oat_data_begin)); 101700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom image_file_location_oat_data_begin_ = image_file_location_oat_data_begin; 102700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom UpdateChecksum(&image_file_location_oat_data_begin_, sizeof(image_file_location_oat_data_begin_)); 10381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 10422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Flatten the map. Will also update variable_size_data_size_. 10522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe Flatten(variable_data); 10622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 10722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Update checksum for variable data size. 10822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe UpdateChecksum(&key_value_store_size_, sizeof(key_value_store_size_)); 10922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 11022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Update for data, if existing. 11122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (key_value_store_size_ > 0U) { 11222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe UpdateChecksum(&key_value_store_, key_value_store_size_); 11322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 11481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 115468532ea115657709bc32ee498e701a4c71762d4Ian Rogers interpreter_to_interpreter_bridge_offset_ = 0; 116468532ea115657709bc32ee498e701a4c71762d4Ian Rogers interpreter_to_compiled_code_bridge_offset_ = 0; 117468532ea115657709bc32ee498e701a4c71762d4Ian Rogers jni_dlsym_lookup_offset_ = 0; 1182da882315a61072664f7ce3c212307342e907207Andreas Gampe quick_generic_jni_trampoline_offset_ = 0; 11988474b416eb257078e590bf9bc7957cee604a186Jeff Hao quick_imt_conflict_trampoline_offset_ = 0; 1200aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao quick_resolution_trampoline_offset_ = 0; 121468532ea115657709bc32ee498e701a4c71762d4Ian Rogers quick_to_interpreter_bridge_offset_ = 0; 122e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 123e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 124e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatHeader::IsValid() const { 125f852fb2921128d3b71a76e6b17c78d10fb7085e2Brian Carlstrom if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) { 126e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 127e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 128f852fb2921128d3b71a76e6b17c78d10fb7085e2Brian Carlstrom if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) { 129e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return false; 130e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 131a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light if (!IsAligned<kPageSize>(executable_offset_)) { 132a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light return false; 133a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light } 134a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light if (!IsAligned<kPageSize>(image_patch_delta_)) { 135a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light return false; 136a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light } 137e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return true; 138e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 139e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 1402bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampestd::string OatHeader::GetValidationErrorMessage() const { 1412bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) { 1422bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(kOatMagic) == 4, "kOatMagic has unexpected length"); 1432bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return StringPrintf("Invalid oat magic, expected 0x%x%x%x%x, got 0x%x%x%x%x.", 1442bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe kOatMagic[0], kOatMagic[1], kOatMagic[2], kOatMagic[3], 1452bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe magic_[0], magic_[1], magic_[2], magic_[3]); 1462bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 1472bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) { 1482bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe static_assert(sizeof(kOatVersion) == 4, "kOatVersion has unexpected length"); 1492bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return StringPrintf("Invalid oat version, expected 0x%x%x%x%x, got 0x%x%x%x%x.", 1502bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe kOatVersion[0], kOatVersion[1], kOatVersion[2], kOatVersion[3], 1512bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe version_[0], version_[1], version_[2], version_[3]); 1522bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 1532bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (!IsAligned<kPageSize>(executable_offset_)) { 1542bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return "Executable offset not page-aligned."; 1552bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 1562bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe if (!IsAligned<kPageSize>(image_patch_delta_)) { 1572bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return "Image patch delta not page-aligned."; 1582bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe } 1592bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe return ""; 1602bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe} 1612bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5Andreas Gampe 162e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromconst char* OatHeader::GetMagic() const { 163e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(IsValid()); 164e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return reinterpret_cast<const char*>(magic_); 165e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 166e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 167e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromuint32_t OatHeader::GetChecksum() const { 168e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(IsValid()); 169e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return adler32_checksum_; 170e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 171e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 172e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatHeader::UpdateChecksum(const void* data, size_t length) { 173e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom DCHECK(IsValid()); 174e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data); 175e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom adler32_checksum_ = adler32(adler32_checksum_, bytes, length); 176e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 177e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 178a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott HughesInstructionSet OatHeader::GetInstructionSet() const { 179a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes CHECK(IsValid()); 180a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes return instruction_set_; 181a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes} 182a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes 1836f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogersuint32_t OatHeader::GetInstructionSetFeaturesBitmap() const { 1847020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison CHECK(IsValid()); 1856f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers return instruction_set_features_bitmap_; 1867020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison} 1877020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison 188e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromuint32_t OatHeader::GetExecutableOffset() const { 189e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom DCHECK(IsValid()); 19006b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes DCHECK_ALIGNED(executable_offset_, kPageSize); 191e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK_GT(executable_offset_, sizeof(OatHeader)); 192e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return executable_offset_; 193e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 194e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 1950aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haovoid OatHeader::SetExecutableOffset(uint32_t executable_offset) { 1960aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK_ALIGNED(executable_offset, kPageSize); 1970aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao CHECK_GT(executable_offset, sizeof(OatHeader)); 1980aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 1990aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK_EQ(executable_offset_, 0U); 2000aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 2010aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao executable_offset_ = executable_offset; 2020aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao UpdateChecksum(&executable_offset_, sizeof(executable_offset)); 2030aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2040aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 205468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetInterpreterToInterpreterBridge() const { 206468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToInterpreterBridgeOffset(); 2070aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2080aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 209468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetInterpreterToInterpreterBridgeOffset() const { 2100aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 211c6104ae36351591157fa09c482796256f82daddcDave Allison CHECK(interpreter_to_interpreter_bridge_offset_ == 0 || 212c6104ae36351591157fa09c482796256f82daddcDave Allison interpreter_to_interpreter_bridge_offset_ >= executable_offset_); 213468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return interpreter_to_interpreter_bridge_offset_; 2140aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2150aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 216468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetInterpreterToInterpreterBridgeOffset(uint32_t offset) { 2170aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao CHECK(offset == 0 || offset >= executable_offset_); 2180aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 219468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(interpreter_to_interpreter_bridge_offset_, 0U) << offset; 2200aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 221468532ea115657709bc32ee498e701a4c71762d4Ian Rogers interpreter_to_interpreter_bridge_offset_ = offset; 222468532ea115657709bc32ee498e701a4c71762d4Ian Rogers UpdateChecksum(&interpreter_to_interpreter_bridge_offset_, sizeof(offset)); 2230aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2240aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 225468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetInterpreterToCompiledCodeBridge() const { 226468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetInterpreterToCompiledCodeBridgeOffset(); 2270aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2280aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 229468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetInterpreterToCompiledCodeBridgeOffset() const { 2300aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 231468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK_GE(interpreter_to_compiled_code_bridge_offset_, interpreter_to_interpreter_bridge_offset_); 232468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return interpreter_to_compiled_code_bridge_offset_; 2330aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2340aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 235468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetInterpreterToCompiledCodeBridgeOffset(uint32_t offset) { 236468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK(offset == 0 || offset >= interpreter_to_interpreter_bridge_offset_); 2370aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 238468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(interpreter_to_compiled_code_bridge_offset_, 0U) << offset; 2390aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 240468532ea115657709bc32ee498e701a4c71762d4Ian Rogers interpreter_to_compiled_code_bridge_offset_ = offset; 241468532ea115657709bc32ee498e701a4c71762d4Ian Rogers UpdateChecksum(&interpreter_to_compiled_code_bridge_offset_, sizeof(offset)); 242468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 243468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 244468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetJniDlsymLookup() const { 245468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetJniDlsymLookupOffset(); 246468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 247468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 248468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetJniDlsymLookupOffset() const { 249468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 250468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK_GE(jni_dlsym_lookup_offset_, interpreter_to_compiled_code_bridge_offset_); 251468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return jni_dlsym_lookup_offset_; 252468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 253468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 254468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetJniDlsymLookupOffset(uint32_t offset) { 255468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK(offset == 0 || offset >= interpreter_to_compiled_code_bridge_offset_); 256468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 257468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(jni_dlsym_lookup_offset_, 0U) << offset; 258468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 259468532ea115657709bc32ee498e701a4c71762d4Ian Rogers jni_dlsym_lookup_offset_ = offset; 260468532ea115657709bc32ee498e701a4c71762d4Ian Rogers UpdateChecksum(&jni_dlsym_lookup_offset_, sizeof(offset)); 2610aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 2620aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 2632da882315a61072664f7ce3c212307342e907207Andreas Gampeconst void* OatHeader::GetQuickGenericJniTrampoline() const { 2642da882315a61072664f7ce3c212307342e907207Andreas Gampe return reinterpret_cast<const uint8_t*>(this) + GetQuickGenericJniTrampolineOffset(); 2652da882315a61072664f7ce3c212307342e907207Andreas Gampe} 2662da882315a61072664f7ce3c212307342e907207Andreas Gampe 2672da882315a61072664f7ce3c212307342e907207Andreas Gampeuint32_t OatHeader::GetQuickGenericJniTrampolineOffset() const { 2682da882315a61072664f7ce3c212307342e907207Andreas Gampe DCHECK(IsValid()); 269956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes CHECK_GE(quick_generic_jni_trampoline_offset_, jni_dlsym_lookup_offset_); 2702da882315a61072664f7ce3c212307342e907207Andreas Gampe return quick_generic_jni_trampoline_offset_; 2712da882315a61072664f7ce3c212307342e907207Andreas Gampe} 2722da882315a61072664f7ce3c212307342e907207Andreas Gampe 2732da882315a61072664f7ce3c212307342e907207Andreas Gampevoid OatHeader::SetQuickGenericJniTrampolineOffset(uint32_t offset) { 274956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes CHECK(offset == 0 || offset >= jni_dlsym_lookup_offset_); 2752da882315a61072664f7ce3c212307342e907207Andreas Gampe DCHECK(IsValid()); 2762da882315a61072664f7ce3c212307342e907207Andreas Gampe DCHECK_EQ(quick_generic_jni_trampoline_offset_, 0U) << offset; 2772da882315a61072664f7ce3c212307342e907207Andreas Gampe 2782da882315a61072664f7ce3c212307342e907207Andreas Gampe quick_generic_jni_trampoline_offset_ = offset; 2792da882315a61072664f7ce3c212307342e907207Andreas Gampe UpdateChecksum(&quick_generic_jni_trampoline_offset_, sizeof(offset)); 2802da882315a61072664f7ce3c212307342e907207Andreas Gampe} 2812da882315a61072664f7ce3c212307342e907207Andreas Gampe 28288474b416eb257078e590bf9bc7957cee604a186Jeff Haoconst void* OatHeader::GetQuickImtConflictTrampoline() const { 28388474b416eb257078e590bf9bc7957cee604a186Jeff Hao return reinterpret_cast<const uint8_t*>(this) + GetQuickImtConflictTrampolineOffset(); 28488474b416eb257078e590bf9bc7957cee604a186Jeff Hao} 28588474b416eb257078e590bf9bc7957cee604a186Jeff Hao 28688474b416eb257078e590bf9bc7957cee604a186Jeff Haouint32_t OatHeader::GetQuickImtConflictTrampolineOffset() const { 28788474b416eb257078e590bf9bc7957cee604a186Jeff Hao DCHECK(IsValid()); 2882da882315a61072664f7ce3c212307342e907207Andreas Gampe CHECK_GE(quick_imt_conflict_trampoline_offset_, quick_generic_jni_trampoline_offset_); 28988474b416eb257078e590bf9bc7957cee604a186Jeff Hao return quick_imt_conflict_trampoline_offset_; 29088474b416eb257078e590bf9bc7957cee604a186Jeff Hao} 29188474b416eb257078e590bf9bc7957cee604a186Jeff Hao 29288474b416eb257078e590bf9bc7957cee604a186Jeff Haovoid OatHeader::SetQuickImtConflictTrampolineOffset(uint32_t offset) { 2932da882315a61072664f7ce3c212307342e907207Andreas Gampe CHECK(offset == 0 || offset >= quick_generic_jni_trampoline_offset_); 29488474b416eb257078e590bf9bc7957cee604a186Jeff Hao DCHECK(IsValid()); 29588474b416eb257078e590bf9bc7957cee604a186Jeff Hao DCHECK_EQ(quick_imt_conflict_trampoline_offset_, 0U) << offset; 29688474b416eb257078e590bf9bc7957cee604a186Jeff Hao 29788474b416eb257078e590bf9bc7957cee604a186Jeff Hao quick_imt_conflict_trampoline_offset_ = offset; 29888474b416eb257078e590bf9bc7957cee604a186Jeff Hao UpdateChecksum(&quick_imt_conflict_trampoline_offset_, sizeof(offset)); 29988474b416eb257078e590bf9bc7957cee604a186Jeff Hao} 30088474b416eb257078e590bf9bc7957cee604a186Jeff Hao 3010aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haoconst void* OatHeader::GetQuickResolutionTrampoline() const { 3020aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao return reinterpret_cast<const uint8_t*>(this) + GetQuickResolutionTrampolineOffset(); 3030aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 3040aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 3050aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haouint32_t OatHeader::GetQuickResolutionTrampolineOffset() const { 3060aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 30788474b416eb257078e590bf9bc7957cee604a186Jeff Hao CHECK_GE(quick_resolution_trampoline_offset_, quick_imt_conflict_trampoline_offset_); 3080aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao return quick_resolution_trampoline_offset_; 3090aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 3100aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 3110aba0ba155bef7346bde19e53581200b89ae8a7aJeff Haovoid OatHeader::SetQuickResolutionTrampolineOffset(uint32_t offset) { 31288474b416eb257078e590bf9bc7957cee604a186Jeff Hao CHECK(offset == 0 || offset >= quick_imt_conflict_trampoline_offset_); 3130aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK(IsValid()); 3140aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao DCHECK_EQ(quick_resolution_trampoline_offset_, 0U) << offset; 3150aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 3160aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao quick_resolution_trampoline_offset_ = offset; 3170aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao UpdateChecksum(&quick_resolution_trampoline_offset_, sizeof(offset)); 3180aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao} 3190aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao 320468532ea115657709bc32ee498e701a4c71762d4Ian Rogersconst void* OatHeader::GetQuickToInterpreterBridge() const { 321468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return reinterpret_cast<const uint8_t*>(this) + GetQuickToInterpreterBridgeOffset(); 322468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 323468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 324468532ea115657709bc32ee498e701a4c71762d4Ian Rogersuint32_t OatHeader::GetQuickToInterpreterBridgeOffset() const { 325468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 326468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK_GE(quick_to_interpreter_bridge_offset_, quick_resolution_trampoline_offset_); 327468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return quick_to_interpreter_bridge_offset_; 328468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 329468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 330468532ea115657709bc32ee498e701a4c71762d4Ian Rogersvoid OatHeader::SetQuickToInterpreterBridgeOffset(uint32_t offset) { 331468532ea115657709bc32ee498e701a4c71762d4Ian Rogers CHECK(offset == 0 || offset >= quick_resolution_trampoline_offset_); 332468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK(IsValid()); 333468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DCHECK_EQ(quick_to_interpreter_bridge_offset_, 0U) << offset; 334468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 335468532ea115657709bc32ee498e701a4c71762d4Ian Rogers quick_to_interpreter_bridge_offset_ = offset; 336468532ea115657709bc32ee498e701a4c71762d4Ian Rogers UpdateChecksum(&quick_to_interpreter_bridge_offset_, sizeof(offset)); 337468532ea115657709bc32ee498e701a4c71762d4Ian Rogers} 338468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 339a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Lightint32_t OatHeader::GetImagePatchDelta() const { 340a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK(IsValid()); 341a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light return image_patch_delta_; 342a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light} 343a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light 344a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Lightvoid OatHeader::RelocateOat(off_t delta) { 345a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK(IsValid()); 346a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK_ALIGNED(delta, kPageSize); 347a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light image_patch_delta_ += delta; 348a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light if (image_file_location_oat_data_begin_ != 0) { 349a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light image_file_location_oat_data_begin_ += delta; 350a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light } 351a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light} 352a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light 353a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Lightvoid OatHeader::SetImagePatchDelta(int32_t off) { 354a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK(IsValid()); 355a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light CHECK_ALIGNED(off, kPageSize); 356a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light image_patch_delta_ = off; 357a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light} 358a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light 35928db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstromuint32_t OatHeader::GetImageFileLocationOatChecksum() const { 36028db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom CHECK(IsValid()); 36128db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom return image_file_location_oat_checksum_; 36228db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom} 36328db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom 364700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromuint32_t OatHeader::GetImageFileLocationOatDataBegin() const { 36581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom CHECK(IsValid()); 366700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom return image_file_location_oat_data_begin_; 36781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom} 36881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 36922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampeuint32_t OatHeader::GetKeyValueStoreSize() const { 37081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom CHECK(IsValid()); 37122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return key_value_store_size_; 37281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom} 37381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 37422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampeconst uint8_t* OatHeader::GetKeyValueStore() const { 37581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom CHECK(IsValid()); 37622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return key_value_store_; 377c87d27b25994da8670d82a8f7bad6327b693bfffAndreas Gampe} 378c87d27b25994da8670d82a8f7bad6327b693bfffAndreas Gampe 37922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe// Advance start until it is either end or \0. 38022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampestatic const char* ParseString(const char* start, const char* end) { 38122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe while (start < end && *start != 0) { 38222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe start++; 38322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 38422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return start; 38522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 38622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 38722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampeconst char* OatHeader::GetStoreValueByKey(const char* key) const { 38822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* ptr = reinterpret_cast<const char*>(&key_value_store_); 38922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* end = ptr + key_value_store_size_; 39022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 39122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe while (ptr < end) { 39222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Scan for a closing zero. 39322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* str_end = ParseString(ptr, end); 39422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (str_end < end) { 39522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (strcmp(key, ptr) == 0) { 39622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Same as key. Check if value is OK. 39722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (ParseString(str_end + 1, end) < end) { 39822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return str_end + 1; 39922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 40022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 40122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Different from key. Advance over the value. 40222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe ptr = ParseString(str_end + 1, end) + 1; 40322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 40422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 40522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe break; 40622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 40722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 40822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Not found. 40922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return nullptr; 41022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 41122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 41222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampebool OatHeader::GetStoreKeyValuePairByIndex(size_t index, const char** key, 41322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char** value) const { 41422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* ptr = reinterpret_cast<const char*>(&key_value_store_); 41522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* end = ptr + key_value_store_size_; 41622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe ssize_t counter = static_cast<ssize_t>(index); 41722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 41822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe while (ptr < end && counter >= 0) { 41922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Scan for a closing zero. 42022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* str_end = ParseString(ptr, end); 42122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (str_end < end) { 42222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const char* maybe_key = ptr; 42322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe ptr = ParseString(str_end + 1, end) + 1; 42422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (ptr <= end) { 42522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (counter == 0) { 42622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe *key = maybe_key; 42722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe *value = str_end + 1; 42822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return true; 42922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 43022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe counter--; 43122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 43222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 43322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return false; 43422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 43522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } else { 43622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe break; 43722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 43822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 43922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Not found. 44022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return false; 44122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 44222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 44322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampesize_t OatHeader::GetHeaderSize() const { 44422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe return sizeof(OatHeader) + key_value_store_size_; 44522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe} 44622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 44746774767fcf7780d1455e755729198648d08742eIgor Murashkinbool OatHeader::IsPic() const { 4480de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz return IsKeyEnabled(OatHeader::kPicKey); 4490de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz} 4500de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz 4510de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertzbool OatHeader::IsDebuggable() const { 4520de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz return IsKeyEnabled(OatHeader::kDebuggableKey); 4530de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz} 4540de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz 4550de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertzbool OatHeader::IsKeyEnabled(const char* key) const { 4560de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz const char* key_value = GetStoreValueByKey(key); 4570de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz return (key_value != nullptr && strncmp(key_value, kTrueValue, sizeof(kTrueValue)) == 0); 45846774767fcf7780d1455e755729198648d08742eIgor Murashkin} 45946774767fcf7780d1455e755729198648d08742eIgor Murashkin 46022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampevoid OatHeader::Flatten(const SafeMap<std::string, std::string>* key_value_store) { 46122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe char* data_ptr = reinterpret_cast<char*>(&key_value_store_); 46222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe if (key_value_store != nullptr) { 46322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string>::const_iterator it = key_value_store->begin(); 46422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe SafeMap<std::string, std::string>::const_iterator end = key_value_store->end(); 46522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe for ( ; it != end; ++it) { 46622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe strcpy(data_ptr, it->first.c_str()); 46722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe data_ptr += it->first.length() + 1; 46822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe strcpy(data_ptr, it->second.c_str()); 46922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe data_ptr += it->second.length() + 1; 47022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 47122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe } 47222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe key_value_store_size_ = data_ptr - reinterpret_cast<char*>(&key_value_store_); 47381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom} 47481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom 475957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu ChartierOatMethodOffsets::OatMethodOffsets(uint32_t code_offset) : code_offset_(code_offset) { 476957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier} 4773320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 4783320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromOatMethodOffsets::~OatMethodOffsets() {} 4793320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 4807624d25dad2d1ba25969ae704fccf68649103ae5Vladimir MarkoOatQuickMethodHeader::OatQuickMethodHeader( 481957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier uint32_t mapping_table_offset, uint32_t vmap_table_offset, uint32_t gc_map_offset, 482957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier uint32_t frame_size_in_bytes, uint32_t core_spill_mask, uint32_t fp_spill_mask, 483957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier uint32_t code_size) 484957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier : mapping_table_offset_(mapping_table_offset), vmap_table_offset_(vmap_table_offset), 485957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier gc_map_offset_(gc_map_offset), 486957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier frame_info_(frame_size_in_bytes, core_spill_mask, fp_spill_mask), code_size_(code_size) { 487957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier} 48896c6ab93336b972a38bd2448bcccf19188b8389bVladimir Marko 4897624d25dad2d1ba25969ae704fccf68649103ae5Vladimir MarkoOatQuickMethodHeader::~OatQuickMethodHeader() {} 49096c6ab93336b972a38bd2448bcccf19188b8389bVladimir Marko 491e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} // namespace art 492