MCCacheReader.cpp revision 5e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14
15e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao/*
25e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao * Copyright 2010, The Android Open Source Project
35e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao *
45e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
55e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao * you may not use this file except in compliance with the License.
65e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao * You may obtain a copy of the License at
75e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao *
85e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
95e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao *
105e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao * Unless required by applicable law or agreed to in writing, software
115e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
125e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao * See the License for the specific language governing permissions and
145e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao * limitations under the License.
155e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao */
165e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
175e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include "MCCacheReader.h"
185e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
195e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include "ContextManager.h"
205e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include "DebugHelper.h"
215e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include "FileHandle.h"
225e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include "ScriptCached.h"
235e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include "Runtime.h"
245e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
255e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include <bcc/bcc_mccache.h>
265e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
275e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include <llvm/ADT/OwningPtr.h>
285e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
295e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include <errno.h>
305e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include <sys/stat.h>
315e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include <sys/types.h>
325e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
335e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include <utility>
345e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include <vector>
355e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
365e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include <new>
375e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
385e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include <stdlib.h>
395e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include <string.h>
405e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
415e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaousing namespace std;
425e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
435e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
445e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#if USE_MCJIT
455e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaonamespace bcc {
465e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
475e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei LiaoMCCacheReader::~MCCacheReader() {
485e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (mpHeader) { free(mpHeader); }
495e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (mpCachedDependTable) { free(mpCachedDependTable); }
505e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (mpPragmaList) { free(mpPragmaList); }
515e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (mpFuncTable) { free(mpFuncTable); }
525e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
535e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
545e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei LiaoScriptCached *MCCacheReader::readCacheFile(FileHandle *objFile, FileHandle *infoFile, Script *S) {
555e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  // Check file handle
565e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (!objFile || objFile->getFD() < 0 || !infoFile || infoFile->getFD() < 0) {
575e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
585e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
595e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
605e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  mObjFile = objFile;
615e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  mInfoFile = infoFile;
625e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
635e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  // Allocate ScriptCached object
645e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  mpResult.reset(new (nothrow) ScriptCached(S));
655e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
665e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (!mpResult) {
675e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Unable to allocate ScriptCached object.\n");
685e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return NULL;
695e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
705e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
715e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  bool result = checkFileSize()
725e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && readHeader()
735e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && checkHeader()
745e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && checkMachineIntType()
755e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && checkSectionOffsetAndSize()
765e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && readStringPool()
775e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && checkStringPool()
785e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && readDependencyTable()
795e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && checkDependency()
805e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && readExportVarList()
815e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && readExportFuncList()
825e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && readPragmaList()
835e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && readFuncTable()
845e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && readObjectSlotList()
855e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && readObjFile()
865e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             && relocate()
875e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao             ;
885e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
895e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return result ? mpResult.take() : NULL;
905e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
915e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
925e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
935e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::checkFileSize() {
945e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  struct stat stfile;
955e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (fstat(mInfoFile->getFD(), &stfile) < 0) {
965e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Unable to stat cache file.\n");
975e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
985e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
995e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1005e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  mInfoFileSize = stfile.st_size;
1015e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1025e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (mInfoFileSize < (off_t)sizeof(MCO_Header)) {
1035e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Cache file is too small to be correct.\n");
1045e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
1055e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
1065e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1075e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
1085e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
1095e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1105e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1115e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::readHeader() {
1125e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (mInfoFile->seek(0, SEEK_SET) != 0) {
1135e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Unable to seek to 0. (reason: %s)\n", strerror(errno));
1145e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
1155e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
1165e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1175e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  mpHeader = (MCO_Header *)malloc(sizeof(MCO_Header));
1185e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (!mpHeader) {
1195e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Unable to allocate for cache header.\n");
1205e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
1215e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
1225e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1235e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (mInfoFile->read(reinterpret_cast<char *>(mpHeader), sizeof(MCO_Header)) !=
1245e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      (ssize_t)sizeof(MCO_Header)) {
1255e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Unable to read cache header.\n");
1265e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
1275e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
1285e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1295e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  // Dirty hack for libRS.
1305e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  // TODO(all): This should be removed in the future.
1315e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (mpHeader->libRS_threadable) {
1325e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    mpResult->mLibRSThreadable = true;
1335e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
1345e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1355e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
1365e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
1375e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1385e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1395e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::checkHeader() {
1405e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (memcmp(mpHeader->magic, OBCC_MAGIC, 4) != 0) {
1415e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Bad magic word\n");
1425e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
1435e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
1445e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1455e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (memcmp(mpHeader->version, OBCC_VERSION, 4) != 0) {
1465e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    mpHeader->version[4 - 1] = '\0'; // ensure c-style string terminated
1475e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGI("Cache file format version mismatch: now %s cached %s\n",
1485e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao         OBCC_VERSION, mpHeader->version);
1495e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
1505e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
1515e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1525e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (memcmp(mpHeader->libbcc_build_time, libbcc_build_time, 24) != 0) {
1535e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    mpHeader->libbcc_build_time[24 - 1] = '\0'; // ensure terminated
1545e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGW("Build time mismatch: lib %s cached %s\n", libbcc_build_time,
1555e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao         mpHeader->libbcc_build_time);
1565e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
1575e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
1585e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1595e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
1605e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
1615e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1625e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1635e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::checkMachineIntType() {
1645e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  uint32_t number = 0x00000001;
1655e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1665e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  bool isLittleEndian = (*reinterpret_cast<char *>(&number) == 1);
1675e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if ((isLittleEndian && mpHeader->endianness != 'e') ||
1685e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      (!isLittleEndian && mpHeader->endianness != 'E')) {
1695e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Machine endianness mismatch.\n");
1705e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
1715e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
1725e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1735e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if ((unsigned int)mpHeader->sizeof_off_t != sizeof(off_t) ||
1745e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      (unsigned int)mpHeader->sizeof_size_t != sizeof(size_t) ||
1755e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      (unsigned int)mpHeader->sizeof_ptr_t != sizeof(void *)) {
1765e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Machine integer size mismatch.\n");
1775e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
1785e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
1795e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1805e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
1815e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
1825e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1835e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1845e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::checkSectionOffsetAndSize() {
1855e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#define CHECK_SECTION_OFFSET(NAME)                                          \
1865e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  do {                                                                      \
1875e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    off_t offset = mpHeader-> NAME##_offset;                                \
1885e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    off_t size = (off_t)mpHeader-> NAME##_size;                             \
1895e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                                                                            \
1905e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    if (mInfoFileSize < offset || mInfoFileSize < offset + size) {          \
1915e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      LOGE(#NAME " section overflow.\n");                                   \
1925e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      return false;                                                         \
1935e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    }                                                                       \
1945e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                                                                            \
1955e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    if (offset % sizeof(int) != 0) {                                        \
1965e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      LOGE(#NAME " offset must aligned to %d.\n", (int)sizeof(int));        \
1975e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      return false;                                                         \
1985e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    }                                                                       \
1995e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                                                                            \
2005e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    if (size < static_cast<off_t>(sizeof(size_t))) {                        \
2015e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      LOGE(#NAME " size is too small to be correct.\n");                    \
2025e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      return false;                                                         \
2035e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    }                                                                       \
2045e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  } while (0)
2055e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2065e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CHECK_SECTION_OFFSET(str_pool);
2075e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CHECK_SECTION_OFFSET(depend_tab);
2085e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  //CHECK_SECTION_OFFSET(reloc_tab);
2095e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CHECK_SECTION_OFFSET(export_var_list);
2105e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CHECK_SECTION_OFFSET(export_func_list);
2115e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CHECK_SECTION_OFFSET(pragma_list);
2125e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2135e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#undef CHECK_SECTION_OFFSET
2145e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2155e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
2165e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
2175e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2185e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2195e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#define CACHE_READER_READ_SECTION(TYPE, AUTO_MANAGED_HOLDER, NAME)          \
2205e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  TYPE *NAME##_raw = (TYPE *)malloc(mpHeader->NAME##_size);                 \
2215e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                                                                            \
2225e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (!NAME##_raw) {                                                        \
2235e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Unable to allocate for " #NAME "\n");                             \
2245e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;                                                           \
2255e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }                                                                         \
2265e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                                                                            \
2275e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  /* We have to ensure that some one will deallocate NAME##_raw */          \
2285e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  AUTO_MANAGED_HOLDER = NAME##_raw;                                         \
2295e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                                                                            \
2305e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (mInfoFile->seek(mpHeader->NAME##_offset, SEEK_SET) == -1) {           \
2315e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Unable to seek to " #NAME " section\n");                          \
2325e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;                                                           \
2335e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }                                                                         \
2345e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                                                                            \
2355e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (mInfoFile->read(reinterpret_cast<char *>(NAME##_raw),                 \
2365e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                  mpHeader->NAME##_size) != (ssize_t)mpHeader->NAME##_size) \
2375e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  {                                                                         \
2385e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Unable to read " #NAME ".\n");                                    \
2395e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;                                                           \
2405e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
2415e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2425e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2435e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::readStringPool() {
2445e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CACHE_READER_READ_SECTION(OBCC_StringPool,
2455e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                            mpResult->mpStringPoolRaw, str_pool);
2465e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2475e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  char *str_base = reinterpret_cast<char *>(str_pool_raw);
2485e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2495e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  vector<char const *> &pool = mpResult->mStringPool;
2505e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  for (size_t i = 0; i < str_pool_raw->count; ++i) {
2515e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    char *str = str_base + str_pool_raw->list[i].offset;
2525e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    pool.push_back(str);
2535e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
2545e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2555e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
2565e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
2575e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2585e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2595e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::checkStringPool() {
2605e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  OBCC_StringPool *poolR = mpResult->mpStringPoolRaw;
2615e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  vector<char const *> &pool = mpResult->mStringPool;
2625e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2635e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  // Ensure that every c-style string is ended with '\0'
2645e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  for (size_t i = 0; i < poolR->count; ++i) {
2655e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    if (pool[i][poolR->list[i].length] != '\0') {
2665e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      LOGE("The %lu-th string does not end with '\\0'.\n", (unsigned long)i);
2675e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      return false;
2685e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    }
2695e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
2705e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2715e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
2725e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
2735e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2745e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2755e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::readDependencyTable() {
2765e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CACHE_READER_READ_SECTION(OBCC_DependencyTable, mpCachedDependTable,
2775e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                            depend_tab);
2785e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
2795e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
2805e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2815e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2825e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::checkDependency() {
2835e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (mDependencies.size() != mpCachedDependTable->count) {
2845e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Dependencies count mismatch. (%lu vs %lu)\n",
2855e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao         (unsigned long)mDependencies.size(),
2865e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao         (unsigned long)mpCachedDependTable->count);
2875e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
2885e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
2895e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2905e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  vector<char const *> &strPool = mpResult->mStringPool;
2915e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  map<string, pair<uint32_t, unsigned char const *> >::iterator dep;
2925e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2935e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  dep = mDependencies.begin();
2945e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  for (size_t i = 0; i < mpCachedDependTable->count; ++i, ++dep) {
2955e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    string const &depName = dep->first;
2965e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    uint32_t depType = dep->second.first;
2975e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    unsigned char const *depSHA1 = dep->second.second;
2985e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
2995e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    OBCC_Dependency *depCached =&mpCachedDependTable->table[i];
3005e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    char const *depCachedName = strPool[depCached->res_name_strp_index];
3015e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    uint32_t depCachedType = depCached->res_type;
3025e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    unsigned char const *depCachedSHA1 = depCached->sha1;
3035e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3045e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    if (depName != depCachedName) {
3055e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      LOGE("Cache dependency name mismatch:\n");
3065e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      LOGE("  given:  %s\n", depName.c_str());
3075e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      LOGE("  cached: %s\n", depCachedName);
3085e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3095e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      return false;
3105e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    }
3115e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3125e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    if (memcmp(depSHA1, depCachedSHA1, 20) != 0) {
3135e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      LOGE("Cache dependency %s sha1 mismatch:\n", depCachedName);
3145e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3155e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#define PRINT_SHA1(PREFIX, X, POSTFIX) \
3165e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      LOGE(PREFIX "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \
3175e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                  "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" POSTFIX, \
3185e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao           X[0], X[1], X[2], X[3], X[4], X[5], X[6], X[7], X[8], X[9], \
3195e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao           X[10],X[11],X[12],X[13],X[14],X[15],X[16],X[17],X[18],X[19]);
3205e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3215e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      PRINT_SHA1("  given:  ", depSHA1, "\n");
3225e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      PRINT_SHA1("  cached: ", depCachedSHA1, "\n");
3235e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3245e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#undef PRINT_SHA1
3255e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3265e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      return false;
3275e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    }
3285e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3295e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    if (depType != depCachedType) {
3305e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      LOGE("Cache dependency %s resource type mismatch.\n", depCachedName);
3315e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      return false;
3325e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    }
3335e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
3345e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3355e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
3365e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
3375e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3385e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::readExportVarList() {
3395e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CACHE_READER_READ_SECTION(OBCC_ExportVarList,
3405e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                            mpResult->mpExportVars, export_var_list);
3415e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
3425e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
3435e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3445e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3455e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::readExportFuncList() {
3465e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CACHE_READER_READ_SECTION(OBCC_ExportFuncList,
3475e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                            mpResult->mpExportFuncs, export_func_list);
3485e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
3495e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
3505e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3515e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3525e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::readPragmaList() {
3535e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CACHE_READER_READ_SECTION(OBCC_PragmaList, mpPragmaList, pragma_list);
3545e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3555e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  vector<char const *> const &strPool = mpResult->mStringPool;
3565e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  ScriptCached::PragmaList &pragmas = mpResult->mPragmas;
3575e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3585e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  for (size_t i = 0; i < pragma_list_raw->count; ++i) {
3595e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    OBCC_Pragma *pragma = &pragma_list_raw->list[i];
3605e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    pragmas.push_back(make_pair(strPool[pragma->key_strp_index],
3615e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                                strPool[pragma->value_strp_index]));
3625e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
3635e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3645e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
3655e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
3665e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3675e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3685e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::readObjectSlotList() {
3695e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CACHE_READER_READ_SECTION(OBCC_ObjectSlotList,
3705e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                            mpResult->mpObjectSlotList, object_slot_list);
3715e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
3725e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
3735e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3745e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaovoid *MCCacheReader::resolveSymbolAdapter(void *context, char const *name) {
3755e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  MCCacheReader *self = reinterpret_cast<MCCacheReader *>(context);
3765e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3775e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (void *Addr = FindRuntimeFunction(name)) {
3785e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return Addr;
3795e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
3805e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3815e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (self->mpSymbolLookupFn) {
3825e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
3835e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      return Addr;
3845e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    }
3855e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
3865e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3875e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  LOGE("Unable to resolve symbol: %s\n", name);
3885e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return NULL;
3895e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
3905e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
3915e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::readObjFile() {
3925e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  llvm::SmallVector<char, 1024> mEmittedELFExecutable;
3935e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  char readBuffer[1024];
3945e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  int readSize;
3955e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  while ((readSize = mObjFile->read(readBuffer, 1024)) > 0) {
3965e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    mEmittedELFExecutable.append(readBuffer, readBuffer + readSize);
3975e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
3985e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  if (readSize != 0) {
3995e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    LOGE("Read file Error");
4005e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    return false;
4015e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
4025e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  LOGD("Read object file size %d", mEmittedELFExecutable.size());
4035e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  mpResult->mRSExecutable =
4045e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
4055e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                     mEmittedELFExecutable.size(),
4065e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                     &resolveSymbolAdapter, this);
4075e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
4085e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
4095e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
4105e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::readFuncTable() {
4115e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  CACHE_READER_READ_SECTION(OBCC_FuncTable, mpFuncTable, func_table);
4125e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
4135e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  vector<char const *> &strPool = mpResult->mStringPool;
4145e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  ScriptCached::FuncTable &table = mpResult->mFunctions;
4155e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  for (size_t i = 0; i < func_table_raw->count; ++i) {
4165e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    OBCC_FuncInfo *func = &func_table_raw->table[i];
4175e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    table.insert(make_pair(strPool[func->name_strp_index],
4185e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                           make_pair(func->cached_addr, func->size)));
4195e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
4205e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
4215e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
4225e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
4235e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
4245e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#undef CACHE_READER_READ_SECTION
4255e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
4265e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::readRelocationTable() {
4275e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  // TODO(logan): Not finished.
4285e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
4295e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
4305e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
4315e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
4325e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaobool MCCacheReader::relocate() {
4335e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  void *rootPtr = rsloaderGetSymbolAddress(mpResult->mRSExecutable, "root");
4345e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  int mRootOffset = reinterpret_cast<char *>(rootPtr) -
4355e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao                    reinterpret_cast<char *>(mpHeader->root_base_addr);
4365e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  for (size_t i = 0; i < mpResult->getExportVarCount(); ++i) {
4375e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    mpResult->mpExportVars->cached_addr_list[i] =
4385e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    reinterpret_cast<void *>(reinterpret_cast<char *>(mpResult->mpExportVars->cached_addr_list[i]) + mRootOffset);
4395e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
4405e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  for (size_t i = 0; i < mpResult->getExportFuncCount(); ++i) {
4415e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    mpResult->mpExportFuncs->cached_addr_list[i] =
4425e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    reinterpret_cast<void *>(reinterpret_cast<char *>(mpResult->mpExportFuncs->cached_addr_list[i]) + mRootOffset);
4435e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  }
4445e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao  return true;
4455e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao}
4465e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
4475e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
4485e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao} // namespace bcc
4495e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#endif
450