CacheReader.cpp revision 42598054d2d278bddde812f160517162e95342c1
1f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan/* 2f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * Copyright 2010, The Android Open Source Project 3f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * 4f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * Licensed under the Apache License, Version 2.0 (the "License"); 5f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * you may not use this file except in compliance with the License. 6f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * You may obtain a copy of the License at 7f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * 8f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * http://www.apache.org/licenses/LICENSE-2.0 9f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * 10f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * Unless required by applicable law or agreed to in writing, software 11f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * distributed under the License is distributed on an "AS IS" BASIS, 12f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * See the License for the specific language governing permissions and 14f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan * limitations under the License. 15f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan */ 16f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 17f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#define LOG_TAG "bcc" 18f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <cutils/log.h> 19f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 20f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include "CacheReader.h" 21f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 22f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include "ContextManager.h" 23f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include "FileHandle.h" 24f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include "ScriptCached.h" 25f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 26f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <bcc/bcc_cache.h> 27f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 28f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <llvm/ADT/OwningPtr.h> 29f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 30f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <errno.h> 31f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <sys/stat.h> 32f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <sys/types.h> 33f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 34f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <utility> 35f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <vector> 36f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 37f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <new> 38f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 39856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#include <stdlib.h> 40f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <string.h> 41f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 42f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganusing namespace std; 43f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 44f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 45f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogannamespace bcc { 46f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 47856ceb2774bd2c601970c2bc26fb87b2e9b00258LoganCacheReader::~CacheReader() { 48856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mpHeader) { free(mpHeader); } 49856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mpCachedDependTable) { free(mpCachedDependTable); } 50856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mpPragmaList) { free(mpPragmaList); } 51856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mpFuncTable) { free(mpFuncTable); } 52856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan} 53856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 54e7eb773baa51408a0f8f871d779888d0d381b5d7LoganScriptCached *CacheReader::readCacheFile(FileHandle *file, Script *S) { 55f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // Check file handle 56f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (!file || file->getFD() < 0) { 57f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return NULL; 58f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 59f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 60a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan mFile = file; 61a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan 62f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // Allocate ScriptCached object 63e7eb773baa51408a0f8f871d779888d0d381b5d7Logan mpResult.reset(new (nothrow) ScriptCached(S)); 64f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 65856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (!mpResult) { 66f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to allocate ScriptCached object.\n"); 67f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return NULL; 68f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 69f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 70f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan bool result = checkFileSize() 71f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readHeader() 72f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkHeader() 73f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkMachineIntType() 74f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkSectionOffsetAndSize() 75f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readStringPool() 76f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkStringPool() 77f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readDependencyTable() 78f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkDependency() 79f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readExportVarList() 80f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readExportFuncList() 81f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readPragmaList() 82f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readFuncTable() 83071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines && readObjectSlotList() 84f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readContext() 85f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkContext() 86f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan //&& readRelocationTable() 87f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan //&& relocate() 88f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan ; 89f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 90856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return result ? mpResult.take() : NULL; 91f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 92f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 93f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 94f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkFileSize() { 95f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan struct stat stfile; 96f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (fstat(mFile->getFD(), &stfile) < 0) { 97f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to stat cache file.\n"); 98f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 99f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 100f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 101f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan mFileSize = stfile.st_size; 102f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 103f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (mFileSize < (off_t)sizeof(OBCC_Header) || 104f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan mFileSize < (off_t)BCC_CONTEXT_SIZE) { 105f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Cache file is too small to be correct.\n"); 106f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 107f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 108f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 109f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 110f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 111f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 112f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 113f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readHeader() { 114f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (mFile->seek(0, SEEK_SET) != 0) { 115f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to seek to 0. (reason: %s)\n", strerror(errno)); 116f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 117f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 118f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 119856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpHeader = (OBCC_Header *)malloc(sizeof(OBCC_Header)); 120856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (!mpHeader) { 121f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to allocate for cache header.\n"); 122f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 123f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 124f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 125856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mFile->read(reinterpret_cast<char *>(mpHeader), sizeof(OBCC_Header)) != 126f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan (ssize_t)sizeof(OBCC_Header)) { 127f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to read cache header.\n"); 128f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 129f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 130f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 131a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan // Dirty hack for libRS. 132a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan // TODO(all): This should be removed in the future. 133a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan if (mpHeader->libRS_threadable) { 134a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan mpResult->mLibRSThreadable = true; 135a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan } 136a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan 137f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 138f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 139f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 140f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 141f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkHeader() { 142856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (memcmp(mpHeader->magic, OBCC_MAGIC, 4) != 0) { 143f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Bad magic word\n"); 144f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 145f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 146f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 147856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (memcmp(mpHeader->version, OBCC_VERSION, 4) != 0) { 148e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan mpHeader->version[4 - 1] = '\0'; // ensure c-style string terminated 149a65266520846ecca8cc95587776c050c646ad624Shih-wei Liao LOGI("Cache file format version mismatch: now %s cached %s\n", 150e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan OBCC_VERSION, mpHeader->version); 151e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan return false; 152e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan } 153e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan 154e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan if (memcmp(mpHeader->libbcc_build_time, libbcc_build_time, 24) != 0) { 155e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan mpHeader->libbcc_build_time[24 - 1] = '\0'; // ensure terminated 15639ebe2c22f8557752065465345bb3006d06e4497Shih-wei Liao LOGW("Build time mismatch: lib %s cached %s\n", libbcc_build_time, 157e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan mpHeader->libbcc_build_time); 158f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 159f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 160f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 161f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 162f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 163f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 164f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 165f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkMachineIntType() { 166f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan uint32_t number = 0x00000001; 167f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 168f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan bool isLittleEndian = (*reinterpret_cast<char *>(&number) == 1); 169856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if ((isLittleEndian && mpHeader->endianness != 'e') || 170856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (!isLittleEndian && mpHeader->endianness != 'E')) { 171f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Machine endianness mismatch.\n"); 172f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 173f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 174f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 175856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if ((unsigned int)mpHeader->sizeof_off_t != sizeof(off_t) || 176856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned int)mpHeader->sizeof_size_t != sizeof(size_t) || 177856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned int)mpHeader->sizeof_ptr_t != sizeof(void *)) { 178f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Machine integer size mismatch.\n"); 179f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 180f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 181f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 182f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 183f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 184f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 185f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 186f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkSectionOffsetAndSize() { 187f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#define CHECK_SECTION_OFFSET(NAME) \ 188f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan do { \ 189856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan off_t offset = mpHeader-> NAME##_offset; \ 190856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan off_t size = (off_t)mpHeader-> NAME##_size; \ 191f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan \ 192f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (mFileSize < offset || mFileSize < offset + size) { \ 193f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE(#NAME " section overflow.\n"); \ 194f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; \ 195f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } \ 196f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan \ 197f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (offset % sizeof(int) != 0) { \ 198f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE(#NAME " offset must aligned to %d.\n", sizeof(int)); \ 199f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; \ 200f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } \ 201f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan \ 202f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (size < static_cast<off_t>(sizeof(size_t))) { \ 203f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE(#NAME " size is too small to be correct.\n"); \ 204f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; \ 205f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } \ 206f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } while (0) 207f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 208f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(str_pool); 209f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(depend_tab); 210a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan //CHECK_SECTION_OFFSET(reloc_tab); 211f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(export_var_list); 212f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(export_func_list); 213f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(pragma_list); 214f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 215f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#undef CHECK_SECTION_OFFSET 216f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 217856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mFileSize < mpHeader->context_offset || 218856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mFileSize < mpHeader->context_offset + BCC_CONTEXT_SIZE) { 219f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("context section overflow.\n"); 220f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 221f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 222f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 223f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan long pagesize = sysconf(_SC_PAGESIZE); 224856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mpHeader->context_offset % pagesize != 0) { 225f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("context offset must aligned to pagesize.\n"); 226f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 227f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 228f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 229f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): Move this to some where else. 230856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if ((uintptr_t)mpHeader->context_cached_addr % pagesize != 0) { 231f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("cached address is not aligned to pagesize.\n"); 232f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 233f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 234f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 235f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 236f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 237f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 238f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 239856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#define CACHE_READER_READ_SECTION(TYPE, AUTO_MANAGED_HOLDER, NAME) \ 240856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan TYPE *NAME##_raw = (TYPE *)malloc(mpHeader->NAME##_size); \ 241856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 242856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (!NAME##_raw) { \ 243856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Unable to allocate for " #NAME "\n"); \ 244856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; \ 245856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } \ 246856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 247856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan /* We have to ensure that some one will deallocate NAME##_raw */ \ 248856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan AUTO_MANAGED_HOLDER = NAME##_raw; \ 249856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 250856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mFile->seek(mpHeader->NAME##_offset, SEEK_SET) == -1) { \ 251856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Unable to seek to " #NAME " section\n"); \ 252856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; \ 253856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } \ 254856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 255856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mFile->read(reinterpret_cast<char *>(NAME##_raw), \ 256856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpHeader->NAME##_size) != (ssize_t)mpHeader->NAME##_size) \ 257856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan { \ 258856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Unable to read " #NAME ".\n"); \ 259856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; \ 260f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 261f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 262f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 263856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readStringPool() { 264856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_StringPool, 265856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpResult->mpStringPoolRaw, str_pool); 266f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 267856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan char *str_base = reinterpret_cast<char *>(str_pool_raw); 268f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 269856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &pool = mpResult->mStringPool; 270856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < str_pool_raw->count; ++i) { 271856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan char *str = str_base + str_pool_raw->list[i].offset; 272f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan pool.push_back(str); 273f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 274f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 275f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 276f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 277f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 278f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 279f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkStringPool() { 280856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_StringPool *poolR = mpResult->mpStringPoolRaw; 281856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &pool = mpResult->mStringPool; 282f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 283f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // Ensure that every c-style string is ended with '\0' 284f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan for (size_t i = 0; i < poolR->count; ++i) { 285f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (pool[i][poolR->list[i].length] != '\0') { 286f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("The %lu-th string does not end with '\\0'.\n", (unsigned long)i); 287f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 288f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 289f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 290f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 291f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 292f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 293f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 294f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 295f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readDependencyTable() { 296856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_DependencyTable, mpCachedDependTable, 297856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan depend_tab); 298f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 299f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 300f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 301f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 302f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkDependency() { 303856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mDependencies.size() != mpCachedDependTable->count) { 304856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Dependencies count mismatch. (%lu vs %lu)\n", 305856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned long)mDependencies.size(), 306856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned long)mpCachedDependTable->count); 307f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 308f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 309f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 310856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &strPool = mpResult->mStringPool; 31175cc8a5c58b3260e530eae9f2edd502b71d25373Logan map<string, pair<uint32_t, unsigned char const *> >::iterator dep; 312f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 313856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan dep = mDependencies.begin(); 314856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < mpCachedDependTable->count; ++i, ++dep) { 315856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan string const &depName = dep->first; 316856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t depType = dep->second.first; 31775cc8a5c58b3260e530eae9f2edd502b71d25373Logan unsigned char const *depSHA1 = dep->second.second; 318f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 319856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_Dependency *depCached =&mpCachedDependTable->table[i]; 320856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan char const *depCachedName = strPool[depCached->res_name_strp_index]; 321856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t depCachedType = depCached->res_type; 32275cc8a5c58b3260e530eae9f2edd502b71d25373Logan unsigned char const *depCachedSHA1 = depCached->sha1; 323f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 324856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (depName != depCachedName) { 325856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Cache dependency name mismatch:\n"); 326856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE(" given: %s\n", depName.c_str()); 327856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE(" cached: %s\n", depCachedName); 328f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 329856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; 330856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 331f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 332856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (memcmp(depSHA1, depCachedSHA1, 20) != 0) { 333856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Cache dependency %s sha1 mismatch:\n", depCachedName); 334f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 335856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#define PRINT_SHA1(PREFIX, X, POSTFIX) \ 336856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE(PREFIX "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \ 337856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" POSTFIX, \ 338856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan X[0], X[1], X[2], X[3], X[4], X[5], X[6], X[7], X[8], X[9], \ 339856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan X[10],X[11],X[12],X[13],X[14],X[15],X[16],X[17],X[18],X[19]); 340f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 341856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan PRINT_SHA1(" given: ", depSHA1, "\n"); 342856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan PRINT_SHA1(" cached: ", depCachedSHA1, "\n"); 343f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 344856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#undef PRINT_SHA1 345f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 346856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; 347856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 348856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 349856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (depType != depCachedType) { 350856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Cache dependency %s resource type mismatch.\n", depCachedName); 351856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; 352856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 353f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 354f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 355f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 356f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 357f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 358856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readExportVarList() { 359856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_ExportVarList, 360856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpResult->mpExportVars, export_var_list); 361856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return true; 362856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan} 363f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 364f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 365856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readExportFuncList() { 366856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_ExportFuncList, 367856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpResult->mpExportFuncs, export_func_list); 368856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return true; 369856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan} 370f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 371f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 372856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readPragmaList() { 373856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_PragmaList, mpPragmaList, pragma_list); 374f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 375856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> const &strPool = mpResult->mStringPool; 376856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan ScriptCached::PragmaList &pragmas = mpResult->mPragmas; 377f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 378856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < pragma_list_raw->count; ++i) { 379856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_Pragma *pragma = &pragma_list_raw->list[i]; 380f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan pragmas.push_back(make_pair(strPool[pragma->key_strp_index], 381f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan strPool[pragma->value_strp_index])); 382f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 383f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 384f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 385f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 386f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 387f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 388071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hinesbool CacheReader::readObjectSlotList() { 389071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines CACHE_READER_READ_SECTION(OBCC_ObjectSlotList, 390071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines mpResult->mpObjectSlotList, object_slot_list); 391071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines return true; 392071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines} 393071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 394071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 395f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readFuncTable() { 396856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_FuncTable, mpFuncTable, func_table); 397856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 398856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &strPool = mpResult->mStringPool; 399856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan ScriptCached::FuncTable &table = mpResult->mFunctions; 400856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < func_table_raw->count; ++i) { 401856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_FuncInfo *func = &func_table_raw->table[i]; 402856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan table.insert(make_pair(strPool[func->name_strp_index], 403856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan make_pair(func->cached_addr, func->size))); 404856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 405856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 406856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return true; 407f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 408f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 409856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#undef CACHE_READER_READ_SECTION 410856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 411f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 412f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readContext() { 413856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpResult->mContext = allocateContext(mpHeader->context_cached_addr, 414f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan mFile->getFD(), 415856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpHeader->context_offset); 416f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 417856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (!mpResult->mContext) { 418f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // Unable to allocate at cached address. Give up. 41942598054d2d278bddde812f160517162e95342c1Logan mIsContextSlotNotAvail = true; 420f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 421f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 422f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): If relocation is fixed, we should try to allocate the 423f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // code in different location, and relocate the context. 424f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 425f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 426f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 427f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 428f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 429f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 430f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkContext() { 431856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t sum = mpHeader->context_parity_checksum; 432856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t *ptr = reinterpret_cast<uint32_t *>(mpResult->mContext); 433f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 434f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan for (size_t i = 0; i < BCC_CONTEXT_SIZE / sizeof(uint32_t); ++i) { 435f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan sum ^= *ptr++; 436f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 437f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 438f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (sum != 0) { 439f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Checksum check failed\n"); 440f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 441f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 442f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 443f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGI("Passed checksum even parity verification.\n"); 444f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 445f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 446f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 447f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 448f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readRelocationTable() { 449f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): Not finished. 450f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 451f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 452f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 453f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 454f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::relocate() { 455f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): Not finished. 456f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 457f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 458f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 459f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 460f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} // namespace bcc 461