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