CacheWriter.cpp revision a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdf
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 93a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Magic word and version 94a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(header->magic, OBCC_MAGIC, 4); 95a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(header->version, OBCC_VERSION, 4); 96a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 97a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Machine Integer Type 98a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan uint32_t number = 0x00000001; 99a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->endianness = (*reinterpret_cast<char *>(&number) == 1) ? 'e' : 'E'; 100a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->sizeof_off_t = sizeof(off_t); 101a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->sizeof_size_t = sizeof(size_t); 102a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->sizeof_ptr_t = sizeof(void *); 103a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 104a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Context 105a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->context_cached_addr = mpOwner->getContext(); 106a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 107a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // libRS is threadable dirty hack 108a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // TODO: This should be removed in the future 109a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan header->libRS_threadable = libRS_threadable; 110a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 111a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 112a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 113a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 114a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 115a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareDependencyTable() { 116a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t tableSize = sizeof(OBCC_DependencyTable) + 117a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_Dependency) * mDependencies.size(); 118a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 119a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_DependencyTable *tab = (OBCC_DependencyTable *)malloc(tableSize); 120a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 121a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!tab) { 122a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for dependency table section.\n"); 123a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 124a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 125a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 126a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpDependencyTableSection = tab; 127a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->depend_tab_size = tableSize; 128a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 129a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan tab->count = mDependencies.size(); 130a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 131a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t i = 0; 132a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (map<string, pair<uint32_t, unsigned char const *> >::iterator 133a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan I = mDependencies.begin(), E = mDependencies.end(); I != E; ++I, ++i) { 134a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_Dependency *dep = &tab->table[i]; 135a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 136a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan dep->res_name_strp_index = addString(I->first.c_str(), I->first.size()); 137a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan dep->res_type = I->second.first; 138a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(dep->sha1, I->second.second, 20); 139a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 140a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 141a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 142a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 143a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 144a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 145a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareFuncTable() { 146a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan ssize_t funcCount = 0; 147a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 148a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner->getFunctions(&funcCount, 0, NULL); 149a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 150a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t tableSize = sizeof(OBCC_FuncTable) + 151a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_FuncInfo) * funcCount; 152a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 153a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_FuncTable *tab = (OBCC_FuncTable *)malloc(tableSize); 154a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 155a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!tab) { 156a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for function table section.\n"); 157a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 158a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 159a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 160a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpFuncTableSection = tab; 161a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->func_table_size = tableSize; 162a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 163a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan tab->count = static_cast<size_t>(funcCount); 164a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 165a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Get the function informations 166a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan vector<char *> funcNameList(funcCount); 167a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner->getFunctions(0, funcCount, &*funcNameList.begin()); 168a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 169a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (int i = 0; i < funcCount; ++i) { 170a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan char *funcName = funcNameList[i]; 171a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t funcNameLen = strlen(funcName); 172a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 173a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan void *funcAddr = NULL; 174a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan ssize_t funcBinarySize = 0; 175a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner->getFunctionBinary(funcName, &funcAddr, &funcBinarySize); 176a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 177a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_FuncInfo *funcInfo = &tab->table[i]; 178a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan funcInfo->name_strp_index = addString(funcName, funcNameLen); 179a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan funcInfo->cached_addr = funcAddr; 180a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan funcInfo->size = static_cast<size_t>(funcBinarySize); 181a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 182a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 183a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 184a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 185a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 186a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 187a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::preparePragmaList() { 188a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan ssize_t stringCount; 189a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 190a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner->getPragmas(&stringCount, 0, NULL); 191a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 192a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t pragmaCount = static_cast<size_t>(stringCount) / 2; 193a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 194a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t listSize = sizeof(OBCC_PragmaList) + 195a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_Pragma) * pragmaCount; 196a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 197a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_PragmaList *list = (OBCC_PragmaList *)malloc(listSize); 198a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 199a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!list) { 200a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for pragma list\n"); 201a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 202a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 203a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 204a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpPragmaListSection = list; 205a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->pragma_list_size = listSize; 206a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 207a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan list->count = pragmaCount; 208a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 209a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan vector<char *> strings(stringCount); 210a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner->getPragmas(&stringCount, stringCount, &*strings.begin()); 211a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 212a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (size_t i = 0; i < pragmaCount; ++i) { 213a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan char *key = strings[2 * i]; 214a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t keyLen = strlen(key); 215a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 216a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan char *value = strings[2 * i + 1]; 217a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t valueLen = strlen(value); 218a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 219a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_Pragma *pragma = &list->list[i]; 220a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan pragma->key_strp_index = addString(key, keyLen); 221a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan pragma->value_strp_index = addString(value, valueLen); 222a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 223a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 224a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 225a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 226a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 227a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 228a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareRelocationTable() { 229a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // TODO(logan): Implement relocation table cache write. 230a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 231a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 232a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 233a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 234a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareStringPool() { 235a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Calculate string pool size 236a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t size = sizeof(OBCC_StringPool) + 237a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sizeof(OBCC_String) * mStringPool.size(); 238a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 239a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan off_t strOffset = size; 240a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 241a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (size_t i = 0; i < mStringPool.size(); ++i) { 242a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size += mStringPool[i].second + 1; 243a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 244a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 245a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Create string pool 246a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_StringPool *pool = (OBCC_StringPool *)malloc(size); 247a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 248a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!pool) { 249a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate string pool.\n"); 250a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 251a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 252a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 253a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpStringPoolSection = pool; 254a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->str_pool_size = size; 255a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 256a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan pool->count = mStringPool.size(); 257a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan 258a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan char *strPtr = reinterpret_cast<char *>(pool) + strOffset; 259a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 260a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (size_t i = 0; i < mStringPool.size(); ++i) { 261a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_String *str = &pool->list[i]; 262a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 263a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan str->length = mStringPool[i].second; 264a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan str->offset = strOffset; 265a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan memcpy(strPtr, mStringPool[i].first, str->length); 266a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 267a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan strPtr += str->length; 268a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan *strPtr++ = '\0'; 269a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 270a2e15af1239e9d5bf6c6c9c5ecb9651217d0efdfLogan strOffset += str->length + 1; 271a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 272a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 273a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 274a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 275a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 276a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 277a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareExportVarList() { 278a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan ssize_t varCount; 279a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 280a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner->getExportVars(&varCount, 0, NULL); 281a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 282a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t listSize = sizeof(OBCC_ExportVarList) + sizeof(void *) * varCount; 283a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 284a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_ExportVarList *list = (OBCC_ExportVarList *)malloc(listSize); 285a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 286a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!list) { 287a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for export variable list\n"); 288a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 289a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 290a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 291a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpExportVarListSection = list; 292a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->export_var_list_size = listSize; 293a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 294a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan list->count = static_cast<size_t>(varCount); 295a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 296a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner->getExportVars(&varCount, varCount, list->cached_addr_list); 297a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 298a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 299a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 300a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 301a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::prepareExportFuncList() { 302a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan ssize_t funcCount; 303a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 304a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner->getExportFuncs(&funcCount, 0, NULL); 305a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 306a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t listSize = sizeof(OBCC_ExportFuncList) + sizeof(void *) * funcCount; 307a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 308a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OBCC_ExportFuncList *list = (OBCC_ExportFuncList *)malloc(listSize); 309a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 310a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (!list) { 311a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to allocate for export function list\n"); 312a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; 313a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 314a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 315a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpExportFuncListSection = list; 316a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->export_func_list_size = listSize; 317a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 318a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan list->count = static_cast<size_t>(funcCount); 319a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 320a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner->getExportFuncs(&funcCount, funcCount, list->cached_addr_list); 321a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 322a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 323a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 324a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 325a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::calcSectionOffset() { 326a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t offset = sizeof(OBCC_Header); 327a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 328a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#define OFFSET_INCREASE(NAME) \ 329a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan do { \ 330a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan /* Align to a word */ \ 331a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t rem = offset % sizeof(int); \ 332a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (rem > 0) { \ 333a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan offset += sizeof(int) - rem; \ 334a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } \ 335a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan \ 336a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan /* Save the offset and increase it */ \ 337a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->NAME##_offset = offset; \ 338a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan offset += mpHeaderSection->NAME##_size; \ 339a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } while (0) 340a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 341a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(str_pool); 342a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(depend_tab); 343a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan //OFFSET_INCREASE(reloc_tab); 344a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(export_var_list); 345a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(export_func_list); 346a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(pragma_list); 347a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan OFFSET_INCREASE(func_table); 348a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 349a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#undef OFFSET_INCREASE 350a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 351a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan // Context 352a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan long pagesize = sysconf(_SC_PAGESIZE); 353a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan size_t context_offset_rem = offset % pagesize; 354a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (context_offset_rem) { 355a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan offset += pagesize - context_offset_rem; 356a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 357a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 358a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->context_offset = offset; 359a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 360a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 361a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 362a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 363a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::calcContextChecksum() { 364a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan uint32_t sum = 0; 365a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan uint32_t *ptr = reinterpret_cast<uint32_t *>(mpOwner->getContext()); 366a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 367a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan for (size_t i = 0; i < BCC_CONTEXT_SIZE / sizeof(uint32_t); ++i) { 368a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan sum ^= *ptr++; 369a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } 370a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 371a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->context_parity_checksum = sum; 372a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 373a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 374a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 375a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 376a27a83f2b01b1710238d077dc9dfd7655f4513cdLoganbool CacheWriter::writeAll() { 377a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#define WRITE_SECTION(NAME, OFFSET, SIZE, SECTION) \ 378a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan do { \ 379a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (mFile->seek(OFFSET, SEEK_SET) == -1) { \ 380a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to seek to " #NAME " section for writing.\n"); \ 381a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; \ 382a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } \ 383a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan \ 384a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan if (mFile->write(reinterpret_cast<char *>(SECTION), (SIZE)) != \ 385a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan static_cast<ssize_t>(SIZE)) { \ 386a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan LOGE("Unable to write " #NAME " section to cache file.\n"); \ 387a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return false; \ 388a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } \ 389a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan } while (0) 390a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 391a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#define WRITE_SECTION_SIMPLE(NAME, SECTION) \ 392a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION(NAME, \ 393a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->NAME##_offset, \ 394a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpHeaderSection->NAME##_size, \ 395a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan SECTION) 396a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 397a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION(header, 0, sizeof(OBCC_Header), mpHeaderSection); 398a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 399a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(str_pool, mpStringPoolSection); 400a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(depend_tab, mpDependencyTableSection); 401a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan //WRITE_SECTION_SIMPLE(reloc_tab, mpRelocationTableSection); 402a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(export_var_list, mpExportVarListSection); 403a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(export_func_list, mpExportFuncListSection); 404a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(pragma_list, mpPragmaListSection); 405a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION_SIMPLE(func_table, mpFuncTableSection); 406a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 407a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan WRITE_SECTION(context, mpHeaderSection->context_offset, BCC_CONTEXT_SIZE, 408a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan mpOwner->getContext()); 409a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 410a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#undef WRITE_SECTION_SIMPLE 411a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan#undef WRITE_SECTION 412a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 413a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan return true; 414a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} 415a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 416a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan 417a27a83f2b01b1710238d077dc9dfd7655f4513cdLogan} // namespace bcc 418