• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 //===----------------------------------------------------------------------===//
18 // This file implements RSInfo::ExtractFromSource()
19 //===----------------------------------------------------------------------===//
20 #include "bcc/Renderscript/RSInfo.h"
21 
22 #include <llvm/IR/Constants.h>
23 #include <llvm/IR/Metadata.h>
24 #include <llvm/IR/Module.h>
25 
26 #include "bcc/Source.h"
27 #include "bcc/Support/Log.h"
28 
29 using namespace bcc;
30 
31 namespace {
32 
33 // Name of metadata node where pragma info resides (should be synced with
34 // slang.cpp)
35 const llvm::StringRef pragma_metadata_name("#pragma");
36 
37 /*
38  * The following names should be synced with the one appeared in
39  * slang_rs_metadata.h.
40  */
41 // Name of metadata node where exported variable names reside
42 const llvm::StringRef export_var_metadata_name("#rs_export_var");
43 
44 // Name of metadata node where exported function names reside
45 const llvm::StringRef export_func_metadata_name("#rs_export_func");
46 
47 // Name of metadata node where exported ForEach name information resides
48 const llvm::StringRef export_foreach_name_metadata_name("#rs_export_foreach_name");
49 
50 // Name of metadata node where exported ForEach signature information resides
51 const llvm::StringRef export_foreach_metadata_name("#rs_export_foreach");
52 
53 // Name of metadata node where RS object slot info resides (should be
54 const llvm::StringRef object_slot_metadata_name("#rs_object_slots");
55 
getStringFromOperand(const llvm::Value * pString)56 inline llvm::StringRef getStringFromOperand(const llvm::Value *pString) {
57   if ((pString != NULL) && (pString->getValueID() == llvm::Value::MDStringVal)) {
58     return static_cast<const llvm::MDString *>(pString)->getString();
59   }
60   return llvm::StringRef();
61 }
62 
63 template<size_t NumOperands>
getMetadataStringLength(const llvm::NamedMDNode * pMetadata)64 inline size_t getMetadataStringLength(const llvm::NamedMDNode *pMetadata) {
65   if (pMetadata == NULL) {
66     return 0;
67   }
68 
69   size_t string_size = 0;
70   for (unsigned i = 0, e = pMetadata->getNumOperands(); i < e; i++) {
71     llvm::MDNode *node = pMetadata->getOperand(i);
72     if ((node != NULL) && (node->getNumOperands() >= NumOperands)) {
73       // Compiler try its best to unroll this loop since NumOperands is a
74       // template parameter (therefore the number of iteration can be determined
75       // at compile-time and it's usually small.)
76       for (unsigned j = 0; j < NumOperands; j++) {
77         llvm::StringRef s = getStringFromOperand(node->getOperand(j));
78         if (s.size() > 0) {
79           // +1 is for the null-terminator at the end of string.
80           string_size += (s.size() + 1);
81         }
82       }
83     }
84   }
85 
86   return string_size;
87 }
88 
89 // Write a string pString to the string pool pStringPool at offset pWriteStart.
90 // Return the pointer the pString resides within the string pool.
91 // Updates pWriteStart to the next available spot.
writeString(const llvm::StringRef & pString,char * pStringPool,off_t * pWriteStart)92 const char *writeString(const llvm::StringRef &pString, char *pStringPool,
93                         off_t *pWriteStart) {
94   if (pString.empty()) {
95     return pStringPool;
96   }
97 
98   char *pStringWriteStart = pStringPool + *pWriteStart;
99   // Copy the string.
100   ::memcpy(pStringWriteStart, pString.data(), pString.size());
101   // Write null-terminator at the end of the string.
102   pStringWriteStart[ pString.size() ] = '\0';
103   // Update pWriteStart.
104   *pWriteStart += (pString.size() + 1);
105 
106   return pStringWriteStart;
107 }
108 
109 } // end anonymous namespace
110 
ExtractFromSource(const Source & pSource,const DependencyHashTy & sourceHashToEmbed,const char * compileCommandLineToEmbed,const char * buildFingerprintToEmbed)111 RSInfo* RSInfo::ExtractFromSource(const Source& pSource, const DependencyHashTy& sourceHashToEmbed,
112                                   const char* compileCommandLineToEmbed,
113                                   const char* buildFingerprintToEmbed) {
114   const llvm::Module &module = pSource.getModule();
115   const char *module_name = module.getModuleIdentifier().c_str();
116 
117   const llvm::NamedMDNode *pragma =
118       module.getNamedMetadata(pragma_metadata_name);
119   const llvm::NamedMDNode *export_var =
120       module.getNamedMetadata(export_var_metadata_name);
121   const llvm::NamedMDNode *export_func =
122       module.getNamedMetadata(export_func_metadata_name);
123   const llvm::NamedMDNode *export_foreach_name =
124       module.getNamedMetadata(export_foreach_name_metadata_name);
125   const llvm::NamedMDNode *export_foreach_signature =
126       module.getNamedMetadata(export_foreach_metadata_name);
127   const llvm::NamedMDNode *object_slots =
128       module.getNamedMetadata(object_slot_metadata_name);
129 
130   // Always write a byte 0x0 at the beginning of the string pool.
131   size_t string_pool_size = 1;
132   off_t cur_string_pool_offset = 0;
133 
134   RSInfo *result = NULL;
135 
136   // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
137   // section for ForEach. We generate a full signature for a "root" function.
138   if ((export_foreach_name == NULL) || (export_foreach_signature == NULL)) {
139     export_foreach_name = NULL;
140     export_foreach_signature = NULL;
141     string_pool_size += 5;  // insert "root\0" for #rs_export_foreach_name
142   }
143 
144   string_pool_size += getMetadataStringLength<2>(pragma);
145   string_pool_size += getMetadataStringLength<1>(export_var);
146   string_pool_size += getMetadataStringLength<1>(export_func);
147   string_pool_size += getMetadataStringLength<1>(export_foreach_name);
148 
149   // Reserve the space for the source hash, command line, and fingerprint
150   string_pool_size += SHA1_DIGEST_LENGTH;
151   string_pool_size += strlen(compileCommandLineToEmbed) + 1;
152   string_pool_size += strlen(buildFingerprintToEmbed) + 1;
153 
154   // Allocate result object
155   result = new (std::nothrow) RSInfo(string_pool_size);
156   if (result == NULL) {
157     ALOGE("Out of memory when create RSInfo object for %s!", module_name);
158     goto bail;
159   }
160 
161   // Check string pool.
162   if (result->mStringPool == NULL) {
163     ALOGE("Out of memory when allocate string pool in RSInfo object for %s!",
164           module_name);
165     goto bail;
166   }
167 
168   // First byte of string pool should be an empty string
169   result->mStringPool[ cur_string_pool_offset++ ] = '\0';
170 
171   // Populate all the strings and data.
172 #define FOR_EACH_NODE_IN(_metadata, _node)  \
173   for (unsigned i = 0, e = (_metadata)->getNumOperands(); i != e; i++)  \
174     if (((_node) = (_metadata)->getOperand(i)) != NULL)
175   //===--------------------------------------------------------------------===//
176   // #pragma
177   //===--------------------------------------------------------------------===//
178   // Pragma is actually a key-value pair. The value can be an empty string while
179   // the key cannot.
180   if (pragma != NULL) {
181     llvm::MDNode *node;
182     FOR_EACH_NODE_IN(pragma, node) {
183         llvm::StringRef key = getStringFromOperand(node->getOperand(0));
184         llvm::StringRef val = getStringFromOperand(node->getOperand(1));
185         if (key.empty()) {
186           ALOGW("%s contains pragma metadata with empty key (skip)!",
187                 module_name);
188         } else {
189           result->mPragmas.push(std::make_pair(
190               writeString(key, result->mStringPool, &cur_string_pool_offset),
191               writeString(val, result->mStringPool, &cur_string_pool_offset)));
192         } // key.empty()
193     } // FOR_EACH_NODE_IN
194   } // pragma != NULL
195 
196   //===--------------------------------------------------------------------===//
197   // #rs_export_var
198   //===--------------------------------------------------------------------===//
199   if (export_var != NULL) {
200     llvm::MDNode *node;
201     FOR_EACH_NODE_IN(export_var, node) {
202       llvm::StringRef name = getStringFromOperand(node->getOperand(0));
203       if (name.empty()) {
204         ALOGW("%s contains empty entry in #rs_export_var metadata (skip)!",
205               module_name);
206       } else {
207           result->mExportVarNames.push(
208               writeString(name, result->mStringPool, &cur_string_pool_offset));
209       }
210     }
211   }
212 
213   //===--------------------------------------------------------------------===//
214   // #rs_export_func
215   //===--------------------------------------------------------------------===//
216   if (export_func != NULL) {
217     llvm::MDNode *node;
218     FOR_EACH_NODE_IN(export_func, node) {
219       llvm::StringRef name = getStringFromOperand(node->getOperand(0));
220       if (name.empty()) {
221         ALOGW("%s contains empty entry in #rs_export_func metadata (skip)!",
222               module_name);
223       } else {
224         result->mExportFuncNames.push(
225             writeString(name, result->mStringPool, &cur_string_pool_offset));
226       }
227     }
228   }
229 
230   //===--------------------------------------------------------------------===//
231   // #rs_export_foreach and #rs_export_foreach_name
232   //===--------------------------------------------------------------------===//
233   // It's a little bit complicated to deal with #rs_export_foreach (the
234   // signature of foreach-able function) and #rs_export_foreach_name (the name
235   // of function which is foreach-able). We have to maintain a legacy case:
236   //
237   //  In pre-ICS bitcode, forEach feature only supports non-graphic root()
238   //  function and only one signature corresponded to that non-graphic root()
239   //  was written to the #rs_export_foreach metadata section. There's no
240   //  #rs_export_foreach_name metadata section.
241   //
242   // Currently, not only non-graphic root() is supported but also other
243   // functions that are exportable. Therefore, a new metadata section
244   // #rs_export_foreach_name is added to specify which functions are
245   // for-eachable. In this case, #rs_export_foreach (the function name) and
246   // #rs_export_foreach metadata (the signature) is one-to-one mapping among
247   // their entries.
248   if ((export_foreach_name != NULL) && (export_foreach_signature != NULL)) {
249     unsigned num_foreach_function;
250 
251     // Should be one-to-one mapping.
252     if (export_foreach_name->getNumOperands() !=
253         export_foreach_signature->getNumOperands()) {
254       ALOGE("Mismatch number of foreach-able function names (%u) in "
255             "#rs_export_foreach_name and number of signatures (%u) "
256             "in %s!", export_foreach_name->getNumOperands(),
257             export_foreach_signature->getNumOperands(), module_name);
258       goto bail;
259     }
260 
261     num_foreach_function = export_foreach_name->getNumOperands();
262     for (unsigned i = 0; i < num_foreach_function; i++) {
263       llvm::MDNode *name_node = export_foreach_name->getOperand(i);
264       llvm::MDNode *signature_node = export_foreach_signature->getOperand(i);
265 
266       llvm::StringRef name, signature_string;
267       if (name_node != NULL) {
268         name = getStringFromOperand(name_node->getOperand(0));
269       }
270       if (signature_node != NULL) {
271         signature_string = getStringFromOperand(signature_node->getOperand(0));
272       }
273 
274       if (!name.empty() && !signature_string.empty()) {
275         // Both name_node and signature_node are not NULL nodes.
276         uint32_t signature;
277         if (signature_string.getAsInteger(10, signature)) {
278           ALOGE("Non-integer signature value '%s' for function %s found in %s!",
279                 signature_string.str().c_str(), name.str().c_str(), module_name);
280           goto bail;
281         }
282         result->mExportForeachFuncs.push(std::make_pair(
283               writeString(name, result->mStringPool, &cur_string_pool_offset),
284               signature));
285       } else {
286         // One or both of the name and signature value are empty. It's safe only
287         // if both of them are empty.
288         if (name.empty() && signature_string.empty()) {
289           ALOGW("Entries #%u at #rs_export_foreach_name and #rs_export_foreach"
290                 " are both NULL in %s! (skip)", i, module_name);
291           continue;
292         } else {
293           ALOGE("Entries #%u at %s is NULL in %s! (skip)", i,
294                 (name.empty() ? "#rs_export_foreach_name" :
295                                 "#rs_export_foreach"), module_name);
296           goto bail;
297         }
298       }
299     } // end for
300   } else {
301     // To handle the legacy case, we generate a full signature for a "root"
302     // function which means that we need to set the bottom 5 bits (0x1f) in the
303     // mask.
304     result->mExportForeachFuncs.push(std::make_pair(
305           writeString(llvm::StringRef("root"), result->mStringPool,
306                       &cur_string_pool_offset), 0x1f));
307   }
308 
309   //===--------------------------------------------------------------------===//
310   // #rs_object_slots
311   //===--------------------------------------------------------------------===//
312   if (object_slots != NULL) {
313     llvm::MDNode *node;
314     for (unsigned int i = 0; i <= export_var->getNumOperands(); i++) {
315       result->mObjectSlots.push(0);
316     }
317     FOR_EACH_NODE_IN(object_slots, node) {
318       llvm::StringRef val = getStringFromOperand(node->getOperand(0));
319       if (val.empty()) {
320         ALOGW("%s contains empty entry in #rs_object_slots (skip)!",
321               module.getModuleIdentifier().c_str());
322       } else {
323         uint32_t slot;
324         if (val.getAsInteger(10, slot)) {
325           ALOGE("Non-integer object slot value '%s' in %s!", val.str().c_str(),
326                 module.getModuleIdentifier().c_str());
327           goto bail;
328         } else {
329           result->mObjectSlots.editItemAt(slot) = 1;
330         }
331       }
332     }
333   }
334 #undef FOR_EACH_NODE_IN
335 
336   //===------------------------------------------------------------------===//
337   // Record information used to invalidate the cache
338   //===------------------------------------------------------------------===//
339   {
340       // Store the SHA-1 in the string pool but without a null-terminator.
341       result->mHeader.sourceSha1Idx = cur_string_pool_offset;
342       uint8_t* sha1 = reinterpret_cast<uint8_t*>(result->mStringPool + cur_string_pool_offset);
343       ::memcpy(sha1, sourceHashToEmbed, SHA1_DIGEST_LENGTH);
344       // Update the string pool pointer.
345       cur_string_pool_offset += SHA1_DIGEST_LENGTH;
346       result->mSourceHash = sha1;
347 
348       result->mHeader.compileCommandLineIdx = cur_string_pool_offset;
349       result->mCompileCommandLine = writeString(compileCommandLineToEmbed, result->mStringPool,
350                                                 &cur_string_pool_offset);
351 
352       result->mHeader.buildFingerprintIdx = cur_string_pool_offset;
353       result->mBuildFingerprint = writeString(buildFingerprintToEmbed, result->mStringPool,
354                                               &cur_string_pool_offset);
355   }
356 
357   //===--------------------------------------------------------------------===//
358   // Determine whether the bitcode contains debug information
359   //===--------------------------------------------------------------------===//
360   // The root context of the debug information in the bitcode is put under
361   // the metadata named "llvm.dbg.cu".
362   result->mHeader.hasDebugInformation =
363       static_cast<uint8_t>(module.getNamedMetadata("llvm.dbg.cu") != NULL);
364 
365   assert((cur_string_pool_offset == string_pool_size) &&
366             "Unexpected string pool size!");
367 
368   return result;
369 
370 bail:
371   delete result;
372   return NULL;
373 }
374