• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
createFromBuffer(char const * resName,char const * bitcode,size_t bitcodeSize,unsigned long flags)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 
createFromFile(char const * path,unsigned long flags)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 
createFromModule(llvm::Module * module,unsigned long flags)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 
prepareModule(ScriptCompiled * SC)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
introDependency(T & checker)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