Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 1 | /* |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 2 | * Copyright 2011-2012, The Android Open Source Project |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 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 | |
Stephen Hines | b67c9e7 | 2012-03-22 11:02:48 -0700 | [diff] [blame] | 19 | #include "bcinfo/BitcodeWrapper.h" |
| 20 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 21 | #define LOG_TAG "bcinfo" |
| 22 | #include <cutils/log.h> |
| 23 | |
| 24 | #include "llvm/ADT/OwningPtr.h" |
| 25 | #include "llvm/Bitcode/ReaderWriter.h" |
Daniel Malea | 094881f | 2011-12-14 17:39:16 -0500 | [diff] [blame] | 26 | #include "llvm/Constants.h" |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 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 | |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 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 | |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 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 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 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) |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 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), |
Stephen Hines | a7e5c8f | 2012-03-28 12:58:24 -0700 | [diff] [blame] | 67 | mObjectSlotCount(0), mObjectSlotList(NULL), |
Stephen Hines | e1fd804 | 2012-03-27 11:03:46 -0700 | [diff] [blame] | 68 | mRSFloatPrecision(RS_FP_Full) { |
Stephen Hines | b67c9e7 | 2012-03-22 11:02:48 -0700 | [diff] [blame] | 69 | BitcodeWrapper wrapper(bitcode, bitcodeSize); |
| 70 | mCompilerVersion = wrapper.getCompilerVersion(); |
| 71 | mOptimizationLevel = wrapper.getOptimizationLevel(); |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 72 | } |
| 73 | |
| 74 | |
| 75 | MetadataExtractor::MetadataExtractor(const llvm::Module *module) |
| 76 | : mModule(module), mBitcode(NULL), mBitcodeSize(0), mExportVarCount(0), |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 77 | mExportFuncCount(0), mExportForEachSignatureCount(0), |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 78 | mExportVarNameList(NULL), mExportFuncNameList(NULL), |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 79 | mExportForEachNameList(NULL), mExportForEachSignatureList(NULL), |
| 80 | mPragmaCount(0), mPragmaKeyList(NULL), mPragmaValueList(NULL), |
Stephen Hines | 98abb2d | 2012-04-06 16:52:51 -0700 | [diff] [blame] | 81 | mObjectSlotCount(0), mObjectSlotList(NULL), |
| 82 | mRSFloatPrecision(RS_FP_Full) { |
Stephen Hines | a7e5c8f | 2012-03-28 12:58:24 -0700 | [diff] [blame] | 83 | mCompilerVersion = 0; |
| 84 | mOptimizationLevel = 3; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 85 | } |
| 86 | |
| 87 | |
| 88 | MetadataExtractor::~MetadataExtractor() { |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 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 | |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 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 | |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 116 | delete [] mExportForEachSignatureList; |
| 117 | mExportForEachSignatureList = NULL; |
| 118 | |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 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; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 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)) { |
Steve Block | 10c1412 | 2012-01-08 10:15:06 +0000 | [diff] [blame] | 165 | ALOGE("Non-integer object slot value '%s'", Slot.str().c_str()); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 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 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 205 | const char **TmpKeyList = new const char*[mPragmaCount]; |
| 206 | const char **TmpValueList = new const char*[mPragmaCount]; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 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); |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 212 | TmpKeyList[i] = createStringFromValue(PragmaKeyMDS); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 213 | llvm::Value *PragmaValueMDS = Pragma->getOperand(1); |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 214 | TmpValueList[i] = createStringFromValue(PragmaValueMDS); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 215 | } |
| 216 | } |
| 217 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 218 | mPragmaKeyList = TmpKeyList; |
| 219 | mPragmaValueList = TmpValueList; |
| 220 | |
Stephen Hines | e1fd804 | 2012-03-27 11:03:46 -0700 | [diff] [blame] | 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 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 249 | return; |
| 250 | } |
| 251 | |
| 252 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 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 | |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 305 | bool MetadataExtractor::populateForEachMetadata( |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 306 | const llvm::NamedMDNode *Names, |
| 307 | const llvm::NamedMDNode *Signatures) { |
Stephen Hines | 6649e6b | 2012-06-06 16:01:59 -0700 | [diff] [blame] | 308 | if (!Names && !Signatures) { |
Stephen Hines | 0231bb0 | 2011-10-10 15:30:25 -0700 | [diff] [blame] | 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; |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 313 | char **TmpNameList = new char*[mExportForEachSignatureCount]; |
| 314 | TmpNameList[0] = new char[5]; |
| 315 | strncpy(TmpNameList[0], "root", 5); |
| 316 | |
Stephen Hines | 0231bb0 | 2011-10-10 15:30:25 -0700 | [diff] [blame] | 317 | uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount]; |
| 318 | TmpSigList[0] = 0x1f; |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 319 | |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 320 | mExportForEachNameList = (const char**)TmpNameList; |
Stephen Hines | 0231bb0 | 2011-10-10 15:30:25 -0700 | [diff] [blame] | 321 | mExportForEachSignatureList = TmpSigList; |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 322 | return true; |
| 323 | } |
| 324 | |
Stephen Hines | 6649e6b | 2012-06-06 16:01:59 -0700 | [diff] [blame] | 325 | if (Signatures) { |
| 326 | mExportForEachSignatureCount = Signatures->getNumOperands(); |
| 327 | if (!mExportForEachSignatureCount) { |
| 328 | return true; |
| 329 | } |
| 330 | } else { |
| 331 | mExportForEachSignatureCount = 0; |
| 332 | mExportForEachSignatureList = NULL; |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 333 | return true; |
| 334 | } |
| 335 | |
| 336 | uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount]; |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 337 | const char **TmpNameList = new const char*[mExportForEachSignatureCount]; |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 338 | |
| 339 | for (size_t i = 0; i < mExportForEachSignatureCount; i++) { |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 340 | llvm::MDNode *SigNode = Signatures->getOperand(i); |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 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)) { |
Steve Block | 10c1412 | 2012-01-08 10:15:06 +0000 | [diff] [blame] | 348 | ALOGE("Non-integer signature value '%s'", SigString.str().c_str()); |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 349 | return false; |
| 350 | } |
| 351 | TmpSigList[i] = Signature; |
| 352 | } |
| 353 | } |
| 354 | } |
| 355 | |
Stephen Hines | 6649e6b | 2012-06-06 16:01:59 -0700 | [diff] [blame] | 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 | } |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 362 | } |
Stephen Hines | 6649e6b | 2012-06-06 16:01:59 -0700 | [diff] [blame] | 363 | } else { |
| 364 | if (mExportForEachSignatureCount != 1) { |
| 365 | ALOGE("mExportForEachSignatureCount = %u, but should be 1", |
| 366 | mExportForEachSignatureCount); |
| 367 | } |
| 368 | char *RootName = new char[5]; |
| 369 | strncpy(RootName, "root", 5); |
| 370 | TmpNameList[0] = RootName; |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 371 | } |
| 372 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 373 | mExportForEachNameList = TmpNameList; |
| 374 | mExportForEachSignatureList = TmpSigList; |
| 375 | |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 376 | return true; |
| 377 | } |
| 378 | |
| 379 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 380 | bool MetadataExtractor::extract() { |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 381 | if (!(mBitcode && mBitcodeSize) && !mModule) { |
| 382 | ALOGE("Invalid/empty bitcode/module"); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 383 | return false; |
| 384 | } |
| 385 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 386 | llvm::OwningPtr<llvm::LLVMContext> mContext; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 387 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 388 | if (!mModule) { |
| 389 | mContext.reset(new llvm::LLVMContext()); |
| 390 | llvm::OwningPtr<llvm::MemoryBuffer> MEM( |
| 391 | llvm::MemoryBuffer::getMemBuffer( |
Stephen Hines | e708ffe | 2012-05-03 15:18:49 -0700 | [diff] [blame] | 392 | llvm::StringRef(mBitcode, mBitcodeSize), "", false)); |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 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 | } |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 402 | } |
| 403 | |
| 404 | const llvm::NamedMDNode *ExportVarMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 405 | mModule->getNamedMetadata(ExportVarMetadataName); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 406 | const llvm::NamedMDNode *ExportFuncMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 407 | mModule->getNamedMetadata(ExportFuncMetadataName); |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 408 | const llvm::NamedMDNode *ExportForEachNameMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 409 | mModule->getNamedMetadata(ExportForEachNameMetadataName); |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 410 | const llvm::NamedMDNode *ExportForEachMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 411 | mModule->getNamedMetadata(ExportForEachMetadataName); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 412 | const llvm::NamedMDNode *PragmaMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 413 | mModule->getNamedMetadata(PragmaMetadataName); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 414 | const llvm::NamedMDNode *ObjectSlotMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 415 | mModule->getNamedMetadata(ObjectSlotMetadataName); |
Daniel Malea | 094881f | 2011-12-14 17:39:16 -0500 | [diff] [blame] | 416 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 417 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 418 | if (!populateVarNameMetadata(ExportVarMetadata)) { |
| 419 | ALOGE("Could not populate export variable metadata"); |
| 420 | return false; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 421 | } |
| 422 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 423 | if (!populateFuncNameMetadata(ExportFuncMetadata)) { |
| 424 | ALOGE("Could not populate export function metadata"); |
| 425 | return false; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 426 | } |
| 427 | |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 428 | if (!populateForEachMetadata(ExportForEachNameMetadata, |
| 429 | ExportForEachMetadata)) { |
Steve Block | 10c1412 | 2012-01-08 10:15:06 +0000 | [diff] [blame] | 430 | ALOGE("Could not populate ForEach signature metadata"); |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 431 | return false; |
| 432 | } |
| 433 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 434 | populatePragmaMetadata(PragmaMetadata); |
| 435 | |
| 436 | if (!populateObjectSlotMetadata(ObjectSlotMetadata)) { |
Steve Block | 10c1412 | 2012-01-08 10:15:06 +0000 | [diff] [blame] | 437 | ALOGE("Could not populate object slot metadata"); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 438 | return false; |
| 439 | } |
| 440 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 441 | return true; |
| 442 | } |
| 443 | |
| 444 | } // namespace bcinfo |
| 445 | |