MetadataExtractor.cpp revision cc366e573e31f43a6101fd6e04b90c6afdc3b7a7
1932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/*
2cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines * Copyright 2011-2012, 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
44cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines// Name of metadata node where exported ForEach name information resides
45cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines// (should be synced with slang_rs_metadata.h)
46cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hinesstatic const llvm::StringRef ExportForEachNameMetadataName =
47cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    "#rs_export_foreach_name";
48cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines
4933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines// Name of metadata node where exported ForEach signature information resides
5033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines// (should be synced with slang_rs_metadata.h)
5133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hinesstatic const llvm::StringRef ExportForEachMetadataName = "#rs_export_foreach";
5233f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
53932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// Name of metadata node where RS object slot info resides (should be
54932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// synced with slang_rs_metadata.h)
55932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const llvm::StringRef ObjectSlotMetadataName = "#rs_object_slots";
56932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
57932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
58932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesMetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
59932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    : mBitcode(bitcode), mBitcodeSize(bitcodeSize), mExportVarCount(0),
6033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines      mExportFuncCount(0), mExportForEachSignatureCount(0),
61cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines      mExportForEachNameList(NULL), mExportForEachSignatureList(NULL),
62cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines      mPragmaCount(0), mPragmaKeyList(NULL), mPragmaValueList(NULL),
63cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines      mObjectSlotCount(0), mObjectSlotList(NULL) {
64932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
65932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
66932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
67932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesMetadataExtractor::~MetadataExtractor() {
68cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  if (mExportForEachNameList) {
69cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
70cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines        delete [] mExportForEachNameList[i];
71cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines        mExportForEachNameList[i] = NULL;
72cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    }
73cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  }
74cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  delete [] mExportForEachNameList;
75cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  mExportForEachNameList = NULL;
76cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines
7733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  delete [] mExportForEachSignatureList;
7833f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  mExportForEachSignatureList = NULL;
7933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
80cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  for (size_t i = 0; i < mPragmaCount; i++) {
81cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    if (mPragmaKeyList) {
82cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines      delete [] mPragmaKeyList[i];
83cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines      mPragmaKeyList[i] = NULL;
84cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    }
85cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    if (mPragmaValueList) {
86cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines      delete [] mPragmaValueList[i];
87cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines      mPragmaValueList[i] = NULL;
88932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    }
89932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
90932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  delete [] mPragmaKeyList;
91932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaKeyList = NULL;
92932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  delete [] mPragmaValueList;
93932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaValueList = NULL;
94932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
95932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  delete [] mObjectSlotList;
96932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mObjectSlotList = NULL;
97932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
98932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return;
99932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
100932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
101932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
102932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesbool MetadataExtractor::populateObjectSlotMetadata(
103932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    const llvm::NamedMDNode *ObjectSlotMetadata) {
104932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!ObjectSlotMetadata) {
105932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return true;
106932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
107932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
108932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mObjectSlotCount = ObjectSlotMetadata->getNumOperands();
109932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
110932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!mObjectSlotCount) {
111932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return true;
112932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
113932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
114932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  uint32_t *TmpSlotList = new uint32_t[mObjectSlotCount];
115932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  memset(TmpSlotList, 0, mObjectSlotCount * sizeof(*TmpSlotList));
116932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
117932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  for (size_t i = 0; i < mObjectSlotCount; i++) {
118932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
119932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    if (ObjectSlot != NULL && ObjectSlot->getNumOperands() == 1) {
120932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
121932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
122932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        llvm::StringRef Slot =
123932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines            static_cast<llvm::MDString*>(SlotMDS)->getString();
124932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        uint32_t USlot = 0;
125932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        if (Slot.getAsInteger(10, USlot)) {
12610c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block          ALOGE("Non-integer object slot value '%s'", Slot.str().c_str());
127932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines          return false;
128932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        }
129932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        TmpSlotList[i] = USlot;
130932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      }
131932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    }
132932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
133932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
134932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mObjectSlotList = TmpSlotList;
135932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
136932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return true;
137932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
138932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
139932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
140932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const char *createStringFromValue(llvm::Value *v) {
141932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (v->getValueID() != llvm::Value::MDStringVal) {
142932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return NULL;
143932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
144932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
145932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::StringRef ref = static_cast<llvm::MDString*>(v)->getString();
146932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
147932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  char *c = new char[ref.size() + 1];
148932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  memcpy(c, ref.data(), ref.size());
149932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  c[ref.size()] = '\0';
150932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
151932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return c;
152932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
153932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
154932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
155932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesvoid MetadataExtractor::populatePragmaMetadata(
156932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    const llvm::NamedMDNode *PragmaMetadata) {
157932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!PragmaMetadata) {
158932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return;
159932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
160932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
161932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaCount = PragmaMetadata->getNumOperands();
162932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!mPragmaCount) {
163932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return;
164932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
165932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
166932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaKeyList = new const char*[mPragmaCount];
167932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaValueList = new const char*[mPragmaCount];
168932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
169932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  for (size_t i = 0; i < mPragmaCount; i++) {
170932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
171932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    if (Pragma != NULL && Pragma->getNumOperands() == 2) {
172932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::Value *PragmaKeyMDS = Pragma->getOperand(0);
173932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      mPragmaKeyList[i] = createStringFromValue(PragmaKeyMDS);
174932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
175932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      mPragmaValueList[i] = createStringFromValue(PragmaValueMDS);
176932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    }
177932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
178932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
179932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return;
180932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
181932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
182932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
18333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hinesbool MetadataExtractor::populateForEachMetadata(
184cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    const llvm::NamedMDNode *Names,
185cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    const llvm::NamedMDNode *Signatures) {
186cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  if (!Names || !Signatures) {
1870231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
1880231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    // section for ForEach. We generate a full signature for a "root" function
1890231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    // which means that we need to set the bottom 5 bits in the mask.
1900231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    mExportForEachSignatureCount = 1;
191cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    char **TmpNameList = new char*[mExportForEachSignatureCount];
192cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    TmpNameList[0] = new char[5];
193cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    strncpy(TmpNameList[0], "root", 5);
194cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines
1950231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
1960231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    TmpSigList[0] = 0x1f;
197cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    mExportForEachNameList = (const char**)TmpNameList;
1980231bb069417690bb4f513b80a9c0238112744f7Stephen Hines    mExportForEachSignatureList = TmpSigList;
19933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    return true;
20033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  }
20133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
202cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  mExportForEachSignatureCount = Signatures->getNumOperands();
20333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  if (!mExportForEachSignatureCount) {
20433f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    return true;
20533f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  }
20633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
20733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
20833f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
20933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
210cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    llvm::MDNode *SigNode = Signatures->getOperand(i);
21133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    if (SigNode != NULL && SigNode->getNumOperands() == 1) {
21233f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines      llvm::Value *SigVal = SigNode->getOperand(0);
21333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines      if (SigVal->getValueID() == llvm::Value::MDStringVal) {
21433f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        llvm::StringRef SigString =
21533f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines            static_cast<llvm::MDString*>(SigVal)->getString();
21633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        uint32_t Signature = 0;
21733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        if (SigString.getAsInteger(10, Signature)) {
21810c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block          ALOGE("Non-integer signature value '%s'", SigString.str().c_str());
21933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines          return false;
22033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        }
22133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines        TmpSigList[i] = Signature;
22233f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines      }
22333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    }
22433f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  }
22533f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
22633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  mExportForEachSignatureList = TmpSigList;
22733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
228cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines
229cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  mExportForEachNameList = new const char*[mExportForEachSignatureCount];
230cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines
231cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
232cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    llvm::MDNode *Name = Names->getOperand(i);
233cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    if (Name != NULL && Name->getNumOperands() == 1) {
234cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines      mExportForEachNameList[i] = createStringFromValue(Name->getOperand(0));
235cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines    }
236cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  }
237cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines
23833f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  return true;
23933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines}
24033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
24133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
24233f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
243932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesbool MetadataExtractor::extract() {
244932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!mBitcode || !mBitcodeSize) {
24510c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Invalid/empty bitcode");
246932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
247932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
248932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
249932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::OwningPtr<llvm::LLVMContext> mContext(new llvm::LLVMContext());
250932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::OwningPtr<llvm::MemoryBuffer> MEM(
251932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    llvm::MemoryBuffer::getMemBuffer(
252932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::StringRef(mBitcode, mBitcodeSize)));
253932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  std::string error;
254932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
255932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // Module ownership is handled by the context, so we don't need to free it.
256932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::Module *module = llvm::ParseBitcodeFile(MEM.get(), *mContext, &error);
257932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!module) {
25810c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Could not parse bitcode file");
25910c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("%s", error.c_str());
260932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
261932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
262932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
263932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *ExportVarMetadata =
264932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(ExportVarMetadataName);
265932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *ExportFuncMetadata =
266932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(ExportFuncMetadataName);
267cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  const llvm::NamedMDNode *ExportForEachNameMetadata =
268cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines      module->getNamedMetadata(ExportForEachNameMetadataName);
26933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  const llvm::NamedMDNode *ExportForEachMetadata =
27033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines      module->getNamedMetadata(ExportForEachMetadataName);
271932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *PragmaMetadata =
272932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(PragmaMetadataName);
273932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *ObjectSlotMetadata =
274932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(ObjectSlotMetadataName);
275932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
276932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (ExportVarMetadata) {
277932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    mExportVarCount = ExportVarMetadata->getNumOperands();
278932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
279932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
280932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (ExportFuncMetadata) {
281932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    mExportFuncCount = ExportFuncMetadata->getNumOperands();
282932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
283932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
284cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines  if (!populateForEachMetadata(ExportForEachNameMetadata,
285cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines                               ExportForEachMetadata)) {
28610c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Could not populate ForEach signature metadata");
28733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines    return false;
28833f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines  }
28933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines
290932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  populatePragmaMetadata(PragmaMetadata);
291932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
292932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
29310c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Could not populate object slot metadata");
294932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
295932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
296932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
297932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return true;
298932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
299932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
300932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}  // namespace bcinfo
301932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
302