1ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines/*
2ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines * Copyright 2010, The Android Open Source Project
3ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines *
4ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
5ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines * you may not use this file except in compliance with the License.
6ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines * You may obtain a copy of the License at
7ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines *
8ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
9ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines *
10ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines * Unless required by applicable law or agreed to in writing, software
11ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
12ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines * See the License for the specific language governing permissions and
14ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines * limitations under the License.
15ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines */
16ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
17ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include "SourceInfo.h"
18ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
19ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include "MCCacheWriter.h"
20ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include "MCCacheReader.h"
21ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
22ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include "DebugHelper.h"
23ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include "ScriptCompiled.h"
24ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include "Sha1Helper.h"
25ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
26ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include <bcc/bcc.h>
27ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
28ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include <llvm/Bitcode/ReaderWriter.h>
29ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include <llvm/Module.h>
30274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines#include <llvm/LLVMContext.h>
31ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include <llvm/ADT/OwningPtr.h>
32ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include <llvm/ADT/StringRef.h>
33ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include <llvm/Support/MemoryBuffer.h>
34ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include <llvm/Support/system_error.h>
35ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
36ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include <stddef.h>
37ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines#include <string.h>
38ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
39ead5ccba05af33df1a061b39847a9be137c00143Stephen Hinesnamespace bcc {
40ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
41ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
42ead5ccba05af33df1a061b39847a9be137c00143Stephen HinesSourceInfo *SourceInfo::createFromBuffer(char const *resName,
43ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines                                         char const *bitcode,
44ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines                                         size_t bitcodeSize,
45ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines                                         unsigned long flags) {
46ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  SourceInfo *result = new SourceInfo();
47ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
48ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  if (!result) {
49ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    return NULL;
50ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  }
51ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
52ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  result->type = SourceKind::Buffer;
53ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  result->buffer.resName = resName;
54ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  result->buffer.bitcode = bitcode;
55ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  result->buffer.bitcodeSize = bitcodeSize;
56ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  result->flags = flags;
57ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
58ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  if (!resName && !(flags & BCC_SKIP_DEP_SHA1)) {
59ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    result->flags |= BCC_SKIP_DEP_SHA1;
60ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
61ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    ALOGW("It is required to give resName for sha1 dependency check.\n");
62ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    ALOGW("Sha1sum dependency check will be skipped.\n");
63ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    ALOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
64ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  }
65ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
66ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  if (result->flags & BCC_SKIP_DEP_SHA1) {
67ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    memset(result->sha1, '\0', 20);
68ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  } else {
69ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    calcSHA1(result->sha1, bitcode, bitcodeSize);
70ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  }
71ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
72ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  return result;
73ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines}
74ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
75ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
76ead5ccba05af33df1a061b39847a9be137c00143Stephen HinesSourceInfo *SourceInfo::createFromFile(char const *path,
77ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines                                       unsigned long flags) {
78ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  SourceInfo *result = new SourceInfo();
79ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
80ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  if (!result) {
81ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    return NULL;
82ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  }
83ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
84ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  result->type = SourceKind::File;
85ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  result->file.path = path;
86ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  result->flags = flags;
87ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
88ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  memset(result->sha1, '\0', 20);
89ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
90ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  if (!(result->flags & BCC_SKIP_DEP_SHA1)) {
91ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    calcFileSHA1(result->sha1, path);
92ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  }
93ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
94ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  return result;
95ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines}
96ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
97ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
98ead5ccba05af33df1a061b39847a9be137c00143Stephen HinesSourceInfo *SourceInfo::createFromModule(llvm::Module *module,
99ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines                                         unsigned long flags) {
100ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  SourceInfo *result = new SourceInfo();
101ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
102ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  if (!result) {
103ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    return NULL;
104ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  }
105ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
106ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  result->type = SourceKind::Module;
107ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  result->module = module;
108ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  result->flags = flags;
109ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
110ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  if (! (flags & BCC_SKIP_DEP_SHA1)) {
111ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    result->flags |= BCC_SKIP_DEP_SHA1;
112ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
113ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    ALOGW("Unable to calculate sha1sum for llvm::Module.\n");
114ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    ALOGW("Sha1sum dependency check will be skipped.\n");
115ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    ALOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
116ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  }
117ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
118ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  memset(result->sha1, '\0', 20);
119ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
120ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  return result;
121ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines}
122ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
123ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
124274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hinesint SourceInfo::prepareModule(llvm::LLVMContext *context) {
125ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  if (module)
126ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    return 0;
127ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
128ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  llvm::OwningPtr<llvm::MemoryBuffer> mem;
129ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  std::string errmsg;
130ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
131ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  switch (type) {
132ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  case SourceKind::Buffer:
133ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    {
134ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines      mem.reset(llvm::MemoryBuffer::getMemBuffer(
135e708ffe612f4566bea20334d2c9dac34db508e6eStephen Hines          llvm::StringRef(buffer.bitcode, buffer.bitcodeSize), "", false));
136ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
137ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines      if (!mem.get()) {
138ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines        ALOGE("Unable to MemoryBuffer::getMemBuffer(addr=%p, size=%lu)\n",
139ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines              buffer.bitcode, (unsigned long)buffer.bitcodeSize);
140ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines        return 1;
141ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines      }
142ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    }
143ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    break;
144ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
145ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  case SourceKind::File:
146ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    {
147ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines      if (llvm::error_code ec = llvm::MemoryBuffer::getFile(file.path, mem)) {
148ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines        ALOGE("Unable to MemoryBuffer::getFile(path=%s, %s)\n",
149ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines              file.path, ec.message().c_str());
150ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines        return 1;
151ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines      }
152ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    }
153ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    break;
154ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
155ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  default:
156ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    return 0;
157ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    break;
158ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  }
159ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
160274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines  if (context)
161274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines    shared_context = true;
162274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines  else
163274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines    context = new llvm::LLVMContext();
164274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines
165274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines  module = llvm::ParseBitcodeFile(mem.get(), *context, &errmsg);
166ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  if (module == NULL) {
167ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    ALOGE("Unable to ParseBitcodeFile: %s\n", errmsg.c_str());
168274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines    if (!shared_context)
169274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines      delete context;
170ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  }
171ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
172ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  return (module == NULL);
173ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines}
174ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
175ead5ccba05af33df1a061b39847a9be137c00143Stephen HinesSourceInfo::~SourceInfo() {
176274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines  if (module != NULL) {
177274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines    llvm::LLVMContext *context = &module->getContext();
178274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines    delete module;
179274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines    if (!shared_context)
180274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines      delete context;
181274926b0bcde562d51cbcf401a6f4a20cc2ddd70Stephen Hines  }
182ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines}
183ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
184ead5ccba05af33df1a061b39847a9be137c00143Stephen Hinestemplate <typename T> void SourceInfo::introDependency(T &checker) {
185ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  if (flags & BCC_SKIP_DEP_SHA1) {
186ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    return;
187ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  }
188ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
189ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  switch (type) {
190ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  case SourceKind::Buffer:
191ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    checker.addDependency(BCC_APK_RESOURCE, buffer.resName, sha1);
192ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    break;
193ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
194ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  case SourceKind::File:
195ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    checker.addDependency(BCC_FILE_RESOURCE, file.path, sha1);
196ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    break;
197ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
198ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  default:
199ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines    break;
200ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines  }
201ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines}
202ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
203ead5ccba05af33df1a061b39847a9be137c00143Stephen Hinestemplate void SourceInfo::introDependency<MCCacheWriter>(MCCacheWriter &);
204ead5ccba05af33df1a061b39847a9be137c00143Stephen Hinestemplate void SourceInfo::introDependency<MCCacheReader>(MCCacheReader &);
205ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
206ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines
207ead5ccba05af33df1a061b39847a9be137c00143Stephen Hines} // namespace bcc
208