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