MetadataExtractor.cpp revision 932bc6e35bcef7adff05d890a9dcc7212426fb6a
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
44932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// Name of metadata node where RS object slot info resides (should be
45932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// synced with slang_rs_metadata.h)
46932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const llvm::StringRef ObjectSlotMetadataName = "#rs_object_slots";
47932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
48932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
49932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesMetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
50932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    : mBitcode(bitcode), mBitcodeSize(bitcodeSize), mExportVarCount(0),
51932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      mExportFuncCount(0), mPragmaCount(0), mPragmaKeyList(NULL),
52932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      mPragmaValueList(NULL), mObjectSlotCount(0), mObjectSlotList(NULL) {
53932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
54932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
55932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
56932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesMetadataExtractor::~MetadataExtractor() {
57932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (mPragmaCount > 0) {
58932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    for (size_t i = 0; i < mPragmaCount; i++) {
59932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      if (mPragmaKeyList) {
60932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        delete [] mPragmaKeyList[i];
61932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      }
62932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      if (mPragmaValueList) {
63932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        delete [] mPragmaValueList[i];
64932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      }
65932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    }
66932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
67932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  delete [] mPragmaKeyList;
68932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaKeyList = NULL;
69932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  delete [] mPragmaValueList;
70932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaValueList = NULL;
71932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
72932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  delete [] mObjectSlotList;
73932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mObjectSlotList = NULL;
74932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
75932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return;
76932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
77932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
78932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
79932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesbool MetadataExtractor::populateObjectSlotMetadata(
80932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    const llvm::NamedMDNode *ObjectSlotMetadata) {
81932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!ObjectSlotMetadata) {
82932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return true;
83932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
84932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
85932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mObjectSlotCount = ObjectSlotMetadata->getNumOperands();
86932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
87932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!mObjectSlotCount) {
88932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return true;
89932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
90932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
91932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  uint32_t *TmpSlotList = new uint32_t[mObjectSlotCount];
92932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  memset(TmpSlotList, 0, mObjectSlotCount * sizeof(*TmpSlotList));
93932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
94932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  for (size_t i = 0; i < mObjectSlotCount; i++) {
95932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
96932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    if (ObjectSlot != NULL && ObjectSlot->getNumOperands() == 1) {
97932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
98932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
99932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        llvm::StringRef Slot =
100932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines            static_cast<llvm::MDString*>(SlotMDS)->getString();
101932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        uint32_t USlot = 0;
102932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        if (Slot.getAsInteger(10, USlot)) {
103932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines          LOGE("Non-integer object slot value '%s'", Slot.str().c_str());
104932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines          return false;
105932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        }
106932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines        TmpSlotList[i] = USlot;
107932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      }
108932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    }
109932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
110932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
111932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mObjectSlotList = TmpSlotList;
112932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
113932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return true;
114932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
115932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
116932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
117932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const char *createStringFromValue(llvm::Value *v) {
118932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (v->getValueID() != llvm::Value::MDStringVal) {
119932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return NULL;
120932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
121932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
122932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::StringRef ref = static_cast<llvm::MDString*>(v)->getString();
123932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
124932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  char *c = new char[ref.size() + 1];
125932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  memcpy(c, ref.data(), ref.size());
126932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  c[ref.size()] = '\0';
127932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
128932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return c;
129932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
130932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
131932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
132932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesvoid MetadataExtractor::populatePragmaMetadata(
133932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    const llvm::NamedMDNode *PragmaMetadata) {
134932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!PragmaMetadata) {
135932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return;
136932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
137932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
138932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaCount = PragmaMetadata->getNumOperands();
139932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!mPragmaCount) {
140932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return;
141932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
142932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
143932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaKeyList = new const char*[mPragmaCount];
144932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mPragmaValueList = new const char*[mPragmaCount];
145932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
146932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  for (size_t i = 0; i < mPragmaCount; i++) {
147932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
148932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    if (Pragma != NULL && Pragma->getNumOperands() == 2) {
149932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::Value *PragmaKeyMDS = Pragma->getOperand(0);
150932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      mPragmaKeyList[i] = createStringFromValue(PragmaKeyMDS);
151932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
152932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      mPragmaValueList[i] = createStringFromValue(PragmaValueMDS);
153932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    }
154932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
155932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
156932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return;
157932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
158932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
159932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
160932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesbool MetadataExtractor::extract() {
161932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!mBitcode || !mBitcodeSize) {
162932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    LOGE("Invalid/empty bitcode");
163932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
164932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
165932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
166932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::OwningPtr<llvm::LLVMContext> mContext(new llvm::LLVMContext());
167932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::OwningPtr<llvm::MemoryBuffer> MEM(
168932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    llvm::MemoryBuffer::getMemBuffer(
169932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::StringRef(mBitcode, mBitcodeSize)));
170932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  std::string error;
171932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
172932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // Module ownership is handled by the context, so we don't need to free it.
173932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::Module *module = llvm::ParseBitcodeFile(MEM.get(), *mContext, &error);
174932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!module) {
175932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    LOGE("Could not parse bitcode file");
176932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    LOGE("%s", error.c_str());
177932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
178932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
179932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
180932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *ExportVarMetadata =
181932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(ExportVarMetadataName);
182932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *ExportFuncMetadata =
183932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(ExportFuncMetadataName);
184932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *PragmaMetadata =
185932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(PragmaMetadataName);
186932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  const llvm::NamedMDNode *ObjectSlotMetadata =
187932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      module->getNamedMetadata(ObjectSlotMetadataName);
188932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
189932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (ExportVarMetadata) {
190932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    mExportVarCount = ExportVarMetadata->getNumOperands();
191932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
192932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
193932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (ExportFuncMetadata) {
194932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    mExportFuncCount = ExportFuncMetadata->getNumOperands();
195932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
196932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
197932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  populatePragmaMetadata(PragmaMetadata);
198932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
199932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
200932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    LOGE("Could not populate object slot metadata");
201932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
202932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
203932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
204932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return true;
205932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
206932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
207932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}  // namespace bcinfo
208932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
209