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> |
Stephen Hines | 32c56ec | 2012-06-01 15:26:30 -0700 | [diff] [blame] | 23 | #include <cutils/properties.h> |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 24 | |
| 25 | #include "llvm/ADT/OwningPtr.h" |
| 26 | #include "llvm/Bitcode/ReaderWriter.h" |
Daniel Malea | 094881f | 2011-12-14 17:39:16 -0500 | [diff] [blame] | 27 | #include "llvm/Constants.h" |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 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 | |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 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 | |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 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 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 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) |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 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), |
Stephen Hines | a7e5c8f | 2012-03-28 12:58:24 -0700 | [diff] [blame] | 68 | mObjectSlotCount(0), mObjectSlotList(NULL), |
Stephen Hines | e1fd804 | 2012-03-27 11:03:46 -0700 | [diff] [blame] | 69 | mRSFloatPrecision(RS_FP_Full) { |
Stephen Hines | b67c9e7 | 2012-03-22 11:02:48 -0700 | [diff] [blame] | 70 | BitcodeWrapper wrapper(bitcode, bitcodeSize); |
| 71 | mCompilerVersion = wrapper.getCompilerVersion(); |
| 72 | mOptimizationLevel = wrapper.getOptimizationLevel(); |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 73 | } |
| 74 | |
| 75 | |
| 76 | MetadataExtractor::MetadataExtractor(const llvm::Module *module) |
| 77 | : mModule(module), mBitcode(NULL), mBitcodeSize(0), mExportVarCount(0), |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 78 | mExportFuncCount(0), mExportForEachSignatureCount(0), |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 79 | mExportVarNameList(NULL), mExportFuncNameList(NULL), |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 80 | mExportForEachNameList(NULL), mExportForEachSignatureList(NULL), |
| 81 | mPragmaCount(0), mPragmaKeyList(NULL), mPragmaValueList(NULL), |
Stephen Hines | 98abb2d | 2012-04-06 16:52:51 -0700 | [diff] [blame] | 82 | mObjectSlotCount(0), mObjectSlotList(NULL), |
| 83 | mRSFloatPrecision(RS_FP_Full) { |
Stephen Hines | a7e5c8f | 2012-03-28 12:58:24 -0700 | [diff] [blame] | 84 | mCompilerVersion = 0; |
| 85 | mOptimizationLevel = 3; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | |
| 89 | MetadataExtractor::~MetadataExtractor() { |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 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 | |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 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 | |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 117 | delete [] mExportForEachSignatureList; |
| 118 | mExportForEachSignatureList = NULL; |
| 119 | |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 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; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 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)) { |
Steve Block | 10c1412 | 2012-01-08 10:15:06 +0000 | [diff] [blame] | 166 | ALOGE("Non-integer object slot value '%s'", Slot.str().c_str()); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 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 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 206 | const char **TmpKeyList = new const char*[mPragmaCount]; |
| 207 | const char **TmpValueList = new const char*[mPragmaCount]; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 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); |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 213 | TmpKeyList[i] = createStringFromValue(PragmaKeyMDS); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 214 | llvm::Value *PragmaValueMDS = Pragma->getOperand(1); |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 215 | TmpValueList[i] = createStringFromValue(PragmaValueMDS); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 216 | } |
| 217 | } |
| 218 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 219 | mPragmaKeyList = TmpKeyList; |
| 220 | mPragmaValueList = TmpValueList; |
| 221 | |
Stephen Hines | e1fd804 | 2012-03-27 11:03:46 -0700 | [diff] [blame] | 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"); |
Stephen Hines | 32c56ec | 2012-06-01 15:26:30 -0700 | [diff] [blame] | 225 | std::string Full("rs_fp_full"); |
Stephen Hines | e1fd804 | 2012-03-27 11:03:46 -0700 | [diff] [blame] | 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 | |
Stephen Hines | 32c56ec | 2012-06-01 15:26:30 -0700 | [diff] [blame] | 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 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 271 | return; |
| 272 | } |
| 273 | |
| 274 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 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 | |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 327 | bool MetadataExtractor::populateForEachMetadata( |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 328 | const llvm::NamedMDNode *Names, |
| 329 | const llvm::NamedMDNode *Signatures) { |
Stephen Hines | 109be67 | 2012-06-06 16:01:59 -0700 | [diff] [blame] | 330 | if (!Names && !Signatures) { |
Stephen Hines | 0231bb0 | 2011-10-10 15:30:25 -0700 | [diff] [blame] | 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; |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 335 | char **TmpNameList = new char*[mExportForEachSignatureCount]; |
| 336 | TmpNameList[0] = new char[5]; |
| 337 | strncpy(TmpNameList[0], "root", 5); |
| 338 | |
Stephen Hines | 0231bb0 | 2011-10-10 15:30:25 -0700 | [diff] [blame] | 339 | uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount]; |
| 340 | TmpSigList[0] = 0x1f; |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 341 | |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 342 | mExportForEachNameList = (const char**)TmpNameList; |
Stephen Hines | 0231bb0 | 2011-10-10 15:30:25 -0700 | [diff] [blame] | 343 | mExportForEachSignatureList = TmpSigList; |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 344 | return true; |
| 345 | } |
| 346 | |
Stephen Hines | 109be67 | 2012-06-06 16:01:59 -0700 | [diff] [blame] | 347 | if (Signatures) { |
| 348 | mExportForEachSignatureCount = Signatures->getNumOperands(); |
| 349 | if (!mExportForEachSignatureCount) { |
| 350 | return true; |
| 351 | } |
| 352 | } else { |
| 353 | mExportForEachSignatureCount = 0; |
| 354 | mExportForEachSignatureList = NULL; |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 355 | return true; |
| 356 | } |
| 357 | |
| 358 | uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount]; |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 359 | const char **TmpNameList = new const char*[mExportForEachSignatureCount]; |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 360 | |
| 361 | for (size_t i = 0; i < mExportForEachSignatureCount; i++) { |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 362 | llvm::MDNode *SigNode = Signatures->getOperand(i); |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 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)) { |
Steve Block | 10c1412 | 2012-01-08 10:15:06 +0000 | [diff] [blame] | 370 | ALOGE("Non-integer signature value '%s'", SigString.str().c_str()); |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 371 | return false; |
| 372 | } |
| 373 | TmpSigList[i] = Signature; |
| 374 | } |
| 375 | } |
| 376 | } |
| 377 | |
Stephen Hines | 109be67 | 2012-06-06 16:01:59 -0700 | [diff] [blame] | 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 | } |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 384 | } |
Stephen Hines | 109be67 | 2012-06-06 16:01:59 -0700 | [diff] [blame] | 385 | } else { |
| 386 | if (mExportForEachSignatureCount != 1) { |
| 387 | ALOGE("mExportForEachSignatureCount = %u, but should be 1", |
| 388 | mExportForEachSignatureCount); |
| 389 | } |
| 390 | char *RootName = new char[5]; |
| 391 | strncpy(RootName, "root", 5); |
| 392 | TmpNameList[0] = RootName; |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 393 | } |
| 394 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 395 | mExportForEachNameList = TmpNameList; |
| 396 | mExportForEachSignatureList = TmpSigList; |
| 397 | |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 398 | return true; |
| 399 | } |
| 400 | |
| 401 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 402 | bool MetadataExtractor::extract() { |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 403 | if (!(mBitcode && mBitcodeSize) && !mModule) { |
| 404 | ALOGE("Invalid/empty bitcode/module"); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 405 | return false; |
| 406 | } |
| 407 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 408 | llvm::OwningPtr<llvm::LLVMContext> mContext; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 409 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 410 | if (!mModule) { |
| 411 | mContext.reset(new llvm::LLVMContext()); |
| 412 | llvm::OwningPtr<llvm::MemoryBuffer> MEM( |
| 413 | llvm::MemoryBuffer::getMemBuffer( |
Stephen Hines | e708ffe | 2012-05-03 15:18:49 -0700 | [diff] [blame] | 414 | llvm::StringRef(mBitcode, mBitcodeSize), "", false)); |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 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 | } |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 424 | } |
| 425 | |
| 426 | const llvm::NamedMDNode *ExportVarMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 427 | mModule->getNamedMetadata(ExportVarMetadataName); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 428 | const llvm::NamedMDNode *ExportFuncMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 429 | mModule->getNamedMetadata(ExportFuncMetadataName); |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 430 | const llvm::NamedMDNode *ExportForEachNameMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 431 | mModule->getNamedMetadata(ExportForEachNameMetadataName); |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 432 | const llvm::NamedMDNode *ExportForEachMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 433 | mModule->getNamedMetadata(ExportForEachMetadataName); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 434 | const llvm::NamedMDNode *PragmaMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 435 | mModule->getNamedMetadata(PragmaMetadataName); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 436 | const llvm::NamedMDNode *ObjectSlotMetadata = |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 437 | mModule->getNamedMetadata(ObjectSlotMetadataName); |
Daniel Malea | 094881f | 2011-12-14 17:39:16 -0500 | [diff] [blame] | 438 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 439 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 440 | if (!populateVarNameMetadata(ExportVarMetadata)) { |
| 441 | ALOGE("Could not populate export variable metadata"); |
| 442 | return false; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 443 | } |
| 444 | |
Stephen Hines | 569986d | 2012-03-09 19:58:45 -0800 | [diff] [blame] | 445 | if (!populateFuncNameMetadata(ExportFuncMetadata)) { |
| 446 | ALOGE("Could not populate export function metadata"); |
| 447 | return false; |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 448 | } |
| 449 | |
Stephen Hines | cc366e5 | 2012-02-21 17:22:04 -0800 | [diff] [blame] | 450 | if (!populateForEachMetadata(ExportForEachNameMetadata, |
| 451 | ExportForEachMetadata)) { |
Steve Block | 10c1412 | 2012-01-08 10:15:06 +0000 | [diff] [blame] | 452 | ALOGE("Could not populate ForEach signature metadata"); |
Stephen Hines | 33f8fe2 | 2011-08-17 12:56:22 -0700 | [diff] [blame] | 453 | return false; |
| 454 | } |
| 455 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 456 | populatePragmaMetadata(PragmaMetadata); |
| 457 | |
| 458 | if (!populateObjectSlotMetadata(ObjectSlotMetadata)) { |
Steve Block | 10c1412 | 2012-01-08 10:15:06 +0000 | [diff] [blame] | 459 | ALOGE("Could not populate object slot metadata"); |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 460 | return false; |
| 461 | } |
| 462 | |
Stephen Hines | 932bc6e | 2011-07-27 16:26:26 -0700 | [diff] [blame] | 463 | return true; |
| 464 | } |
| 465 | |
| 466 | } // namespace bcinfo |
| 467 | |