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