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