14a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines/*
24a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines * Copyright 2010-2012, The Android Open Source Project
34a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines *
44a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
54a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines * you may not use this file except in compliance with the License.
64a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines * You may obtain a copy of the License at
74a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines *
84a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
94a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines *
104a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines * Unless required by applicable law or agreed to in writing, software
114a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
124a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines * See the License for the specific language governing permissions and
144a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines * limitations under the License.
154a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines */
164a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
174a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "MCCacheWriter.h"
184a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
194a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include "DebugHelper.h"
20758d00c68b5bb43ed8062563bdd55285b883e8caStephen Hines#include "FileHandle.h"
2197c92c2d0604ea9cc4cd878f0f1901efc79c8835Stephen Hines#include "Script.h"
224a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
234a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <map>
244a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <string>
254a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <vector>
264a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <utility>
274a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
284a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <stdint.h>
294a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <stdlib.h>
304a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#include <string.h>
314a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
324a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesusing namespace std;
334a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
344a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesnamespace bcc {
354a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
364a68b1cb89df9507584a51c3444aff99347afb74Stephen HinesMCCacheWriter::~MCCacheWriter() {
374a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#define CHECK_AND_FREE(VAR) if (VAR) { free(VAR); }
384a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
394a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  CHECK_AND_FREE(mpHeaderSection);
404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  CHECK_AND_FREE(mpStringPoolSection);
414a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  CHECK_AND_FREE(mpDependencyTableSection);
424a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  CHECK_AND_FREE(mpPragmaListSection);
434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  CHECK_AND_FREE(mpObjectSlotSection);
444a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  CHECK_AND_FREE(mpExportVarNameListSection);
454a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  CHECK_AND_FREE(mpExportFuncNameListSection);
464a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
474a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#undef CHECK_AND_FREE
484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
494a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
50758d00c68b5bb43ed8062563bdd55285b883e8caStephen Hinesbool MCCacheWriter::writeCacheFile(FileHandle *objFile, FileHandle *infoFile,
5197c92c2d0604ea9cc4cd878f0f1901efc79c8835Stephen Hines                                 Script *S, uint32_t libRS_threadable) {
52758d00c68b5bb43ed8062563bdd55285b883e8caStephen Hines  if (!objFile || objFile->getFD() < 0 || !infoFile || infoFile->getFD() < 0) {
534a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return false;
544a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
554a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
56758d00c68b5bb43ed8062563bdd55285b883e8caStephen Hines  mObjFile = objFile;
57758d00c68b5bb43ed8062563bdd55285b883e8caStephen Hines  mInfoFile = infoFile;
584a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpOwner = S;
594a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
604a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  bool result = prepareHeader(libRS_threadable)
614a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines             && prepareDependencyTable()
624a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines             && preparePragmaList()
634a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines             && prepareExportVarNameList()
644a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines             && prepareExportFuncNameList()
654a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines             && prepareExportForEachNameList()
664a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines             && prepareStringPool()
674a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines             && prepareObjectSlotList()
684a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines             && calcSectionOffset()
694a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines             && writeAll()
704a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines             ;
714a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
724a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return result;
734a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
744a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
754a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
764a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesbool MCCacheWriter::prepareHeader(uint32_t libRS_threadable) {
774a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  MCO_Header *header = (MCO_Header *)malloc(sizeof(MCO_Header));
784a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
794a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (!header) {
804a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ALOGE("Unable to allocate for header.\n");
814a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return false;
824a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
834a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
844a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpHeaderSection = header;
854a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
864a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Initialize
874a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  memset(header, '\0', sizeof(MCO_Header));
884a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
894a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Magic word and version
904a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  memcpy(header->magic, MCO_MAGIC, 4);
914a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  memcpy(header->version, MCO_VERSION, 4);
924a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
934a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Machine Integer Type
944a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  uint32_t number = 0x00000001;
954a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  header->endianness = (*reinterpret_cast<char *>(&number) == 1) ? 'e' : 'E';
964a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  header->sizeof_off_t = sizeof(off_t);
974a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  header->sizeof_size_t = sizeof(size_t);
984a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  header->sizeof_ptr_t = sizeof(void *);
994a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1004a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // libRS is threadable dirty hack
1014a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // TODO: This should be removed in the future
1024a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  header->libRS_threadable = libRS_threadable;
1034a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1044a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return true;
1054a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
1064a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1074a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1084a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesbool MCCacheWriter::prepareDependencyTable() {
1094a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t tableSize = sizeof(MCO_DependencyTable) +
1104a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                     sizeof(MCO_Dependency) * mDependencies.size();
1114a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1124a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  MCO_DependencyTable *tab = (MCO_DependencyTable *)malloc(tableSize);
1134a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1144a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (!tab) {
1154a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ALOGE("Unable to allocate for dependency table section.\n");
1164a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return false;
1174a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
1184a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1194a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpDependencyTableSection = tab;
1204a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpHeaderSection->depend_tab_size = tableSize;
1214a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1224a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  tab->count = mDependencies.size();
1234a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1244a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t i = 0;
1250f6b1d319d0d3605042345c4a6973e9c4e9161d7Stephen Hines  for (map<string, pair<uint32_t, unsigned char const *> >::iterator
1264a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines       I = mDependencies.begin(), E = mDependencies.end(); I != E; ++I, ++i) {
1274a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    MCO_Dependency *dep = &tab->table[i];
1284a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1294a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    dep->res_name_strp_index = addString(I->first.c_str(), I->first.size());
1300f6b1d319d0d3605042345c4a6973e9c4e9161d7Stephen Hines    dep->res_type = I->second.first;
1310f6b1d319d0d3605042345c4a6973e9c4e9161d7Stephen Hines    memcpy(dep->sha1, I->second.second, 20);
1324a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
1334a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1344a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return true;
1354a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
1364a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1374a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesbool MCCacheWriter::preparePragmaList() {
1384a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t pragmaCount = mpOwner->getPragmaCount();
1394a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t listSize = sizeof(MCO_PragmaList) +
1414a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                    sizeof(MCO_Pragma) * pragmaCount;
1424a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  MCO_PragmaList *list = (MCO_PragmaList *)malloc(listSize);
1444a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1454a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (!list) {
1464a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ALOGE("Unable to allocate for pragma list\n");
1474a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return false;
1484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
1494a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1504a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpPragmaListSection = list;
1514a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpHeaderSection->pragma_list_size = listSize;
1524a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1534a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  list->count = pragmaCount;
1544a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1554a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  vector<char const *> keyList(pragmaCount);
1564a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  vector<char const *> valueList(pragmaCount);
1574a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpOwner->getPragmaList(pragmaCount, &*keyList.begin(), &*valueList.begin());
1584a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1594a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  for (size_t i = 0; i < pragmaCount; ++i) {
1604a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    char const *key = keyList[i];
1614a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    char const *value = valueList[i];
1624a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1634a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    size_t keyLen = strlen(key);
1644a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    size_t valueLen = strlen(value);
1654a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1664a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    MCO_Pragma *pragma = &list->list[i];
1674a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    pragma->key_strp_index = addString(key, keyLen);
1684a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    pragma->value_strp_index = addString(value, valueLen);
1694a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
1704a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1714a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return true;
1724a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
1734a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1744a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesbool MCCacheWriter::prepareStringPool() {
1754a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Calculate string pool size
1764a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t size = sizeof(MCO_StringPool) +
1774a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                sizeof(MCO_String) * mStringPool.size();
1784a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1794a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  off_t strOffset = size;
1804a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1814a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  for (size_t i = 0; i < mStringPool.size(); ++i) {
1824a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    size += mStringPool[i].second + 1;
1834a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
1844a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1854a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  // Create string pool
1864a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  MCO_StringPool *pool = (MCO_StringPool *)malloc(size);
1874a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1884a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (!pool) {
1894a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ALOGE("Unable to allocate string pool.\n");
1904a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return false;
1914a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
1924a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1934a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpStringPoolSection = pool;
1944a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpHeaderSection->str_pool_size = size;
1954a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1964a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  pool->count = mStringPool.size();
1974a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
1984a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  char *strPtr = reinterpret_cast<char *>(pool) + strOffset;
1994a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2004a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  for (size_t i = 0; i < mStringPool.size(); ++i) {
2014a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    MCO_String *str = &pool->list[i];
2024a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2034a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    str->length = mStringPool[i].second;
2044a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    str->offset = strOffset;
2054a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    memcpy(strPtr, mStringPool[i].first, str->length);
2064a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2074a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    strPtr += str->length;
2084a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    *strPtr++ = '\0';
2094a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2104a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    strOffset += str->length + 1;
2114a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
2124a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2134a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return true;
2144a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
2154a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2164a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2174a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesbool MCCacheWriter::prepareExportVarNameList() {
2184a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t varCount = mpOwner->getExportVarCount();
2194a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t listSize = sizeof(MCO_String_Ptr) + sizeof(size_t) * varCount;
2204a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2214a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  MCO_String_Ptr *list = (MCO_String_Ptr*)malloc(listSize);
2224a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2234a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (!list) {
2244a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ALOGE("Unable to allocate for export variable name list\n");
2254a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return false;
2264a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
2274a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2284a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpExportVarNameListSection = list;
2294a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpHeaderSection->export_var_name_list_size = listSize;
2304a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2314a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  list->count = static_cast<size_t>(varCount);
2324a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2334a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpOwner->getExportVarNameList(varNameList);
2344a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  for (size_t i = 0; i < varCount; ++i) {
2354a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    list->strp_indexs[i] = addString(varNameList[i].c_str(), varNameList[i].length());
2364a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
2374a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return true;
2384a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
2394a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2414a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesbool MCCacheWriter::prepareExportFuncNameList() {
2424a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t funcCount = mpOwner->getExportFuncCount();
2434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t listSize = sizeof(MCO_String_Ptr) + sizeof(size_t) * funcCount;
2444a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2454a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  MCO_String_Ptr *list = (MCO_String_Ptr*)malloc(listSize);
2464a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2474a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (!list) {
2484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ALOGE("Unable to allocate for export function name list\n");
2494a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return false;
2504a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
2514a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2524a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpExportFuncNameListSection = list;
2534a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpHeaderSection->export_func_name_list_size = listSize;
2544a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2554a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  list->count = static_cast<size_t>(funcCount);
2564a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2574a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpOwner->getExportFuncNameList(funcNameList);
2584a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  for (size_t i = 0; i < funcCount; ++i) {
2594a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    list->strp_indexs[i] = addString(funcNameList[i].c_str(), funcNameList[i].length());
2604a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
2614a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return true;
2624a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
2634a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2644a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2654a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesbool MCCacheWriter::prepareExportForEachNameList() {
2664a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t forEachCount = mpOwner->getExportForEachCount();
2674a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t listSize = sizeof(MCO_String_Ptr) + sizeof(size_t) * forEachCount;
2684a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2694a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  MCO_String_Ptr *list = (MCO_String_Ptr*)malloc(listSize);
2704a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2714a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (!list) {
2724a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ALOGE("Unable to allocate for export forEach name list\n");
2734a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return false;
2744a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
2754a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2764a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpExportForEachNameListSection = list;
2774a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpHeaderSection->export_foreach_name_list_size = listSize;
2784a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2794a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  list->count = static_cast<size_t>(forEachCount);
2804a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2814a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpOwner->getExportForEachNameList(forEachNameList);
2824a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  for (size_t i = 0; i < forEachCount; ++i) {
2834a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    list->strp_indexs[i] = addString(forEachNameList[i].c_str(), forEachNameList[i].length());
2844a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
2854a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return true;
2864a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
2874a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2884a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2894a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesbool MCCacheWriter::prepareObjectSlotList() {
2904a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t objectSlotCount = mpOwner->getObjectSlotCount();
2914a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2924a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t listSize = sizeof(MCO_ObjectSlotList) +
2934a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                    sizeof(uint32_t) * objectSlotCount;
2944a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2954a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  MCO_ObjectSlotList *list = (MCO_ObjectSlotList *)malloc(listSize);
2964a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
2974a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (!list) {
2984a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    ALOGE("Unable to allocate for object slot list\n");
2994a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    return false;
3004a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
3014a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3024a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpObjectSlotSection = list;
3034a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpHeaderSection->object_slot_list_size = listSize;
3044a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3054a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  list->count = objectSlotCount;
3064a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3074a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  mpOwner->getObjectSlotList(objectSlotCount, list->object_slot_list);
3084a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return true;
3094a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
3104a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3114a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3124a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesbool MCCacheWriter::calcSectionOffset() {
3134a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  size_t offset = sizeof(MCO_Header);
3144a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3154a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#define OFFSET_INCREASE(NAME)                                               \
3164a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  do {                                                                      \
3174a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    /* Align to a word */                                                   \
3184a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    size_t rem = offset % sizeof(int);                                      \
3194a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    if (rem > 0) {                                                          \
3204a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      offset += sizeof(int) - rem;                                          \
3214a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }                                                                       \
3224a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                                                                            \
3234a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    /* Save the offset and increase it */                                   \
3244a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    mpHeaderSection->NAME##_offset = offset;                                \
3254a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    offset += mpHeaderSection->NAME##_size;                                 \
3264a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  } while (0)
3274a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3284a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  OFFSET_INCREASE(str_pool);
3294a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  OFFSET_INCREASE(depend_tab);
3304a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  OFFSET_INCREASE(pragma_list);
3314a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  OFFSET_INCREASE(func_table);
3324a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  OFFSET_INCREASE(object_slot_list);
3334a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  OFFSET_INCREASE(export_var_name_list);
3344a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  OFFSET_INCREASE(export_func_name_list);
3354a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  OFFSET_INCREASE(export_foreach_name_list);
3364a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3374a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#undef OFFSET_INCREASE
3384a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3394a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return true;
3404a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
3414a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3424a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3434a68b1cb89df9507584a51c3444aff99347afb74Stephen Hinesbool MCCacheWriter::writeAll() {
3444a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#define WRITE_SECTION(NAME, OFFSET, SIZE, SECTION)                          \
3454a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  do {                                                                      \
346758d00c68b5bb43ed8062563bdd55285b883e8caStephen Hines    if (mInfoFile->seek(OFFSET, SEEK_SET) == -1) {                          \
347758d00c68b5bb43ed8062563bdd55285b883e8caStephen Hines      ALOGE("Unable to seek to " #NAME " section for writing.\n");           \
3484a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      return false;                                                         \
3494a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }                                                                       \
3504a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                                                                            \
3514a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    if (mInfoFile->write(reinterpret_cast<char *>(SECTION), (SIZE)) !=      \
3524a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines        static_cast<ssize_t>(SIZE)) {                                       \
353758d00c68b5bb43ed8062563bdd55285b883e8caStephen Hines      ALOGE("Unable to write " #NAME " section to cache file.\n");           \
3544a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      return false;                                                         \
3554a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines    }                                                                       \
3564a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  } while (0)
3574a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3584a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#define WRITE_SECTION_SIMPLE(NAME, SECTION)                                 \
3594a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  WRITE_SECTION(NAME,                                                       \
3604a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                mpHeaderSection->NAME##_offset,                             \
3614a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                mpHeaderSection->NAME##_size,                               \
3624a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                SECTION)
3634a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3644a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  WRITE_SECTION(header, 0, sizeof(MCO_Header), mpHeaderSection);
3654a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3664a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  WRITE_SECTION_SIMPLE(str_pool, mpStringPoolSection);
3674a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  WRITE_SECTION_SIMPLE(depend_tab, mpDependencyTableSection);
3684a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  WRITE_SECTION_SIMPLE(pragma_list, mpPragmaListSection);
3694a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  WRITE_SECTION_SIMPLE(object_slot_list, mpObjectSlotSection);
3704a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3714a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  WRITE_SECTION_SIMPLE(export_var_name_list, mpExportVarNameListSection);
3724a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  WRITE_SECTION_SIMPLE(export_func_name_list, mpExportFuncNameListSection);
3734a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  WRITE_SECTION_SIMPLE(export_foreach_name_list, mpExportForEachNameListSection);
3744a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3754a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#undef WRITE_SECTION_SIMPLE
3764a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines#undef WRITE_SECTION
3774a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3784a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  if (static_cast<size_t>(mObjFile->write(mpOwner->getELF(),
3794a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines                                          mpOwner->getELFSize()))
3804a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      != mpOwner->getELFSize()) {
3814a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      ALOGE("Unable to write ELF to cache file.\n");
3824a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines      return false;
3834a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  }
3844a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3854a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines  return true;
3864a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines}
3874a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines
3884a68b1cb89df9507584a51c3444aff99347afb74Stephen Hines} // namespace bcc
389