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