CacheWriter.cpp revision f340bf71ff377979d279132dcf5a801d76747d1f
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#define LOG_TAG "bcc" 18a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <cutils/log.h> 19a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 20a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include "CacheWriter.h" 21a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 22a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include "ContextManager.h" 23a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include "FileHandle.h" 24a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include "Script.h" 25a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 26a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <map> 27a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <string> 28a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <vector> 29a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <utility> 30a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 31a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <stdint.h> 32a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <stdlib.h> 33a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#include <string.h> 34a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 35a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganusing namespace std; 36a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 37a27a83f2b01b1710238d077dc9dfd7655f4513cdLogannamespace bcc { 38a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 399d93894295ac70d85c5792da4c1398391fb67915LoganCacheWriter::~CacheWriter() { 409d93894295ac70d85c5792da4c1398391fb67915Logan#define CHECK_AND_FREE(VAR) if (VAR) { free(VAR); } 419d93894295ac70d85c5792da4c1398391fb67915Logan 429d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpHeaderSection); 439d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpStringPoolSection); 449d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpDependencyTableSection); 459d93894295ac70d85c5792da4c1398391fb67915Logan //CHECK_AND_FREE(mpRelocationTableSection); 469d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpExportVarListSection); 479d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpExportFuncListSection); 489d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpPragmaListSection); 499d93894295ac70d85c5792da4c1398391fb67915Logan CHECK_AND_FREE(mpFuncTableSection); 509d93894295ac70d85c5792da4c1398391fb67915Logan 519d93894295ac70d85c5792da4c1398391fb67915Logan#undef CHECK_AND_FREE 529d93894295ac70d85c5792da4c1398391fb67915Logan} 539d93894295ac70d85c5792da4c1398391fb67915Logan 54a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::writeCacheFile(FileHandle *file, Script *S, 55a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan uint32_t libRS_threadable) { 56a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!file || file->getFD() < 0) { 57a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 58a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 59a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 60a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mFile = file; 61a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner = S; 62a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 63a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan bool result = prepareHeader(libRS_threadable) 64a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && prepareDependencyTable() 65a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && prepareFuncTable() 66a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && preparePragmaList() 67a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan //&& prepareRelocationTable() 68a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && prepareStringPool() 69a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && prepareExportVarList() 70a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && prepareExportFuncList() 71a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && calcSectionOffset() 72a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && calcContextChecksum() 73a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan && writeAll() 74a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan ; 75a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 76a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return result; 77a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 78a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 79a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 80a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareHeader(uint32_t libRS_threadable) { 81a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_Header *header = (OBCC_Header *)malloc(sizeof(OBCC_Header)); 82a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 83a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!header) { 84a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for header.\n"); 85a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 86a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 87a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 88a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection = header; 89a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 90a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Initialize 91a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memset(header, '\0', sizeof(OBCC_Header)); 92a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 93f7cfc026ec9e3a307d1252c46be9a089d74d3ef3Shih-wei Liao // Magic word and version 94a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(header->magic, OBCC_MAGIC, 4); 95a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(header->version, OBCC_VERSION, 4); 96e132399eb9dc93123d50e9492ac7b01c2c9a4d35Logan memcpy(header->libbcc_build_time, libbcc_build_time, 24); 97a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 98a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Machine Integer Type 99a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan uint32_t number = 0x00000001; 100a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->endianness = (*reinterpret_cast<char *>(&number) == 1) ? 'e' : 'E'; 101a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->sizeof_off_t = sizeof(off_t); 102a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->sizeof_size_t = sizeof(size_t); 103a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->sizeof_ptr_t = sizeof(void *); 104a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 105a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Context 106a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->context_cached_addr = mpOwner->getContext(); 107a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 108a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // libRS is threadable dirty hack 109a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // TODO: This should be removed in the future 110a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->libRS_threadable = libRS_threadable; 111a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 112a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 113a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 114a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 115a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 116a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareDependencyTable() { 117a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t tableSize = sizeof(OBCC_DependencyTable) + 118a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_Dependency) * mDependencies.size(); 119a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 120a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_DependencyTable *tab = (OBCC_DependencyTable *)malloc(tableSize); 121f7cfc026ec9e3a307d1252c46be9a089d74d3ef3Shih-wei Liao 122a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!tab) { 123a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for dependency table section.\n"); 124a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 125a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 126a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 127a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpDependencyTableSection = tab; 128a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->depend_tab_size = tableSize; 129a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 130a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan tab->count = mDependencies.size(); 131a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 132a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t i = 0; 133a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (map<string, pair<uint32_t, unsigned char const *> >::iterator 134a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan I = mDependencies.begin(), E = mDependencies.end(); I != E; ++I, ++i) { 135a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_Dependency *dep = &tab->table[i]; 136a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 137a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan dep->res_name_strp_index = addString(I->first.c_str(), I->first.size()); 138a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan dep->res_type = I->second.first; 139a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(dep->sha1, I->second.second, 20); 140a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 141a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 142a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 143a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 144a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 145a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 146a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareFuncTable() { 147be79ada39b5e77b638940d2e157a45904ee09275Logan size_t funcCount = mpOwner->getFuncCount(); 148a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 149a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t tableSize = sizeof(OBCC_FuncTable) + 150a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_FuncInfo) * funcCount; 151a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 152a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_FuncTable *tab = (OBCC_FuncTable *)malloc(tableSize); 153a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 154a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!tab) { 155a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for function table section.\n"); 156a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 157a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 158a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 159a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpFuncTableSection = tab; 160f7cfc026ec9e3a307d1252c46be9a089d74d3ef3Shih-wei Liao mpHeaderSection->func_table_size = tableSize; 161a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 162a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan tab->count = static_cast<size_t>(funcCount); 163a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 164f7cfc026ec9e3a307d1252c46be9a089d74d3ef3Shih-wei Liao // Get the function informations 165f340bf71ff377979d279132dcf5a801d76747d1fLogan vector<FuncInfo> funcInfoList(funcCount); 166f340bf71ff377979d279132dcf5a801d76747d1fLogan mpOwner->getFuncInfoList(funcCount, &*funcInfoList.begin()); 167a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 168be79ada39b5e77b638940d2e157a45904ee09275Logan for (size_t i = 0; i < funcCount; ++i) { 169f340bf71ff377979d279132dcf5a801d76747d1fLogan FuncInfo *info = &funcInfoList[i]; 170f340bf71ff377979d279132dcf5a801d76747d1fLogan OBCC_FuncInfo *outputInfo = &tab->table[i]; 171a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 172f340bf71ff377979d279132dcf5a801d76747d1fLogan outputInfo->name_strp_index = addString(info->name, strlen(info->name)); 173f340bf71ff377979d279132dcf5a801d76747d1fLogan outputInfo->cached_addr = info->addr; 174f340bf71ff377979d279132dcf5a801d76747d1fLogan outputInfo->size = info->size; 175a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 176a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 177a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 178a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 179a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 180a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 181a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::preparePragmaList() { 182be79ada39b5e77b638940d2e157a45904ee09275Logan size_t pragmaCount = mpOwner->getPragmaCount(); 183a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 184a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t listSize = sizeof(OBCC_PragmaList) + 185a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_Pragma) * pragmaCount; 186a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 187a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_PragmaList *list = (OBCC_PragmaList *)malloc(listSize); 188a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 189a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!list) { 190a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for pragma list\n"); 191a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 192a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 193a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 194a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpPragmaListSection = list; 195a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->pragma_list_size = listSize; 196a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 197a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan list->count = pragmaCount; 198a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 199be79ada39b5e77b638940d2e157a45904ee09275Logan vector<char const *> keyList(pragmaCount); 200be79ada39b5e77b638940d2e157a45904ee09275Logan vector<char const *> valueList(pragmaCount); 201be79ada39b5e77b638940d2e157a45904ee09275Logan mpOwner->getPragmaList(pragmaCount, &*keyList.begin(), &*valueList.begin()); 202a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 203a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (size_t i = 0; i < pragmaCount; ++i) { 204be79ada39b5e77b638940d2e157a45904ee09275Logan char const *key = keyList[i]; 205be79ada39b5e77b638940d2e157a45904ee09275Logan char const *value = valueList[i]; 206a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 207be79ada39b5e77b638940d2e157a45904ee09275Logan size_t keyLen = strlen(key); 208a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t valueLen = strlen(value); 209a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 210a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_Pragma *pragma = &list->list[i]; 211a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan pragma->key_strp_index = addString(key, keyLen); 212a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan pragma->value_strp_index = addString(value, valueLen); 213a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 214a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 215a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 216a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 217a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 218a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 219a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareRelocationTable() { 220a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // TODO(logan): Implement relocation table cache write. 221a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 222a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 223a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 224a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 225a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareStringPool() { 226a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Calculate string pool size 227a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t size = sizeof(OBCC_StringPool) + 228a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_String) * mStringPool.size(); 229a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 230a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan off_t strOffset = size; 231a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 232a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (size_t i = 0; i < mStringPool.size(); ++i) { 233a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size += mStringPool[i].second + 1; 234a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 235a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 236a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Create string pool 237a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_StringPool *pool = (OBCC_StringPool *)malloc(size); 238a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 239a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!pool) { 240a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate string pool.\n"); 241a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 242a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 243a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 244a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpStringPoolSection = pool; 245a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->str_pool_size = size; 246a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 247a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan pool->count = mStringPool.size(); 248a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan 249a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan char *strPtr = reinterpret_cast<char *>(pool) + strOffset; 250a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 251a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (size_t i = 0; i < mStringPool.size(); ++i) { 252a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_String *str = &pool->list[i]; 253a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 254a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan str->length = mStringPool[i].second; 255a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan str->offset = strOffset; 256a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(strPtr, mStringPool[i].first, str->length); 257a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 258a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan strPtr += str->length; 259a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan *strPtr++ = '\0'; 260a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 261a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan strOffset += str->length + 1; 262a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 263a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 264a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 265a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 266a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 267a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 268a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareExportVarList() { 269be79ada39b5e77b638940d2e157a45904ee09275Logan size_t varCount = mpOwner->getExportVarCount(); 270a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t listSize = sizeof(OBCC_ExportVarList) + sizeof(void *) * varCount; 271a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 272a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_ExportVarList *list = (OBCC_ExportVarList *)malloc(listSize); 273a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 274a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!list) { 275a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for export variable list\n"); 276a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 277a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 278a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 279a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpExportVarListSection = list; 280a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->export_var_list_size = listSize; 281a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 282a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan list->count = static_cast<size_t>(varCount); 283a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 284be79ada39b5e77b638940d2e157a45904ee09275Logan mpOwner->getExportVarList(varCount, list->cached_addr_list); 285a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 286a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 287a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 288a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 289a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareExportFuncList() { 290be79ada39b5e77b638940d2e157a45904ee09275Logan size_t funcCount = mpOwner->getExportFuncCount(); 291a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t listSize = sizeof(OBCC_ExportFuncList) + sizeof(void *) * funcCount; 292a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 293a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_ExportFuncList *list = (OBCC_ExportFuncList *)malloc(listSize); 294a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 295a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!list) { 296a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for export function list\n"); 297a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 298a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 299a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 300a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpExportFuncListSection = list; 301a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->export_func_list_size = listSize; 302a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 303a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan list->count = static_cast<size_t>(funcCount); 304a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 305be79ada39b5e77b638940d2e157a45904ee09275Logan mpOwner->getExportFuncList(funcCount, list->cached_addr_list); 306a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 307a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 308a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 309a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 310a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::calcSectionOffset() { 311a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t offset = sizeof(OBCC_Header); 312a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 313a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#define OFFSET_INCREASE(NAME) \ 314a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan do { \ 315a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan /* Align to a word */ \ 316a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t rem = offset % sizeof(int); \ 317a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (rem > 0) { \ 318a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan offset += sizeof(int) - rem; \ 319a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } \ 320a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan \ 321a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan /* Save the offset and increase it */ \ 322a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->NAME##_offset = offset; \ 323a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan offset += mpHeaderSection->NAME##_size; \ 324a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } while (0) 325a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 326a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(str_pool); 327a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(depend_tab); 328a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan //OFFSET_INCREASE(reloc_tab); 329a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(export_var_list); 330a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(export_func_list); 331a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(pragma_list); 332a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(func_table); 333a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 334a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#undef OFFSET_INCREASE 335a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 336a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Context 337a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan long pagesize = sysconf(_SC_PAGESIZE); 338a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t context_offset_rem = offset % pagesize; 339a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (context_offset_rem) { 340a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan offset += pagesize - context_offset_rem; 341a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 342a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 343a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->context_offset = offset; 344a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 345a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 346a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 347a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 348a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::calcContextChecksum() { 349a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan uint32_t sum = 0; 350a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan uint32_t *ptr = reinterpret_cast<uint32_t *>(mpOwner->getContext()); 351a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 352a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (size_t i = 0; i < BCC_CONTEXT_SIZE / sizeof(uint32_t); ++i) { 353a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sum ^= *ptr++; 354a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 355a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 356a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->context_parity_checksum = sum; 357a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 358a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 359a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 360a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 361a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::writeAll() { 362a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#define WRITE_SECTION(NAME, OFFSET, SIZE, SECTION) \ 363a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan do { \ 364a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (mFile->seek(OFFSET, SEEK_SET) == -1) { \ 365a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to seek to " #NAME " section for writing.\n"); \ 366a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; \ 367a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } \ 368a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan \ 369a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (mFile->write(reinterpret_cast<char *>(SECTION), (SIZE)) != \ 370a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan static_cast<ssize_t>(SIZE)) { \ 371a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to write " #NAME " section to cache file.\n"); \ 372a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; \ 373a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } \ 374a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } while (0) 375a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 376a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#define WRITE_SECTION_SIMPLE(NAME, SECTION) \ 377a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION(NAME, \ 378a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->NAME##_offset, \ 379a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->NAME##_size, \ 380a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan SECTION) 381a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 382a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION(header, 0, sizeof(OBCC_Header), mpHeaderSection); 383a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 384a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(str_pool, mpStringPoolSection); 385a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(depend_tab, mpDependencyTableSection); 386a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan //WRITE_SECTION_SIMPLE(reloc_tab, mpRelocationTableSection); 387a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(export_var_list, mpExportVarListSection); 388a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(export_func_list, mpExportFuncListSection); 389a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(pragma_list, mpPragmaListSection); 390a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(func_table, mpFuncTableSection); 391a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 392a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION(context, mpHeaderSection->context_offset, BCC_CONTEXT_SIZE, 393a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner->getContext()); 394a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 395a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#undef WRITE_SECTION_SIMPLE 396a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#undef WRITE_SECTION 397a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 398a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 399a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 400a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 401a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 402a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} // namespace bcc 403