• 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 
21 #define LOG_TAG "bcinfo"
22 #include <cutils/log.h>
23 
24 #include "llvm/ADT/OwningPtr.h"
25 #include "llvm/Bitcode/ReaderWriter.h"
26 #include "llvm/Constants.h"
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 
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 
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 
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 
MetadataExtractor(const char * bitcode,size_t bitcodeSize)61 MetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
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),
67       mObjectSlotCount(0), mObjectSlotList(NULL),
68       mRSFloatPrecision(RS_FP_Full) {
69   BitcodeWrapper wrapper(bitcode, bitcodeSize);
70   mCompilerVersion = wrapper.getCompilerVersion();
71   mOptimizationLevel = wrapper.getOptimizationLevel();
72 }
73 
74 
MetadataExtractor(const llvm::Module * module)75 MetadataExtractor::MetadataExtractor(const llvm::Module *module)
76     : mModule(module), mBitcode(NULL), mBitcodeSize(0), mExportVarCount(0),
77       mExportFuncCount(0), mExportForEachSignatureCount(0),
78       mExportVarNameList(NULL), mExportFuncNameList(NULL),
79       mExportForEachNameList(NULL), mExportForEachSignatureList(NULL),
80       mPragmaCount(0), mPragmaKeyList(NULL), mPragmaValueList(NULL),
81       mObjectSlotCount(0), mObjectSlotList(NULL),
82       mRSFloatPrecision(RS_FP_Full) {
83   mCompilerVersion = 0;
84   mOptimizationLevel = 3;
85 }
86 
87 
~MetadataExtractor()88 MetadataExtractor::~MetadataExtractor() {
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 
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 
116   delete [] mExportForEachSignatureList;
117   mExportForEachSignatureList = NULL;
118 
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;
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 
populateObjectSlotMetadata(const llvm::NamedMDNode * ObjectSlotMetadata)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)) {
165           ALOGE("Non-integer object slot value '%s'", Slot.str().c_str());
166           return false;
167         }
168         TmpSlotList[i] = USlot;
169       }
170     }
171   }
172 
173   mObjectSlotList = TmpSlotList;
174 
175   return true;
176 }
177 
178 
createStringFromValue(llvm::Value * v)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 
populatePragmaMetadata(const llvm::NamedMDNode * PragmaMetadata)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 
205   const char **TmpKeyList = new const char*[mPragmaCount];
206   const char **TmpValueList = new const char*[mPragmaCount];
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);
212       TmpKeyList[i] = createStringFromValue(PragmaKeyMDS);
213       llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
214       TmpValueList[i] = createStringFromValue(PragmaValueMDS);
215     }
216   }
217 
218   mPragmaKeyList = TmpKeyList;
219   mPragmaValueList = TmpValueList;
220 
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 
249   return;
250 }
251 
252 
populateVarNameMetadata(const llvm::NamedMDNode * VarNameMetadata)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 
populateFuncNameMetadata(const llvm::NamedMDNode * FuncNameMetadata)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 
populateForEachMetadata(const llvm::NamedMDNode * Names,const llvm::NamedMDNode * Signatures)305 bool MetadataExtractor::populateForEachMetadata(
306     const llvm::NamedMDNode *Names,
307     const llvm::NamedMDNode *Signatures) {
308   if (!Names && !Signatures) {
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;
313     char **TmpNameList = new char*[mExportForEachSignatureCount];
314     TmpNameList[0] = new char[5];
315     strncpy(TmpNameList[0], "root", 5);
316 
317     uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
318     TmpSigList[0] = 0x1f;
319 
320     mExportForEachNameList = (const char**)TmpNameList;
321     mExportForEachSignatureList = TmpSigList;
322     return true;
323   }
324 
325   if (Signatures) {
326     mExportForEachSignatureCount = Signatures->getNumOperands();
327     if (!mExportForEachSignatureCount) {
328       return true;
329     }
330   } else {
331     mExportForEachSignatureCount = 0;
332     mExportForEachSignatureList = NULL;
333     return true;
334   }
335 
336   uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
337   const char **TmpNameList = new const char*[mExportForEachSignatureCount];
338 
339   for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
340     llvm::MDNode *SigNode = Signatures->getOperand(i);
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)) {
348           ALOGE("Non-integer signature value '%s'", SigString.str().c_str());
349           return false;
350         }
351         TmpSigList[i] = Signature;
352       }
353     }
354   }
355 
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       }
362     }
363   } else {
364     if (mExportForEachSignatureCount != 1) {
365       ALOGE("mExportForEachSignatureCount = %zu, but should be 1",
366             mExportForEachSignatureCount);
367     }
368     char *RootName = new char[5];
369     strncpy(RootName, "root", 5);
370     TmpNameList[0] = RootName;
371   }
372 
373   mExportForEachNameList = TmpNameList;
374   mExportForEachSignatureList = TmpSigList;
375 
376   return true;
377 }
378 
379 
extract()380 bool MetadataExtractor::extract() {
381   if (!(mBitcode && mBitcodeSize) && !mModule) {
382     ALOGE("Invalid/empty bitcode/module");
383     return false;
384   }
385 
386   llvm::OwningPtr<llvm::LLVMContext> mContext;
387 
388   if (!mModule) {
389     mContext.reset(new llvm::LLVMContext());
390     llvm::OwningPtr<llvm::MemoryBuffer> MEM(
391       llvm::MemoryBuffer::getMemBuffer(
392         llvm::StringRef(mBitcode, mBitcodeSize), "", false));
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     }
402   }
403 
404   const llvm::NamedMDNode *ExportVarMetadata =
405       mModule->getNamedMetadata(ExportVarMetadataName);
406   const llvm::NamedMDNode *ExportFuncMetadata =
407       mModule->getNamedMetadata(ExportFuncMetadataName);
408   const llvm::NamedMDNode *ExportForEachNameMetadata =
409       mModule->getNamedMetadata(ExportForEachNameMetadataName);
410   const llvm::NamedMDNode *ExportForEachMetadata =
411       mModule->getNamedMetadata(ExportForEachMetadataName);
412   const llvm::NamedMDNode *PragmaMetadata =
413       mModule->getNamedMetadata(PragmaMetadataName);
414   const llvm::NamedMDNode *ObjectSlotMetadata =
415       mModule->getNamedMetadata(ObjectSlotMetadataName);
416 
417 
418   if (!populateVarNameMetadata(ExportVarMetadata)) {
419     ALOGE("Could not populate export variable metadata");
420     return false;
421   }
422 
423   if (!populateFuncNameMetadata(ExportFuncMetadata)) {
424     ALOGE("Could not populate export function metadata");
425     return false;
426   }
427 
428   if (!populateForEachMetadata(ExportForEachNameMetadata,
429                                ExportForEachMetadata)) {
430     ALOGE("Could not populate ForEach signature metadata");
431     return false;
432   }
433 
434   populatePragmaMetadata(PragmaMetadata);
435 
436   if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
437     ALOGE("Could not populate object slot metadata");
438     return false;
439   }
440 
441   return true;
442 }
443 
444 }  // namespace bcinfo
445 
446