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