blob: 9c49fcc7923b9773e40f658ca57938e66a20421d [file] [log] [blame]
Logan474cbd22011-01-31 01:47:44 +08001/*
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
Logan474cbd22011-01-31 01:47:44 +080017#include "SourceInfo.h"
18
19#if USE_CACHE
Logan Chiend2a5f302011-07-19 20:32:25 +080020#if USE_OLD_JIT
21#include "OldJIT/CacheReader.h"
22#include "OldJIT/CacheWriter.h"
23#endif
24#if USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -070025#include "MCCacheWriter.h"
26#include "MCCacheReader.h"
Logan474cbd22011-01-31 01:47:44 +080027#endif
Logan Chiend2a5f302011-07-19 20:32:25 +080028#endif
Logan474cbd22011-01-31 01:47:44 +080029
Logan4dcd6792011-02-28 05:12:00 +080030#include "DebugHelper.h"
Logan474cbd22011-01-31 01:47:44 +080031#include "ScriptCompiled.h"
32#include "Sha1Helper.h"
33
34#include <bcc/bcc.h>
35#include <bcc/bcc_cache.h>
36
Zonr Changdf3fee42012-01-10 15:58:36 +080037#include <llvm/Bitcode/ReaderWriter.h>
38#include <llvm/Module.h>
39#include <llvm/LLVMContext.h>
Logan474cbd22011-01-31 01:47:44 +080040#include <llvm/ADT/OwningPtr.h>
41#include <llvm/ADT/StringRef.h>
42#include <llvm/Support/MemoryBuffer.h>
Logan Chienc4ea07f2011-03-09 17:27:50 +080043#include <llvm/Support/system_error.h>
Logan474cbd22011-01-31 01:47:44 +080044
45#include <stddef.h>
46#include <string.h>
47
48namespace bcc {
49
50
51SourceInfo *SourceInfo::createFromBuffer(char const *resName,
52 char const *bitcode,
53 size_t bitcodeSize,
54 unsigned long flags) {
55 SourceInfo *result = new SourceInfo();
56
57 if (!result) {
58 return NULL;
59 }
60
61 result->type = SourceKind::Buffer;
62 result->buffer.resName = resName;
63 result->buffer.bitcode = bitcode;
64 result->buffer.bitcodeSize = bitcodeSize;
65 result->flags = flags;
66
67#if USE_CACHE
68 if (!resName && !(flags & BCC_SKIP_DEP_SHA1)) {
69 result->flags |= BCC_SKIP_DEP_SHA1;
70
Steve Block10c51452012-01-05 23:23:07 +000071 ALOGW("It is required to give resName for sha1 dependency check.\n");
72 ALOGW("Sha1sum dependency check will be skipped.\n");
73 ALOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
Logan474cbd22011-01-31 01:47:44 +080074 }
75
76 if (result->flags & BCC_SKIP_DEP_SHA1) {
77 memset(result->sha1, '\0', 20);
78 } else {
79 calcSHA1(result->sha1, bitcode, bitcodeSize);
80 }
81#endif
82
83 return result;
84}
85
86
87SourceInfo *SourceInfo::createFromFile(char const *path,
88 unsigned long flags) {
89 SourceInfo *result = new SourceInfo();
90
91 if (!result) {
92 return NULL;
93 }
94
95 result->type = SourceKind::File;
96 result->file.path = path;
97 result->flags = flags;
98
99#if USE_CACHE
100 memset(result->sha1, '\0', 20);
101
102 if (!(result->flags & BCC_SKIP_DEP_SHA1)) {
103 calcFileSHA1(result->sha1, path);
104 }
105#endif
106
107 return result;
108}
109
110
111SourceInfo *SourceInfo::createFromModule(llvm::Module *module,
112 unsigned long flags) {
113 SourceInfo *result = new SourceInfo();
114
115 if (!result) {
116 return NULL;
117 }
118
119 result->type = SourceKind::Module;
Zonr Changdf3fee42012-01-10 15:58:36 +0800120 result->module = module;
Logan474cbd22011-01-31 01:47:44 +0800121 result->flags = flags;
122
123#if USE_CACHE
124 if (! (flags & BCC_SKIP_DEP_SHA1)) {
125 result->flags |= BCC_SKIP_DEP_SHA1;
126
Steve Block10c51452012-01-05 23:23:07 +0000127 ALOGW("Unable to calculate sha1sum for llvm::Module.\n");
128 ALOGW("Sha1sum dependency check will be skipped.\n");
129 ALOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
Logan474cbd22011-01-31 01:47:44 +0800130 }
131
132 memset(result->sha1, '\0', 20);
133#endif
134
135 return result;
136}
137
138
Zonr Changdf3fee42012-01-10 15:58:36 +0800139int SourceInfo::prepareModule(llvm::LLVMContext *context) {
140 if (module)
141 return 0;
142
143 llvm::OwningPtr<llvm::MemoryBuffer> mem;
144 std::string errmsg;
145
Logan474cbd22011-01-31 01:47:44 +0800146 switch (type) {
147 case SourceKind::Buffer:
148 {
Zonr Changdf3fee42012-01-10 15:58:36 +0800149 mem.reset(llvm::MemoryBuffer::getMemBuffer(
Logan474cbd22011-01-31 01:47:44 +0800150 llvm::StringRef(buffer.bitcode, buffer.bitcodeSize)));
151
Zonr Changdf3fee42012-01-10 15:58:36 +0800152 if (!mem.get()) {
Steve Block10c14122012-01-08 10:15:06 +0000153 ALOGE("Unable to MemoryBuffer::getMemBuffer(addr=%p, size=%lu)\n",
Zonr Changdf3fee42012-01-10 15:58:36 +0800154 buffer.bitcode, (unsigned long)buffer.bitcodeSize);
Logan474cbd22011-01-31 01:47:44 +0800155 return 1;
156 }
Logan474cbd22011-01-31 01:47:44 +0800157 }
158 break;
159
160 case SourceKind::File:
161 {
Zonr Changdf3fee42012-01-10 15:58:36 +0800162 if (llvm::error_code ec = llvm::MemoryBuffer::getFile(file.path, mem)) {
163 ALOGE("Unable to MemoryBuffer::getFile(path=%s, %s)\n",
164 file.path, ec.message().c_str());
Logan474cbd22011-01-31 01:47:44 +0800165 return 1;
166 }
Logan474cbd22011-01-31 01:47:44 +0800167 }
168 break;
169
170 default:
Zonr Changdf3fee42012-01-10 15:58:36 +0800171 return 0;
Logan474cbd22011-01-31 01:47:44 +0800172 break;
173 }
174
Zonr Changdf3fee42012-01-10 15:58:36 +0800175 if (context)
176 shared_context = true;
177 else
178 context = new llvm::LLVMContext();
179
180 module = llvm::ParseBitcodeFile(mem.get(), *context, &errmsg);
181 if (module == NULL) {
182 ALOGE("Unable to ParseBitcodeFile: %s\n", errmsg.c_str());
183 if (!shared_context)
184 delete context;
185 }
186
187 return (module == NULL);
Logan474cbd22011-01-31 01:47:44 +0800188}
189
Zonr Changdf3fee42012-01-10 15:58:36 +0800190SourceInfo::~SourceInfo() {
191 llvm::LLVMContext *context = &module->getContext();
192 delete module;
193 if (!shared_context)
194 delete context;
195}
Logan474cbd22011-01-31 01:47:44 +0800196
197#if USE_CACHE
198template <typename T> void SourceInfo::introDependency(T &checker) {
199 if (flags & BCC_SKIP_DEP_SHA1) {
200 return;
201 }
202
203 switch (type) {
204 case SourceKind::Buffer:
205 checker.addDependency(BCC_APK_RESOURCE, buffer.resName, sha1);
206 break;
207
208 case SourceKind::File:
209 checker.addDependency(BCC_FILE_RESOURCE, file.path, sha1);
210 break;
211
212 default:
213 break;
214 }
215}
216
Logan Chiend2a5f302011-07-19 20:32:25 +0800217#if USE_OLD_JIT
Logan474cbd22011-01-31 01:47:44 +0800218template void SourceInfo::introDependency<CacheReader>(CacheReader &);
219template void SourceInfo::introDependency<CacheWriter>(CacheWriter &);
Logan Chiend2a5f302011-07-19 20:32:25 +0800220#endif
221
222#if USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700223template void SourceInfo::introDependency<MCCacheWriter>(MCCacheWriter &);
224template void SourceInfo::introDependency<MCCacheReader>(MCCacheReader &);
Logan Chiend2a5f302011-07-19 20:32:25 +0800225#endif
Logan474cbd22011-01-31 01:47:44 +0800226#endif // USE_CACHE
227
228
229} // namespace bcc