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/Constants.h>
23#include <llvm/Metadata.h>
24#include <llvm/Module.h>
25
26#include "bcc/Source.h"
27#include "bcc/Support/Log.h"
28
29using namespace bcc;
30
31namespace {
32
33// Name of metadata node where pragma info resides (should be synced with
34// slang.cpp)
35const 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
42const llvm::StringRef export_var_metadata_name("#rs_export_var");
43
44// Name of metadata node where exported function names reside
45const llvm::StringRef export_func_metadata_name("#rs_export_func");
46
47// Name of metadata node where exported ForEach name information resides
48const llvm::StringRef export_foreach_name_metadata_name("#rs_export_foreach_name");
49
50// Name of metadata node where exported ForEach signature information resides
51const llvm::StringRef export_foreach_metadata_name("#rs_export_foreach");
52
53// Name of metadata node where RS object slot info resides (should be
54const llvm::StringRef object_slot_metadata_name("#rs_object_slots");
55
56inline 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
63template<size_t NumOperands>
64inline 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.
91const char *writeString(const llvm::StringRef &pString, char *pStringPool,
92                        off_t *pWriteStart) {
93  if (pString.empty()) {
94    return pStringPool;
95  }
96
97  char *pStringWriteStart = pStringPool + *pWriteStart;
98  // Copy the string.
99  ::memcpy(pStringWriteStart, pString.data(), pString.size());
100  // Write null-terminator at the end of the string.
101  pStringWriteStart[ pString.size() ] = '\0';
102  // Update pWriteStart.
103  *pWriteStart += (pString.size() + 1);
104
105  return pStringWriteStart;
106}
107
108bool writeDependency(const std::string &pSourceName, const uint8_t *pSHA1,
109                     char *pStringPool, off_t *pWriteStart,
110                     RSInfo::DependencyTableTy &pDepTable) {
111  const char *source_name = writeString(pSourceName, pStringPool, pWriteStart);
112
113  uint8_t *sha1 = reinterpret_cast<uint8_t *>(pStringPool + *pWriteStart);
114
115  // SHA-1 is special. It's size of SHA1_DIGEST_LENGTH (=20) bytes long without
116  // null-terminator.
117  ::memcpy(sha1, pSHA1, SHA1_DIGEST_LENGTH);
118  // Record in the result RSInfo object.
119  pDepTable.push(std::make_pair(source_name, sha1));
120  // Update the string pool pointer.
121  *pWriteStart += SHA1_DIGEST_LENGTH;
122
123  return true;
124}
125
126} // end anonymous namespace
127
128RSInfo *RSInfo::ExtractFromSource(const Source &pSource,
129                                  const DependencyTableTy &pDeps)
130{
131  const llvm::Module &module = pSource.getModule();
132  const char *module_name = module.getModuleIdentifier().c_str();
133
134  const llvm::NamedMDNode *pragma =
135      module.getNamedMetadata(pragma_metadata_name);
136  const llvm::NamedMDNode *export_var =
137      module.getNamedMetadata(export_var_metadata_name);
138  const llvm::NamedMDNode *export_func =
139      module.getNamedMetadata(export_func_metadata_name);
140  const llvm::NamedMDNode *export_foreach_name =
141      module.getNamedMetadata(export_foreach_name_metadata_name);
142  const llvm::NamedMDNode *export_foreach_signature =
143      module.getNamedMetadata(export_foreach_metadata_name);
144  const llvm::NamedMDNode *object_slots =
145      module.getNamedMetadata(object_slot_metadata_name);
146
147  // Always write a byte 0x0 at the beginning of the string pool.
148  size_t string_pool_size = 1;
149  off_t cur_string_pool_offset = 0;
150
151  RSInfo *result = NULL;
152
153  // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
154  // section for ForEach. We generate a full signature for a "root" function.
155  if ((export_foreach_name == NULL) || (export_foreach_signature == NULL)) {
156    export_foreach_name = NULL;
157    export_foreach_signature = NULL;
158    string_pool_size += 5;  // insert "root\0" for #rs_export_foreach_name
159  }
160
161  string_pool_size += getMetadataStringLength<2>(pragma);
162  string_pool_size += getMetadataStringLength<1>(export_var);
163  string_pool_size += getMetadataStringLength<1>(export_func);
164  string_pool_size += getMetadataStringLength<1>(export_foreach_name);
165
166  // Don't forget to reserve the space for the dependency informationin string
167  // pool.
168  string_pool_size += ::strlen(LibBCCPath) + 1 + SHA1_DIGEST_LENGTH;
169  string_pool_size += ::strlen(LibRSPath) + 1 + SHA1_DIGEST_LENGTH;
170  string_pool_size += ::strlen(LibCLCorePath) + 1 + SHA1_DIGEST_LENGTH;
171#if defined(ARCH_ARM_HAVE_NEON)
172  string_pool_size += ::strlen(LibCLCoreNEONPath) + 1 + SHA1_DIGEST_LENGTH;
173#endif
174  for (unsigned i = 0, e = pDeps.size(); i != e; i++) {
175    // +1 for null-terminator
176    string_pool_size += ::strlen(/* name */pDeps[i].first) + 1;
177    // +SHA1_DIGEST_LENGTH for SHA-1 checksum
178    string_pool_size += SHA1_DIGEST_LENGTH;
179  }
180
181  // Allocate result object
182  result = new (std::nothrow) RSInfo(string_pool_size);
183  if (result == NULL) {
184    ALOGE("Out of memory when create RSInfo object for %s!", module_name);
185    goto bail;
186  }
187
188  // Check string pool.
189  if (result->mStringPool == NULL) {
190    ALOGE("Out of memory when allocate string pool in RSInfo object for %s!",
191          module_name);
192    goto bail;
193  }
194
195  // First byte of string pool should be an empty string
196  result->mStringPool[ cur_string_pool_offset++ ] = '\0';
197
198  // Populate all the strings and data.
199#define FOR_EACH_NODE_IN(_metadata, _node)  \
200  for (unsigned i = 0, e = (_metadata)->getNumOperands(); i != e; i++)  \
201    if (((_node) = (_metadata)->getOperand(i)) != NULL)
202  //===--------------------------------------------------------------------===//
203  // #pragma
204  //===--------------------------------------------------------------------===//
205  // Pragma is actually a key-value pair. The value can be an empty string while
206  // the key cannot.
207  if (pragma != NULL) {
208    llvm::MDNode *node;
209    FOR_EACH_NODE_IN(pragma, node) {
210        llvm::StringRef key = getStringFromOperand(node->getOperand(0));
211        llvm::StringRef val = getStringFromOperand(node->getOperand(1));
212        if (key.empty()) {
213          ALOGW("%s contains pragma metadata with empty key (skip)!",
214                module_name);
215        } else {
216          result->mPragmas.push(std::make_pair(
217              writeString(key, result->mStringPool, &cur_string_pool_offset),
218              writeString(val, result->mStringPool, &cur_string_pool_offset)));
219        } // key.empty()
220    } // FOR_EACH_NODE_IN
221  } // pragma != NULL
222
223  //===--------------------------------------------------------------------===//
224  // #rs_export_var
225  //===--------------------------------------------------------------------===//
226  if (export_var != NULL) {
227    llvm::MDNode *node;
228    FOR_EACH_NODE_IN(export_var, node) {
229      llvm::StringRef name = getStringFromOperand(node->getOperand(0));
230      if (name.empty()) {
231        ALOGW("%s contains empty entry in #rs_export_var metadata (skip)!",
232              module_name);
233      } else {
234          result->mExportVarNames.push(
235              writeString(name, result->mStringPool, &cur_string_pool_offset));
236      }
237    }
238  }
239
240  //===--------------------------------------------------------------------===//
241  // #rs_export_func
242  //===--------------------------------------------------------------------===//
243  if (export_func != NULL) {
244    llvm::MDNode *node;
245    FOR_EACH_NODE_IN(export_func, node) {
246      llvm::StringRef name = getStringFromOperand(node->getOperand(0));
247      if (name.empty()) {
248        ALOGW("%s contains empty entry in #rs_export_func metadata (skip)!",
249              module_name);
250      } else {
251        result->mExportFuncNames.push(
252            writeString(name, result->mStringPool, &cur_string_pool_offset));
253      }
254    }
255  }
256
257  //===--------------------------------------------------------------------===//
258  // #rs_export_foreach and #rs_export_foreach_name
259  //===--------------------------------------------------------------------===//
260  // It's a little bit complicated to deal with #rs_export_foreach (the
261  // signature of foreach-able function) and #rs_export_foreach_name (the name
262  // of function which is foreach-able). We have to maintain a legacy case:
263  //
264  //  In pre-ICS bitcode, forEach feature only supports non-graphic root()
265  //  function and only one signature corresponded to that non-graphic root()
266  //  was written to the #rs_export_foreach metadata section. There's no
267  //  #rs_export_foreach_name metadata section.
268  //
269  // Currently, not only non-graphic root() is supported but also other
270  // functions that are exportable. Therefore, a new metadata section
271  // #rs_export_foreach_name is added to specify which functions are
272  // for-eachable. In this case, #rs_export_foreach (the function name) and
273  // #rs_export_foreach metadata (the signature) is one-to-one mapping among
274  // their entries.
275  if ((export_foreach_name != NULL) && (export_foreach_signature != NULL)) {
276    unsigned num_foreach_function;
277
278    // Should be one-to-one mapping.
279    if (export_foreach_name->getNumOperands() !=
280        export_foreach_signature->getNumOperands()) {
281      ALOGE("Mismatch number of foreach-able function names (%u) in "
282            "#rs_export_foreach_name and number of signatures (%u) "
283            "in %s!", export_foreach_name->getNumOperands(),
284            export_foreach_signature->getNumOperands(), module_name);
285      goto bail;
286    }
287
288    num_foreach_function = export_foreach_name->getNumOperands();
289    for (unsigned i = 0; i < num_foreach_function; i++) {
290      llvm::MDNode *name_node = export_foreach_name->getOperand(i);
291      llvm::MDNode *signature_node = export_foreach_signature->getOperand(i);
292
293      llvm::StringRef name, signature_string;
294      if (name_node != NULL) {
295        name = getStringFromOperand(name_node->getOperand(0));
296      }
297      if (signature_node != NULL) {
298        signature_string = getStringFromOperand(signature_node->getOperand(0));
299      }
300
301      if (!name.empty() && !signature_string.empty()) {
302        // Both name_node and signature_node are not NULL nodes.
303        uint32_t signature;
304        if (signature_string.getAsInteger(10, signature)) {
305          ALOGE("Non-integer signature value '%s' for function %s found in %s!",
306                signature_string.str().c_str(), name.str().c_str(), module_name);
307          goto bail;
308        }
309        result->mExportForeachFuncs.push(std::make_pair(
310              writeString(name, result->mStringPool, &cur_string_pool_offset),
311              signature));
312      } else {
313        // One or both of the name and signature value are empty. It's safe only
314        // if both of them are empty.
315        if (name.empty() && signature_string.empty()) {
316          ALOGW("Entries #%u at #rs_export_foreach_name and #rs_export_foreach"
317                " are both NULL in %s! (skip)", i, module_name);
318          continue;
319        } else {
320          ALOGE("Entries #%u at %s is NULL in %s! (skip)", i,
321                (name.empty() ? "#rs_export_foreach_name" :
322                                "#rs_export_foreach"), module_name);
323          goto bail;
324        }
325      }
326    } // end for
327  } else {
328    // To handle the legacy case, we generate a full signature for a "root"
329    // function which means that we need to set the bottom 5 bits (0x1f) in the
330    // mask.
331    result->mExportForeachFuncs.push(std::make_pair(
332          writeString(llvm::StringRef("root"), result->mStringPool,
333                      &cur_string_pool_offset), 0x1f));
334  }
335
336  //===--------------------------------------------------------------------===//
337  // #rs_object_slots
338  //===--------------------------------------------------------------------===//
339  if (object_slots != NULL) {
340    llvm::MDNode *node;
341    for (unsigned int i = 0; i <= export_var->getNumOperands(); i++) {
342      result->mObjectSlots.push(0);
343    }
344    FOR_EACH_NODE_IN(object_slots, node) {
345      llvm::StringRef val = getStringFromOperand(node->getOperand(0));
346      if (val.empty()) {
347        ALOGW("%s contains empty entry in #rs_object_slots (skip)!",
348              module.getModuleIdentifier().c_str());
349      } else {
350        uint32_t slot;
351        if (val.getAsInteger(10, slot)) {
352          ALOGE("Non-integer object slot value '%s' in %s!", val.str().c_str(),
353                module.getModuleIdentifier().c_str());
354          goto bail;
355        } else {
356          result->mObjectSlots.editItemAt(slot) = 1;
357        }
358      }
359    }
360  }
361#undef FOR_EACH_NODE_IN
362
363  //===--------------------------------------------------------------------===//
364  // Record built-in dependency information.
365  //===--------------------------------------------------------------------===//
366  LoadBuiltInSHA1Information();
367
368  if (!writeDependency(LibBCCPath, LibBCCSHA1,
369                       result->mStringPool, &cur_string_pool_offset,
370                       result->mDependencyTable)) {
371    goto bail;
372  }
373
374  if (!writeDependency(LibRSPath, LibRSSHA1,
375                       result->mStringPool, &cur_string_pool_offset,
376                       result->mDependencyTable)) {
377    goto bail;
378  }
379
380  if (!writeDependency(LibCLCorePath, LibCLCoreSHA1,
381                       result->mStringPool, &cur_string_pool_offset,
382                       result->mDependencyTable)) {
383    goto bail;
384  }
385
386#if defined(ARCH_ARM_HAVE_NEON)
387  if (!writeDependency(LibCLCoreNEONPath, LibCLCoreNEONSHA1,
388                       result->mStringPool, &cur_string_pool_offset,
389                       result->mDependencyTable)) {
390    goto bail;
391  }
392#endif
393
394  //===--------------------------------------------------------------------===//
395  // Record dependency information.
396  //===--------------------------------------------------------------------===//
397  for (unsigned i = 0, e = pDeps.size(); i != e; i++) {
398    if (!writeDependency(/* name */pDeps[i].first, /* SHA-1 */pDeps[i].second,
399                         result->mStringPool, &cur_string_pool_offset,
400                         result->mDependencyTable)) {
401      goto bail;
402    }
403  }
404
405  //===--------------------------------------------------------------------===//
406  // Determine whether the bitcode contains debug information
407  //===--------------------------------------------------------------------===//
408  // The root context of the debug information in the bitcode is put under
409  // the metadata named "llvm.dbg.cu".
410  result->mHeader.hasDebugInformation =
411      static_cast<uint8_t>(module.getNamedMetadata("llvm.dbg.cu") != NULL);
412
413  assert((cur_string_pool_offset == string_pool_size) &&
414            "Unexpected string pool size!");
415
416  return result;
417
418bail:
419  delete result;
420  return NULL;
421}
422