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#include "CacheReader.h" 18f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 19f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include "ContextManager.h" 204dcd6798f3db374a056ea6acc6b425f544c5207cLogan#include "DebugHelper.h" 21f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include "FileHandle.h" 22f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include "ScriptCached.h" 23f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 24f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <bcc/bcc_cache.h> 25f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 26f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <llvm/ADT/OwningPtr.h> 27f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 28f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <errno.h> 29f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <sys/stat.h> 30f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <sys/types.h> 31f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 32f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <utility> 33f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <vector> 34f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 35f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <new> 36f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 37856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#include <stdlib.h> 38f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#include <string.h> 39f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 40f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganusing namespace std; 41f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 42f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 43f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogannamespace bcc { 44f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 45856ceb2774bd2c601970c2bc26fb87b2e9b00258LoganCacheReader::~CacheReader() { 46856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mpHeader) { free(mpHeader); } 47856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mpCachedDependTable) { free(mpCachedDependTable); } 48856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mpPragmaList) { free(mpPragmaList); } 49856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mpFuncTable) { free(mpFuncTable); } 50856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan} 51856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 5203a2e30e9ee0e3a880eb60f5047302d216db9582Logan ChienScriptCached *CacheReader::readCacheFile(FileHandle *objFile, 5303a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien FileHandle *infoFile, 5403a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien Script *S) { 55f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // Check file handle 5603a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (!objFile || objFile->getFD() < 0 || 5703a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien !infoFile || infoFile->getFD() < 0) { 58f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return NULL; 59f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 60f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 6103a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien mObjFile = objFile; 6203a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien mInfoFile = infoFile; 63a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan 64f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // Allocate ScriptCached object 65e7eb773baa51408a0f8f871d779888d0d381b5d7Logan mpResult.reset(new (nothrow) ScriptCached(S)); 66f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 67856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (!mpResult) { 68f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to allocate ScriptCached object.\n"); 69f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return NULL; 70f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 71f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 72f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan bool result = checkFileSize() 73f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readHeader() 74f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkHeader() 75f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkMachineIntType() 76f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkSectionOffsetAndSize() 77f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readStringPool() 78f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkStringPool() 79f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readDependencyTable() 80f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkDependency() 81f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readExportVarList() 82f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readExportFuncList() 83f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readPragmaList() 84f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readFuncTable() 85071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines && readObjectSlotList() 86f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readContext() 87f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkContext() 88f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan //&& readRelocationTable() 89f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan //&& relocate() 90f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan ; 91f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 92856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return result ? mpResult.take() : NULL; 93f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 94f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 95f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 96f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkFileSize() { 97f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan struct stat stfile; 9803a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien 9903a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (fstat(mInfoFile->getFD(), &stfile) < 0) { 10003a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien LOGE("Unable to stat metadata information file.\n"); 10103a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien return false; 10203a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien } 10303a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien 10403a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien mInfoFileSize = stfile.st_size; 10503a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien 10603a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (mInfoFileSize < (off_t)sizeof(OBCC_Header)) { 10703a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien LOGE("Metadata information file is too small to be correct.\n"); 108f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 109f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 110f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 11103a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (fstat(mObjFile->getFD(), &stfile) < 0) { 11203a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien LOGE("Unable to stat executable file.\n"); 11303a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien return false; 11403a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien } 115f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 11603a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (stfile.st_size < (off_t)ContextManager::ContextSize) { 11703a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien LOGE("Executable file is too small to be correct.\n"); 118f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 119f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 120f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 121f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 122f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 123f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 124f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 125f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readHeader() { 12603a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (mInfoFile->seek(0, SEEK_SET) != 0) { 127f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to seek to 0. (reason: %s)\n", strerror(errno)); 128f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 129f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 130f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 131856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpHeader = (OBCC_Header *)malloc(sizeof(OBCC_Header)); 132856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (!mpHeader) { 133f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to allocate for cache header.\n"); 134f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 135f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 136f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 13703a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (mInfoFile->read((char *)mpHeader, sizeof(OBCC_Header)) != 138f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan (ssize_t)sizeof(OBCC_Header)) { 139f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to read cache header.\n"); 140f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 141f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 142f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 143a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan // Dirty hack for libRS. 144a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan // TODO(all): This should be removed in the future. 145a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan if (mpHeader->libRS_threadable) { 146a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan mpResult->mLibRSThreadable = true; 147a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan } 148a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan 149f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 150f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 151f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 152f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 153f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkHeader() { 154856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (memcmp(mpHeader->magic, OBCC_MAGIC, 4) != 0) { 155f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Bad magic word\n"); 156f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 157f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 158f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 159856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (memcmp(mpHeader->version, OBCC_VERSION, 4) != 0) { 160e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan mpHeader->version[4 - 1] = '\0'; // ensure c-style string terminated 161a65266520846ecca8cc95587776c050c646ad624Shih-wei Liao LOGI("Cache file format version mismatch: now %s cached %s\n", 162e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan OBCC_VERSION, mpHeader->version); 163e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan return false; 164e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan } 165f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 166f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 167f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 168f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 169f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkMachineIntType() { 170f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan uint32_t number = 0x00000001; 171f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 172f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan bool isLittleEndian = (*reinterpret_cast<char *>(&number) == 1); 173856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if ((isLittleEndian && mpHeader->endianness != 'e') || 174856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (!isLittleEndian && mpHeader->endianness != 'E')) { 175f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Machine endianness mismatch.\n"); 176f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 177f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 178f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 179856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if ((unsigned int)mpHeader->sizeof_off_t != sizeof(off_t) || 180856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned int)mpHeader->sizeof_size_t != sizeof(size_t) || 181856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned int)mpHeader->sizeof_ptr_t != sizeof(void *)) { 182f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Machine integer size mismatch.\n"); 183f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 184f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 185f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 186f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 187f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 188f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 189f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 190f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkSectionOffsetAndSize() { 191f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#define CHECK_SECTION_OFFSET(NAME) \ 192f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan do { \ 193856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan off_t offset = mpHeader-> NAME##_offset; \ 194856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan off_t size = (off_t)mpHeader-> NAME##_size; \ 195f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan \ 19603a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (mInfoFileSize < offset || mInfoFileSize < offset + size) { \ 197f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE(#NAME " section overflow.\n"); \ 198f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; \ 199f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } \ 200f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan \ 201f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (offset % sizeof(int) != 0) { \ 20240b7fba14f35a159991067132990463bfaa800c0Stephen Hines LOGE(#NAME " offset must aligned to %d.\n", (int)sizeof(int)); \ 203f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; \ 204f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } \ 205f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan \ 206f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (size < static_cast<off_t>(sizeof(size_t))) { \ 207f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE(#NAME " size is too small to be correct.\n"); \ 208f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; \ 209f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } \ 210f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } while (0) 211f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 212f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(str_pool); 213f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(depend_tab); 214a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan //CHECK_SECTION_OFFSET(reloc_tab); 215f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(export_var_list); 216f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(export_func_list); 217f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(pragma_list); 218f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 219f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#undef CHECK_SECTION_OFFSET 220f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 221f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): Move this to some where else. 22203a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien long pagesize = sysconf(_SC_PAGESIZE); 223856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if ((uintptr_t)mpHeader->context_cached_addr % pagesize != 0) { 224f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("cached address is not aligned to pagesize.\n"); 225f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 226f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 227f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 228f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 229f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 230f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 231f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 232856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#define CACHE_READER_READ_SECTION(TYPE, AUTO_MANAGED_HOLDER, NAME) \ 233856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan TYPE *NAME##_raw = (TYPE *)malloc(mpHeader->NAME##_size); \ 234856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 235856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (!NAME##_raw) { \ 236856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Unable to allocate for " #NAME "\n"); \ 237856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; \ 238856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } \ 239856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 240856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan /* We have to ensure that some one will deallocate NAME##_raw */ \ 241856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan AUTO_MANAGED_HOLDER = NAME##_raw; \ 242856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 24303a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (mInfoFile->seek(mpHeader->NAME##_offset, SEEK_SET) == -1) { \ 244856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Unable to seek to " #NAME " section\n"); \ 245856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; \ 246856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } \ 247856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 24803a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (mInfoFile->read(reinterpret_cast<char *>(NAME##_raw), \ 249856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpHeader->NAME##_size) != (ssize_t)mpHeader->NAME##_size) \ 250856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan { \ 251856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Unable to read " #NAME ".\n"); \ 252856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; \ 253f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 254f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 255f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 256856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readStringPool() { 257856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_StringPool, 258856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpResult->mpStringPoolRaw, str_pool); 259f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 260856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan char *str_base = reinterpret_cast<char *>(str_pool_raw); 261f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 262856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &pool = mpResult->mStringPool; 263856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < str_pool_raw->count; ++i) { 264856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan char *str = str_base + str_pool_raw->list[i].offset; 265f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan pool.push_back(str); 266f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 267f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 268f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 269f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 270f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 271f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 272f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkStringPool() { 273856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_StringPool *poolR = mpResult->mpStringPoolRaw; 274856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &pool = mpResult->mStringPool; 275f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 276f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // Ensure that every c-style string is ended with '\0' 277f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan for (size_t i = 0; i < poolR->count; ++i) { 278f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (pool[i][poolR->list[i].length] != '\0') { 279f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("The %lu-th string does not end with '\\0'.\n", (unsigned long)i); 280f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 281f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 282f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 283f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 284f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 285f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 286f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 287f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 288f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readDependencyTable() { 289856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_DependencyTable, mpCachedDependTable, 290856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan depend_tab); 291f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 292f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 293f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 294f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 295f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkDependency() { 296856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mDependencies.size() != mpCachedDependTable->count) { 297856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Dependencies count mismatch. (%lu vs %lu)\n", 298856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned long)mDependencies.size(), 299856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned long)mpCachedDependTable->count); 300f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 301f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 302f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 303856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &strPool = mpResult->mStringPool; 30475cc8a5c58b3260e530eae9f2edd502b71d25373Logan map<string, pair<uint32_t, unsigned char const *> >::iterator dep; 305f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 306856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan dep = mDependencies.begin(); 307856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < mpCachedDependTable->count; ++i, ++dep) { 308856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan string const &depName = dep->first; 309856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t depType = dep->second.first; 31075cc8a5c58b3260e530eae9f2edd502b71d25373Logan unsigned char const *depSHA1 = dep->second.second; 311f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 312856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_Dependency *depCached =&mpCachedDependTable->table[i]; 313856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan char const *depCachedName = strPool[depCached->res_name_strp_index]; 314856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t depCachedType = depCached->res_type; 31575cc8a5c58b3260e530eae9f2edd502b71d25373Logan unsigned char const *depCachedSHA1 = depCached->sha1; 316f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 317856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (depName != depCachedName) { 318856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Cache dependency name mismatch:\n"); 319856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE(" given: %s\n", depName.c_str()); 320856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE(" cached: %s\n", depCachedName); 321f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 322856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; 323856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 324f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 325856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (memcmp(depSHA1, depCachedSHA1, 20) != 0) { 326856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Cache dependency %s sha1 mismatch:\n", depCachedName); 327f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 328856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#define PRINT_SHA1(PREFIX, X, POSTFIX) \ 329856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE(PREFIX "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \ 330856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" POSTFIX, \ 331856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan X[0], X[1], X[2], X[3], X[4], X[5], X[6], X[7], X[8], X[9], \ 332856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan X[10],X[11],X[12],X[13],X[14],X[15],X[16],X[17],X[18],X[19]); 333f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 334856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan PRINT_SHA1(" given: ", depSHA1, "\n"); 335856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan PRINT_SHA1(" cached: ", depCachedSHA1, "\n"); 336f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 337856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#undef PRINT_SHA1 338f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 339856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; 340856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 341856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 342856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (depType != depCachedType) { 343856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Cache dependency %s resource type mismatch.\n", depCachedName); 344856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; 345856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 346f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 347f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 348f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 349f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 350f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 351856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readExportVarList() { 352856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_ExportVarList, 353856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpResult->mpExportVars, export_var_list); 354856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return true; 355856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan} 356f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 357f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 358856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readExportFuncList() { 359856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_ExportFuncList, 360856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpResult->mpExportFuncs, export_func_list); 361856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return true; 362856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan} 363f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 364f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 365856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readPragmaList() { 366856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_PragmaList, mpPragmaList, pragma_list); 367f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 368856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> const &strPool = mpResult->mStringPool; 369856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan ScriptCached::PragmaList &pragmas = mpResult->mPragmas; 370f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 371856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < pragma_list_raw->count; ++i) { 372856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_Pragma *pragma = &pragma_list_raw->list[i]; 373f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan pragmas.push_back(make_pair(strPool[pragma->key_strp_index], 374f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan strPool[pragma->value_strp_index])); 375f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 376f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 377f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 378f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 379f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 380f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 381071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hinesbool CacheReader::readObjectSlotList() { 382071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines CACHE_READER_READ_SECTION(OBCC_ObjectSlotList, 383071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines mpResult->mpObjectSlotList, object_slot_list); 384071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines return true; 385071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines} 386071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 387071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 388f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readFuncTable() { 389856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_FuncTable, mpFuncTable, func_table); 390856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 391856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &strPool = mpResult->mStringPool; 392856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan ScriptCached::FuncTable &table = mpResult->mFunctions; 393856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < func_table_raw->count; ++i) { 394856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_FuncInfo *func = &func_table_raw->table[i]; 395856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan table.insert(make_pair(strPool[func->name_strp_index], 396856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan make_pair(func->cached_addr, func->size))); 397856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 398856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 399856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return true; 400f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 401f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 402856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#undef CACHE_READER_READ_SECTION 403856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 404f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 405f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readContext() { 4061dc6314a03b320f9ba5431834c2deeba13f5f065Logan mpResult->mContext = 4071dc6314a03b320f9ba5431834c2deeba13f5f065Logan ContextManager::get().allocateContext(mpHeader->context_cached_addr, 40803a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien mObjFile->getFD(), 0); 409f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 410856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (!mpResult->mContext) { 411f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // Unable to allocate at cached address. Give up. 41242598054d2d278bddde812f160517162e95342c1Logan mIsContextSlotNotAvail = true; 413f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 414f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 415f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): If relocation is fixed, we should try to allocate the 416f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // code in different location, and relocate the context. 417f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 418f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 419f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 420f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 421f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 422f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 423f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkContext() { 424856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t sum = mpHeader->context_parity_checksum; 425856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t *ptr = reinterpret_cast<uint32_t *>(mpResult->mContext); 426f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 4271dc6314a03b320f9ba5431834c2deeba13f5f065Logan for (size_t i = 0; i < ContextManager::ContextSize / sizeof(uint32_t); ++i) { 428f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan sum ^= *ptr++; 429f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 430f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 431f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (sum != 0) { 432f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Checksum check failed\n"); 433f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 434f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 435f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 436f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGI("Passed checksum even parity verification.\n"); 437f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 438f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 439f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 440f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 441f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readRelocationTable() { 442f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): Not finished. 443f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 444f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 445f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 446f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 447f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::relocate() { 448f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): Not finished. 449f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 450f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 451f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 452f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 453f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} // namespace bcc 454