/*
 * Copyright 2011-2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "bcinfo/MetadataExtractor.h"

#include "bcinfo/BitcodeWrapper.h"
#include "rsDefines.h"

#define LOG_TAG "bcinfo"
#include <log/log.h>

#include "Assert.h"

#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/MemoryBuffer.h"

#ifdef __ANDROID__
#include "Properties.h"
#endif

#include <cstdlib>

namespace bcinfo {

namespace {

llvm::StringRef getStringOperand(const llvm::Metadata *node) {
  if (auto *mds = llvm::dyn_cast_or_null<const llvm::MDString>(node)) {
    return mds->getString();
  }
  return llvm::StringRef();
}

bool extractUIntFromMetadataString(uint32_t *value,
    const llvm::Metadata *m) {
  llvm::StringRef SigString = getStringOperand(m);
  if (SigString != "") {
    if (!SigString.getAsInteger(10, *value)) {
      return true;
    }
  }
  return false;
}

const char *createStringFromValue(llvm::Metadata *m) {
  auto ref = getStringOperand(m);
  char *c = new char[ref.size() + 1];
  memcpy(c, ref.data(), ref.size());
  c[ref.size()] = '\0';
  return c;
}

const char *createStringFromOptionalValue(llvm::MDNode *n, unsigned opndNum) {
  llvm::Metadata *opnd;
  if (opndNum >= n->getNumOperands() || !(opnd = n->getOperand(opndNum)))
    return nullptr;
  return createStringFromValue(opnd);
}

// Collect metadata from NamedMDNodes that contain a list of names
// (strings).
//
// Inputs:
//
// NamedMetadata - An LLVM metadata node, each of whose operands have
// a string as their first entry
//
// NameList - A reference that will hold an allocated array of strings
//
// Count - A reference that will hold the length of the allocated
// array of strings
//
// Return value:
//
// Return true on success, false on error.
//
// Upon success, the function sets NameList to an array of strings
// corresponding the names found in the metadata. The function sets
// Count to the number of entries in NameList.
//
// An error occurs if one of the metadata operands doesn't have a
// first entry.
bool populateNameMetadata(const llvm::NamedMDNode *NameMetadata,
                          const char **&NameList, size_t &Count) {
  if (!NameMetadata) {
    NameList = nullptr;
    Count = 0;
    return true;
  }

  Count = NameMetadata->getNumOperands();
  if (!Count) {
    NameList = nullptr;
    return true;
  }

  NameList = new const char *[Count];

  for (size_t i = 0; i < Count; i++) {
    llvm::MDNode *Name = NameMetadata->getOperand(i);
    if (Name && Name->getNumOperands() > 0) {
      NameList[i] = createStringFromValue(Name->getOperand(0));
    } else {
      ALOGE("Metadata operand does not contain a name string");
      for (size_t AllocatedIndex = 0; AllocatedIndex < i; AllocatedIndex++) {
        delete [] NameList[AllocatedIndex];
      }
      delete [] NameList;
      NameList = nullptr;
      Count = 0;

      return false;
    }
  }

  return true;
}

} // end anonymous namespace

// Name of metadata node where pragma info resides (should be synced with
// slang.cpp)
static const llvm::StringRef PragmaMetadataName = "#pragma";

// Name of metadata node where exported variable names reside (should be
// synced with slang_rs_metadata.h)
static const llvm::StringRef ExportVarMetadataName = "#rs_export_var";

// Name of metadata node where exported function names reside (should be
// synced with slang_rs_metadata.h)
static const llvm::StringRef ExportFuncMetadataName = "#rs_export_func";

// Name of metadata node where exported ForEach name information resides
// (should be synced with slang_rs_metadata.h)
static const llvm::StringRef ExportForEachNameMetadataName =
    "#rs_export_foreach_name";

// Name of metadata node where exported ForEach signature information resides
// (should be synced with slang_rs_metadata.h)
static const llvm::StringRef ExportForEachMetadataName = "#rs_export_foreach";

// Name of metadata node where exported general reduce information resides
// (should be synced with slang_rs_metadata.h)
static const llvm::StringRef ExportReduceMetadataName = "#rs_export_reduce";

// Name of metadata node where RS object slot info resides (should be
// synced with slang_rs_metadata.h)
static const llvm::StringRef ObjectSlotMetadataName = "#rs_object_slots";

static const llvm::StringRef ThreadableMetadataName = "#rs_is_threadable";

// Name of metadata node where the checksum for this build is stored.  (should
// be synced with libbcc/lib/Core/Source.cpp)
static const llvm::StringRef ChecksumMetadataName = "#rs_build_checksum";

// Name of metadata node which contains a list of compile units that have debug
// metadata. If this is null then there is no debug metadata in the compile
// unit.
static const llvm::StringRef DebugInfoMetadataName = "llvm.dbg.cu";

const char MetadataExtractor::kWrapperMetadataName[] = "#rs_wrapper";

MetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
    : mModule(nullptr), mBitcode(bitcode), mBitcodeSize(bitcodeSize),
      mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
      mExportReduceCount(0), mExportVarNameList(nullptr),
      mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
      mExportForEachSignatureList(nullptr),
      mExportForEachInputCountList(nullptr),
      mExportReduceList(nullptr),
      mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
      mObjectSlotCount(0), mObjectSlotList(nullptr),
      mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
      mBuildChecksum(nullptr), mHasDebugInfo(false) {
  BitcodeWrapper wrapper(bitcode, bitcodeSize);
  mCompilerVersion = wrapper.getCompilerVersion();
  mOptimizationLevel = wrapper.getOptimizationLevel();
}

MetadataExtractor::MetadataExtractor(const llvm::Module *module)
    : mModule(module), mBitcode(nullptr), mBitcodeSize(0),
      mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
      mExportReduceCount(0), mExportVarNameList(nullptr),
      mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
      mExportForEachSignatureList(nullptr),
      mExportForEachInputCountList(nullptr),
      mExportReduceList(nullptr),
      mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
      mObjectSlotCount(0), mObjectSlotList(nullptr),
      mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
      mBuildChecksum(nullptr) {
  const llvm::NamedMDNode *const wrapperMDNode = module->getNamedMetadata(kWrapperMetadataName);
  bccAssert((wrapperMDNode != nullptr) && (wrapperMDNode->getNumOperands() == 1));
  const llvm::MDNode *const wrapperMDTuple = wrapperMDNode->getOperand(0);

  bool success = true;
  success &= extractUIntFromMetadataString(&mCompilerVersion, wrapperMDTuple->getOperand(0));
  success &= extractUIntFromMetadataString(&mOptimizationLevel, wrapperMDTuple->getOperand(1));
  bccAssert(success);
}


MetadataExtractor::~MetadataExtractor() {
  if (mExportVarNameList) {
    for (size_t i = 0; i < mExportVarCount; i++) {
        delete [] mExportVarNameList[i];
        mExportVarNameList[i] = nullptr;
    }
  }
  delete [] mExportVarNameList;
  mExportVarNameList = nullptr;

  if (mExportFuncNameList) {
    for (size_t i = 0; i < mExportFuncCount; i++) {
        delete [] mExportFuncNameList[i];
        mExportFuncNameList[i] = nullptr;
    }
  }
  delete [] mExportFuncNameList;
  mExportFuncNameList = nullptr;

  if (mExportForEachNameList) {
    for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
        delete [] mExportForEachNameList[i];
        mExportForEachNameList[i] = nullptr;
    }
  }
  delete [] mExportForEachNameList;
  mExportForEachNameList = nullptr;

  delete [] mExportForEachSignatureList;
  mExportForEachSignatureList = nullptr;

  delete [] mExportForEachInputCountList;
  mExportForEachInputCountList = nullptr;

  delete [] mExportReduceList;
  mExportReduceList = nullptr;

  for (size_t i = 0; i < mPragmaCount; i++) {
    if (mPragmaKeyList) {
      delete [] mPragmaKeyList[i];
      mPragmaKeyList[i] = nullptr;
    }
    if (mPragmaValueList) {
      delete [] mPragmaValueList[i];
      mPragmaValueList[i] = nullptr;
    }
  }
  delete [] mPragmaKeyList;
  mPragmaKeyList = nullptr;
  delete [] mPragmaValueList;
  mPragmaValueList = nullptr;

  delete [] mObjectSlotList;
  mObjectSlotList = nullptr;

  delete [] mBuildChecksum;

  return;
}


bool MetadataExtractor::populateObjectSlotMetadata(
    const llvm::NamedMDNode *ObjectSlotMetadata) {
  if (!ObjectSlotMetadata) {
    return true;
  }

  mObjectSlotCount = ObjectSlotMetadata->getNumOperands();

  if (!mObjectSlotCount) {
    return true;
  }

  uint32_t *TmpSlotList = new uint32_t[mObjectSlotCount];
  memset(TmpSlotList, 0, mObjectSlotCount * sizeof(*TmpSlotList));

  for (size_t i = 0; i < mObjectSlotCount; i++) {
    llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
    if (ObjectSlot != nullptr && ObjectSlot->getNumOperands() == 1) {
      if (!extractUIntFromMetadataString(&TmpSlotList[i], ObjectSlot->getOperand(0))) {
        ALOGE("Non-integer object slot value");
        return false;
      }
    } else {
      ALOGE("Corrupt object slot information");
      return false;
    }
  }

  mObjectSlotList = TmpSlotList;

  return true;
}


void MetadataExtractor::populatePragmaMetadata(
    const llvm::NamedMDNode *PragmaMetadata) {
  if (!PragmaMetadata) {
    return;
  }

  mPragmaCount = PragmaMetadata->getNumOperands();
  if (!mPragmaCount) {
    return;
  }

  const char **TmpKeyList = new const char*[mPragmaCount];
  const char **TmpValueList = new const char*[mPragmaCount];

  for (size_t i = 0; i < mPragmaCount; i++) {
    llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
    if (Pragma != nullptr && Pragma->getNumOperands() == 2) {
      llvm::Metadata *PragmaKeyMDS = Pragma->getOperand(0);
      TmpKeyList[i] = createStringFromValue(PragmaKeyMDS);
      llvm::Metadata *PragmaValueMDS = Pragma->getOperand(1);
      TmpValueList[i] = createStringFromValue(PragmaValueMDS);
    }
  }

  mPragmaKeyList = TmpKeyList;
  mPragmaValueList = TmpValueList;

  // Check to see if we have any FP precision-related pragmas.
  std::string Relaxed("rs_fp_relaxed");
  std::string Imprecise("rs_fp_imprecise");
  std::string Full("rs_fp_full");
  bool RelaxedPragmaSeen = false;
  bool FullPragmaSeen = false;
  for (size_t i = 0; i < mPragmaCount; i++) {
    if (!Relaxed.compare(mPragmaKeyList[i])) {
      RelaxedPragmaSeen = true;
    } else if (!Imprecise.compare(mPragmaKeyList[i])) {
      ALOGW("rs_fp_imprecise is deprecated.  Assuming rs_fp_relaxed instead.");
      RelaxedPragmaSeen = true;
    } else if (!Full.compare(mPragmaKeyList[i])) {
      FullPragmaSeen = true;
    }
  }

  if (RelaxedPragmaSeen && FullPragmaSeen) {
    ALOGE("Full and relaxed precision specified at the same time!");
  }
  mRSFloatPrecision = RelaxedPragmaSeen ? RS_FP_Relaxed : RS_FP_Full;

#ifdef __ANDROID__
  // Provide an override for precsiion via adb shell setprop
  // adb shell setprop debug.rs.precision rs_fp_full
  // adb shell setprop debug.rs.precision rs_fp_relaxed
  // adb shell setprop debug.rs.precision rs_fp_imprecise
  char PrecisionPropBuf[PROP_VALUE_MAX];
  const std::string PrecisionPropName("debug.rs.precision");
  property_get("debug.rs.precision", PrecisionPropBuf, "");
  if (PrecisionPropBuf[0]) {
    if (!Relaxed.compare(PrecisionPropBuf)) {
      ALOGI("Switching to RS FP relaxed mode via setprop");
      mRSFloatPrecision = RS_FP_Relaxed;
    } else if (!Imprecise.compare(PrecisionPropBuf)) {
      ALOGW("Switching to RS FP relaxed mode via setprop. rs_fp_imprecise was "
            "specified but is deprecated ");
      mRSFloatPrecision = RS_FP_Relaxed;
    } else if (!Full.compare(PrecisionPropBuf)) {
      ALOGI("Switching to RS FP full mode via setprop");
      mRSFloatPrecision = RS_FP_Full;
    } else {
      ALOGE("Unrecognized debug.rs.precision %s", PrecisionPropBuf);
    }
  }
#endif
}

uint32_t MetadataExtractor::calculateNumInputs(const llvm::Function *Function,
                                               uint32_t Signature) {

  if (hasForEachSignatureIn(Signature)) {
    uint32_t OtherCount = 0;

    OtherCount += hasForEachSignatureUsrData(Signature);
    OtherCount += hasForEachSignatureX(Signature);
    OtherCount += hasForEachSignatureY(Signature);
    OtherCount += hasForEachSignatureZ(Signature);
    OtherCount += hasForEachSignatureCtxt(Signature);
    OtherCount += hasForEachSignatureOut(Signature) &&
                  Function->getReturnType()->isVoidTy();

    return Function->arg_size() - OtherCount;

  } else {
    return 0;
  }
}


bool MetadataExtractor::populateForEachMetadata(
    const llvm::NamedMDNode *Names,
    const llvm::NamedMDNode *Signatures) {
  if (!Names && !Signatures && mCompilerVersion == 0) {
    // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
    // section for ForEach. We generate a full signature for a "root" function
    // which means that we need to set the bottom 5 bits in the mask.
    mExportForEachSignatureCount = 1;
    char **TmpNameList = new char*[mExportForEachSignatureCount];
    size_t RootLen = strlen(kRoot) + 1;
    TmpNameList[0] = new char[RootLen];
    strncpy(TmpNameList[0], kRoot, RootLen);

    uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
    TmpSigList[0] = 0x1f;

    mExportForEachNameList = (const char**)TmpNameList;
    mExportForEachSignatureList = TmpSigList;
    return true;
  }

  if (Signatures) {
    mExportForEachSignatureCount = Signatures->getNumOperands();
    if (!mExportForEachSignatureCount) {
      return true;
    }
  } else {
    mExportForEachSignatureCount = 0;
    mExportForEachSignatureList = nullptr;
    return true;
  }

  uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
  const char **TmpNameList = new const char*[mExportForEachSignatureCount];
  uint32_t *TmpInputCountList = new uint32_t[mExportForEachSignatureCount];

  for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
    llvm::MDNode *SigNode = Signatures->getOperand(i);
    if (SigNode != nullptr && SigNode->getNumOperands() == 1) {
      if (!extractUIntFromMetadataString(&TmpSigList[i], SigNode->getOperand(0))) {
        ALOGE("Non-integer signature value");
        return false;
      }
    } else {
      ALOGE("Corrupt signature information");
      return false;
    }
  }

  if (Names) {
    for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
      llvm::MDNode *Name = Names->getOperand(i);
      if (Name != nullptr && Name->getNumOperands() == 1) {
        TmpNameList[i] = createStringFromValue(Name->getOperand(0));

        // Note that looking up the function by name can fail: One of
        // the uses of MetadataExtractor is as part of the
        // RSEmbedInfoPass, which bcc_compat runs sufficiently late in
        // the phase order that RSKernelExpandPass has already run and
        // the original (UNexpanded) kernel function (TmpNameList[i])
        // may have been deleted as having no references (if it has
        // been inlined into the expanded kernel function and is
        // otherwise unreferenced).
        llvm::Function *Func =
            mModule->getFunction(llvm::StringRef(TmpNameList[i]));

        TmpInputCountList[i] = (Func != nullptr) ?
          calculateNumInputs(Func, TmpSigList[i]) : 0;
      }
    }
  } else {
    if (mExportForEachSignatureCount != 1) {
      ALOGE("mExportForEachSignatureCount = %zu, but should be 1",
            mExportForEachSignatureCount);
    }
    char *RootName = new char[5];
    strncpy(RootName, "root", 5);
    TmpNameList[0] = RootName;
  }

  mExportForEachNameList = TmpNameList;
  mExportForEachSignatureList = TmpSigList;
  mExportForEachInputCountList = TmpInputCountList;

  return true;
}


bool MetadataExtractor::populateReduceMetadata(const llvm::NamedMDNode *ReduceMetadata) {
  mExportReduceCount = 0;
  mExportReduceList = nullptr;

  if (!ReduceMetadata || !(mExportReduceCount = ReduceMetadata->getNumOperands()))
    return true;

  std::unique_ptr<Reduce[]> TmpReduceList(new Reduce[mExportReduceCount]);

  for (size_t i = 0; i < mExportReduceCount; i++) {
    llvm::MDNode *Node = ReduceMetadata->getOperand(i);
    if (!Node || Node->getNumOperands() < 3) {
      ALOGE("Missing reduce metadata");
      return false;
    }

    TmpReduceList[i].mReduceName = createStringFromValue(Node->getOperand(0));

    if (!extractUIntFromMetadataString(&TmpReduceList[i].mAccumulatorDataSize,
                                       Node->getOperand(1))) {
      ALOGE("Non-integer accumulator data size value in reduce metadata");
      return false;
    }

    llvm::MDNode *AccumulatorNode = llvm::dyn_cast<llvm::MDNode>(Node->getOperand(2));
    if (!AccumulatorNode || AccumulatorNode->getNumOperands() != 2) {
      ALOGE("Malformed accumulator node in reduce metadata");
      return false;
    }
    TmpReduceList[i].mAccumulatorName = createStringFromValue(AccumulatorNode->getOperand(0));
    if (!extractUIntFromMetadataString(&TmpReduceList[i].mSignature,
                                       AccumulatorNode->getOperand(1))) {
      ALOGE("Non-integer signature value in reduce metadata");
      return false;
    }
    // Note that looking up the function by name can fail: One of the
    // uses of MetadataExtractor is as part of the RSEmbedInfoPass,
    // which bcc_compat runs sufficiently late in the phase order that
    // RSKernelExpandPass has already run and the original
    // (UNexpanded) accumulator function (mAccumulatorName) may have
    // been deleted as having no references (if it has been inlined
    // into the expanded accumulator function and is otherwise
    // unreferenced).
    llvm::Function *Func =
        mModule->getFunction(llvm::StringRef(TmpReduceList[i].mAccumulatorName));
    // Why calculateNumInputs() - 1?  The "-1" is because we don't
    // want to treat the accumulator argument as an input.
    TmpReduceList[i].mInputCount = (Func ? calculateNumInputs(Func, TmpReduceList[i].mSignature) - 1 : 0);

    TmpReduceList[i].mInitializerName = createStringFromOptionalValue(Node, 3);
    TmpReduceList[i].mCombinerName = createStringFromOptionalValue(Node, 4);
    TmpReduceList[i].mOutConverterName = createStringFromOptionalValue(Node, 5);
    TmpReduceList[i].mHalterName = createStringFromOptionalValue(Node, 6);
  }

  mExportReduceList = TmpReduceList.release();
  return true;
}

void MetadataExtractor::readThreadableFlag(
    const llvm::NamedMDNode *ThreadableMetadata) {

  // Scripts are threadable by default.  If we read a valid metadata value for
  // 'ThreadableMetadataName' and it is set to 'no', we mark script as non
  // threadable.  All other exception paths retain the default value.

  mIsThreadable = true;
  if (ThreadableMetadata == nullptr)
    return;

  llvm::MDNode *mdNode = ThreadableMetadata->getOperand(0);
  if (mdNode == nullptr)
    return;

  llvm::Metadata *mdValue = mdNode->getOperand(0);
  if (mdValue == nullptr)
    return;

  if (getStringOperand(mdValue) == "no")
    mIsThreadable = false;
}

void MetadataExtractor::readBuildChecksumMetadata(
    const llvm::NamedMDNode *ChecksumMetadata) {

  if (ChecksumMetadata == nullptr)
    return;

  llvm::MDNode *mdNode = ChecksumMetadata->getOperand(0);
  if (mdNode == nullptr)
    return;

  llvm::Metadata *mdValue = mdNode->getOperand(0);
  if (mdValue == nullptr)
    return;

  mBuildChecksum = createStringFromValue(mdValue);
}

bool MetadataExtractor::extract() {
  if (!(mBitcode && mBitcodeSize) && !mModule) {
    ALOGE("Invalid/empty bitcode/module");
    return false;
  }

  std::unique_ptr<llvm::LLVMContext> mContext;
  bool shouldNullModule = false;

  if (!mModule) {
    mContext.reset(new llvm::LLVMContext());
    std::unique_ptr<llvm::MemoryBuffer> MEM(
      llvm::MemoryBuffer::getMemBuffer(
        llvm::StringRef(mBitcode, mBitcodeSize), "", false));
    std::string error;

    llvm::ErrorOr<std::unique_ptr<llvm::Module> > errval =
        llvm::parseBitcodeFile(MEM.get()->getMemBufferRef(), *mContext);
    if (std::error_code ec = errval.getError()) {
        ALOGE("Could not parse bitcode file");
        ALOGE("%s", ec.message().c_str());
        return false;
    }

    mModule = errval.get().release();
    shouldNullModule = true;
  }

  const llvm::NamedMDNode *ExportVarMetadata =
      mModule->getNamedMetadata(ExportVarMetadataName);
  const llvm::NamedMDNode *ExportFuncMetadata =
      mModule->getNamedMetadata(ExportFuncMetadataName);
  const llvm::NamedMDNode *ExportForEachNameMetadata =
      mModule->getNamedMetadata(ExportForEachNameMetadataName);
  const llvm::NamedMDNode *ExportForEachMetadata =
      mModule->getNamedMetadata(ExportForEachMetadataName);
  const llvm::NamedMDNode *ExportReduceMetadata =
      mModule->getNamedMetadata(ExportReduceMetadataName);
  const llvm::NamedMDNode *PragmaMetadata =
      mModule->getNamedMetadata(PragmaMetadataName);
  const llvm::NamedMDNode *ObjectSlotMetadata =
      mModule->getNamedMetadata(ObjectSlotMetadataName);
  const llvm::NamedMDNode *ThreadableMetadata =
      mModule->getNamedMetadata(ThreadableMetadataName);
  const llvm::NamedMDNode *ChecksumMetadata =
      mModule->getNamedMetadata(ChecksumMetadataName);
  const llvm::NamedMDNode *DebugInfoMetadata =
      mModule->getNamedMetadata(DebugInfoMetadataName);

  if (!populateNameMetadata(ExportVarMetadata, mExportVarNameList,
                            mExportVarCount)) {
    ALOGE("Could not populate export variable metadata");
    goto err;
  }

  if (!populateNameMetadata(ExportFuncMetadata, mExportFuncNameList,
                            mExportFuncCount)) {
    ALOGE("Could not populate export function metadata");
    goto err;
  }

  if (!populateForEachMetadata(ExportForEachNameMetadata,
                               ExportForEachMetadata)) {
    ALOGE("Could not populate ForEach signature metadata");
    goto err;
  }

  if (!populateReduceMetadata(ExportReduceMetadata)) {
    ALOGE("Could not populate export general reduction metadata");
    goto err;
  }

  populatePragmaMetadata(PragmaMetadata);

  if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
    ALOGE("Could not populate object slot metadata");
    goto err;
  }

  readThreadableFlag(ThreadableMetadata);
  readBuildChecksumMetadata(ChecksumMetadata);

  mHasDebugInfo = DebugInfoMetadata != nullptr;

  if (shouldNullModule) {
    mModule = nullptr;
  }
  return true;

err:
  if (shouldNullModule) {
    mModule = nullptr;
  }
  return false;
}

}  // namespace bcinfo
