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 235 inline bool isThreadable() const 236 { return mHeader.isThreadable; } 237 inline bool hasDebugInformation() const 238 { return mHeader.hasDebugInformation; } 239 inline const DependencyTableTy &getDependencyTable() const 240 { return mDependencyTable; } 241 inline const PragmaListTy &getPragmas() const 242 { return mPragmas; } 243 inline const ObjectSlotListTy &getObjectSlots() const 244 { return mObjectSlots; } 245 inline const ExportVarNameListTy &getExportVarNames() const 246 { return mExportVarNames; } 247 inline const ExportFuncNameListTy &getExportFuncNames() const 248 { return mExportFuncNames; } 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