• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 __ANDROID__
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 
getStringOperand(const llvm::Metadata * node)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 
extractUIntFromMetadataString(uint32_t * value,const llvm::Metadata * m)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 
createStringFromValue(llvm::Metadata * m)59 const char *createStringFromValue(llvm::Metadata *m) {
60   auto ref = getStringOperand(m);
61   char *c = new char[ref.size() + 1];
62   memcpy(c, ref.data(), ref.size());
63   c[ref.size()] = '\0';
64   return c;
65 }
66 
createStringFromOptionalValue(llvm::MDNode * n,unsigned opndNum)67 const char *createStringFromOptionalValue(llvm::MDNode *n, unsigned opndNum) {
68   llvm::Metadata *opnd;
69   if (opndNum >= n->getNumOperands() || !(opnd = n->getOperand(opndNum)))
70     return nullptr;
71   return createStringFromValue(opnd);
72 }
73 
74 // Collect metadata from NamedMDNodes that contain a list of names
75 // (strings).
76 //
77 // Inputs:
78 //
79 // NamedMetadata - An LLVM metadata node, each of whose operands have
80 // a string as their first entry
81 //
82 // NameList - A reference that will hold an allocated array of strings
83 //
84 // Count - A reference that will hold the length of the allocated
85 // array of strings
86 //
87 // Return value:
88 //
89 // Return true on success, false on error.
90 //
91 // Upon success, the function sets NameList to an array of strings
92 // corresponding the names found in the metadata. The function sets
93 // Count to the number of entries in NameList.
94 //
95 // An error occurs if one of the metadata operands doesn't have a
96 // first entry.
populateNameMetadata(const llvm::NamedMDNode * NameMetadata,const char ** & NameList,size_t & Count)97 bool populateNameMetadata(const llvm::NamedMDNode *NameMetadata,
98                           const char **&NameList, size_t &Count) {
99   if (!NameMetadata) {
100     NameList = nullptr;
101     Count = 0;
102     return true;
103   }
104 
105   Count = NameMetadata->getNumOperands();
106   if (!Count) {
107     NameList = nullptr;
108     return true;
109   }
110 
111   NameList = new const char *[Count];
112 
113   for (size_t i = 0; i < Count; i++) {
114     llvm::MDNode *Name = NameMetadata->getOperand(i);
115     if (Name && Name->getNumOperands() > 0) {
116       NameList[i] = createStringFromValue(Name->getOperand(0));
117     } else {
118       ALOGE("Metadata operand does not contain a name string");
119       for (size_t AllocatedIndex = 0; AllocatedIndex < i; AllocatedIndex++) {
120         delete [] NameList[AllocatedIndex];
121       }
122       delete [] NameList;
123       NameList = nullptr;
124       Count = 0;
125 
126       return false;
127     }
128   }
129 
130   return true;
131 }
132 
133 } // end anonymous namespace
134 
135 // Name of metadata node where pragma info resides (should be synced with
136 // slang.cpp)
137 static const llvm::StringRef PragmaMetadataName = "#pragma";
138 
139 // Name of metadata node where exported variable names reside (should be
140 // synced with slang_rs_metadata.h)
141 static const llvm::StringRef ExportVarMetadataName = "#rs_export_var";
142 
143 // Name of metadata node where exported function names reside (should be
144 // synced with slang_rs_metadata.h)
145 static const llvm::StringRef ExportFuncMetadataName = "#rs_export_func";
146 
147 // Name of metadata node where exported ForEach name information resides
148 // (should be synced with slang_rs_metadata.h)
149 static const llvm::StringRef ExportForEachNameMetadataName =
150     "#rs_export_foreach_name";
151 
152 // Name of metadata node where exported ForEach signature information resides
153 // (should be synced with slang_rs_metadata.h)
154 static const llvm::StringRef ExportForEachMetadataName = "#rs_export_foreach";
155 
156 // Name of metadata node where exported general reduce information resides
157 // (should be synced with slang_rs_metadata.h)
158 static const llvm::StringRef ExportReduceMetadataName = "#rs_export_reduce";
159 
160 // Name of metadata node where RS object slot info resides (should be
161 // synced with slang_rs_metadata.h)
162 static const llvm::StringRef ObjectSlotMetadataName = "#rs_object_slots";
163 
164 static const llvm::StringRef ThreadableMetadataName = "#rs_is_threadable";
165 
166 // Name of metadata node where the checksum for this build is stored.  (should
167 // be synced with libbcc/lib/Core/Source.cpp)
168 static const llvm::StringRef ChecksumMetadataName = "#rs_build_checksum";
169 
170 // Name of metadata node which contains a list of compile units that have debug
171 // metadata. If this is null then there is no debug metadata in the compile
172 // unit.
173 static const llvm::StringRef DebugInfoMetadataName = "llvm.dbg.cu";
174 
MetadataExtractor(const char * bitcode,size_t bitcodeSize)175 MetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
176     : mModule(nullptr), mBitcode(bitcode), mBitcodeSize(bitcodeSize),
177       mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
178       mExportReduceCount(0), mExportVarNameList(nullptr),
179       mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
180       mExportForEachSignatureList(nullptr),
181       mExportForEachInputCountList(nullptr),
182       mExportReduceList(nullptr),
183       mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
184       mObjectSlotCount(0), mObjectSlotList(nullptr),
185       mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
186       mBuildChecksum(nullptr), mHasDebugInfo(false) {
187   BitcodeWrapper wrapper(bitcode, bitcodeSize);
188   mTargetAPI = wrapper.getTargetAPI();
189   mCompilerVersion = wrapper.getCompilerVersion();
190   mOptimizationLevel = wrapper.getOptimizationLevel();
191 }
192 
MetadataExtractor(const llvm::Module * module)193 MetadataExtractor::MetadataExtractor(const llvm::Module *module)
194     : mModule(module), mBitcode(nullptr), mBitcodeSize(0),
195       mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
196       mExportReduceCount(0), mExportVarNameList(nullptr),
197       mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
198       mExportForEachSignatureList(nullptr),
199       mExportForEachInputCountList(nullptr),
200       mExportReduceList(nullptr),
201       mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
202       mObjectSlotCount(0), mObjectSlotList(nullptr),
203       mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
204       mBuildChecksum(nullptr) {
205   mCompilerVersion = RS_VERSION;  // Default to the actual current version.
206   mOptimizationLevel = 3;
207 }
208 
209 
~MetadataExtractor()210 MetadataExtractor::~MetadataExtractor() {
211   if (mExportVarNameList) {
212     for (size_t i = 0; i < mExportVarCount; i++) {
213         delete [] mExportVarNameList[i];
214         mExportVarNameList[i] = nullptr;
215     }
216   }
217   delete [] mExportVarNameList;
218   mExportVarNameList = nullptr;
219 
220   if (mExportFuncNameList) {
221     for (size_t i = 0; i < mExportFuncCount; i++) {
222         delete [] mExportFuncNameList[i];
223         mExportFuncNameList[i] = nullptr;
224     }
225   }
226   delete [] mExportFuncNameList;
227   mExportFuncNameList = nullptr;
228 
229   if (mExportForEachNameList) {
230     for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
231         delete [] mExportForEachNameList[i];
232         mExportForEachNameList[i] = nullptr;
233     }
234   }
235   delete [] mExportForEachNameList;
236   mExportForEachNameList = nullptr;
237 
238   delete [] mExportForEachSignatureList;
239   mExportForEachSignatureList = nullptr;
240 
241   delete [] mExportForEachInputCountList;
242   mExportForEachInputCountList = nullptr;
243 
244   delete [] mExportReduceList;
245   mExportReduceList = nullptr;
246 
247   for (size_t i = 0; i < mPragmaCount; i++) {
248     if (mPragmaKeyList) {
249       delete [] mPragmaKeyList[i];
250       mPragmaKeyList[i] = nullptr;
251     }
252     if (mPragmaValueList) {
253       delete [] mPragmaValueList[i];
254       mPragmaValueList[i] = nullptr;
255     }
256   }
257   delete [] mPragmaKeyList;
258   mPragmaKeyList = nullptr;
259   delete [] mPragmaValueList;
260   mPragmaValueList = nullptr;
261 
262   delete [] mObjectSlotList;
263   mObjectSlotList = nullptr;
264 
265   delete [] mBuildChecksum;
266 
267   return;
268 }
269 
270 
populateObjectSlotMetadata(const llvm::NamedMDNode * ObjectSlotMetadata)271 bool MetadataExtractor::populateObjectSlotMetadata(
272     const llvm::NamedMDNode *ObjectSlotMetadata) {
273   if (!ObjectSlotMetadata) {
274     return true;
275   }
276 
277   mObjectSlotCount = ObjectSlotMetadata->getNumOperands();
278 
279   if (!mObjectSlotCount) {
280     return true;
281   }
282 
283   uint32_t *TmpSlotList = new uint32_t[mObjectSlotCount];
284   memset(TmpSlotList, 0, mObjectSlotCount * sizeof(*TmpSlotList));
285 
286   for (size_t i = 0; i < mObjectSlotCount; i++) {
287     llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
288     if (ObjectSlot != nullptr && ObjectSlot->getNumOperands() == 1) {
289       if (!extractUIntFromMetadataString(&TmpSlotList[i], ObjectSlot->getOperand(0))) {
290         ALOGE("Non-integer object slot value");
291         return false;
292       }
293     } else {
294       ALOGE("Corrupt object slot information");
295       return false;
296     }
297   }
298 
299   mObjectSlotList = TmpSlotList;
300 
301   return true;
302 }
303 
304 
populatePragmaMetadata(const llvm::NamedMDNode * PragmaMetadata)305 void MetadataExtractor::populatePragmaMetadata(
306     const llvm::NamedMDNode *PragmaMetadata) {
307   if (!PragmaMetadata) {
308     return;
309   }
310 
311   mPragmaCount = PragmaMetadata->getNumOperands();
312   if (!mPragmaCount) {
313     return;
314   }
315 
316   const char **TmpKeyList = new const char*[mPragmaCount];
317   const char **TmpValueList = new const char*[mPragmaCount];
318 
319   for (size_t i = 0; i < mPragmaCount; i++) {
320     llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
321     if (Pragma != nullptr && Pragma->getNumOperands() == 2) {
322       llvm::Metadata *PragmaKeyMDS = Pragma->getOperand(0);
323       TmpKeyList[i] = createStringFromValue(PragmaKeyMDS);
324       llvm::Metadata *PragmaValueMDS = Pragma->getOperand(1);
325       TmpValueList[i] = createStringFromValue(PragmaValueMDS);
326     }
327   }
328 
329   mPragmaKeyList = TmpKeyList;
330   mPragmaValueList = TmpValueList;
331 
332   // Check to see if we have any FP precision-related pragmas.
333   std::string Relaxed("rs_fp_relaxed");
334   std::string Imprecise("rs_fp_imprecise");
335   std::string Full("rs_fp_full");
336   bool RelaxedPragmaSeen = false;
337   bool FullPragmaSeen = false;
338   for (size_t i = 0; i < mPragmaCount; i++) {
339     if (!Relaxed.compare(mPragmaKeyList[i])) {
340       RelaxedPragmaSeen = true;
341     } else if (!Imprecise.compare(mPragmaKeyList[i])) {
342       ALOGW("rs_fp_imprecise is deprecated.  Assuming rs_fp_relaxed instead.");
343       RelaxedPragmaSeen = true;
344     } else if (!Full.compare(mPragmaKeyList[i])) {
345       FullPragmaSeen = true;
346     }
347   }
348 
349   if (RelaxedPragmaSeen && FullPragmaSeen) {
350     ALOGE("Full and relaxed precision specified at the same time!");
351   }
352   mRSFloatPrecision = RelaxedPragmaSeen ? RS_FP_Relaxed : RS_FP_Full;
353 
354 #ifdef __ANDROID__
355   // Provide an override for precsiion via adb shell setprop
356   // adb shell setprop debug.rs.precision rs_fp_full
357   // adb shell setprop debug.rs.precision rs_fp_relaxed
358   // adb shell setprop debug.rs.precision rs_fp_imprecise
359   char PrecisionPropBuf[PROPERTY_VALUE_MAX];
360   const std::string PrecisionPropName("debug.rs.precision");
361   property_get("debug.rs.precision", PrecisionPropBuf, "");
362   if (PrecisionPropBuf[0]) {
363     if (!Relaxed.compare(PrecisionPropBuf)) {
364       ALOGI("Switching to RS FP relaxed mode via setprop");
365       mRSFloatPrecision = RS_FP_Relaxed;
366     } else if (!Imprecise.compare(PrecisionPropBuf)) {
367       ALOGW("Switching to RS FP relaxed mode via setprop. rs_fp_imprecise was "
368             "specified but is deprecated ");
369       mRSFloatPrecision = RS_FP_Relaxed;
370     } else if (!Full.compare(PrecisionPropBuf)) {
371       ALOGI("Switching to RS FP full mode via setprop");
372       mRSFloatPrecision = RS_FP_Full;
373     } else {
374       ALOGE("Unrecognized debug.rs.precision %s", PrecisionPropBuf);
375     }
376   }
377 #endif
378 }
379 
calculateNumInputs(const llvm::Function * Function,uint32_t Signature)380 uint32_t MetadataExtractor::calculateNumInputs(const llvm::Function *Function,
381                                                uint32_t Signature) {
382 
383   if (hasForEachSignatureIn(Signature)) {
384     uint32_t OtherCount = 0;
385 
386     OtherCount += hasForEachSignatureUsrData(Signature);
387     OtherCount += hasForEachSignatureX(Signature);
388     OtherCount += hasForEachSignatureY(Signature);
389     OtherCount += hasForEachSignatureZ(Signature);
390     OtherCount += hasForEachSignatureCtxt(Signature);
391     OtherCount += hasForEachSignatureOut(Signature) &&
392                   Function->getReturnType()->isVoidTy();
393 
394     return Function->arg_size() - OtherCount;
395 
396   } else {
397     return 0;
398   }
399 }
400 
401 
populateForEachMetadata(const llvm::NamedMDNode * Names,const llvm::NamedMDNode * Signatures)402 bool MetadataExtractor::populateForEachMetadata(
403     const llvm::NamedMDNode *Names,
404     const llvm::NamedMDNode *Signatures) {
405   if (!Names && !Signatures && mCompilerVersion == 0) {
406     // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
407     // section for ForEach. We generate a full signature for a "root" function
408     // which means that we need to set the bottom 5 bits in the mask.
409     mExportForEachSignatureCount = 1;
410     char **TmpNameList = new char*[mExportForEachSignatureCount];
411     size_t RootLen = strlen(kRoot) + 1;
412     TmpNameList[0] = new char[RootLen];
413     strncpy(TmpNameList[0], kRoot, RootLen);
414 
415     uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
416     TmpSigList[0] = 0x1f;
417 
418     mExportForEachNameList = (const char**)TmpNameList;
419     mExportForEachSignatureList = TmpSigList;
420     return true;
421   }
422 
423   if (Signatures) {
424     mExportForEachSignatureCount = Signatures->getNumOperands();
425     if (!mExportForEachSignatureCount) {
426       return true;
427     }
428   } else {
429     mExportForEachSignatureCount = 0;
430     mExportForEachSignatureList = nullptr;
431     return true;
432   }
433 
434   uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
435   const char **TmpNameList = new const char*[mExportForEachSignatureCount];
436   uint32_t *TmpInputCountList = new uint32_t[mExportForEachSignatureCount];
437 
438   for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
439     llvm::MDNode *SigNode = Signatures->getOperand(i);
440     if (SigNode != nullptr && SigNode->getNumOperands() == 1) {
441       if (!extractUIntFromMetadataString(&TmpSigList[i], SigNode->getOperand(0))) {
442         ALOGE("Non-integer signature value");
443         return false;
444       }
445     } else {
446       ALOGE("Corrupt signature information");
447       return false;
448     }
449   }
450 
451   if (Names) {
452     for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
453       llvm::MDNode *Name = Names->getOperand(i);
454       if (Name != nullptr && Name->getNumOperands() == 1) {
455         TmpNameList[i] = createStringFromValue(Name->getOperand(0));
456 
457         // Note that looking up the function by name can fail: One of
458         // the uses of MetadataExtractor is as part of the
459         // RSEmbedInfoPass, which bcc_compat runs sufficiently late in
460         // the phase order that RSKernelExpandPass has already run and
461         // the original (UNexpanded) kernel function (TmpNameList[i])
462         // may have been deleted as having no references (if it has
463         // been inlined into the expanded kernel function and is
464         // otherwise unreferenced).
465         llvm::Function *Func =
466             mModule->getFunction(llvm::StringRef(TmpNameList[i]));
467 
468         TmpInputCountList[i] = (Func != nullptr) ?
469           calculateNumInputs(Func, TmpSigList[i]) : 0;
470       }
471     }
472   } else {
473     if (mExportForEachSignatureCount != 1) {
474       ALOGE("mExportForEachSignatureCount = %zu, but should be 1",
475             mExportForEachSignatureCount);
476     }
477     char *RootName = new char[5];
478     strncpy(RootName, "root", 5);
479     TmpNameList[0] = RootName;
480   }
481 
482   mExportForEachNameList = TmpNameList;
483   mExportForEachSignatureList = TmpSigList;
484   mExportForEachInputCountList = TmpInputCountList;
485 
486   return true;
487 }
488 
489 
populateReduceMetadata(const llvm::NamedMDNode * ReduceMetadata)490 bool MetadataExtractor::populateReduceMetadata(const llvm::NamedMDNode *ReduceMetadata) {
491   mExportReduceCount = 0;
492   mExportReduceList = nullptr;
493 
494   if (!ReduceMetadata || !(mExportReduceCount = ReduceMetadata->getNumOperands()))
495     return true;
496 
497   Reduce *TmpReduceList = new Reduce[mExportReduceCount];
498 
499   for (size_t i = 0; i < mExportReduceCount; i++) {
500     llvm::MDNode *Node = ReduceMetadata->getOperand(i);
501     if (!Node || Node->getNumOperands() < 3) {
502       ALOGE("Missing reduce metadata");
503       return false;
504     }
505 
506     TmpReduceList[i].mReduceName = createStringFromValue(Node->getOperand(0));
507 
508     if (!extractUIntFromMetadataString(&TmpReduceList[i].mAccumulatorDataSize,
509                                        Node->getOperand(1))) {
510       ALOGE("Non-integer accumulator data size value in reduce metadata");
511       return false;
512     }
513 
514     llvm::MDNode *AccumulatorNode = llvm::dyn_cast<llvm::MDNode>(Node->getOperand(2));
515     if (!AccumulatorNode || AccumulatorNode->getNumOperands() != 2) {
516       ALOGE("Malformed accumulator node in reduce metadata");
517       return false;
518     }
519     TmpReduceList[i].mAccumulatorName = createStringFromValue(AccumulatorNode->getOperand(0));
520     if (!extractUIntFromMetadataString(&TmpReduceList[i].mSignature,
521                                        AccumulatorNode->getOperand(1))) {
522       ALOGE("Non-integer signature value in reduce metadata");
523       return false;
524     }
525     // Note that looking up the function by name can fail: One of the
526     // uses of MetadataExtractor is as part of the RSEmbedInfoPass,
527     // which bcc_compat runs sufficiently late in the phase order that
528     // RSKernelExpandPass has already run and the original
529     // (UNexpanded) accumulator function (mAccumulatorName) may have
530     // been deleted as having no references (if it has been inlined
531     // into the expanded accumulator function and is otherwise
532     // unreferenced).
533     llvm::Function *Func =
534         mModule->getFunction(llvm::StringRef(TmpReduceList[i].mAccumulatorName));
535     // Why calculateNumInputs() - 1?  The "-1" is because we don't
536     // want to treat the accumulator argument as an input.
537     TmpReduceList[i].mInputCount = (Func ? calculateNumInputs(Func, TmpReduceList[i].mSignature) - 1 : 0);
538 
539     TmpReduceList[i].mInitializerName = createStringFromOptionalValue(Node, 3);
540     TmpReduceList[i].mCombinerName = createStringFromOptionalValue(Node, 4);
541     TmpReduceList[i].mOutConverterName = createStringFromOptionalValue(Node, 5);
542     TmpReduceList[i].mHalterName = createStringFromOptionalValue(Node, 6);
543   }
544 
545   mExportReduceList = TmpReduceList;
546   return true;
547 }
548 
readThreadableFlag(const llvm::NamedMDNode * ThreadableMetadata)549 void MetadataExtractor::readThreadableFlag(
550     const llvm::NamedMDNode *ThreadableMetadata) {
551 
552   // Scripts are threadable by default.  If we read a valid metadata value for
553   // 'ThreadableMetadataName' and it is set to 'no', we mark script as non
554   // threadable.  All other exception paths retain the default value.
555 
556   mIsThreadable = true;
557   if (ThreadableMetadata == nullptr)
558     return;
559 
560   llvm::MDNode *mdNode = ThreadableMetadata->getOperand(0);
561   if (mdNode == nullptr)
562     return;
563 
564   llvm::Metadata *mdValue = mdNode->getOperand(0);
565   if (mdValue == nullptr)
566     return;
567 
568   if (getStringOperand(mdValue) == "no")
569     mIsThreadable = false;
570 }
571 
readBuildChecksumMetadata(const llvm::NamedMDNode * ChecksumMetadata)572 void MetadataExtractor::readBuildChecksumMetadata(
573     const llvm::NamedMDNode *ChecksumMetadata) {
574 
575   if (ChecksumMetadata == nullptr)
576     return;
577 
578   llvm::MDNode *mdNode = ChecksumMetadata->getOperand(0);
579   if (mdNode == nullptr)
580     return;
581 
582   llvm::Metadata *mdValue = mdNode->getOperand(0);
583   if (mdValue == nullptr)
584     return;
585 
586   mBuildChecksum = createStringFromValue(mdValue);
587 }
588 
extract()589 bool MetadataExtractor::extract() {
590   if (!(mBitcode && mBitcodeSize) && !mModule) {
591     ALOGE("Invalid/empty bitcode/module");
592     return false;
593   }
594 
595   std::unique_ptr<llvm::LLVMContext> mContext;
596   bool shouldNullModule = false;
597 
598   if (!mModule) {
599     mContext.reset(new llvm::LLVMContext());
600     std::unique_ptr<llvm::MemoryBuffer> MEM(
601       llvm::MemoryBuffer::getMemBuffer(
602         llvm::StringRef(mBitcode, mBitcodeSize), "", false));
603     std::string error;
604 
605     llvm::ErrorOr<std::unique_ptr<llvm::Module> > errval =
606         llvm::parseBitcodeFile(MEM.get()->getMemBufferRef(), *mContext);
607     if (std::error_code ec = errval.getError()) {
608         ALOGE("Could not parse bitcode file");
609         ALOGE("%s", ec.message().c_str());
610         return false;
611     }
612 
613     mModule = errval.get().release();
614     shouldNullModule = true;
615   }
616 
617   const llvm::NamedMDNode *ExportVarMetadata =
618       mModule->getNamedMetadata(ExportVarMetadataName);
619   const llvm::NamedMDNode *ExportFuncMetadata =
620       mModule->getNamedMetadata(ExportFuncMetadataName);
621   const llvm::NamedMDNode *ExportForEachNameMetadata =
622       mModule->getNamedMetadata(ExportForEachNameMetadataName);
623   const llvm::NamedMDNode *ExportForEachMetadata =
624       mModule->getNamedMetadata(ExportForEachMetadataName);
625   const llvm::NamedMDNode *ExportReduceMetadata =
626       mModule->getNamedMetadata(ExportReduceMetadataName);
627   const llvm::NamedMDNode *PragmaMetadata =
628       mModule->getNamedMetadata(PragmaMetadataName);
629   const llvm::NamedMDNode *ObjectSlotMetadata =
630       mModule->getNamedMetadata(ObjectSlotMetadataName);
631   const llvm::NamedMDNode *ThreadableMetadata =
632       mModule->getNamedMetadata(ThreadableMetadataName);
633   const llvm::NamedMDNode *ChecksumMetadata =
634       mModule->getNamedMetadata(ChecksumMetadataName);
635   const llvm::NamedMDNode *DebugInfoMetadata =
636       mModule->getNamedMetadata(DebugInfoMetadataName);
637 
638   if (!populateNameMetadata(ExportVarMetadata, mExportVarNameList,
639                             mExportVarCount)) {
640     ALOGE("Could not populate export variable metadata");
641     goto err;
642   }
643 
644   if (!populateNameMetadata(ExportFuncMetadata, mExportFuncNameList,
645                             mExportFuncCount)) {
646     ALOGE("Could not populate export function metadata");
647     goto err;
648   }
649 
650   if (!populateForEachMetadata(ExportForEachNameMetadata,
651                                ExportForEachMetadata)) {
652     ALOGE("Could not populate ForEach signature metadata");
653     goto err;
654   }
655 
656   if (!populateReduceMetadata(ExportReduceMetadata)) {
657     ALOGE("Could not populate export general reduction metadata");
658     goto err;
659   }
660 
661   populatePragmaMetadata(PragmaMetadata);
662 
663   if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
664     ALOGE("Could not populate object slot metadata");
665     goto err;
666   }
667 
668   readThreadableFlag(ThreadableMetadata);
669   readBuildChecksumMetadata(ChecksumMetadata);
670 
671   mHasDebugInfo = DebugInfoMetadata != nullptr;
672 
673   if (shouldNullModule) {
674     mModule = nullptr;
675   }
676   return true;
677 
678 err:
679   if (shouldNullModule) {
680     mModule = nullptr;
681   }
682   return false;
683 }
684 
685 }  // namespace bcinfo
686