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