Home | History | Annotate | Download | only in bcinfo
      1 /*
      2  * Copyright 2011-2012, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "bcinfo/MetadataExtractor.h"
     18 
     19 #include "bcinfo/BitcodeWrapper.h"
     20 
     21 #define LOG_TAG "bcinfo"
     22 #include <cutils/log.h>
     23 
     24 #include "llvm/ADT/OwningPtr.h"
     25 #include "llvm/Bitcode/ReaderWriter.h"
     26 #include "llvm/Constants.h"
     27 #include "llvm/LLVMContext.h"
     28 #include "llvm/Module.h"
     29 #include "llvm/Support/MemoryBuffer.h"
     30 
     31 #include <cstdlib>
     32 
     33 namespace bcinfo {
     34 
     35 // Name of metadata node where pragma info resides (should be synced with
     36 // slang.cpp)
     37 static const llvm::StringRef PragmaMetadataName = "#pragma";
     38 
     39 // Name of metadata node where exported variable names reside (should be
     40 // synced with slang_rs_metadata.h)
     41 static const llvm::StringRef ExportVarMetadataName = "#rs_export_var";
     42 
     43 // Name of metadata node where exported function names reside (should be
     44 // synced with slang_rs_metadata.h)
     45 static const llvm::StringRef ExportFuncMetadataName = "#rs_export_func";
     46 
     47 // Name of metadata node where exported ForEach name information resides
     48 // (should be synced with slang_rs_metadata.h)
     49 static const llvm::StringRef ExportForEachNameMetadataName =
     50     "#rs_export_foreach_name";
     51 
     52 // Name of metadata node where exported ForEach signature information resides
     53 // (should be synced with slang_rs_metadata.h)
     54 static const llvm::StringRef ExportForEachMetadataName = "#rs_export_foreach";
     55 
     56 // Name of metadata node where RS object slot info resides (should be
     57 // synced with slang_rs_metadata.h)
     58 static const llvm::StringRef ObjectSlotMetadataName = "#rs_object_slots";
     59 
     60 
     61 MetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
     62     : mModule(NULL), mBitcode(bitcode), mBitcodeSize(bitcodeSize),
     63       mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
     64       mExportVarNameList(NULL), mExportFuncNameList(NULL),
     65       mExportForEachNameList(NULL), mExportForEachSignatureList(NULL),
     66       mPragmaCount(0), mPragmaKeyList(NULL), mPragmaValueList(NULL),
     67       mObjectSlotCount(0), mObjectSlotList(NULL),
     68       mRSFloatPrecision(RS_FP_Full) {
     69   BitcodeWrapper wrapper(bitcode, bitcodeSize);
     70   mCompilerVersion = wrapper.getCompilerVersion();
     71   mOptimizationLevel = wrapper.getOptimizationLevel();
     72 }
     73 
     74 
     75 MetadataExtractor::MetadataExtractor(const llvm::Module *module)
     76     : mModule(module), mBitcode(NULL), mBitcodeSize(0), mExportVarCount(0),
     77       mExportFuncCount(0), mExportForEachSignatureCount(0),
     78       mExportVarNameList(NULL), mExportFuncNameList(NULL),
     79       mExportForEachNameList(NULL), mExportForEachSignatureList(NULL),
     80       mPragmaCount(0), mPragmaKeyList(NULL), mPragmaValueList(NULL),
     81       mObjectSlotCount(0), mObjectSlotList(NULL),
     82       mRSFloatPrecision(RS_FP_Full) {
     83   mCompilerVersion = 0;
     84   mOptimizationLevel = 3;
     85 }
     86 
     87 
     88 MetadataExtractor::~MetadataExtractor() {
     89   if (mExportVarNameList) {
     90     for (size_t i = 0; i < mExportVarCount; i++) {
     91         delete [] mExportVarNameList[i];
     92         mExportVarNameList[i] = NULL;
     93     }
     94   }
     95   delete [] mExportVarNameList;
     96   mExportVarNameList = NULL;
     97 
     98   if (mExportFuncNameList) {
     99     for (size_t i = 0; i < mExportFuncCount; i++) {
    100         delete [] mExportFuncNameList[i];
    101         mExportFuncNameList[i] = NULL;
    102     }
    103   }
    104   delete [] mExportFuncNameList;
    105   mExportFuncNameList = NULL;
    106 
    107   if (mExportForEachNameList) {
    108     for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
    109         delete [] mExportForEachNameList[i];
    110         mExportForEachNameList[i] = NULL;
    111     }
    112   }
    113   delete [] mExportForEachNameList;
    114   mExportForEachNameList = NULL;
    115 
    116   delete [] mExportForEachSignatureList;
    117   mExportForEachSignatureList = NULL;
    118 
    119   for (size_t i = 0; i < mPragmaCount; i++) {
    120     if (mPragmaKeyList) {
    121       delete [] mPragmaKeyList[i];
    122       mPragmaKeyList[i] = NULL;
    123     }
    124     if (mPragmaValueList) {
    125       delete [] mPragmaValueList[i];
    126       mPragmaValueList[i] = NULL;
    127     }
    128   }
    129   delete [] mPragmaKeyList;
    130   mPragmaKeyList = NULL;
    131   delete [] mPragmaValueList;
    132   mPragmaValueList = NULL;
    133 
    134   delete [] mObjectSlotList;
    135   mObjectSlotList = NULL;
    136 
    137   return;
    138 }
    139 
    140 
    141 bool MetadataExtractor::populateObjectSlotMetadata(
    142     const llvm::NamedMDNode *ObjectSlotMetadata) {
    143   if (!ObjectSlotMetadata) {
    144     return true;
    145   }
    146 
    147   mObjectSlotCount = ObjectSlotMetadata->getNumOperands();
    148 
    149   if (!mObjectSlotCount) {
    150     return true;
    151   }
    152 
    153   uint32_t *TmpSlotList = new uint32_t[mObjectSlotCount];
    154   memset(TmpSlotList, 0, mObjectSlotCount * sizeof(*TmpSlotList));
    155 
    156   for (size_t i = 0; i < mObjectSlotCount; i++) {
    157     llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
    158     if (ObjectSlot != NULL && ObjectSlot->getNumOperands() == 1) {
    159       llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
    160       if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
    161         llvm::StringRef Slot =
    162             static_cast<llvm::MDString*>(SlotMDS)->getString();
    163         uint32_t USlot = 0;
    164         if (Slot.getAsInteger(10, USlot)) {
    165           ALOGE("Non-integer object slot value '%s'", Slot.str().c_str());
    166           return false;
    167         }
    168         TmpSlotList[i] = USlot;
    169       }
    170     }
    171   }
    172 
    173   mObjectSlotList = TmpSlotList;
    174 
    175   return true;
    176 }
    177 
    178 
    179 static const char *createStringFromValue(llvm::Value *v) {
    180   if (v->getValueID() != llvm::Value::MDStringVal) {
    181     return NULL;
    182   }
    183 
    184   llvm::StringRef ref = static_cast<llvm::MDString*>(v)->getString();
    185 
    186   char *c = new char[ref.size() + 1];
    187   memcpy(c, ref.data(), ref.size());
    188   c[ref.size()] = '\0';
    189 
    190   return c;
    191 }
    192 
    193 
    194 void MetadataExtractor::populatePragmaMetadata(
    195     const llvm::NamedMDNode *PragmaMetadata) {
    196   if (!PragmaMetadata) {
    197     return;
    198   }
    199 
    200   mPragmaCount = PragmaMetadata->getNumOperands();
    201   if (!mPragmaCount) {
    202     return;
    203   }
    204 
    205   const char **TmpKeyList = new const char*[mPragmaCount];
    206   const char **TmpValueList = new const char*[mPragmaCount];
    207 
    208   for (size_t i = 0; i < mPragmaCount; i++) {
    209     llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
    210     if (Pragma != NULL && Pragma->getNumOperands() == 2) {
    211       llvm::Value *PragmaKeyMDS = Pragma->getOperand(0);
    212       TmpKeyList[i] = createStringFromValue(PragmaKeyMDS);
    213       llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
    214       TmpValueList[i] = createStringFromValue(PragmaValueMDS);
    215     }
    216   }
    217 
    218   mPragmaKeyList = TmpKeyList;
    219   mPragmaValueList = TmpValueList;
    220 
    221   // Check to see if we have any FP precision-related pragmas.
    222   std::string Relaxed("rs_fp_relaxed");
    223   std::string Imprecise("rs_fp_imprecise");
    224   bool RelaxedPragmaSeen = false;
    225   bool ImprecisePragmaSeen = false;
    226 
    227   for (size_t i = 0; i < mPragmaCount; i++) {
    228     if (!Relaxed.compare(mPragmaKeyList[i])) {
    229       if (RelaxedPragmaSeen || ImprecisePragmaSeen) {
    230         ALOGE("Multiple float precision pragmas specified!");
    231       }
    232       RelaxedPragmaSeen = true;
    233     } else if (!Imprecise.compare(mPragmaKeyList[i])) {
    234       if (RelaxedPragmaSeen || ImprecisePragmaSeen) {
    235         ALOGE("Multiple float precision pragmas specified!");
    236       }
    237       ImprecisePragmaSeen = true;
    238     }
    239   }
    240 
    241   // Imprecise is selected over Relaxed precision.
    242   // In the absence of both, we stick to the default Full precision.
    243   if (ImprecisePragmaSeen) {
    244     mRSFloatPrecision = RS_FP_Imprecise;
    245   } else if (RelaxedPragmaSeen) {
    246     mRSFloatPrecision = RS_FP_Relaxed;
    247   }
    248 
    249   return;
    250 }
    251 
    252 
    253 bool MetadataExtractor::populateVarNameMetadata(
    254     const llvm::NamedMDNode *VarNameMetadata) {
    255   if (!VarNameMetadata) {
    256     return true;
    257   }
    258 
    259   mExportVarCount = VarNameMetadata->getNumOperands();
    260   if (!mExportVarCount) {
    261     return true;
    262   }
    263 
    264   const char **TmpNameList = new const char *[mExportVarCount];
    265 
    266   for (size_t i = 0; i < mExportVarCount; i++) {
    267     llvm::MDNode *Name = VarNameMetadata->getOperand(i);
    268     if (Name != NULL && Name->getNumOperands() > 1) {
    269       TmpNameList[i] = createStringFromValue(Name->getOperand(0));
    270     }
    271   }
    272 
    273   mExportVarNameList = TmpNameList;
    274 
    275   return true;
    276 }
    277 
    278 
    279 bool MetadataExtractor::populateFuncNameMetadata(
    280     const llvm::NamedMDNode *FuncNameMetadata) {
    281   if (!FuncNameMetadata) {
    282     return true;
    283   }
    284 
    285   mExportFuncCount = FuncNameMetadata->getNumOperands();
    286   if (!mExportFuncCount) {
    287     return true;
    288   }
    289 
    290   const char **TmpNameList = new const char*[mExportFuncCount];
    291 
    292   for (size_t i = 0; i < mExportFuncCount; i++) {
    293     llvm::MDNode *Name = FuncNameMetadata->getOperand(i);
    294     if (Name != NULL && Name->getNumOperands() == 1) {
    295       TmpNameList[i] = createStringFromValue(Name->getOperand(0));
    296     }
    297   }
    298 
    299   mExportFuncNameList = TmpNameList;
    300 
    301   return true;
    302 }
    303 
    304 
    305 bool MetadataExtractor::populateForEachMetadata(
    306     const llvm::NamedMDNode *Names,
    307     const llvm::NamedMDNode *Signatures) {
    308   if (!Names && !Signatures) {
    309     // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
    310     // section for ForEach. We generate a full signature for a "root" function
    311     // which means that we need to set the bottom 5 bits in the mask.
    312     mExportForEachSignatureCount = 1;
    313     char **TmpNameList = new char*[mExportForEachSignatureCount];
    314     TmpNameList[0] = new char[5];
    315     strncpy(TmpNameList[0], "root", 5);
    316 
    317     uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
    318     TmpSigList[0] = 0x1f;
    319 
    320     mExportForEachNameList = (const char**)TmpNameList;
    321     mExportForEachSignatureList = TmpSigList;
    322     return true;
    323   }
    324 
    325   if (Signatures) {
    326     mExportForEachSignatureCount = Signatures->getNumOperands();
    327     if (!mExportForEachSignatureCount) {
    328       return true;
    329     }
    330   } else {
    331     mExportForEachSignatureCount = 0;
    332     mExportForEachSignatureList = NULL;
    333     return true;
    334   }
    335 
    336   uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
    337   const char **TmpNameList = new const char*[mExportForEachSignatureCount];
    338 
    339   for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
    340     llvm::MDNode *SigNode = Signatures->getOperand(i);
    341     if (SigNode != NULL && SigNode->getNumOperands() == 1) {
    342       llvm::Value *SigVal = SigNode->getOperand(0);
    343       if (SigVal->getValueID() == llvm::Value::MDStringVal) {
    344         llvm::StringRef SigString =
    345             static_cast<llvm::MDString*>(SigVal)->getString();
    346         uint32_t Signature = 0;
    347         if (SigString.getAsInteger(10, Signature)) {
    348           ALOGE("Non-integer signature value '%s'", SigString.str().c_str());
    349           return false;
    350         }
    351         TmpSigList[i] = Signature;
    352       }
    353     }
    354   }
    355 
    356   if (Names) {
    357     for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
    358       llvm::MDNode *Name = Names->getOperand(i);
    359       if (Name != NULL && Name->getNumOperands() == 1) {
    360         TmpNameList[i] = createStringFromValue(Name->getOperand(0));
    361       }
    362     }
    363   } else {
    364     if (mExportForEachSignatureCount != 1) {
    365       ALOGE("mExportForEachSignatureCount = %zu, but should be 1",
    366             mExportForEachSignatureCount);
    367     }
    368     char *RootName = new char[5];
    369     strncpy(RootName, "root", 5);
    370     TmpNameList[0] = RootName;
    371   }
    372 
    373   mExportForEachNameList = TmpNameList;
    374   mExportForEachSignatureList = TmpSigList;
    375 
    376   return true;
    377 }
    378 
    379 
    380 bool MetadataExtractor::extract() {
    381   if (!(mBitcode && mBitcodeSize) && !mModule) {
    382     ALOGE("Invalid/empty bitcode/module");
    383     return false;
    384   }
    385 
    386   llvm::OwningPtr<llvm::LLVMContext> mContext;
    387 
    388   if (!mModule) {
    389     mContext.reset(new llvm::LLVMContext());
    390     llvm::OwningPtr<llvm::MemoryBuffer> MEM(
    391       llvm::MemoryBuffer::getMemBuffer(
    392         llvm::StringRef(mBitcode, mBitcodeSize), "", false));
    393     std::string error;
    394 
    395     // Module ownership is handled by the context, so we don't need to free it.
    396     mModule = llvm::ParseBitcodeFile(MEM.get(), *mContext, &error);
    397     if (!mModule) {
    398       ALOGE("Could not parse bitcode file");
    399       ALOGE("%s", error.c_str());
    400       return false;
    401     }
    402   }
    403 
    404   const llvm::NamedMDNode *ExportVarMetadata =
    405       mModule->getNamedMetadata(ExportVarMetadataName);
    406   const llvm::NamedMDNode *ExportFuncMetadata =
    407       mModule->getNamedMetadata(ExportFuncMetadataName);
    408   const llvm::NamedMDNode *ExportForEachNameMetadata =
    409       mModule->getNamedMetadata(ExportForEachNameMetadataName);
    410   const llvm::NamedMDNode *ExportForEachMetadata =
    411       mModule->getNamedMetadata(ExportForEachMetadataName);
    412   const llvm::NamedMDNode *PragmaMetadata =
    413       mModule->getNamedMetadata(PragmaMetadataName);
    414   const llvm::NamedMDNode *ObjectSlotMetadata =
    415       mModule->getNamedMetadata(ObjectSlotMetadataName);
    416 
    417 
    418   if (!populateVarNameMetadata(ExportVarMetadata)) {
    419     ALOGE("Could not populate export variable metadata");
    420     return false;
    421   }
    422 
    423   if (!populateFuncNameMetadata(ExportFuncMetadata)) {
    424     ALOGE("Could not populate export function metadata");
    425     return false;
    426   }
    427 
    428   if (!populateForEachMetadata(ExportForEachNameMetadata,
    429                                ExportForEachMetadata)) {
    430     ALOGE("Could not populate ForEach signature metadata");
    431     return false;
    432   }
    433 
    434   populatePragmaMetadata(PragmaMetadata);
    435 
    436   if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
    437     ALOGE("Could not populate object slot metadata");
    438     return false;
    439   }
    440 
    441   return true;
    442 }
    443 
    444 }  // namespace bcinfo
    445 
    446