11e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang/*
21e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Copyright 2012, The Android Open Source Project
31e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *
41e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
51e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * you may not use this file except in compliance with the License.
61e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * You may obtain a copy of the License at
71e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *
81e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
91e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *
101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Unless required by applicable law or agreed to in writing, software
111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * See the License for the specific language governing permissions and
141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * limitations under the License.
151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang */
161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang//===----------------------------------------------------------------------===//
181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// This file implements RSInfo::ReadFromFile()
191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang//===----------------------------------------------------------------------===//
201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
21e198abec6c5e3eab380ccf6897b0a0b9c2dd92ddStephen Hines#include "bcc/Renderscript/RSInfo.h"
221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
231e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#include <new>
241e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#include <utils/FileMap.h>
261e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
27ef73a242762bcd8113b9b65ceccbe7d909b5acbcZonr Chang#include "bcc/Support/Log.h"
28c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/InputFile.h"
291e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changusing namespace bcc;
311e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
321e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changnamespace {
331e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
341e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<typename ItemType, typename ItemContainer>
351e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changinline bool helper_read_list_item(const ItemType &pItem,
361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                                  const RSInfo &pInfo,
371e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                                  ItemContainer &pResult);
381e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Process DependencyTableItem in the file
401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<> inline bool
411e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_read_list_item<rsinfo::DependencyTableItem, RSInfo::DependencyTableTy>(
421e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const rsinfo::DependencyTableItem &pItem,
431e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo &pInfo,
441e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    RSInfo::DependencyTableTy &pResult)
451e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang{
461e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const char *id = pInfo.getStringFromPool(pItem.id);
471e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const uint8_t *sha1 =
481e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      reinterpret_cast<const uint8_t *>(pInfo.getStringFromPool(pItem.sha1));
491e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
501e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (id == NULL) {
511e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Invalid string index %d for source id in RS dependenct table.",
521e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          pItem.id);
531e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
541e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
551e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
561e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (sha1 == NULL) {
571e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Invalid string index %d for SHA-1 checksum in RS dependenct table.",
581e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          pItem.id);
591e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
601e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
611e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
621e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.push(std::make_pair(id, sha1));
631e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
641e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
651e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
661e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Process PragmaItem in the file
671e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<> inline bool
681e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_read_list_item<rsinfo::PragmaItem, RSInfo::PragmaListTy>(
691e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const rsinfo::PragmaItem &pItem,
701e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo &pInfo,
711e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    RSInfo::PragmaListTy &pResult)
721e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang{
731e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const char *key = pInfo.getStringFromPool(pItem.key);
741e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const char *value =pInfo.getStringFromPool(pItem.value);
751e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
761e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (key == NULL) {
771e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Invalid string index %d for key in RS pragma list.", pItem.key);
781e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
791e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
801e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
811e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (value == NULL) {
821e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Invalid string index %d for value in RS pragma list.", pItem.value);
831e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
841e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
851e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
861e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.push(std::make_pair(key, value));
871e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
881e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
891e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
901e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Procee ObjectSlotItem in the file
911e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<> inline bool
921e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_read_list_item<rsinfo::ObjectSlotItem, RSInfo::ObjectSlotListTy>(
931e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const rsinfo::ObjectSlotItem &pItem,
941e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo &pInfo,
951e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    RSInfo::ObjectSlotListTy &pResult)
961e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang{
971e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.push(pItem.slot);
981e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
991e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
1001e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1011e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Procee ExportVarNameItem in the file
1021e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<> inline bool
1031e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_read_list_item<rsinfo::ExportVarNameItem, RSInfo::ExportVarNameListTy>(
1041e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const rsinfo::ExportVarNameItem &pItem,
1051e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo &pInfo,
1061e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    RSInfo::ExportVarNameListTy &pResult)
1071e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang{
1081e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const char *name = pInfo.getStringFromPool(pItem.name);
1091e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (name == NULL) {
1111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Invalid string index %d for name in RS export vars.", pItem.name);
1121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.push(name);
1161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
1171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
1181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Procee ExportFuncNameItem in the file
1201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<> inline bool
1211e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_read_list_item<rsinfo::ExportFuncNameItem, RSInfo::ExportFuncNameListTy>(
1221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const rsinfo::ExportFuncNameItem &pItem,
1231e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo &pInfo,
1241e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    RSInfo::ExportFuncNameListTy &pResult)
1251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang{
1261e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const char *name = pInfo.getStringFromPool(pItem.name);
1271e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1281e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (name == NULL) {
1291e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Invalid string index %d for name in RS export funcs.", pItem.name);
1301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1311e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1321e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1331e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.push(name);
1341e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
1351e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
1361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1371e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Procee ExportForeachFuncItem in the file
1381e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<> inline bool
1391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_read_list_item<rsinfo::ExportForeachFuncItem, RSInfo::ExportForeachFuncListTy>(
1401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const rsinfo::ExportForeachFuncItem &pItem,
1411e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo &pInfo,
1421e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    RSInfo::ExportForeachFuncListTy &pResult)
1431e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang{
1441e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const char *name = pInfo.getStringFromPool(pItem.name);
1451e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1461e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (name == NULL) {
1471e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Invalid string index %d for name in RS export foreachs.", pItem.name);
1481e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1491e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1501e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1511e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.push(std::make_pair(name, pItem.signature));
1521e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
1531e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
1541e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1551e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<typename ItemType, typename ItemContainer>
1561e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changinline bool helper_read_list(const uint8_t *pData,
1571e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                             const RSInfo &pInfo,
1581e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                             const rsinfo::ListHeader &pHeader,
1591e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                             ItemContainer &pResult) {
1601e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const ItemType *item;
1611e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1621e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Out-of-range exception has been checked.
1631e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  for (uint32_t i = 0; i < pHeader.count; i++) {
1641e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    item = reinterpret_cast<const ItemType *>(pData +
1651e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                                              pHeader.offset +
1661e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                                              i * pHeader.itemSize);
1671e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    if (!helper_read_list_item<ItemType, ItemContainer>(*item, pInfo, pResult)) {
1681e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      return false;
1691e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    }
1701e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1711e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
1721e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
1731e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1741e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang} // end anonymous namespace
1751e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1767bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei LiaoRSInfo *RSInfo::ReadFromFile(InputFile &pInput, const DependencyTableTy &pDeps) {
1771e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  android::FileMap *map = NULL;
1781e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  RSInfo *result = NULL;
1791e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const uint8_t *data;
1801e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const rsinfo::Header *header;
1811e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  size_t filesize;
1821e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const char *input_filename = pInput.getName().c_str();
1831e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const off_t cur_input_offset = pInput.tell();
1841e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1851e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (pInput.hasError()) {
1861e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Invalid RS info file %s! (%s)", input_filename,
1871e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                                           pInput.getErrorMessage().c_str());
1881e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
1891e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1901e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1911e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  filesize = pInput.getSize();
1921e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (pInput.hasError()) {
1931e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Failed to get the size of RS info file %s! (%s)",
1941e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          input_filename, pInput.getErrorMessage().c_str());
1951e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
1961e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1971e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1981e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Create memory map for the file.
1991e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  map = pInput.createMap(/* pOffset */cur_input_offset,
2001e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                         /* pLength */filesize - cur_input_offset);
2011e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (map == NULL) {
2021e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Failed to map RS info file %s to the memory! (%s)",
2031e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          input_filename, pInput.getErrorMessage().c_str());
2041e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
2051e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2061e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2071e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  data = reinterpret_cast<const uint8_t *>(map->getDataPtr());
2081e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2091e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Header starts at the beginning of the file.
2101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  header = reinterpret_cast<const rsinfo::Header *>(data);
2111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Check the magic.
2131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (::memcmp(header->magic, RSINFO_MAGIC, sizeof(header->magic)) != 0) {
2141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGV("Wrong magic found in the RS info file %s. Treat it as a dirty "
2151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          "cache.", input_filename);
2161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
2171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Check the version.
2201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (::memcmp(header->version,
2211e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang               RSINFO_VERSION,
2221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang               sizeof((header->version)) != 0)) {
2231e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGV("Mismatch the version of RS info file %s: (current) %s v.s. (file) "
2241e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          "%s. Treat it as as a dirty cache.", input_filename, RSINFO_VERSION,
2251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          header->version);
2261e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
2271e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2281e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2291e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Check the size.
2301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if ((header->headerSize != sizeof(rsinfo::Header)) ||
2311e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (header->dependencyTable.itemSize != sizeof(rsinfo::DependencyTableItem)) ||
2321e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (header->pragmaList.itemSize != sizeof(rsinfo::PragmaItem)) ||
2331e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (header->objectSlotList.itemSize != sizeof(rsinfo::ObjectSlotItem)) ||
2341e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (header->exportVarNameList.itemSize != sizeof(rsinfo::ExportVarNameItem)) ||
2351e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (header->exportFuncNameList.itemSize != sizeof(rsinfo::ExportFuncNameItem)) ||
2361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (header->exportForeachFuncList.itemSize != sizeof(rsinfo::ExportForeachFuncItem))) {
2371e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGW("Corrupted RS info file %s! (unexpected size found)", input_filename);
2381e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
2391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2411e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Check the range.
2421e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#define LIST_DATA_RANGE(_list_header) \
2431e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ((_list_header).offset + (_list_header).count * (_list_header).itemSize)
2441e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (((header->headerSize + header->strPoolSize) > filesize) ||
2451e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (LIST_DATA_RANGE(header->dependencyTable) > filesize) ||
2461e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (LIST_DATA_RANGE(header->pragmaList) > filesize) ||
2471e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (LIST_DATA_RANGE(header->objectSlotList) > filesize) ||
2481e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (LIST_DATA_RANGE(header->exportVarNameList) > filesize) ||
2491e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (LIST_DATA_RANGE(header->exportFuncNameList) > filesize) ||
2501e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      (LIST_DATA_RANGE(header->exportForeachFuncList) > filesize)) {
2511e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGW("Corrupted RS info file %s! (data out of the range)", input_filename);
2521e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
2531e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2541e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#undef LIST_DATA_RANGE
2551e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2561e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // File seems ok, create result RSInfo object.
2571e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  result = new (std::nothrow) RSInfo(header->strPoolSize);
2581e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (result == NULL) {
2591e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Out of memory when create RSInfo object for %s!", input_filename);
2601e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
2611e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2621e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2631e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Make advice on our access pattern.
2641e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  map->advise(android::FileMap::SEQUENTIAL);
2651e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2661e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Copy the header.
2671e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ::memcpy(&result->mHeader, header, sizeof(rsinfo::Header));
2681e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2691e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (header->strPoolSize > 0) {
2701e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    // Copy the string pool. The string pool is immediately after the header at
2711e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    // the offset header->headerSize.
2721e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    if (result->mStringPool == NULL) {
2731e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      ALOGE("Out of memory when allocate string pool for RS info file %s!",
2741e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang            input_filename);
2751e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      goto bail;
2761e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    }
2771e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ::memcpy(result->mStringPool, data + result->mHeader.headerSize,
2781e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang             result->mHeader.strPoolSize);
2791e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2801e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2811e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Populate all the data to the result object.
2821e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!helper_read_list<rsinfo::DependencyTableItem, DependencyTableTy>
2831e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        (data, *result, header->dependencyTable, result->mDependencyTable)) {
2841e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
2851e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2861e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2871e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Check dependency to see whether the cache is dirty or not.
2881e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!CheckDependency(*result, pInput.getName().c_str(), pDeps)) {
2891e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
2901e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2911e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2921e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!helper_read_list<rsinfo::PragmaItem, PragmaListTy>
2931e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        (data, *result, header->pragmaList, result->mPragmas)) {
2941e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
2951e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2961e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2971e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!helper_read_list<rsinfo::ObjectSlotItem, ObjectSlotListTy>
2981e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        (data, *result, header->objectSlotList, result->mObjectSlots)) {
2991e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
3001e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
3011e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
3021e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!helper_read_list<rsinfo::ExportVarNameItem, ExportVarNameListTy>
3031e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        (data, *result, header->exportVarNameList, result->mExportVarNames)) {
3041e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
3051e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
3061e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
3071e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!helper_read_list<rsinfo::ExportFuncNameItem, ExportFuncNameListTy>
3081e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        (data, *result, header->exportFuncNameList, result->mExportFuncNames)) {
3091e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
3101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
3111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
3121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!helper_read_list<rsinfo::ExportForeachFuncItem, ExportForeachFuncListTy>
3131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        (data, *result, header->exportForeachFuncList, result->mExportForeachFuncs)) {
3141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    goto bail;
3151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
3161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
3171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Clean up.
3181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  map->release();
3191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
3201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return result;
3211e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
3221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changbail:
3231e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (map != NULL) {
3241e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    map->release();
3251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
3261e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
3271e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  delete result;
3281e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
3291e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return NULL;
3301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang} // RSInfo::ReadFromFile
331