• 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 <string>
23 #include <utility>
24 
25 #include "bcc/Support/Log.h"
26 #include "bcc/Support/Sha1Util.h"
27 
28 #include <utils/String8.h>
29 #include <utils/Vector.h>
30 
31 namespace llvm {
32 class Module;
33 }
34 
35 namespace bcc {
36 
37 // Forward declarations
38 class FileBase;
39 class InputFile;
40 class OutputFile;
41 class Source;
42 class RSScript;
43 
44 typedef llvm::Module* (*RSLinkRuntimeCallback) (bcc::RSScript *, llvm::Module *, llvm::Module *);
45 
46 namespace rsinfo {
47 
48 /* RS info file magic */
49 #define RSINFO_MAGIC      "\0rsinfo\n"
50 
51 /* RS info file version, encoded in 4 bytes of ASCII */
52 #define RSINFO_VERSION    "006\0"
53 
54 struct __attribute__((packed)) ListHeader {
55   // The offset from the beginning of the file of data
56   uint32_t offset;
57   // Number of item in the list
58   uint32_t count;
59   // Size of each item
60   uint8_t itemSize;
61 };
62 
63 typedef uint32_t StringIndexTy;
64 
65 /* RS info file header */
66 struct __attribute__((packed)) Header {
67   // Magic versus version
68   uint8_t magic[8];
69   uint8_t version[4];
70 
71   uint8_t isThreadable;
72   uint8_t hasDebugInformation;
73 
74   uint16_t headerSize;
75 
76   uint32_t strPoolSize;
77 
78   // The index in the pool of the SHA-1 checksum of the source file.
79   // It has a fixed-length of SHA1_DIGEST_LENGTH (=20) bytes.
80   StringIndexTy sourceSha1Idx;
81   // The index in the pool of the command used to compile this source.
82   StringIndexTy compileCommandLineIdx;
83   // The index in the pool of the build fingerprint of Android when the source was compiled.
84   StringIndexTy buildFingerprintIdx;
85 
86   struct ListHeader pragmaList;
87   struct ListHeader objectSlotList;
88   struct ListHeader exportVarNameList;
89   struct ListHeader exportFuncNameList;
90   struct ListHeader exportForeachFuncList;
91 };
92 
93 // Use value -1 as an invalid string index marker. No need to declare with
94 // 'static' modifier since 'const' variable has internal linkage by default.
95 const StringIndexTy gInvalidStringIndex = static_cast<StringIndexTy>(-1);
96 
97 struct __attribute__((packed)) PragmaItem {
98   // Pragma is a key-value pair.
99   StringIndexTy key;
100   StringIndexTy value;
101 };
102 
103 struct __attribute__((packed)) ObjectSlotItem {
104   uint32_t slot;
105 };
106 
107 struct __attribute__((packed)) ExportVarNameItem {
108   StringIndexTy name;
109 };
110 
111 struct __attribute__((packed)) ExportFuncNameItem {
112   StringIndexTy name;
113 };
114 
115 struct __attribute__((packed)) ExportForeachFuncItem {
116   StringIndexTy name;
117   uint32_t signature;
118 };
119 
120 // Return the human-readable name of the given rsinfo::*Item in the template
121 // parameter. This is for debugging and error message.
122 template<typename Item>
123 inline const char *GetItemTypeName();
124 
125 template<>
126 inline const char *GetItemTypeName<PragmaItem>()
127 {  return "rs pragma"; }
128 
129 template<>
130 inline const char *GetItemTypeName<ObjectSlotItem>()
131 {  return "rs object slot"; }
132 
133 template<>
134 inline const char *GetItemTypeName<ExportVarNameItem>()
135 { return "rs export var"; }
136 
137 template<>
138 inline const char *GetItemTypeName<ExportFuncNameItem>()
139 {  return "rs export func"; }
140 
141 template<>
142 inline const char *GetItemTypeName<ExportForeachFuncItem>()
143 { return "rs export foreach"; }
144 
145 } // end namespace rsinfo
146 
147 class RSInfo {
148 public:
149   typedef const uint8_t* DependencyHashTy;
150   typedef android::Vector<std::pair<const char*, const char*> > PragmaListTy;
151   typedef android::Vector<uint32_t> ObjectSlotListTy;
152   typedef android::Vector<const char *> ExportVarNameListTy;
153   typedef android::Vector<const char *> ExportFuncNameListTy;
154   typedef android::Vector<std::pair<const char *,
155                                     uint32_t> > ExportForeachFuncListTy;
156 
157 public:
158   // Return the path of the RS info file corresponded to the given output
159   // executable file.
160   static android::String8 GetPath(const char *pFilename);
161 
162   // Check whether this info contains the same source hash, compile command line, and fingerprint.
163   // If not, it's an indication we need to recompile.
164   bool IsConsistent(const char* pInputFilename, const DependencyHashTy& sourceHash,
165                     const char* compileCommandLine, const char* buildFingerprint);
166 
167 private:
168 
169   rsinfo::Header mHeader;
170 
171   char *mStringPool;
172 
173   // Pointer to the hash of the souce file, somewhere in the string pool.
174   DependencyHashTy mSourceHash;
175   // Pointer to the command used to compile this source, somewhere in the string pool.
176   const char* mCompileCommandLine;
177   // Pointer to the build fingerprint of Android when the source was compiled, somewhere in the
178   // string pool.
179   const char* mBuildFingerprint;
180 
181   PragmaListTy mPragmas;
182   ObjectSlotListTy mObjectSlots;
183   ExportVarNameListTy mExportVarNames;
184   ExportFuncNameListTy mExportFuncNames;
185   ExportForeachFuncListTy mExportForeachFuncs;
186 
187   // Initialize an empty RSInfo with its size of string pool is pStringPoolSize.
188   RSInfo(size_t pStringPoolSize);
189 
190   // layout() assigns value of offset in each ListHeader (i.e., it decides where
191   // data should go in the file.) It also updates fields other than offset to
192   // reflect the current RSInfo object states to mHeader.
193   bool layout(off_t initial_offset);
194 
195 public:
196   ~RSInfo();
197 
198   // Implemented in RSInfoExtractor.cpp.
199   static RSInfo *ExtractFromSource(const Source &pSource,
200                                    const DependencyHashTy &sourceHashToEmbed,
201                                    const char* compileCommandLineToEmbed,
202                                    const char* buildFingerprintToEmbed);
203 
204   // Implemented in RSInfoReader.cpp.
205   static RSInfo *ReadFromFile(InputFile &pInput);
206 
207   // Implemneted in RSInfoWriter.cpp
208   bool write(OutputFile &pOutput);
209 
210   void dump() const;
211 
212   // const getter
isThreadable()213   inline bool isThreadable() const
214   { return mHeader.isThreadable; }
hasDebugInformation()215   inline bool hasDebugInformation() const
216   { return mHeader.hasDebugInformation; }
getPragmas()217   inline const PragmaListTy &getPragmas() const
218   { return mPragmas; }
getObjectSlots()219   inline const ObjectSlotListTy &getObjectSlots() const
220   { return mObjectSlots; }
getExportVarNames()221   inline const ExportVarNameListTy &getExportVarNames() const
222   { return mExportVarNames; }
getExportFuncNames()223   inline const ExportFuncNameListTy &getExportFuncNames() const
224   { return mExportFuncNames; }
getExportForeachFuncs()225   inline const ExportForeachFuncListTy &getExportForeachFuncs() const
226   { return mExportForeachFuncs; }
227 
228   const char *getStringFromPool(rsinfo::StringIndexTy pStrIdx) const;
229   rsinfo::StringIndexTy getStringIdxInPool(const char *pStr) const;
230 
231   // setter
232   inline void setThreadable(bool pThreadable = true)
233   { mHeader.isThreadable = pThreadable; }
234 
235 public:
236   enum FloatPrecision {
237     FP_Full,
238     FP_Relaxed,
239   };
240 
241   // Return the minimal floating point precision required for the associated
242   // script.
243   FloatPrecision getFloatPrecisionRequirement() const;
244 };
245 
246 // Returns the arguments concatenated into one string.
247 std::string getCommandLine(int argc, const char* const* argv);
248 
249 } // end namespace bcc
250 
251 #endif  // BCC_RS_INFO_H
252