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