1 /* 2 * Copyright 2010, 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 #include "SourceInfo.h" 18 19 #if USE_CACHE 20 #if USE_OLD_JIT 21 #include "OldJIT/CacheReader.h" 22 #include "OldJIT/CacheWriter.h" 23 #endif 24 #if USE_MCJIT 25 #include "MCCacheWriter.h" 26 #include "MCCacheReader.h" 27 #endif 28 #endif 29 30 #include "DebugHelper.h" 31 #include "ScriptCompiled.h" 32 #include "Sha1Helper.h" 33 34 #include <bcc/bcc.h> 35 #include <bcc/bcc_cache.h> 36 37 #include <llvm/ADT/OwningPtr.h> 38 #include <llvm/ADT/StringRef.h> 39 #include <llvm/Support/MemoryBuffer.h> 40 #include <llvm/Support/system_error.h> 41 42 #include <stddef.h> 43 #include <string.h> 44 45 namespace bcc { 46 47 48 SourceInfo *SourceInfo::createFromBuffer(char const *resName, 49 char const *bitcode, 50 size_t bitcodeSize, 51 unsigned long flags) { 52 SourceInfo *result = new SourceInfo(); 53 54 if (!result) { 55 return NULL; 56 } 57 58 result->type = SourceKind::Buffer; 59 result->buffer.resName = resName; 60 result->buffer.bitcode = bitcode; 61 result->buffer.bitcodeSize = bitcodeSize; 62 result->flags = flags; 63 64 #if USE_CACHE 65 if (!resName && !(flags & BCC_SKIP_DEP_SHA1)) { 66 result->flags |= BCC_SKIP_DEP_SHA1; 67 68 LOGW("It is required to give resName for sha1 dependency check.\n"); 69 LOGW("Sha1sum dependency check will be skipped.\n"); 70 LOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n"); 71 } 72 73 if (result->flags & BCC_SKIP_DEP_SHA1) { 74 memset(result->sha1, '\0', 20); 75 } else { 76 calcSHA1(result->sha1, bitcode, bitcodeSize); 77 } 78 #endif 79 80 return result; 81 } 82 83 84 SourceInfo *SourceInfo::createFromFile(char const *path, 85 unsigned long flags) { 86 SourceInfo *result = new SourceInfo(); 87 88 if (!result) { 89 return NULL; 90 } 91 92 result->type = SourceKind::File; 93 result->file.path = path; 94 result->flags = flags; 95 96 #if USE_CACHE 97 memset(result->sha1, '\0', 20); 98 99 if (!(result->flags & BCC_SKIP_DEP_SHA1)) { 100 calcFileSHA1(result->sha1, path); 101 } 102 #endif 103 104 return result; 105 } 106 107 108 SourceInfo *SourceInfo::createFromModule(llvm::Module *module, 109 unsigned long flags) { 110 SourceInfo *result = new SourceInfo(); 111 112 if (!result) { 113 return NULL; 114 } 115 116 result->type = SourceKind::Module; 117 result->module.reset(module); 118 result->flags = flags; 119 120 #if USE_CACHE 121 if (! (flags & BCC_SKIP_DEP_SHA1)) { 122 result->flags |= BCC_SKIP_DEP_SHA1; 123 124 LOGW("Unable to calculate sha1sum for llvm::Module.\n"); 125 LOGW("Sha1sum dependency check will be skipped.\n"); 126 LOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n"); 127 } 128 129 memset(result->sha1, '\0', 20); 130 #endif 131 132 return result; 133 } 134 135 136 int SourceInfo::prepareModule(ScriptCompiled *SC) { 137 switch (type) { 138 case SourceKind::Buffer: 139 { 140 llvm::OwningPtr<llvm::MemoryBuffer> MEM( 141 llvm::MemoryBuffer::getMemBuffer( 142 llvm::StringRef(buffer.bitcode, buffer.bitcodeSize))); 143 144 if (!MEM.get()) { 145 LOGE("Unable to MemoryBuffer::getMemBuffer(addr=%p, size=%lu)\n", 146 buffer.bitcode, (unsigned long)buffer.bitcodeSize); 147 return 1; 148 } 149 150 module.reset(SC->parseBitcodeFile(MEM.get())); 151 } 152 break; 153 154 case SourceKind::File: 155 { 156 llvm::OwningPtr<llvm::MemoryBuffer> MEM; 157 158 if (llvm::error_code ec = llvm::MemoryBuffer::getFile(file.path, MEM)) { 159 LOGE("Unable to MemoryBuffer::getFile(path=%s)\n", file.path); 160 return 1; 161 } 162 163 module.reset(SC->parseBitcodeFile(MEM.get())); 164 } 165 break; 166 167 default: 168 break; 169 } 170 171 return (module.get()) ? 0 : 1; 172 } 173 174 175 #if USE_CACHE 176 template <typename T> void SourceInfo::introDependency(T &checker) { 177 if (flags & BCC_SKIP_DEP_SHA1) { 178 return; 179 } 180 181 switch (type) { 182 case SourceKind::Buffer: 183 checker.addDependency(BCC_APK_RESOURCE, buffer.resName, sha1); 184 break; 185 186 case SourceKind::File: 187 checker.addDependency(BCC_FILE_RESOURCE, file.path, sha1); 188 break; 189 190 default: 191 break; 192 } 193 } 194 195 #if USE_OLD_JIT 196 template void SourceInfo::introDependency<CacheReader>(CacheReader &); 197 template void SourceInfo::introDependency<CacheWriter>(CacheWriter &); 198 #endif 199 200 #if USE_MCJIT 201 template void SourceInfo::introDependency<MCCacheWriter>(MCCacheWriter &); 202 template void SourceInfo::introDependency<MCCacheReader>(MCCacheReader &); 203 #endif 204 #endif // USE_CACHE 205 206 207 } // namespace bcc 208