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