CacheReader.cpp revision a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdf
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() 83f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && readContext() 84f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan && checkContext() 85f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan //&& readRelocationTable() 86f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan //&& relocate() 87f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan ; 88f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 89856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return result ? mpResult.take() : NULL; 90f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 91f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 92f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 93f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkFileSize() { 94f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan struct stat stfile; 95f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (fstat(mFile->getFD(), &stfile) < 0) { 96f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to stat cache file.\n"); 97f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 98f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 99f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 100f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan mFileSize = stfile.st_size; 101f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 102f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (mFileSize < (off_t)sizeof(OBCC_Header) || 103f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan mFileSize < (off_t)BCC_CONTEXT_SIZE) { 104f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Cache file is too small to be correct.\n"); 105f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 106f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 107f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 108f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 109f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 110f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 111f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 112f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readHeader() { 113f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (mFile->seek(0, SEEK_SET) != 0) { 114f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to seek to 0. (reason: %s)\n", strerror(errno)); 115f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 116f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 117f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 118856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpHeader = (OBCC_Header *)malloc(sizeof(OBCC_Header)); 119856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (!mpHeader) { 120f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to allocate for cache header.\n"); 121f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 122f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 123f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 124856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mFile->read(reinterpret_cast<char *>(mpHeader), sizeof(OBCC_Header)) != 125f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan (ssize_t)sizeof(OBCC_Header)) { 126f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Unable to read cache header.\n"); 127f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 128f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 129f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 130a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan // Dirty hack for libRS. 131a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan // TODO(all): This should be removed in the future. 132a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan if (mpHeader->libRS_threadable) { 133a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan mpResult->mLibRSThreadable = true; 134a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan } 135a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan 136f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 137f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 138f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 139f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 140f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkHeader() { 141856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (memcmp(mpHeader->magic, OBCC_MAGIC, 4) != 0) { 142f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Bad magic word\n"); 143f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 144f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 145f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 146856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (memcmp(mpHeader->version, OBCC_VERSION, 4) != 0) { 147f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Bad oBCC version 0x%08x\n", 148856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan *reinterpret_cast<uint32_t *>(mpHeader->version)); 149f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 150f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 151f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 152f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 153f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 154f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 155f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 156f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkMachineIntType() { 157f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan uint32_t number = 0x00000001; 158f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 159f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan bool isLittleEndian = (*reinterpret_cast<char *>(&number) == 1); 160856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if ((isLittleEndian && mpHeader->endianness != 'e') || 161856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (!isLittleEndian && mpHeader->endianness != 'E')) { 162f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Machine endianness mismatch.\n"); 163f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 164f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 165f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 166856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if ((unsigned int)mpHeader->sizeof_off_t != sizeof(off_t) || 167856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned int)mpHeader->sizeof_size_t != sizeof(size_t) || 168856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned int)mpHeader->sizeof_ptr_t != sizeof(void *)) { 169f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Machine integer size mismatch.\n"); 170f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 171f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 172f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 173f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 174f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 175f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 176f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 177f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkSectionOffsetAndSize() { 178f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#define CHECK_SECTION_OFFSET(NAME) \ 179f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan do { \ 180856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan off_t offset = mpHeader-> NAME##_offset; \ 181856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan off_t size = (off_t)mpHeader-> NAME##_size; \ 182f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan \ 183f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (mFileSize < offset || mFileSize < offset + size) { \ 184f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE(#NAME " section overflow.\n"); \ 185f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; \ 186f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } \ 187f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan \ 188f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (offset % sizeof(int) != 0) { \ 189f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE(#NAME " offset must aligned to %d.\n", sizeof(int)); \ 190f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; \ 191f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } \ 192f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan \ 193f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (size < static_cast<off_t>(sizeof(size_t))) { \ 194f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE(#NAME " size is too small to be correct.\n"); \ 195f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; \ 196f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } \ 197f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } while (0) 198f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 199f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(str_pool); 200f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(depend_tab); 201a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan //CHECK_SECTION_OFFSET(reloc_tab); 202f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(export_var_list); 203f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(export_func_list); 204f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan CHECK_SECTION_OFFSET(pragma_list); 205f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 206f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan#undef CHECK_SECTION_OFFSET 207f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 208856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mFileSize < mpHeader->context_offset || 209856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mFileSize < mpHeader->context_offset + BCC_CONTEXT_SIZE) { 210f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("context section overflow.\n"); 211f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 212f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 213f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 214f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan long pagesize = sysconf(_SC_PAGESIZE); 215856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mpHeader->context_offset % pagesize != 0) { 216f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("context offset must aligned to pagesize.\n"); 217f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 218f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 219f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 220f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): Move this to some where else. 221856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if ((uintptr_t)mpHeader->context_cached_addr % pagesize != 0) { 222f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("cached address is not aligned to pagesize.\n"); 223f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 224f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 225f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 226f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 227f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 228f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 229f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 230856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#define CACHE_READER_READ_SECTION(TYPE, AUTO_MANAGED_HOLDER, NAME) \ 231856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan TYPE *NAME##_raw = (TYPE *)malloc(mpHeader->NAME##_size); \ 232856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 233856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (!NAME##_raw) { \ 234856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Unable to allocate for " #NAME "\n"); \ 235856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; \ 236856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } \ 237856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 238856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan /* We have to ensure that some one will deallocate NAME##_raw */ \ 239856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan AUTO_MANAGED_HOLDER = NAME##_raw; \ 240856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 241856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mFile->seek(mpHeader->NAME##_offset, SEEK_SET) == -1) { \ 242856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Unable to seek to " #NAME " section\n"); \ 243856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; \ 244856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } \ 245856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan \ 246856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mFile->read(reinterpret_cast<char *>(NAME##_raw), \ 247856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpHeader->NAME##_size) != (ssize_t)mpHeader->NAME##_size) \ 248856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan { \ 249856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Unable to read " #NAME ".\n"); \ 250856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; \ 251f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 252f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 253f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 254856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readStringPool() { 255856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_StringPool, 256856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpResult->mpStringPoolRaw, str_pool); 257f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 258856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan char *str_base = reinterpret_cast<char *>(str_pool_raw); 259f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 260856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &pool = mpResult->mStringPool; 261856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < str_pool_raw->count; ++i) { 262856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan char *str = str_base + str_pool_raw->list[i].offset; 263f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan pool.push_back(str); 264f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 265f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 266f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 267f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 268f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 269f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 270f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkStringPool() { 271856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_StringPool *poolR = mpResult->mpStringPoolRaw; 272856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &pool = mpResult->mStringPool; 273f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 274f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // Ensure that every c-style string is ended with '\0' 275f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan for (size_t i = 0; i < poolR->count; ++i) { 276f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (pool[i][poolR->list[i].length] != '\0') { 277f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("The %lu-th string does not end with '\\0'.\n", (unsigned long)i); 278f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 279f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 280f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 281f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 282f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 283f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 284f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 285f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 286f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readDependencyTable() { 287856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_DependencyTable, mpCachedDependTable, 288856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan depend_tab); 289f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 290f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 291f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 292f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 293f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkDependency() { 294856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (mDependencies.size() != mpCachedDependTable->count) { 295856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Dependencies count mismatch. (%lu vs %lu)\n", 296856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned long)mDependencies.size(), 297856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan (unsigned long)mpCachedDependTable->count); 298f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 299f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 300f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 301856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &strPool = mpResult->mStringPool; 30275cc8a5c58b3260e530eae9f2edd502b71d25373Logan map<string, pair<uint32_t, unsigned char const *> >::iterator dep; 303f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 304856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan dep = mDependencies.begin(); 305856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < mpCachedDependTable->count; ++i, ++dep) { 306856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan string const &depName = dep->first; 307856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t depType = dep->second.first; 30875cc8a5c58b3260e530eae9f2edd502b71d25373Logan unsigned char const *depSHA1 = dep->second.second; 309f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 310856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_Dependency *depCached =&mpCachedDependTable->table[i]; 311856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan char const *depCachedName = strPool[depCached->res_name_strp_index]; 312856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t depCachedType = depCached->res_type; 31375cc8a5c58b3260e530eae9f2edd502b71d25373Logan unsigned char const *depCachedSHA1 = depCached->sha1; 314f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 315856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (depName != depCachedName) { 316856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Cache dependency name mismatch:\n"); 317856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE(" given: %s\n", depName.c_str()); 318856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE(" cached: %s\n", depCachedName); 319f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 320856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; 321856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 322f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 323856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (memcmp(depSHA1, depCachedSHA1, 20) != 0) { 324856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Cache dependency %s sha1 mismatch:\n", depCachedName); 325f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 326856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#define PRINT_SHA1(PREFIX, X, POSTFIX) \ 327856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE(PREFIX "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \ 328856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" POSTFIX, \ 329856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan X[0], X[1], X[2], X[3], X[4], X[5], X[6], X[7], X[8], X[9], \ 330856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan X[10],X[11],X[12],X[13],X[14],X[15],X[16],X[17],X[18],X[19]); 331f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 332856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan PRINT_SHA1(" given: ", depSHA1, "\n"); 333856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan PRINT_SHA1(" cached: ", depCachedSHA1, "\n"); 334f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 335856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#undef PRINT_SHA1 336f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 337856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; 338856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 339856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 340856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (depType != depCachedType) { 341856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan LOGE("Cache dependency %s resource type mismatch.\n", depCachedName); 342856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return false; 343856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 344f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 345f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 346f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 347f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 348f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 349856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readExportVarList() { 350856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_ExportVarList, 351856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpResult->mpExportVars, export_var_list); 352856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return true; 353856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan} 354f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 355f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 356856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readExportFuncList() { 357856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_ExportFuncList, 358856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpResult->mpExportFuncs, export_func_list); 359856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return true; 360856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan} 361f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 362f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 363856ceb2774bd2c601970c2bc26fb87b2e9b00258Loganbool CacheReader::readPragmaList() { 364856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_PragmaList, mpPragmaList, pragma_list); 365f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 366856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> const &strPool = mpResult->mStringPool; 367856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan ScriptCached::PragmaList &pragmas = mpResult->mPragmas; 368f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 369856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < pragma_list_raw->count; ++i) { 370856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_Pragma *pragma = &pragma_list_raw->list[i]; 371f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan pragmas.push_back(make_pair(strPool[pragma->key_strp_index], 372f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan strPool[pragma->value_strp_index])); 373f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 374f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 375f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 376f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 377f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 378f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 379f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readFuncTable() { 380856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan CACHE_READER_READ_SECTION(OBCC_FuncTable, mpFuncTable, func_table); 381856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 382856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan vector<char const *> &strPool = mpResult->mStringPool; 383856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan ScriptCached::FuncTable &table = mpResult->mFunctions; 384856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan for (size_t i = 0; i < func_table_raw->count; ++i) { 385856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan OBCC_FuncInfo *func = &func_table_raw->table[i]; 386856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan table.insert(make_pair(strPool[func->name_strp_index], 387856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan make_pair(func->cached_addr, func->size))); 388856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan } 389856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 390856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan return true; 391f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 392f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 393856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan#undef CACHE_READER_READ_SECTION 394856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan 395f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 396f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readContext() { 397856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpResult->mContext = allocateContext(mpHeader->context_cached_addr, 398f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan mFile->getFD(), 399856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan mpHeader->context_offset); 400f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 401856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan if (!mpResult->mContext) { 402f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // Unable to allocate at cached address. Give up. 403f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 404f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 405f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): If relocation is fixed, we should try to allocate the 406f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // code in different location, and relocate the context. 407f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 408f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 409f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 410f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 411f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 412f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 413f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::checkContext() { 414856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t sum = mpHeader->context_parity_checksum; 415856ceb2774bd2c601970c2bc26fb87b2e9b00258Logan uint32_t *ptr = reinterpret_cast<uint32_t *>(mpResult->mContext); 416f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 417f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan for (size_t i = 0; i < BCC_CONTEXT_SIZE / sizeof(uint32_t); ++i) { 418f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan sum ^= *ptr++; 419f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 420f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 421f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan if (sum != 0) { 422f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGE("Checksum check failed\n"); 423f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return false; 424f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan } 425f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 426f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan LOGI("Passed checksum even parity verification.\n"); 427f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 428f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 429f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 430f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 431f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::readRelocationTable() { 432f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): Not finished. 433f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 434f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 435f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 436f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 437f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLoganbool CacheReader::relocate() { 438f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan // TODO(logan): Not finished. 439f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan return true; 440f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} 441f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 442f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan 443f7f0ac5d3e12b2e84bd18aa32add4a11bf296dbbLogan} // namespace bcc 444