• 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 #ifndef BCC_RS_INFO_H
18 #define BCC_RS_INFO_H
19 
20 #include <stdint.h>
21 
22 #include <utility>
23 
24 #include "bcc/Support/Log.h"
25 #include "bcc/Support/Sha1Util.h"
26 
27 #include <utils/String8.h>
28 #include <utils/Vector.h>
29 
30 namespace llvm {
31 class Module;
32 }
33 
34 namespace bcc {
35 
36 // Forward declarations
37 class FileBase;
38 class InputFile;
39 class OutputFile;
40 class Source;
41 class RSScript;
42 
43 typedef llvm::Module* (*RSLinkRuntimeCallback) (bcc::RSScript *, llvm::Module *, llvm::Module *);
44 
45 namespace rsinfo {
46 
47 /* RS info file magic */
48 #define RSINFO_MAGIC      "\0rsinfo\n"
49 
50 /* RS info file version, encoded in 4 bytes of ASCII */
51 #define RSINFO_VERSION    "004\0"
52 
53 struct __attribute__((packed)) ListHeader {
54   // The offset from the beginning of the file of data
55   uint32_t offset;
56   // Number of item in the list
57   uint32_t count;
58   // Size of each item
59   uint8_t itemSize;
60 };
61 
62 /* RS info file header */
63 struct __attribute__((packed)) Header {
64   // Magic versus version
65   uint8_t magic[8];
66   uint8_t version[4];
67 
68   uint8_t isThreadable;
69   uint8_t hasDebugInformation;
70 
71   uint16_t headerSize;
72 
73   uint32_t strPoolSize;
74 
75   struct ListHeader dependencyTable;
76   struct ListHeader pragmaList;
77   struct ListHeader objectSlotList;
78   struct ListHeader exportVarNameList;
79   struct ListHeader exportFuncNameList;
80   struct ListHeader exportForeachFuncList;
81 };
82 
83 typedef uint32_t StringIndexTy;
84 // Use value -1 as an invalid string index marker. No need to declare with
85 // 'static' modifier since 'const' variable has internal linkage by default.
86 const StringIndexTy gInvalidStringIndex = static_cast<StringIndexTy>(-1);
87 
88 struct __attribute__((packed)) DependencyTableItem {
89   StringIndexTy id;
90   // SHA-1 checksum is stored as a string in string pool (and has fixed-length
91   // SHA1_DIGEST_LENGTH (=20) bytes)
92   StringIndexTy sha1;
93 };
94 
95 struct __attribute__((packed)) PragmaItem {
96   // Pragma is a key-value pair.
97   StringIndexTy key;
98   StringIndexTy value;
99 };
100 
101 struct __attribute__((packed)) ObjectSlotItem {
102   uint32_t slot;
103 };
104 
105 struct __attribute__((packed)) ExportVarNameItem {
106   StringIndexTy name;
107 };
108 
109 struct __attribute__((packed)) ExportFuncNameItem {
110   StringIndexTy name;
111 };
112 
113 struct __attribute__((packed)) ExportForeachFuncItem {
114   StringIndexTy name;
115   uint32_t signature;
116 };
117 
118 // Return the human-readable name of the given rsinfo::*Item in the template
119 // parameter. This is for debugging and error message.
120 template<typename Item>
121 inline const char *GetItemTypeName();
122 
123 template<>
124 inline const char *GetItemTypeName<DependencyTableItem>()
125 { return "rs dependency info"; }
126 
127 template<>
128 inline const char *GetItemTypeName<PragmaItem>()
129 {  return "rs pragma"; }
130 
131 template<>
132 inline const char *GetItemTypeName<ObjectSlotItem>()
133 {  return "rs object slot"; }
134 
135 template<>
136 inline const char *GetItemTypeName<ExportVarNameItem>()
137 { return "rs export var"; }
138 
139 template<>
140 inline const char *GetItemTypeName<ExportFuncNameItem>()
141 {  return "rs export func"; }
142 
143 template<>
144 inline const char *GetItemTypeName<ExportForeachFuncItem>()
145 { return "rs export foreach"; }
146 
147 } // end namespace rsinfo
148 
149 class RSInfo {
150 public:
151   typedef android::Vector<std::pair<const char *,
152                                     const uint8_t *> > DependencyTableTy;
153   typedef android::Vector<std::pair<const char*, const char*> > PragmaListTy;
154   typedef android::Vector<uint32_t> ObjectSlotListTy;
155   typedef android::Vector<const char *> ExportVarNameListTy;
156   typedef android::Vector<const char *> ExportFuncNameListTy;
157   typedef android::Vector<std::pair<const char *,
158                                     uint32_t> > ExportForeachFuncListTy;
159 
160 public:
161   // Calculate or load the SHA-1 information of the built-in dependencies.
162   static bool LoadBuiltInSHA1Information();
163 
164   // Return the path of the RS info file corresponded to the given output
165   // executable file.
166   static android::String8 GetPath(const char *pFilename);
167 
168   static const char LibBCCPath[];
169   static const char LibCompilerRTPath[];
170   static const char LibRSPath[];
171   static const char LibCLCorePath[];
172   static const char LibCLCoreDebugPath[];
173 #if defined(ARCH_X86_HAVE_SSE2)
174   static const char LibCLCoreX86Path[];
175 #endif
176 #if defined(ARCH_ARM_HAVE_NEON)
177   static const char LibCLCoreNEONPath[];
178 #endif
179 
180 private:
181   // SHA-1 of the built-in dependencies. Will be initialized in
182   // LoadBuiltInSHA1Information().
183   static const uint8_t *LibBCCSHA1;
184   static const uint8_t *LibCompilerRTSHA1;
185   static const uint8_t *LibRSSHA1;
186   static const uint8_t *LibCLCoreSHA1;
187   static const uint8_t *LibCLCoreDebugSHA1;
188 #if defined(ARCH_ARM_HAVE_NEON)
189   static const uint8_t *LibCLCoreNEONSHA1;
190 #endif
191 
192   static bool CheckDependency(const RSInfo &pInfo,
193                               const char *pInputFilename,
194                               const DependencyTableTy &pDeps);
195   static bool AddBuiltInDependencies(RSInfo &pInfo);
196 
197   rsinfo::Header mHeader;
198 
199   char *mStringPool;
200 
201   // In most of the time, there're 4 source dependencies stored (libbcc.so,
202   // libRS.so, libclcore and the input bitcode itself.)
203   DependencyTableTy mDependencyTable;
204   PragmaListTy mPragmas;
205   ObjectSlotListTy mObjectSlots;
206   ExportVarNameListTy mExportVarNames;
207   ExportFuncNameListTy mExportFuncNames;
208   ExportForeachFuncListTy mExportForeachFuncs;
209 
210   // Initialize an empty RSInfo with its size of string pool is pStringPoolSize.
211   RSInfo(size_t pStringPoolSize);
212 
213   // layout() assigns value of offset in each ListHeader (i.e., it decides where
214   // data should go in the file.) It also updates fields other than offset to
215   // reflect the current RSInfo object states to mHeader.
216   bool layout(off_t initial_offset);
217 
218 public:
219   ~RSInfo();
220 
221   // Implemented in RSInfoExtractor.cpp.
222   static RSInfo *ExtractFromSource(const Source &pSource,
223                                    const DependencyTableTy &pDeps);
224 
225   // Implemented in RSInfoReader.cpp.
226   static RSInfo *ReadFromFile(InputFile &pInput,
227                               const DependencyTableTy &pDeps);
228 
229   // Implemneted in RSInfoWriter.cpp
230   bool write(OutputFile &pOutput);
231 
232   void dump() const;
233 
234   // const getter
isThreadable()235   inline bool isThreadable() const
236   { return mHeader.isThreadable; }
hasDebugInformation()237   inline bool hasDebugInformation() const
238   { return mHeader.hasDebugInformation; }
getDependencyTable()239   inline const DependencyTableTy &getDependencyTable() const
240   { return mDependencyTable; }
getPragmas()241   inline const PragmaListTy &getPragmas() const
242   { return mPragmas; }
getObjectSlots()243   inline const ObjectSlotListTy &getObjectSlots() const
244   { return mObjectSlots; }
getExportVarNames()245   inline const ExportVarNameListTy &getExportVarNames() const
246   { return mExportVarNames; }
getExportFuncNames()247   inline const ExportFuncNameListTy &getExportFuncNames() const
248   { return mExportFuncNames; }
getExportForeachFuncs()249   inline const ExportForeachFuncListTy &getExportForeachFuncs() const
250   { return mExportForeachFuncs; }
251 
252   const char *getStringFromPool(rsinfo::StringIndexTy pStrIdx) const;
253   rsinfo::StringIndexTy getStringIdxInPool(const char *pStr) const;
254 
255   // setter
256   inline void setThreadable(bool pThreadable = true)
257   { mHeader.isThreadable = pThreadable; }
258 
259 public:
260   enum FloatPrecision {
261     FP_Full,
262     FP_Relaxed,
263     FP_Imprecise,
264   };
265 
266   // Return the minimal floating point precision required for the associated
267   // script.
268   FloatPrecision getFloatPrecisionRequirement() const;
269 };
270 
271 } // end namespace bcc
272 
273 #endif  // BCC_RS_INFO_H
274