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 31namespace llvm { 32class Module; 33} 34 35namespace bcc { 36 37// Forward declarations 38class FileBase; 39class InputFile; 40class OutputFile; 41class Source; 42class RSScript; 43 44typedef llvm::Module* (*RSLinkRuntimeCallback) (bcc::RSScript *, llvm::Module *, llvm::Module *); 45 46namespace 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 54struct __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 63typedef uint32_t StringIndexTy; 64 65/* RS info file header */ 66struct __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. 95const StringIndexTy gInvalidStringIndex = static_cast<StringIndexTy>(-1); 96 97struct __attribute__((packed)) PragmaItem { 98 // Pragma is a key-value pair. 99 StringIndexTy key; 100 StringIndexTy value; 101}; 102 103struct __attribute__((packed)) ObjectSlotItem { 104 uint32_t slot; 105}; 106 107struct __attribute__((packed)) ExportVarNameItem { 108 StringIndexTy name; 109}; 110 111struct __attribute__((packed)) ExportFuncNameItem { 112 StringIndexTy name; 113}; 114 115struct __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. 122template<typename Item> 123inline const char *GetItemTypeName(); 124 125template<> 126inline const char *GetItemTypeName<PragmaItem>() 127{ return "rs pragma"; } 128 129template<> 130inline const char *GetItemTypeName<ObjectSlotItem>() 131{ return "rs object slot"; } 132 133template<> 134inline const char *GetItemTypeName<ExportVarNameItem>() 135{ return "rs export var"; } 136 137template<> 138inline const char *GetItemTypeName<ExportFuncNameItem>() 139{ return "rs export func"; } 140 141template<> 142inline const char *GetItemTypeName<ExportForeachFuncItem>() 143{ return "rs export foreach"; } 144 145} // end namespace rsinfo 146 147class RSInfo { 148public: 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 157public: 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 167private: 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 195public: 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 213 inline bool isThreadable() const 214 { return mHeader.isThreadable; } 215 inline bool hasDebugInformation() const 216 { return mHeader.hasDebugInformation; } 217 inline const PragmaListTy &getPragmas() const 218 { return mPragmas; } 219 inline const ObjectSlotListTy &getObjectSlots() const 220 { return mObjectSlots; } 221 inline const ExportVarNameListTy &getExportVarNames() const 222 { return mExportVarNames; } 223 inline const ExportFuncNameListTy &getExportFuncNames() const 224 { return mExportFuncNames; } 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 235public: 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. 247std::string getCommandLine(int argc, const char* const* argv); 248 249} // end namespace bcc 250 251#endif // BCC_RS_INFO_H 252