MetadataExtractor.cpp revision 10c1412e6cb35cfc90abb5e36ba1340a8c55f44e
1932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/*
2932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Copyright 2011, The Android Open Source Project
3932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines *
4932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
5932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * you may not use this file except in compliance with the License.
6932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * You may obtain a copy of the License at
7932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines *
8932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
9932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines *
10932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Unless required by applicable law or agreed to in writing, software
11932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
12932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * See the License for the specific language governing permissions and
14932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * limitations under the License.
15932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines */
16932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
17932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "bcinfo/MetadataExtractor.h"
18932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
19932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#define LOG_TAG "bcinfo"
20932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <cutils/log.h>
21932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
22932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/ADT/OwningPtr.h"
23932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/Bitcode/ReaderWriter.h"
24932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/LLVMContext.h"
25932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/Module.h"
26932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/Support/MemoryBuffer.h"
27932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
28932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <cstdlib>
29932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
30932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesnamespace bcinfo {
31932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
32932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// Name of metadata node where pragma info resides (should be synced with
33932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// slang.cpp)
34932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const llvm::StringRef PragmaMetadataName = "#pragma";
35932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
36932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// Name of metadata node where exported variable names reside (should be
37932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// synced with slang_rs_metadata.h)
38932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const llvm::StringRef ExportVarMetadataName = "#rs_export_var";
39932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
40932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// Name of metadata node where exported function names reside (should be
41932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// synced with slang_rs_metadata.h)
42932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const llvm::StringRef ExportFuncMetadataName = "#rs_export_func";
43932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
4433f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines// Name of metadata node where exported ForEach signature information resides
4533f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines// (should be synced with slang_rs_metadata.h)
4633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hinesstatic const llvm::StringRef ExportForEachMetadataName = "#rs_export_foreach";
4733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
48932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// Name of metadata node where RS object slot info resides (should be
49932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// synced with slang_rs_metadata.h)
50932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const llvm::StringRef ObjectSlotMetadataName = "#rs_object_slots";
51932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
52932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
53932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesMetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
54932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    : mBitcode(bitcode), mBitcodeSize(bitcodeSize), mExportVarCount(0),
5533f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines      mExportFuncCount(0), mExportForEachSignatureCount(0),
5633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines      mExportForEachSignatureList(NULL), mPragmaCount(0), mPragmaKeyList(NULL),
57932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      mPragmaValueList(NULL), mObjectSlotCount(0), mObjectSlotList(NULL) {
58932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
59932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
60932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
61932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesMetadataExtractor::~MetadataExtractor() {
6233f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  delete [] mExportForEachSignatureList;
6333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  mExportForEachSignatureList = NULL;
6433f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
65932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (mPragmaCount > 0) {
66932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    for (size_t i = 0; i < mPragmaCount; i++) {
67932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      if (mPragmaKeyList) {
68932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        delete [] mPragmaKeyList[i];
6933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        mPragmaKeyList[i] = NULL;
70932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      }
71932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      if (mPragmaValueList) {
72932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        delete [] mPragmaValueList[i];
7333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        mPragmaValueList[i] = NULL;
74932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      }
75932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    }
76932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
77932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  delete [] mPragmaKeyList;
78932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaKeyList = NULL;
79932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  delete [] mPragmaValueList;
80932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaValueList = NULL;
81932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
82932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  delete [] mObjectSlotList;
83932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mObjectSlotList = NULL;
84932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
85932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return;
86932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
87932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
88932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
89932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesbool MetadataExtractor::populateObjectSlotMetadata(
90932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    const llvm::NamedMDNode *ObjectSlotMetadata) {
91932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!ObjectSlotMetadata) {
92932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return true;
93932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
94932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
95932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mObjectSlotCount = ObjectSlotMetadata->getNumOperands();
96932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
97932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!mObjectSlotCount) {
98932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return true;
99932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
100932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
101932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  uint32_t *TmpSlotList = new uint32_t[mObjectSlotCount];
102932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  memset(TmpSlotList, 0, mObjectSlotCount * sizeof(*TmpSlotList));
103932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
104932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  for (size_t i = 0; i < mObjectSlotCount; i++) {
105932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
106932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    if (ObjectSlot != NULL && ObjectSlot->getNumOperands() == 1) {
107932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
108932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
109932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        llvm::StringRef Slot =
110932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines            static_cast<llvm::MDString*>(SlotMDS)->getString();
111932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        uint32_t USlot = 0;
112932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        if (Slot.getAsInteger(10, USlot)) {
11310c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block          ALOGE("Non-integer object slot value '%s'", Slot.str().c_str());
114932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines          return false;
115932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        }
116932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        TmpSlotList[i] = USlot;
117932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      }
118932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    }
119932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
120932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
121932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mObjectSlotList = TmpSlotList;
122932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
123932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return true;
124932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
125932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
126932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
127932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const char *createStringFromValue(llvm::Value *v) {
128932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (v->getValueID() != llvm::Value::MDStringVal) {
129932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return NULL;
130932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
131932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
132932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::StringRef ref = static_cast<llvm::MDString*>(v)->getString();
133932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
134932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  char *c = new char[ref.size() + 1];
135932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  memcpy(c, ref.data(), ref.size());
136932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  c[ref.size()] = '\0';
137932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
138932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return c;
139932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
140932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
141932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
142932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesvoid MetadataExtractor::populatePragmaMetadata(
143932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    const llvm::NamedMDNode *PragmaMetadata) {
144932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!PragmaMetadata) {
145932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return;
146932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
147932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
148932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaCount = PragmaMetadata->getNumOperands();
149932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!mPragmaCount) {
150932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return;
151932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
152932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
153932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaKeyList = new const char*[mPragmaCount];
154932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaValueList = new const char*[mPragmaCount];
155932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
156932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  for (size_t i = 0; i < mPragmaCount; i++) {
157932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
158932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    if (Pragma != NULL && Pragma->getNumOperands() == 2) {
159932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::Value *PragmaKeyMDS = Pragma->getOperand(0);
160932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      mPragmaKeyList[i] = createStringFromValue(PragmaKeyMDS);
161932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
162932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      mPragmaValueList[i] = createStringFromValue(PragmaValueMDS);
163932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    }
164932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
165932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
166932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return;
167932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
168932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
169932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
17033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hinesbool MetadataExtractor::populateForEachMetadata(
17133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    const llvm::NamedMDNode *ExportForEachMetadata) {
17233f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  if (!ExportForEachMetadata) {
1730231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
1740231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    // section for ForEach. We generate a full signature for a "root" function
1750231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    // which means that we need to set the bottom 5 bits in the mask.
1760231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    mExportForEachSignatureCount = 1;
1770231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
1780231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    TmpSigList[0] = 0x1f;
1790231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    mExportForEachSignatureList = TmpSigList;
18033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    return true;
18133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  }
18233f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
18333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  mExportForEachSignatureCount = ExportForEachMetadata->getNumOperands();
18433f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  if (!mExportForEachSignatureCount) {
18533f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    return true;
18633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  }
18733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
18833f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
18933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
19033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
19133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    llvm::MDNode *SigNode = ExportForEachMetadata->getOperand(i);
19233f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    if (SigNode != NULL && SigNode->getNumOperands() == 1) {
19333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines      llvm::Value *SigVal = SigNode->getOperand(0);
19433f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines      if (SigVal->getValueID() == llvm::Value::MDStringVal) {
19533f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        llvm::StringRef SigString =
19633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines            static_cast<llvm::MDString*>(SigVal)->getString();
19733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        uint32_t Signature = 0;
19833f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        if (SigString.getAsInteger(10, Signature)) {
19910c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block          ALOGE("Non-integer signature value '%s'", SigString.str().c_str());
20033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines          return false;
20133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        }
20233f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        TmpSigList[i] = Signature;
20333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines      }
20433f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    }
20533f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  }
20633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
20733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  mExportForEachSignatureList = TmpSigList;
20833f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
20933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  return true;
21033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines}
21133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
21233f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
21333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
214932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesbool MetadataExtractor::extract() {
215932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!mBitcode || !mBitcodeSize) {
21610c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Invalid/empty bitcode");
217932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
218932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
219932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
220932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::OwningPtr<llvm::LLVMContext> mContext(new llvm::LLVMContext());
221932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::OwningPtr<llvm::MemoryBuffer> MEM(
222932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    llvm::MemoryBuffer::getMemBuffer(
223932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::StringRef(mBitcode, mBitcodeSize)));
224932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  std::string error;
225932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
226932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // Module ownership is handled by the context, so we don't need to free it.
227932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::Module *module = llvm::ParseBitcodeFile(MEM.get(), *mContext, &error);
228932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!module) {
22910c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Could not parse bitcode file");
23010c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("%s", error.c_str());
231932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
232932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
233932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
234932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *ExportVarMetadata =
235932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(ExportVarMetadataName);
236932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *ExportFuncMetadata =
237932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(ExportFuncMetadataName);
23833f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  const llvm::NamedMDNode *ExportForEachMetadata =
23933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines      module->getNamedMetadata(ExportForEachMetadataName);
240932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *PragmaMetadata =
241932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(PragmaMetadataName);
242932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *ObjectSlotMetadata =
243932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(ObjectSlotMetadataName);
244932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
245932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (ExportVarMetadata) {
246932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    mExportVarCount = ExportVarMetadata->getNumOperands();
247932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
248932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
249932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (ExportFuncMetadata) {
250932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    mExportFuncCount = ExportFuncMetadata->getNumOperands();
251932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
252932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
25333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  if (!populateForEachMetadata(ExportForEachMetadata)) {
25410c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Could not populate ForEach signature metadata");
25533f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    return false;
25633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  }
25733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
258932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  populatePragmaMetadata(PragmaMetadata);
259932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
260932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
26110c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Could not populate object slot metadata");
262932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
263932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
264932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
265932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return true;
266932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
267932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
268932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}  // namespace bcinfo
269932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
270