1a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan/* 2a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * Copyright 2010, The Android Open Source Project 3a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * 4a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * Licensed under the Apache License, Version 2.0 (the "License"); 5a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * you may not use this file except in compliance with the License. 6a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * You may obtain a copy of the License at 7a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * 8a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * http://www.apache.org/licenses/LICENSE-2.0 9a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * 10a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * Unless required by applicable law or agreed to in writing, software 11a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * distributed under the License is distributed on an "AS IS" BASIS, 12a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * See the License for the specific language governing permissions and 14a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan * limitations under the License. 15a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan */ 16a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 17a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include "CacheWriter.h" 18a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 19a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include "ContextManager.h" 204dcd6798f3db374a056ea6acc6b425f544c5207cLogan#include "DebugHelper.h" 21a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include "FileHandle.h" 22a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include "Script.h" 23a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 24a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <map> 25a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <string> 26a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <vector> 27a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <utility> 28a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 29a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <stdint.h> 30a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <stdlib.h> 31a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <string.h> 32a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 33a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganusing namespace std; 34a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 35a27a83f2b01b1710238d077dc9dfd7655f4513cdLogannamespace bcc { 36a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 379d93894295ac70d85c5792da4c1398391fb67915LoganCacheWriter::~CacheWriter() { 389d93894295ac70d85c5792da4c1398391fb67915Logan#define CHECK_AND_FREE(VAR) if (VAR) { free(VAR); } 399d93894295ac70d85c5792da4c1398391fb67915Logan 409d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpHeaderSection); 419d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpStringPoolSection); 429d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpDependencyTableSection); 439d93894295ac70d85c5792da4c1398391fb67915Logan //CHECK_AND_FREE(mpRelocationTableSection); 449d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpExportVarListSection); 459d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpExportFuncListSection); 469d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpPragmaListSection); 479d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpFuncTableSection); 48071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines CHECK_AND_FREE(mpObjectSlotSection); 499d93894295ac70d85c5792da4c1398391fb67915Logan 509d93894295ac70d85c5792da4c1398391fb67915Logan#undef CHECK_AND_FREE 519d93894295ac70d85c5792da4c1398391fb67915Logan} 529d93894295ac70d85c5792da4c1398391fb67915Logan 5303a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chienbool CacheWriter::writeCacheFile(FileHandle *objFile, 5403a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien FileHandle *infoFile, 5503a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien Script *S, 56a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan uint32_t libRS_threadable) { 5703a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (!objFile || objFile->getFD() < 0 || 5803a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien !infoFile || infoFile->getFD() < 0) { 59a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 60a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 61a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 6203a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien mObjFile = objFile; 6303a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien mInfoFile = infoFile; 64a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner = S; 65a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 66a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan bool result = prepareHeader(libRS_threadable) 67a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && prepareDependencyTable() 68a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && prepareFuncTable() 69a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && preparePragmaList() 70a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan //&& prepareRelocationTable() 71a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && prepareStringPool() 72a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && prepareExportVarList() 73a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && prepareExportFuncList() 74071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines && prepareObjectSlotList() 75a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && calcSectionOffset() 76a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && calcContextChecksum() 77a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && writeAll() 78a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan ; 79a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 80a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return result; 81a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 82a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 83a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 84a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareHeader(uint32_t libRS_threadable) { 85a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_Header *header = (OBCC_Header *)malloc(sizeof(OBCC_Header)); 86a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 87a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!header) { 88a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for header.\n"); 89a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 90a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 91a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 92a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection = header; 93a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 94a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Initialize 95a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memset(header, '\0', sizeof(OBCC_Header)); 96a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 97f7cfc026ec9e3a307d1252c46be9a089d74d3ef3Shih-wei Liao // Magic word and version 98a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(header->magic, OBCC_MAGIC, 4); 99a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(header->version, OBCC_VERSION, 4); 100a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 101a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Machine Integer Type 102a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan uint32_t number = 0x00000001; 103a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->endianness = (*reinterpret_cast<char *>(&number) == 1) ? 'e' : 'E'; 104a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->sizeof_off_t = sizeof(off_t); 105a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->sizeof_size_t = sizeof(size_t); 106a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->sizeof_ptr_t = sizeof(void *); 107a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 108a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Context 109a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->context_cached_addr = mpOwner->getContext(); 110a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 111a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // libRS is threadable dirty hack 112a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // TODO: This should be removed in the future 113a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->libRS_threadable = libRS_threadable; 114a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 115a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 116a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 117a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 118a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 119a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareDependencyTable() { 120a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t tableSize = sizeof(OBCC_DependencyTable) + 121a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_Dependency) * mDependencies.size(); 122a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 123a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_DependencyTable *tab = (OBCC_DependencyTable *)malloc(tableSize); 124f7cfc026ec9e3a307d1252c46be9a089d74d3ef3Shih-wei Liao 125a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!tab) { 126a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for dependency table section.\n"); 127a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 128a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 129a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 130a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpDependencyTableSection = tab; 131a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->depend_tab_size = tableSize; 132a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 133a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan tab->count = mDependencies.size(); 134a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 135a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t i = 0; 136a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (map<string, pair<uint32_t, unsigned char const *> >::iterator 137a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan I = mDependencies.begin(), E = mDependencies.end(); I != E; ++I, ++i) { 138a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_Dependency *dep = &tab->table[i]; 139a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 140a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan dep->res_name_strp_index = addString(I->first.c_str(), I->first.size()); 141a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan dep->res_type = I->second.first; 142a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(dep->sha1, I->second.second, 20); 143a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 144a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 145a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 146a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 147a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 148a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 149a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareFuncTable() { 150be79ada39b5e77b638940d2e157a45904ee09275Logan size_t funcCount = mpOwner->getFuncCount(); 151a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 152a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t tableSize = sizeof(OBCC_FuncTable) + 153a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_FuncInfo) * funcCount; 154a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 155a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_FuncTable *tab = (OBCC_FuncTable *)malloc(tableSize); 156a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 157a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!tab) { 158a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for function table section.\n"); 159a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 160a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 161a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 162a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpFuncTableSection = tab; 163f7cfc026ec9e3a307d1252c46be9a089d74d3ef3Shih-wei Liao mpHeaderSection->func_table_size = tableSize; 164a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 165a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan tab->count = static_cast<size_t>(funcCount); 166a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 167f7cfc026ec9e3a307d1252c46be9a089d74d3ef3Shih-wei Liao // Get the function informations 168f340bf71ff377979d279132dcf5a801d76747d1fLogan vector<FuncInfo> funcInfoList(funcCount); 169f340bf71ff377979d279132dcf5a801d76747d1fLogan mpOwner->getFuncInfoList(funcCount, &*funcInfoList.begin()); 170a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 171be79ada39b5e77b638940d2e157a45904ee09275Logan for (size_t i = 0; i < funcCount; ++i) { 172f340bf71ff377979d279132dcf5a801d76747d1fLogan FuncInfo *info = &funcInfoList[i]; 173f340bf71ff377979d279132dcf5a801d76747d1fLogan OBCC_FuncInfo *outputInfo = &tab->table[i]; 174a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 175f340bf71ff377979d279132dcf5a801d76747d1fLogan outputInfo->name_strp_index = addString(info->name, strlen(info->name)); 176f340bf71ff377979d279132dcf5a801d76747d1fLogan outputInfo->cached_addr = info->addr; 177f340bf71ff377979d279132dcf5a801d76747d1fLogan outputInfo->size = info->size; 178a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 179a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 180a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 181a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 182a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 183a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 184a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::preparePragmaList() { 185be79ada39b5e77b638940d2e157a45904ee09275Logan size_t pragmaCount = mpOwner->getPragmaCount(); 186a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 187a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t listSize = sizeof(OBCC_PragmaList) + 188a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_Pragma) * pragmaCount; 189a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 190a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_PragmaList *list = (OBCC_PragmaList *)malloc(listSize); 191a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 192a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!list) { 193a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for pragma list\n"); 194a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 195a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 196a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 197a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpPragmaListSection = list; 198a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->pragma_list_size = listSize; 199a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 200a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan list->count = pragmaCount; 201a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 202be79ada39b5e77b638940d2e157a45904ee09275Logan vector<char const *> keyList(pragmaCount); 203be79ada39b5e77b638940d2e157a45904ee09275Logan vector<char const *> valueList(pragmaCount); 204be79ada39b5e77b638940d2e157a45904ee09275Logan mpOwner->getPragmaList(pragmaCount, &*keyList.begin(), &*valueList.begin()); 205a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 206a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (size_t i = 0; i < pragmaCount; ++i) { 207be79ada39b5e77b638940d2e157a45904ee09275Logan char const *key = keyList[i]; 208be79ada39b5e77b638940d2e157a45904ee09275Logan char const *value = valueList[i]; 209a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 210be79ada39b5e77b638940d2e157a45904ee09275Logan size_t keyLen = strlen(key); 211a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t valueLen = strlen(value); 212a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 213a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_Pragma *pragma = &list->list[i]; 214a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan pragma->key_strp_index = addString(key, keyLen); 215a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan pragma->value_strp_index = addString(value, valueLen); 216a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 217a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 218a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 219a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 220a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 221a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 222a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareRelocationTable() { 223a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // TODO(logan): Implement relocation table cache write. 224a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 225a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 226a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 227a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 228a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareStringPool() { 229a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Calculate string pool size 230a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t size = sizeof(OBCC_StringPool) + 231a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_String) * mStringPool.size(); 232a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 233a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan off_t strOffset = size; 234a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 235a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (size_t i = 0; i < mStringPool.size(); ++i) { 236a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size += mStringPool[i].second + 1; 237a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 238a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 239a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Create string pool 240a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_StringPool *pool = (OBCC_StringPool *)malloc(size); 241a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 242a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!pool) { 243a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate string pool.\n"); 244a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 245a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 246a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 247a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpStringPoolSection = pool; 248a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->str_pool_size = size; 249a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 250a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan pool->count = mStringPool.size(); 251a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan 252a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan char *strPtr = reinterpret_cast<char *>(pool) + strOffset; 253a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 254a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (size_t i = 0; i < mStringPool.size(); ++i) { 255a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_String *str = &pool->list[i]; 256a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 257a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan str->length = mStringPool[i].second; 258a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan str->offset = strOffset; 259a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(strPtr, mStringPool[i].first, str->length); 260a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 261a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan strPtr += str->length; 262a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan *strPtr++ = '\0'; 263a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 264a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan strOffset += str->length + 1; 265a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 266a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 267a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 268a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 269a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 270a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 271a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareExportVarList() { 272be79ada39b5e77b638940d2e157a45904ee09275Logan size_t varCount = mpOwner->getExportVarCount(); 273a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t listSize = sizeof(OBCC_ExportVarList) + sizeof(void *) * varCount; 274a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 275a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_ExportVarList *list = (OBCC_ExportVarList *)malloc(listSize); 276a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 277a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!list) { 278a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for export variable list\n"); 279a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 280a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 281a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 282a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpExportVarListSection = list; 283a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->export_var_list_size = listSize; 284a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 285a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan list->count = static_cast<size_t>(varCount); 286a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 287be79ada39b5e77b638940d2e157a45904ee09275Logan mpOwner->getExportVarList(varCount, list->cached_addr_list); 288a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 289a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 290a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 291a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 292a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareExportFuncList() { 293be79ada39b5e77b638940d2e157a45904ee09275Logan size_t funcCount = mpOwner->getExportFuncCount(); 294a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t listSize = sizeof(OBCC_ExportFuncList) + sizeof(void *) * funcCount; 295a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 296a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_ExportFuncList *list = (OBCC_ExportFuncList *)malloc(listSize); 297a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 298a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!list) { 299a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for export function list\n"); 300a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 301a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 302a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 303a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpExportFuncListSection = list; 304a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->export_func_list_size = listSize; 305a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 306a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan list->count = static_cast<size_t>(funcCount); 307a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 308be79ada39b5e77b638940d2e157a45904ee09275Logan mpOwner->getExportFuncList(funcCount, list->cached_addr_list); 309a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 310a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 311a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 312a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 313071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hinesbool CacheWriter::prepareObjectSlotList() { 314071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines size_t objectSlotCount = mpOwner->getObjectSlotCount(); 315071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 316071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines size_t listSize = sizeof(OBCC_ObjectSlotList) + 317071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines sizeof(uint32_t) * objectSlotCount; 318071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 319071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines OBCC_ObjectSlotList *list = (OBCC_ObjectSlotList *)malloc(listSize); 320071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 321071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines if (!list) { 322071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines LOGE("Unable to allocate for object slot list\n"); 323071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines return false; 324071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines } 325071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 326071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines mpObjectSlotSection = list; 327071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines mpHeaderSection->object_slot_list_size = listSize; 328071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 329071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines list->count = objectSlotCount; 330071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 331071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines mpOwner->getObjectSlotList(objectSlotCount, list->object_slot_list); 332071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines return true; 333071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines} 334071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 335071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines 336a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::calcSectionOffset() { 337a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t offset = sizeof(OBCC_Header); 338a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 339a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#define OFFSET_INCREASE(NAME) \ 340a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan do { \ 341a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan /* Align to a word */ \ 342a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t rem = offset % sizeof(int); \ 343a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (rem > 0) { \ 344a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan offset += sizeof(int) - rem; \ 345a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } \ 346a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan \ 347a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan /* Save the offset and increase it */ \ 348a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->NAME##_offset = offset; \ 349a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan offset += mpHeaderSection->NAME##_size; \ 350a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } while (0) 351a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 352a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(str_pool); 353a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(depend_tab); 354a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan //OFFSET_INCREASE(reloc_tab); 355a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(export_var_list); 356a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(export_func_list); 357a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(pragma_list); 358a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(func_table); 359071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines OFFSET_INCREASE(object_slot_list); 360a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 361a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#undef OFFSET_INCREASE 362a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 363a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 364a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 365a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 366a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::calcContextChecksum() { 367a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan uint32_t sum = 0; 368a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan uint32_t *ptr = reinterpret_cast<uint32_t *>(mpOwner->getContext()); 369a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 3701dc6314a03b320f9ba5431834c2deeba13f5f065Logan for (size_t i = 0; i < ContextManager::ContextSize / sizeof(uint32_t); ++i) { 371a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sum ^= *ptr++; 372a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 373a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 374a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->context_parity_checksum = sum; 375a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 376a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 377a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 378a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 379a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::writeAll() { 380a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#define WRITE_SECTION(NAME, OFFSET, SIZE, SECTION) \ 381a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan do { \ 38203a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (mInfoFile->seek(OFFSET, SEEK_SET) == -1) { \ 383a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to seek to " #NAME " section for writing.\n"); \ 384a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; \ 385a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } \ 386a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan \ 38703a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (mInfoFile->write(reinterpret_cast<char *>(SECTION), (SIZE)) != \ 388a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan static_cast<ssize_t>(SIZE)) { \ 389a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to write " #NAME " section to cache file.\n"); \ 390a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; \ 391a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } \ 392a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } while (0) 393a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 394a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#define WRITE_SECTION_SIMPLE(NAME, SECTION) \ 395a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION(NAME, \ 396a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->NAME##_offset, \ 397a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->NAME##_size, \ 398a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan SECTION) 399a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 400a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION(header, 0, sizeof(OBCC_Header), mpHeaderSection); 401a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 402a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(str_pool, mpStringPoolSection); 403a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(depend_tab, mpDependencyTableSection); 404a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan //WRITE_SECTION_SIMPLE(reloc_tab, mpRelocationTableSection); 405a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(export_var_list, mpExportVarListSection); 406a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(export_func_list, mpExportFuncListSection); 407a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(pragma_list, mpPragmaListSection); 408a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(func_table, mpFuncTableSection); 409071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines WRITE_SECTION_SIMPLE(object_slot_list, mpObjectSlotSection); 410a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 411a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#undef WRITE_SECTION_SIMPLE 412a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#undef WRITE_SECTION 413a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 41403a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien 41503a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien // Write Context to Executable File 41603a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien char const *context = (char const *)mpOwner->getContext(); 41703a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien size_t context_size = ContextManager::ContextSize; 41803a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien if (mObjFile->write(context, context_size) != (ssize_t)context_size) { 41903a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien LOGE("Unable to write context image to executable file\n"); 42003a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien return false; 42103a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien } 42203a2e30e9ee0e3a880eb60f5047302d216db9582Logan Chien 423a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 424a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 425a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 426a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 427a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} // namespace bcc 428