blob: 54775142981e7ef731a93c005b8b64f16db41714 [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
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -070019#include "MCCacheWriter.h"
20#include "MCCacheReader.h"
Logan474cbd22011-01-31 01:47:44 +080021
Logan4dcd6792011-02-28 05:12:00 +080022#include "DebugHelper.h"
Logan474cbd22011-01-31 01:47:44 +080023#include "ScriptCompiled.h"
24#include "Sha1Helper.h"
25
26#include <bcc/bcc.h>
Logan474cbd22011-01-31 01:47:44 +080027
Zonr Changdf3fee42012-01-10 15:58:36 +080028#include <llvm/Bitcode/ReaderWriter.h>
29#include <llvm/Module.h>
Logan474cbd22011-01-31 01:47:44 +080030#include <llvm/ADT/OwningPtr.h>
31#include <llvm/ADT/StringRef.h>
32#include <llvm/Support/MemoryBuffer.h>
Logan Chienc4ea07f2011-03-09 17:27:50 +080033#include <llvm/Support/system_error.h>
Logan474cbd22011-01-31 01:47:44 +080034
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
Logan474cbd22011-01-31 01:47:44 +080057 if (!resName && !(flags & BCC_SKIP_DEP_SHA1)) {
58 result->flags |= BCC_SKIP_DEP_SHA1;
59
Steve Block10c51452012-01-05 23:23:07 +000060 ALOGW("It is required to give resName for sha1 dependency check.\n");
61 ALOGW("Sha1sum dependency check will be skipped.\n");
62 ALOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
Logan474cbd22011-01-31 01:47:44 +080063 }
64
65 if (result->flags & BCC_SKIP_DEP_SHA1) {
66 memset(result->sha1, '\0', 20);
67 } else {
68 calcSHA1(result->sha1, bitcode, bitcodeSize);
69 }
Logan474cbd22011-01-31 01:47:44 +080070
71 return result;
72}
73
74
75SourceInfo *SourceInfo::createFromFile(char const *path,
76 unsigned long flags) {
77 SourceInfo *result = new SourceInfo();
78
79 if (!result) {
80 return NULL;
81 }
82
83 result->type = SourceKind::File;
84 result->file.path = path;
85 result->flags = flags;
86
Logan474cbd22011-01-31 01:47:44 +080087 memset(result->sha1, '\0', 20);
88
89 if (!(result->flags & BCC_SKIP_DEP_SHA1)) {
90 calcFileSHA1(result->sha1, path);
91 }
Logan474cbd22011-01-31 01:47:44 +080092
93 return result;
94}
95
96
97SourceInfo *SourceInfo::createFromModule(llvm::Module *module,
98 unsigned long flags) {
99 SourceInfo *result = new SourceInfo();
100
101 if (!result) {
102 return NULL;
103 }
104
105 result->type = SourceKind::Module;
Zonr Changdf3fee42012-01-10 15:58:36 +0800106 result->module = module;
Logan474cbd22011-01-31 01:47:44 +0800107 result->flags = flags;
108
Logan474cbd22011-01-31 01:47:44 +0800109 if (! (flags & BCC_SKIP_DEP_SHA1)) {
110 result->flags |= BCC_SKIP_DEP_SHA1;
111
Steve Block10c51452012-01-05 23:23:07 +0000112 ALOGW("Unable to calculate sha1sum for llvm::Module.\n");
113 ALOGW("Sha1sum dependency check will be skipped.\n");
114 ALOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
Logan474cbd22011-01-31 01:47:44 +0800115 }
116
117 memset(result->sha1, '\0', 20);
Logan474cbd22011-01-31 01:47:44 +0800118
119 return result;
120}
121
122
Zonr Changc09dee62012-04-12 17:15:30 +0800123int SourceInfo::prepareModule(llvm::LLVMContext &context) {
Zonr Changdf3fee42012-01-10 15:58:36 +0800124 if (module)
125 return 0;
126
127 llvm::OwningPtr<llvm::MemoryBuffer> mem;
128 std::string errmsg;
129
Logan474cbd22011-01-31 01:47:44 +0800130 switch (type) {
131 case SourceKind::Buffer:
132 {
Zonr Changdf3fee42012-01-10 15:58:36 +0800133 mem.reset(llvm::MemoryBuffer::getMemBuffer(
Logan474cbd22011-01-31 01:47:44 +0800134 llvm::StringRef(buffer.bitcode, buffer.bitcodeSize)));
135
Zonr Changdf3fee42012-01-10 15:58:36 +0800136 if (!mem.get()) {
Steve Block10c14122012-01-08 10:15:06 +0000137 ALOGE("Unable to MemoryBuffer::getMemBuffer(addr=%p, size=%lu)\n",
Zonr Changdf3fee42012-01-10 15:58:36 +0800138 buffer.bitcode, (unsigned long)buffer.bitcodeSize);
Logan474cbd22011-01-31 01:47:44 +0800139 return 1;
140 }
Logan474cbd22011-01-31 01:47:44 +0800141 }
142 break;
143
144 case SourceKind::File:
145 {
Zonr Changdf3fee42012-01-10 15:58:36 +0800146 if (llvm::error_code ec = llvm::MemoryBuffer::getFile(file.path, mem)) {
147 ALOGE("Unable to MemoryBuffer::getFile(path=%s, %s)\n",
148 file.path, ec.message().c_str());
Logan474cbd22011-01-31 01:47:44 +0800149 return 1;
150 }
Logan474cbd22011-01-31 01:47:44 +0800151 }
152 break;
153
154 default:
Zonr Changdf3fee42012-01-10 15:58:36 +0800155 return 0;
Logan474cbd22011-01-31 01:47:44 +0800156 break;
157 }
158
Zonr Changc09dee62012-04-12 17:15:30 +0800159 module = llvm::ParseBitcodeFile(mem.get(), context, &errmsg);
Zonr Changdf3fee42012-01-10 15:58:36 +0800160 if (module == NULL) {
161 ALOGE("Unable to ParseBitcodeFile: %s\n", errmsg.c_str());
Zonr Changdf3fee42012-01-10 15:58:36 +0800162 }
163
164 return (module == NULL);
Logan474cbd22011-01-31 01:47:44 +0800165}
166
Zonr Changdf3fee42012-01-10 15:58:36 +0800167SourceInfo::~SourceInfo() {
Zonr Changc09dee62012-04-12 17:15:30 +0800168 delete module;
Zonr Changdf3fee42012-01-10 15:58:36 +0800169}
Logan474cbd22011-01-31 01:47:44 +0800170
Logan474cbd22011-01-31 01:47:44 +0800171template <typename T> void SourceInfo::introDependency(T &checker) {
172 if (flags & BCC_SKIP_DEP_SHA1) {
173 return;
174 }
175
176 switch (type) {
177 case SourceKind::Buffer:
178 checker.addDependency(BCC_APK_RESOURCE, buffer.resName, sha1);
179 break;
180
181 case SourceKind::File:
182 checker.addDependency(BCC_FILE_RESOURCE, file.path, sha1);
183 break;
184
185 default:
186 break;
187 }
188}
189
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700190template void SourceInfo::introDependency<MCCacheWriter>(MCCacheWriter &);
191template void SourceInfo::introDependency<MCCacheReader>(MCCacheReader &);
Logan474cbd22011-01-31 01:47:44 +0800192
193
194} // namespace bcc