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