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